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>
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(