p2m: use defines for page sizes rather hardcoding them
PATCH 1/4 p2m: use defines for page sizes rather hardcoding them
Contains pieces I missed in previous patch. Sorry.
Signature · 6 lines
---to satisfy European Law for business letters: Advanced Micro Devices GmbH Einsteinring 24, 85689 Dornach b. Muenchen Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632
use defines for page sizes rather hardcoding them.
xen/arch/x86/mm/p2m.c +3 -3
@@ -881,7 +881,7 @@ void p2m_mem_access_check(unsigned longif ( access_w && p2ma == p2m_access_rx2rw ) { - p2m->set_entry (p2m, gfn, mfn,0 , p2mt, p2m_access_rw); + p2m->set_entry (p2m, gfn, mfn,PAGE_ORDER_4K , p2mt, p2m_access_rw);p2m_unlock (p2m);return ; }
@@ -904,7 +904,7 @@ void p2m_mem_access_check(unsigned long {/* A listener is not required, so clear the access restrictions */ p2m_lock (p2m); - p2m->set_entry (p2m, gfn, mfn,0 , p2mt, p2m_access_rwx); + p2m->set_entry (p2m, gfn, mfn,PAGE_ORDER_4K , p2mt, p2m_access_rwx);p2m_unlock (p2m); }
@@ -996,7 +996,7 @@ int p2m_set_mem_access(struct domain *d,for ( pfn = start_pfn; pfn < start_pfn + nr; pfn++ ) { mfn =gfn_to_mfn_query (d, pfn, &t); -if ( p2m->set_entry (p2m, pfn, mfn,0 , t, a) ==0 ) +if ( p2m->set_entry (p2m, pfn, mfn,PAGE_ORDER_4K , t, a) ==0 ) { rc = -ENOMEM ;break ;
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
Tim Deegan
AppliedContent-Description: xen_superpage1.diff
Quoted 3 lines
use defines for page sizes rather hardcoding them.
Signed-off-by Christoph Egger <[email protected]>
Applied, thanks.
Tim.
Signature · 3 lines
Tim Deegan <[email protected]> Principal Software Engineer, Xen Platform Team Citrix Systems UK Ltd. (Company #02937203, SL9 0BG)
Quoted 6 lines · Tim Deegan
Content-Description: xen_superpage1.diff
Quoted 3 lines
use defines for page sizes rather hardcoding them.
Signed-off-by Christoph Egger <[email protected]>Applied, thanks.
The rest of this series looks OK in principle but I haven't time to look at the detail today (and I'm wondering whether there's a way of doing it without adding yet another argument to the p2m interfaces, but I suspect
not). I'll get to it as soon as I can.
Tim.
Quoted 4 lines · Tim Deegan
Quoted 3 lines · Tim Deegan
Content-Description: xen_superpage1.diff
Quoted 2 lines
use defines for page sizes rather hardcoding them.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Christoph Egger <[email protected]>Applied, thanks.
The rest of this series looks OK in principle but I haven't time to look at the detail today (and I'm wondering whether there's a way of doing it without adding yet another argument to the p2m interfaces, but I suspect
not). I'll get to it as soon as I can.
I've had a look and the mechanism is good, but the patches are not quite ready. Patch #2 touches too much of the p2m interfaces with the new page-order argument -- there are functions in it that now have a new argument that's _never_ called except with NULL.
Patches #4 and #5 have a lot of churn in and around spage_* for what's basically a mask operation on an MFN. I don't think any of it is necessary. Also, please don't send patches that contain things like:
+/* XXX: defines should be moved to a proper header */
It might make me think you didn't re-read them before posting. :)
I think they really just need trimmed back a bit before they go in. I'll have some time on Wednesday, so I might just do that then.
Cheers,
Tim.
Quoted 2 lines · Tim Deegan
I think they really just need trimmed back a bit before they go in. I'll have some time on Wednesday, so I might just do that then.
OK, I've cut them back to just the bits that are needed by the new callers. I ended up shuffling the code around as well, so could you please test that the attached series works for you?
Cheers,
Tim.
x86/mm: adjust p2m interface to return superpage sizes
xen/arch/x86/hvm/hvm.c +1 -1
@@ -1216,7 +1216,7 @@ int hvm_hap_nested_page_fault(unsigned l } p2m =p2m_get_hostp2m (v->domain); - mfn =gfn_to_mfn_type_p2m (p2m, gfn, &p2mt, &p2ma, p2m_guest); + mfn =gfn_to_mfn_type_p2m (p2m, gfn, &p2mt, &p2ma, p2m_guest,NULL );/* Check access permissions first, then handle faults */ if ( access_valid && (mfn_x (mfn) !=INVALID_MFN ) )
xen/arch/x86/hvm/svm/svm.c +2 -2
@@ -1160,7 +1160,7 @@ static void svm_do_nested_pgfault(struct p2m =p2m_get_p2m (v); _d.gpa = gpa; _d.qualification =0 ; - _d.mfn =mfn_x (gfn_to_mfn_type_p2m (p2m, gfn, &_d.p2mt, &p2ma, p2m_query)); + _d.mfn =mfn_x (gfn_to_mfn_type_p2m (p2m, gfn, &_d.p2mt, &p2ma, p2m_query,NULL ));__trace_var (TRC_HVM_NPF ,0 ,sizeof (_d), &_d); }
@@ -1180,7 +1180,7 @@ static void svm_do_nested_pgfault(structif ( p2m ==NULL ) p2m =p2m_get_p2m (v);/* Everything else is an error. */ - mfn =gfn_to_mfn_type_p2m (p2m, gfn, &p2mt, &p2ma, p2m_guest); + mfn =gfn_to_mfn_type_p2m (p2m, gfn, &p2mt, &p2ma, p2m_guest,NULL );gdprintk (XENLOG_ERR ,"SVM violation gpa %#" PRIpaddr", mfn %#lx, type %i\n" , gpa,mfn_x (mfn), p2mt);
xen/arch/x86/mm/guest_walk.c +1 -1
@@ -95,7 +95,7 @@ static inline void *map_domain_gfn(strucp2m_access_t a;/* Translate the gfn, unsharing if shared */ - *mfn =gfn_to_mfn_type_p2m (p2m,gfn_x (gfn), p2mt, &a, p2m_unshare); + *mfn =gfn_to_mfn_type_p2m (p2m,gfn_x (gfn), p2mt, &a, p2m_unshare,NULL );if (p2m_is_paging (*p2mt) ) {ASSERT (!p2m_is_nestedp2m (p2m));
xen/arch/x86/mm/hap/guest_walk.c +2 -2
@@ -59,7 +59,7 @@ unsigned long hap_p2m_ga_to_gfn(GUEST_PA/* Get the top-level table's MFN */ top_mfn =gfn_to_mfn_type_p2m (p2m, cr3 >>PAGE_SHIFT , - &p2mt, &p2ma, p2m_unshare); + &p2mt, &p2ma, p2m_unshare,NULL );if (p2m_is_paging (p2mt) ) {ASSERT (!p2m_is_nestedp2m (p2m));
@@ -92,7 +92,7 @@ unsigned long hap_p2m_ga_to_gfn(GUEST_PAif ( missing ==0 ) {gfn_t gfn =guest_l1e_get_gfn (gw.l1e); -gfn_to_mfn_type_p2m (p2m,gfn_x (gfn), &p2mt, &p2ma, p2m_unshare); +gfn_to_mfn_type_p2m (p2m,gfn_x (gfn), &p2mt, &p2ma, p2m_unshare,NULL );if (p2m_is_paging (p2mt) ) {ASSERT (!p2m_is_nestedp2m (p2m));
xen/arch/x86/mm/hap/nested_hap.c +2 -1
@@ -136,7 +136,8 @@ nestedhap_walk_L0_p2m(struct p2m_domainp2m_access_t p2ma;/* walk L0 P2M table */ - mfn =gfn_to_mfn_type_p2m (p2m, L1_gpa >>PAGE_SHIFT , &p2mt, &p2ma, p2m_query); + mfn =gfn_to_mfn_type_p2m (p2m, L1_gpa >>PAGE_SHIFT , &p2mt, &p2ma, + p2m_query,NULL );if (p2m_is_paging (p2mt) ||p2m_is_shared (p2mt) || !p2m_is_ram (p2mt) )return NESTEDHVM_PAGEFAULT_ERROR ;
xen/arch/x86/mm/p2m-ept.c +4 -1
@@ -509,7 +509,7 @@ out:/* Read ept p2m entries */ static mfn_t ept_get_entry (struct p2m_domain *p2m,unsigned long gfn,p2m_type_t *t,p2m_access_t * a, -p2m_query_t q) +p2m_query_t q,unsigned int *page_order) {struct domain *d = p2m->domain;ept_entry_t *table =map_domain_page (ept_get_asr (d));
@@ -596,6 +596,9 @@ static mfn_t ept_get_entry(struct p2m_do ((1 << (i * EPT_TABLE_ORDER)) - 1)); mfn =_mfn (split_mfn); } + +if ( page_order ) + *page_order = i *EPT_TABLE_ORDER ; } out:
xen/arch/x86/mm/p2m-pt.c +17 -3
@@ -503,7 +503,8 @@ static int p2m_pod_check_and_populate(st/* Read the current domain's p2m table (through the linear mapping). */ static mfn_t p2m_gfn_to_mfn_current (struct p2m_domain *p2m,unsigned long gfn,p2m_type_t *t, -p2m_access_t *a,p2m_query_t q) +p2m_access_t *a,p2m_query_t q, +unsigned int *page_order) {mfn_t mfn =_mfn (INVALID_MFN );p2m_type_t p2mt = p2m_mmio_dm;
@@ -567,6 +568,8 @@ pod_retry_l3: else p2mt = p2m_mmio_dm; +if ( page_order ) + *page_order =PAGE_ORDER_1G ; goto out; }#endif
@@ -620,6 +623,8 @@ pod_retry_l2:else p2mt = p2m_mmio_dm; +if ( page_order ) + *page_order =PAGE_ORDER_2M ; goto out; }
@@ -669,6 +674,8 @@ pod_retry_l1: p2mt = p2m_mmio_dm; } +if ( page_order ) + *page_order =PAGE_ORDER_4K ; out: *t = p2mt;return mfn;
@@ -676,7 +683,8 @@ out:static mfn_t p2m_gfn_to_mfn (struct p2m_domain *p2m,unsigned long gfn, -p2m_type_t *t,p2m_access_t *a,p2m_query_t q) +p2m_type_t *t,p2m_access_t *a,p2m_query_t q, +unsigned int *page_order) {mfn_t mfn;paddr_t addr = ((paddr_t )gfn) <<PAGE_SHIFT ;
@@ -699,7 +707,7 @@ p2m_gfn_to_mfn(struct p2m_domain *p2m, u/* Use the fast path with the linear mapping if we can */ if ( p2m ==p2m_get_hostp2m (current->domain) ) -return p2m_gfn_to_mfn_current (p2m, gfn, t, a, q); +return p2m_gfn_to_mfn_current (p2m, gfn, t, a, q, page_order); mfn =pagetable_get_mfn (p2m_get_pagetable (p2m));
@@ -753,6 +761,8 @@ pod_retry_l3:unmap_domain_page (l3e);ASSERT (mfn_valid (mfn) || !p2m_is_ram (*t)); +if ( page_order ) + *page_order =PAGE_ORDER_1G ;return (p2m_is_valid (*t)) ? mfn :_mfn (INVALID_MFN ); }
@@ -787,6 +797,8 @@ pod_retry_l2:unmap_domain_page (l2e);ASSERT (mfn_valid (mfn) || !p2m_is_ram (*t)); +if ( page_order ) + *page_order =PAGE_ORDER_2M ;return (p2m_is_valid (*t)) ? mfn :_mfn (INVALID_MFN ); }
@@ -817,6 +829,8 @@ pod_retry_l1:unmap_domain_page (l1e);ASSERT (mfn_valid (mfn) || !p2m_is_ram (*t)); +if ( page_order ) + *page_order =PAGE_ORDER_4K ;return (p2m_is_valid (*t) ||p2m_is_grant (*t)) ? mfn :_mfn (INVALID_MFN ); }
xen/arch/x86/mm/p2m.c +4 -4
@@ -307,7 +307,7 @@ void p2m_teardown(struct p2m_domain *p2m#ifdef __x86_64__for ( gfn=0 ; gfn < p2m->max_mapped_pfn; gfn++ ) { - mfn =gfn_to_mfn_type_p2m (p2m, gfn, &t, &a, p2m_query); + mfn =gfn_to_mfn_type_p2m (p2m, gfn, &t, &a, p2m_query,NULL );if (mfn_valid (mfn) && (t == p2m_ram_shared) ) {ASSERT (!p2m_is_nestedp2m (p2m));
@@ -372,7 +372,7 @@ p2m_remove_page(struct p2m_domain *p2m, {for ( i =0 ; i < (1UL << page_order); i++ ) { - mfn_return = p2m->get_entry (p2m, gfn + i, &t, &a, p2m_query); + mfn_return = p2m->get_entry (p2m, gfn + i, &t, &a, p2m_query,NULL );if ( !p2m_is_grant (t) )set_gpfn_from_mfn (mfn+i,INVALID_M2P_ENTRY );ASSERT ( !p2m_is_valid (t) || mfn + i ==mfn_x (mfn_return) );
@@ -877,7 +877,7 @@ void p2m_mem_access_check(unsigned long/* First, handle rx2rw conversion automatically */ p2m_lock (p2m); - mfn = p2m->get_entry (p2m, gfn, &p2mt, &p2ma, p2m_query); + mfn = p2m->get_entry (p2m, gfn, &p2mt, &p2ma, p2m_query,NULL );if ( access_w && p2ma == p2m_access_rx2rw ) {
@@ -1035,7 +1035,7 @@ int p2m_get_mem_access(struct domain *d,return 0 ; } - mfn = p2m->get_entry (p2m, pfn, &t, &a, p2m_query); + mfn = p2m->get_entry (p2m, pfn, &t, &a, p2m_query,NULL );if (mfn_x (mfn) ==INVALID_MFN )return -ESRCH ;
xen/include/asm-x86/p2m.h +11 -6
@@ -233,7 +233,8 @@ struct p2m_domain {unsigned long gfn, p2m_type_t *p2mt, p2m_access_t *p2ma, - p2m_query_t q); + p2m_query_t q, + unsigned int *page_order);void (*change_entry_type_global)(struct p2m_domain *p2m,p2m_type_t ot,p2m_type_t nt);
@@ -303,10 +304,14 @@ struct p2m_domain *p2m_get_p2m(struct vc/* Read a particular P2M table, mapping pages as we go. Most callers * should _not_ call this directly; use the other gfn_to_mfn_* functions * below unless you know you want to walk a p2m that isn't a domain's -* main one. */ +* main one. +* If the lookup succeeds, the return value is != INVALID_MFN and +* *page_order is filled in with the order of the superpage (if any) that +* the entry was found in. */ static inline mfn_t gfn_to_mfn_type_p2m (struct p2m_domain *p2m,unsigned long gfn, -p2m_type_t *t,p2m_access_t *a,p2m_query_t q) +p2m_type_t *t,p2m_access_t *a,p2m_query_t q, +unsigned int *page_order) {mfn_t mfn;
@@ -318,14 +323,14 @@ gfn_to_mfn_type_p2m(struct p2m_domain *preturn _mfn (gfn); } - mfn = p2m->get_entry (p2m, gfn, t, a, q); + mfn = p2m->get_entry (p2m, gfn, t, a, q, page_order);#ifdef __x86_64__if ( q == p2m_unshare &&p2m_is_shared (*t) ) {ASSERT (!p2m_is_nestedp2m (p2m));mem_sharing_unshare_page (p2m->domain, gfn,0 ); - mfn = p2m->get_entry (p2m, gfn, t, a, q); + mfn = p2m->get_entry (p2m, gfn, t, a, q, page_order); }#endif
@@ -349,7 +354,7 @@ static inline mfn_t gfn_to_mfn_type(stru p2m_query_t q) {p2m_access_t a; -return gfn_to_mfn_type_p2m (p2m_get_hostp2m (d), gfn, t, &a, q); +return gfn_to_mfn_type_p2m (p2m_get_hostp2m (d), gfn, t, &a, q,NULL ); }/* Syntactic sugar: most callers will use one of these.
x86/mm: adjust paging interface to return superpage sizes to the caller of paging_ga_to_gfn_cr3()
xen/arch/x86/mm/hap/guest_walk.c +5 -2
@@ -43,12 +43,12 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN struct vcpu *v, struct p2m_domain *p2m, unsigned long gva, uint32_t *pfec) { unsigned long cr3 = v->arch.hvm_vcpu.guest_cr[3]; -return hap_p2m_ga_to_gfn (GUEST_PAGING_LEVELS )(v, p2m, cr3, gva, pfec); +return hap_p2m_ga_to_gfn (GUEST_PAGING_LEVELS )(v, p2m, cr3, gva, pfec,NULL ); }unsigned long hap_p2m_ga_to_gfn (GUEST_PAGING_LEVELS )(struct vcpu *v,struct p2m_domain *p2m,unsigned long cr3, -paddr_t ga,uint32_t *pfec) +paddr_t ga,uint32_t *pfec,unsigned int *page_order) {uint32_t missing;mfn_t top_mfn;
@@ -107,6 +108,9 @@ unsigned long hap_p2m_ga_to_gfn(GUEST_PAreturn INVALID_GFN ; } +if ( page_order ) + *page_order =guest_walk_to_page_order (&gw); +return gfn_x (gfn); }
xen/arch/x86/mm/hap/hap.c +3 -1
@@ -897,8 +897,10 @@ static unsigned long hap_gva_to_gfn_realstatic unsigned long hap_p2m_ga_to_gfn_real_mode (struct vcpu *v,struct p2m_domain *p2m,unsigned long cr3, -paddr_t ga,uint32_t *pfec) +paddr_t ga,uint32_t *pfec,unsigned int *page_order) { +if ( page_order ) + *page_order =PAGE_ORDER_4K ;return (ga >>PAGE_SHIFT ); }
xen/arch/x86/mm/hap/nested_hap.c +1 -1
@@ -162,7 +162,7 @@ nestedhap_walk_L1_p2m(struct vcpu *v, pa nested_cr3 =nhvm_vcpu_hostcr3 (v);/* Walk the guest-supplied NPT table, just as if it were a pagetable */ - gfn =paging_ga_to_gfn_cr3 (v, nested_cr3, L2_gpa, &pfec); + gfn =paging_ga_to_gfn_cr3 (v, nested_cr3, L2_gpa, &pfec,NULL );if ( gfn ==INVALID_GFN )return NESTEDHVM_PAGEFAULT_INJECT ;
xen/arch/x86/mm/hap/private.h +3 -3
@@ -40,12 +40,12 @@ unsigned long hap_gva_to_gfn_4_levels(stunsigned long hap_p2m_ga_to_gfn_2_levels (struct vcpu *v,struct p2m_domain *p2m,unsigned long cr3, -paddr_t ga,uint32_t *pfec); +paddr_t ga,uint32_t *pfec,unsigned int *page_order);unsigned long hap_p2m_ga_to_gfn_3_levels (struct vcpu *v,struct p2m_domain *p2m,unsigned long cr3, -paddr_t ga,uint32_t *pfec); +paddr_t ga,uint32_t *pfec,unsigned int *page_order);unsigned long hap_p2m_ga_to_gfn_4_levels (struct vcpu *v,struct p2m_domain *p2m,unsigned long cr3, -paddr_t ga,uint32_t *pfec); +paddr_t ga,uint32_t *pfec,unsigned int *page_order);#endif /* __HAP_PRIVATE_H__ */
xen/arch/x86/mm/p2m.c +1 -1
@@ -1205,7 +1205,7 @@ unsigned long paging_gva_to_gfn(struct v/* translate l2 guest gfn into l1 guest gfn */ return hostmode->p2m_ga_to_gfn (v, hostp2m, ncr3, - gfn <<PAGE_SHIFT , pfec); + gfn <<PAGE_SHIFT , pfec,NULL ); }return hostmode->gva_to_gfn (v, hostp2m, va, pfec);
xen/include/asm-x86/guest_pt.h +18 -0
@@ -272,6 +272,24 @@ guest_walk_to_gpa(walk_t *gw)return guest_l1e_get_paddr (gw->l1e) + (gw->va & ~PAGE_MASK ); } +/* Given a walk_t from a successful walk, return the page-order of the +* page or superpage that the virtual address is in. */ +static inline unsigned int +guest_walk_to_page_order (walk_t *gw) +{ +/* This is only valid for successful walks - otherwise the +* PSE bits might be invalid. */ +ASSERT (guest_l1e_get_flags (gw->l1e) & _PAGE_PRESENT); +#if GUEST_PAGING_LEVELS >=3 +if (guest_l3e_get_flags (gw->l3e) & _PAGE_PSE ) +return GUEST_L3_PAGETABLE_SHIFT -PAGE_SHIFT ; +#endif +if (guest_l2e_get_flags (gw->l2e) & _PAGE_PSE ) +return GUEST_L2_PAGETABLE_SHIFT -PAGE_SHIFT ; +return GUEST_L1_PAGETABLE_SHIFT -PAGE_SHIFT ; +} + +/* Walk the guest pagetables, after the manner of a hardware walker. * * Inputs: a vcpu, a virtual address, a walk_t to fill, a
xen/include/asm-x86/paging.h +9 -5
@@ -115,7 +115,8 @@ struct paging_mode {unsigned long (*p2m_ga_to_gfn )(struct vcpu *v,struct p2m_domain *p2m,unsigned long cr3, -paddr_t ga,uint32_t *pfec); +paddr_t ga,uint32_t *pfec, +unsigned int *page_order);void (*update_cr3 )(struct vcpu *v,int do_locking);void (*update_paging_modes )(struct vcpu *v); void (*write_p2m_entry )(struct vcpu *v, unsigned long gfn,
@@ -270,15 +271,18 @@ unsigned long paging_gva_to_gfn(struct v* to by nested HAP code, to walk the guest-supplied NPT tables as if * they were pagetables. * Use 'paddr_t' for the guest address so it won't overflow when -* guest or nested guest is in 32bit PAE mode. -*/ +* l1 or l2 guest is in 32bit PAE mode. +* If the GFN returned is not INVALID_GFN, *page_order gives +* the size of the superpage (if any) it was found in. */ static inline unsigned long paging_ga_to_gfn_cr3 (struct vcpu *v,unsigned long cr3,paddr_t ga, -uint32_t *pfec) +uint32_t *pfec, +unsigned int *page_order) {struct p2m_domain *p2m = v->domain->arch.p2m; -return paging_get_hostmode (v)->p2m_ga_to_gfn (v, p2m, cr3, ga, pfec); +return paging_get_hostmode (v)->p2m_ga_to_gfn (v, p2m, cr3, ga, pfec, + page_order); }/* Update all the things that are derived from the guest's CR3.
x86/mm: use new page-order interfaces in nested HAP code to make 2M and 1G mappings in the nested p2m tables.
xen/arch/x86/mm/hap/nested_hap.c +27 -11
@@ -99,7 +99,7 @@ nestedp2m_write_p2m_entry(struct p2m_domstatic void nestedhap_fix_p2m (struct vcpu *v,struct p2m_domain *p2m,paddr_t L2_gpa,paddr_t L0_gpa, -p2m_type_t p2mt,p2m_access_t p2ma) +unsigned int page_order,p2m_type_t p2mt,p2m_access_t p2ma) {int rv =1 ;ASSERT (p2m);
@@ -111,9 +111,20 @@ nestedhap_fix_p2m(struct vcpu *v, struct* leave it alone. We'll pick up the right one as we try to * vmenter the guest. */ if ( p2m->cr3 ==nhvm_vcpu_hostcr3 (v) ) - rv =set_p2m_entry (p2m, L2_gpa >>PAGE_SHIFT , -page_to_mfn (maddr_to_page (L0_gpa)), -0 /*4K*/ , p2mt, p2ma); + { +unsigned long gfn, mask; +mfn_t mfn; + +/* If this is a superpage mapping, round down both addresses +* to the start of the superpage. */ + mask = ~((1UL << page_order) -1 ); + + gfn = (L2_gpa >>PAGE_SHIFT ) & mask; + mfn =_mfn ((L0_gpa >>PAGE_SHIFT ) & mask); + + rv =set_p2m_entry (p2m, gfn, mfn, page_order, p2mt, p2ma); + } +p2m_unlock (p2m);if (rv ==0 ) {
@@ -129,7 +140,8 @@ nestedhap_fix_p2m(struct vcpu *v, struct* value tells the upper level what to do. */ static int -nestedhap_walk_L0_p2m (struct p2m_domain *p2m,paddr_t L1_gpa,paddr_t *L0_gpa) +nestedhap_walk_L0_p2m (struct p2m_domain *p2m,paddr_t L1_gpa,paddr_t *L0_gpa, +unsigned int *page_order) {mfn_t mfn;p2m_type_t p2mt;
@@ -137,7 +149,7 @@ nestedhap_walk_L0_p2m(struct p2m_domain/* walk L0 P2M table */ mfn =gfn_to_mfn_type_p2m (p2m, L1_gpa >>PAGE_SHIFT , &p2mt, &p2ma, - p2m_query,NULL ); + p2m_query, page_order);if (p2m_is_paging (p2mt) ||p2m_is_shared (p2mt) || !p2m_is_ram (p2mt) )return NESTEDHVM_PAGEFAULT_ERROR ;
@@ -154,7 +166,8 @@ nestedhap_walk_L0_p2m(struct p2m_domain* L1_gpa. The result value tells what to do next. */ static int -nestedhap_walk_L1_p2m (struct vcpu *v,paddr_t L2_gpa,paddr_t *L1_gpa) +nestedhap_walk_L1_p2m (struct vcpu *v,paddr_t L2_gpa,paddr_t *L1_gpa, +unsigned int *page_order) {uint32_t pfec;unsigned long nested_cr3, gfn;
@@ -162,7 +175,7 @@ nestedhap_walk_L1_p2m(struct vcpu *v, pa nested_cr3 =nhvm_vcpu_hostcr3 (v);/* Walk the guest-supplied NPT table, just as if it were a pagetable */ - gfn =paging_ga_to_gfn_cr3 (v, nested_cr3, L2_gpa, &pfec,NULL ); + gfn =paging_ga_to_gfn_cr3 (v, nested_cr3, L2_gpa, &pfec, page_order);if ( gfn ==INVALID_GFN )return NESTEDHVM_PAGEFAULT_INJECT ;
@@ -183,12 +196,13 @@ nestedhvm_hap_nested_page_fault(struct vpaddr_t L1_gpa, L0_gpa;struct domain *d = v->domain;struct p2m_domain *p2m, *nested_p2m; +unsigned int page_order_21, page_order_10, page_order_20; p2m =p2m_get_hostp2m (d);/* L0 p2m */ nested_p2m =p2m_get_nestedp2m (v,nhvm_vcpu_hostcr3 (v));/* walk the L1 P2M table */ - rv =nestedhap_walk_L1_p2m (v, L2_gpa, &L1_gpa); + rv =nestedhap_walk_L1_p2m (v, L2_gpa, &L1_gpa, &page_order_21);/* let caller to handle these two cases */ switch (rv) {
@@ -204,7 +218,7 @@ nestedhvm_hap_nested_page_fault(struct v }/* ==> we have to walk L0 P2M */ - rv =nestedhap_walk_L0_p2m (p2m, L1_gpa, &L0_gpa); + rv =nestedhap_walk_L0_p2m (p2m, L1_gpa, &L0_gpa, &page_order_10);/* let upper level caller to handle these two cases */ switch (rv) {
@@ -219,8 +233,10 @@ nestedhvm_hap_nested_page_fault(struct vbreak ; } + page_order_20 =min (page_order_21, page_order_10); +/* fix p2m_get_pagetable(nested_p2m) */ -nestedhap_fix_p2m (v, nested_p2m, L2_gpa, L0_gpa, +nestedhap_fix_p2m (v, nested_p2m, L2_gpa, L0_gpa, page_order_20, p2m_ram_rw, p2m_access_rwx/* FIXME: Should use same permission as l1 guest */ );
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel
Christoph Egger
Acked-byQuoted 7 lines · Tim Deegan
Quoted 2 lines · Tim Deegan
I think they really just need trimmed back a bit before they go in. I'll have some time on Wednesday, so I might just do that then.
OK, I've cut them back to just the bits that are needed by the new callers. I ended up shuffling the code around as well, so could you please test that the attached series works for you?
Yes, the patch series works very well.
Please apply them.
Signature · 6 lines
---to satisfy European Law for business letters: Advanced Micro Devices GmbH Einsteinring 24, 85689 Dornach b. Muenchen Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen Registergericht Muenchen, HRB Nr. 43632