[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Fix get_mfn_from_gpfn_foreign for HVM guests.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 20b95517cbf100150b014ad349f848f687d178d5
# Parent  864dcee1f899c52e022fadcfab9929dcdbcb1ac4
Fix get_mfn_from_gpfn_foreign for HVM guests.

Signed-off-by: Yunhong Jiang <yunhong.jiang@xxxxxxxxx>
Signed-off-by: Xin B Li <xin.b.li@xxxxxxxxx>
Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx>

diff -r 864dcee1f899 -r 20b95517cbf1 xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Sat Feb 18 10:56:51 2006
+++ b/xen/arch/x86/shadow32.c   Sun Feb 19 08:06:44 2006
@@ -1630,27 +1630,58 @@
 
     perfc_incrc(get_mfn_from_gpfn_foreign);
 
-    va = gpfn << PAGE_SHIFT;
-    tabpfn = pagetable_get_pfn(d->arch.phys_table);
-    l2 = map_domain_page(tabpfn);
-    l2e = l2[l2_table_offset(va)];
-    unmap_domain_page(l2);
-    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
-    {
-        printk("%s(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte "\n",
-               __func__, d->domain_id, gpfn, l2e_get_intpte(l2e));
-        return INVALID_MFN;
-    }
-    l1 = map_domain_page(l2e_get_pfn(l2e));
-    l1e = l1[l1_table_offset(va)];
-    unmap_domain_page(l1);
-
+    if ( shadow_mode_external(d) )
+    {
+        unsigned long mfn;
+        unsigned long *l0;
+
+        va = RO_MPT_VIRT_START + (gpfn * sizeof(mfn));
+
+        tabpfn = pagetable_get_pfn(d->vcpu[0]->arch.monitor_table);
+        if ( !tabpfn )
+            return INVALID_MFN;
+
+        l2 = map_domain_page(tabpfn);
+        l2e = l2[l2_table_offset(va)];
+        unmap_domain_page(l2);
+        if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+            return INVALID_MFN;
+
+        l1 = map_domain_page(l2e_get_pfn(l2e));
+        l1e = l1[l1_table_offset(va)];
+        unmap_domain_page(l1);
+        if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) )
+            return INVALID_MFN;
+
+        l0 = map_domain_page(l1e_get_pfn(l1e));
+        mfn = l0[gpfn & ((PAGE_SIZE / sizeof(mfn)) - 1)];
+        unmap_domain_page(l0);
+        return mfn;
+    }
+    else
+    {
+        va = gpfn << PAGE_SHIFT;
+        tabpfn = pagetable_get_pfn(d->arch.phys_table);
+        l2 = map_domain_page(tabpfn);
+        l2e = l2[l2_table_offset(va)];
+        unmap_domain_page(l2);
+        if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+        {
+            printk("%s(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte "\n",
+                   __func__, d->domain_id, gpfn, l2e_get_intpte(l2e));
+            return INVALID_MFN;
+        }
+        l1 = map_domain_page(l2e_get_pfn(l2e));
+        l1e = l1[l1_table_offset(va)];
+        unmap_domain_page(l1);
 #if 0
-    printk("%s(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx l1tab=%lx, 
l1e=%lx\n",
-           __func__, d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, 
tabpfn, l2e, l1tab, l1e);
+        printk("%s(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx l1tab=%lx, 
l1e=%lx\n",
+               __func__, d->domain_id, gpfn, l1_pgentry_val(l1e) >> 
PAGE_SHIFT, tabpfn, l2e, l1tab, l1e);
 #endif
 
-    return l1e_get_intpte(l1e);
+        return l1e_get_intpte(l1e);
+    }
+
 }
 
 static unsigned long
diff -r 864dcee1f899 -r 20b95517cbf1 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c      Sat Feb 18 10:56:51 2006
+++ b/xen/arch/x86/shadow_public.c      Sun Feb 19 08:06:44 2006
@@ -1790,39 +1790,56 @@
     unsigned long va, tabpfn;
     l1_pgentry_t *l1, l1e;
     l2_pgentry_t *l2, l2e;
+#if CONFIG_PAGING_LEVELS >= 4
+    pgentry_64_t *l4 = NULL;
+    pgentry_64_t l4e = { 0 };
+#endif
+    pgentry_64_t *l3 = NULL;
+    pgentry_64_t l3e = { 0 };
+    unsigned long *l0tab = NULL;
+    unsigned long mfn;
 
     ASSERT(shadow_mode_translate(d));
 
     perfc_incrc(get_mfn_from_gpfn_foreign);
 
-    va = gpfn << PAGE_SHIFT;
-    tabpfn = pagetable_get_pfn(d->arch.phys_table);
-    l2 = map_domain_page(tabpfn);
+    va = RO_MPT_VIRT_START + (gpfn * sizeof(mfn));
+
+    tabpfn = pagetable_get_pfn(d->vcpu[0]->arch.monitor_table);
+    if ( !tabpfn )
+        return INVALID_MFN;
+
+#if CONFIG_PAGING_LEVELS >= 4
+    l4 = map_domain_page(tabpfn);
+    l4e = l4[l4_table_offset(va)];
+    unmap_domain_page(l4);
+    if ( !(entry_get_flags(l4e) & _PAGE_PRESENT) )
+        return INVALID_MFN;
+
+    l3 = map_domain_page(entry_get_pfn(l4e));
+#else
+    l3 = map_domain_page(tabpfn);
+#endif
+    l3e = l3[l3_table_offset(va)];
+    unmap_domain_page(l3);
+    if ( !(entry_get_flags(l3e) & _PAGE_PRESENT) )
+        return INVALID_MFN;
+    l2 = map_domain_page(entry_get_pfn(l3e));
     l2e = l2[l2_table_offset(va)];
     unmap_domain_page(l2);
     if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
-    {
-        printk("%s(d->id=%d, gpfn=%lx) => 0 l2e=%" PRIpte "\n",
-               __func__, d->domain_id, gpfn, l2e_get_intpte(l2e));
         return INVALID_MFN;
-    }
+
     l1 = map_domain_page(l2e_get_pfn(l2e));
     l1e = l1[l1_table_offset(va)];
     unmap_domain_page(l1);
-
-#if 0
-    printk("%s(d->id=%d, gpfn=%lx) => %lx tabpfn=%lx l2e=%lx l1tab=%lx, 
l1e=%lx\n",
-           __func__, d->domain_id, gpfn, l1_pgentry_val(l1e) >> PAGE_SHIFT, 
tabpfn, l2e, l1tab, l1e);
-#endif
-
     if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) )
-    {
-        printk("%s(d->id=%d, gpfn=%lx) => 0 l1e=%" PRIpte "\n",
-               __func__, d->domain_id, gpfn, l1e_get_intpte(l1e));
         return INVALID_MFN;
-    }
-
-    return l1e_get_pfn(l1e);
+
+    l0tab = map_domain_page(l1e_get_pfn(l1e));
+    mfn = l0tab[gpfn & ((PAGE_SIZE / sizeof (mfn)) - 1)];
+    unmap_domain_page(l0tab);
+    return mfn;
 }
 
 static u32 remove_all_access_in_page(

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.