ia64/xen-unstable
changeset 8920:20b95517cbf1
Fix get_mfn_from_gpfn_foreign for HVM guests.
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Xin B Li <xin.b.li@intel.com>
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Xin B Li <xin.b.li@intel.com>
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Sun Feb 19 09:06:44 2006 +0100 (2006-02-19) |
parents | 864dcee1f899 |
children | 5b4ff470dcc6 |
files | xen/arch/x86/shadow32.c xen/arch/x86/shadow_public.c |
line diff
1.1 --- a/xen/arch/x86/shadow32.c Sat Feb 18 11:56:51 2006 +0100 1.2 +++ b/xen/arch/x86/shadow32.c Sun Feb 19 09:06:44 2006 +0100 1.3 @@ -1630,27 +1630,58 @@ get_mfn_from_gpfn_foreign(struct domain 1.4 1.5 perfc_incrc(get_mfn_from_gpfn_foreign); 1.6 1.7 - va = gpfn << PAGE_SHIFT; 1.8 - tabpfn = pagetable_get_pfn(d->arch.phys_table); 1.9 - l2 = map_domain_page(tabpfn); 1.10 - l2e = l2[l2_table_offset(va)]; 1.11 - unmap_domain_page(l2); 1.12 - if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) 1.13 + if ( shadow_mode_external(d) ) 1.14 { 1.15 - printk("%s(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte "\n", 1.16 - __func__, d->domain_id, gpfn, l2e_get_intpte(l2e)); 1.17 - return INVALID_MFN; 1.18 + unsigned long mfn; 1.19 + unsigned long *l0; 1.20 + 1.21 + va = RO_MPT_VIRT_START + (gpfn * sizeof(mfn)); 1.22 + 1.23 + tabpfn = pagetable_get_pfn(d->vcpu[0]->arch.monitor_table); 1.24 + if ( !tabpfn ) 1.25 + return INVALID_MFN; 1.26 + 1.27 + l2 = map_domain_page(tabpfn); 1.28 + l2e = l2[l2_table_offset(va)]; 1.29 + unmap_domain_page(l2); 1.30 + if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) 1.31 + return INVALID_MFN; 1.32 + 1.33 + l1 = map_domain_page(l2e_get_pfn(l2e)); 1.34 + l1e = l1[l1_table_offset(va)]; 1.35 + unmap_domain_page(l1); 1.36 + if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) ) 1.37 + return INVALID_MFN; 1.38 + 1.39 + l0 = map_domain_page(l1e_get_pfn(l1e)); 1.40 + mfn = l0[gpfn & ((PAGE_SIZE / sizeof(mfn)) - 1)]; 1.41 + unmap_domain_page(l0); 1.42 + return mfn; 1.43 } 1.44 - l1 = map_domain_page(l2e_get_pfn(l2e)); 1.45 - l1e = l1[l1_table_offset(va)]; 1.46 - unmap_domain_page(l1); 1.47 - 1.48 + else 1.49 + { 1.50 + va = gpfn << PAGE_SHIFT; 1.51 + tabpfn = pagetable_get_pfn(d->arch.phys_table); 1.52 + l2 = map_domain_page(tabpfn); 1.53 + l2e = l2[l2_table_offset(va)]; 1.54 + unmap_domain_page(l2); 1.55 + if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) 1.56 + { 1.57 + printk("%s(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte "\n", 1.58 + __func__, d->domain_id, gpfn, l2e_get_intpte(l2e)); 1.59 + return INVALID_MFN; 1.60 + } 1.61 + l1 = map_domain_page(l2e_get_pfn(l2e)); 1.62 + l1e = l1[l1_table_offset(va)]; 1.63 + unmap_domain_page(l1); 1.64 #if 0 1.65 - printk("%s(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx l1tab=%lx, l1e=%lx\n", 1.66 - __func__, d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, tabpfn, l2e, l1tab, l1e); 1.67 + printk("%s(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx l1tab=%lx, l1e=%lx\n", 1.68 + __func__, d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, tabpfn, l2e, l1tab, l1e); 1.69 #endif 1.70 1.71 - return l1e_get_intpte(l1e); 1.72 + return l1e_get_intpte(l1e); 1.73 + } 1.74 + 1.75 } 1.76 1.77 static unsigned long
2.1 --- a/xen/arch/x86/shadow_public.c Sat Feb 18 11:56:51 2006 +0100 2.2 +++ b/xen/arch/x86/shadow_public.c Sun Feb 19 09:06:44 2006 +0100 2.3 @@ -1790,39 +1790,56 @@ get_mfn_from_gpfn_foreign(struct domain 2.4 unsigned long va, tabpfn; 2.5 l1_pgentry_t *l1, l1e; 2.6 l2_pgentry_t *l2, l2e; 2.7 +#if CONFIG_PAGING_LEVELS >= 4 2.8 + pgentry_64_t *l4 = NULL; 2.9 + pgentry_64_t l4e = { 0 }; 2.10 +#endif 2.11 + pgentry_64_t *l3 = NULL; 2.12 + pgentry_64_t l3e = { 0 }; 2.13 + unsigned long *l0tab = NULL; 2.14 + unsigned long mfn; 2.15 2.16 ASSERT(shadow_mode_translate(d)); 2.17 2.18 perfc_incrc(get_mfn_from_gpfn_foreign); 2.19 2.20 - va = gpfn << PAGE_SHIFT; 2.21 - tabpfn = pagetable_get_pfn(d->arch.phys_table); 2.22 - l2 = map_domain_page(tabpfn); 2.23 + va = RO_MPT_VIRT_START + (gpfn * sizeof(mfn)); 2.24 + 2.25 + tabpfn = pagetable_get_pfn(d->vcpu[0]->arch.monitor_table); 2.26 + if ( !tabpfn ) 2.27 + return INVALID_MFN; 2.28 + 2.29 +#if CONFIG_PAGING_LEVELS >= 4 2.30 + l4 = map_domain_page(tabpfn); 2.31 + l4e = l4[l4_table_offset(va)]; 2.32 + unmap_domain_page(l4); 2.33 + if ( !(entry_get_flags(l4e) & _PAGE_PRESENT) ) 2.34 + return INVALID_MFN; 2.35 + 2.36 + l3 = map_domain_page(entry_get_pfn(l4e)); 2.37 +#else 2.38 + l3 = map_domain_page(tabpfn); 2.39 +#endif 2.40 + l3e = l3[l3_table_offset(va)]; 2.41 + unmap_domain_page(l3); 2.42 + if ( !(entry_get_flags(l3e) & _PAGE_PRESENT) ) 2.43 + return INVALID_MFN; 2.44 + l2 = map_domain_page(entry_get_pfn(l3e)); 2.45 l2e = l2[l2_table_offset(va)]; 2.46 unmap_domain_page(l2); 2.47 if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) 2.48 - { 2.49 - printk("%s(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte "\n", 2.50 - __func__, d->domain_id, gpfn, l2e_get_intpte(l2e)); 2.51 return INVALID_MFN; 2.52 - } 2.53 + 2.54 l1 = map_domain_page(l2e_get_pfn(l2e)); 2.55 l1e = l1[l1_table_offset(va)]; 2.56 unmap_domain_page(l1); 2.57 - 2.58 -#if 0 2.59 - printk("%s(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx l1tab=%lx, l1e=%lx\n", 2.60 - __func__, d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, tabpfn, l2e, l1tab, l1e); 2.61 -#endif 2.62 + if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) ) 2.63 + return INVALID_MFN; 2.64 2.65 - if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) ) 2.66 - { 2.67 - printk("%s(d->id=%d, gpfn=%lx) => 0 l1e=%" PRIpte "\n", 2.68 - __func__, d->domain_id, gpfn, l1e_get_intpte(l1e)); 2.69 - return INVALID_MFN; 2.70 - } 2.71 - 2.72 - return l1e_get_pfn(l1e); 2.73 + l0tab = map_domain_page(l1e_get_pfn(l1e)); 2.74 + mfn = l0tab[gpfn & ((PAGE_SIZE / sizeof (mfn)) - 1)]; 2.75 + unmap_domain_page(l0tab); 2.76 + return mfn; 2.77 } 2.78 2.79 static u32 remove_all_access_in_page(