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

[Xen-changelog] [xen-unstable] hap: Merge the guest-walking functions into one.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1184677785 -3600
# Node ID 45b97e0f2dc817b903bca37a507c8586cddc2919
# Parent  ee7a5ddc184728e2a82078e382eb21e5c54505df
hap: Merge the guest-walking functions into one.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/mm/hap/support.c    |  340 ---------------------------------------
 xen/arch/x86/mm/hap/Makefile     |   10 +
 xen/arch/x86/mm/hap/guest_walk.c |  181 ++++++++++++++++++++
 xen/arch/x86/mm/hap/hap.c        |   35 ++--
 xen/arch/x86/mm/hap/private.h    |   55 ------
 5 files changed, 215 insertions(+), 406 deletions(-)

diff -r ee7a5ddc1847 -r 45b97e0f2dc8 xen/arch/x86/mm/hap/Makefile
--- a/xen/arch/x86/mm/hap/Makefile      Tue Jul 17 10:36:33 2007 +0100
+++ b/xen/arch/x86/mm/hap/Makefile      Tue Jul 17 14:09:45 2007 +0100
@@ -1,2 +1,10 @@ obj-y += hap.o
 obj-y += hap.o
-obj-y += support.o
+obj-y += guest_walk_2level.o
+obj-y += guest_walk_3level.o
+obj-y += guest_walk_4level.o
+
+guest_levels  = $(subst level,,$(filter %level,$(subst ., ,$(subst _, ,$(1)))))
+guest_walk_defns = -DGUEST_PAGING_LEVELS=$(call guest_levels,$(1))
+
+guest_walk_%level.o: guest_walk.c $(HDRS) Makefile
+       $(CC) $(CFLAGS) $(call guest_walk_defns,$(@F)) -c $< -o $@
diff -r ee7a5ddc1847 -r 45b97e0f2dc8 xen/arch/x86/mm/hap/guest_walk.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/mm/hap/guest_walk.c  Tue Jul 17 14:09:45 2007 +0100
@@ -0,0 +1,181 @@
+/*
+ * arch/x86/mm/hap/guest_walk.c
+ *
+ * Guest page table walker
+ * Copyright (c) 2007, AMD Corporation (Wei Huang)
+ * Copyright (c) 2007, XenSource Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <xen/mm.h>
+#include <xen/domain_page.h>
+#include <asm/page.h>
+#include <xen/event.h>
+#include <xen/sched.h>
+#include <asm/hvm/svm/vmcb.h>
+#include <asm/domain.h>
+#include <asm/shadow.h>
+#include <asm/hap.h>
+
+#include "private.h"
+
+#define _hap_gva_to_gfn(levels) hap_gva_to_gfn_##levels##level
+#define hap_gva_to_gfn(levels) _hap_gva_to_gfn(levels)
+
+#if GUEST_PAGING_LEVELS > CONFIG_PAGING_LEVELS
+
+unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)(
+    struct vcpu *v, unsigned long gva)
+{
+    gdprintk(XENLOG_ERR,
+             "Guest paging level is greater than host paging level!\n");
+    domain_crash(v->domain);
+    return INVALID_GFN;
+}
+
+#else
+
+#if GUEST_PAGING_LEVELS == 2
+#include "../page-guest32.h"
+#define l1_pgentry_t l1_pgentry_32_t
+#define l2_pgentry_t l2_pgentry_32_t
+#undef l2e_get_flags
+#define l2e_get_flags(x) l2e_get_flags_32(x)
+#undef l1e_get_flags
+#define l1e_get_flags(x) l1e_get_flags_32(x)
+#endif
+
+unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)(
+    struct vcpu *v, unsigned long gva)
+{
+    unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3);
+    int mode = GUEST_PAGING_LEVELS;
+    int lev, index;
+    paddr_t gpa = 0;
+    unsigned long gpfn, mfn;
+    int success = 1;
+
+    l1_pgentry_t *l1e;
+    l2_pgentry_t *l2e;
+#if GUEST_PAGING_LEVELS >= 3
+    l3_pgentry_t *l3e;
+#endif
+#if GUEST_PAGING_LEVELS >= 4
+    l4_pgentry_t *l4e;
+#endif
+
+    gpfn = (gcr3 >> PAGE_SHIFT);
+    for ( lev = mode; lev >= 1; lev-- )
+    {
+        mfn = get_mfn_from_gpfn(gpfn);
+        if ( mfn == INVALID_MFN )
+        {
+            HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, 
+                       lev);
+            success = 0;
+            break;
+        }
+        index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1);
+
+#if GUEST_PAGING_LEVELS >= 4
+        if ( lev == 4 )
+        {
+            l4e = map_domain_page(mfn);
+            if ( !(l4e_get_flags(l4e[index]) & _PAGE_PRESENT) )
+            {
+                HAP_PRINTK("Level 4 entry not present at index = %d\n", index);
+                success = 0;
+            }
+            gpfn = l4e_get_pfn(l4e[index]);
+            unmap_domain_page(l4e);
+        }
+#endif
+
+#if GUEST_PAGING_LEVELS >= 3
+        if ( lev == 3 )
+        {
+            l3e = map_domain_page(mfn);
+#if GUEST_PAGING_LEVELS == 3
+            index += ((gcr3 >> 5) & 127) * 4;
+#endif
+            if ( !(l3e_get_flags(l3e[index]) & _PAGE_PRESENT) )
+            {
+                HAP_PRINTK("Level 3 entry not present at index = %d\n", index);
+                success = 0;
+            }
+            gpfn = l3e_get_pfn(l3e[index]);
+            unmap_domain_page(l3e);
+        }
+#endif
+
+        if ( lev == 2 )
+        {
+            l2e = map_domain_page(mfn);
+            if ( !(l2e_get_flags(l2e[index]) & _PAGE_PRESENT) )
+            {
+                HAP_PRINTK("Level 2 entry not present at index = %d\n", index);
+                success = 0;
+            }
+
+            if ( l2e_get_flags(l2e[index]) & _PAGE_PSE )
+            {
+                paddr_t mask = ((paddr_t)1 << PT_SHIFT[mode][2]) - 1;
+                HAP_PRINTK("guest page table is PSE\n");
+                gpa = (l2e_get_intpte(l2e[index]) & ~mask) + (gva & mask);
+                unmap_domain_page(l2e);
+                break; /* last level page table, jump out from here */
+            }
+
+            gpfn = l2e_get_pfn(l2e[index]);
+            unmap_domain_page(l2e);
+        }
+
+        if ( lev == 1 )
+        {
+            l1e = map_domain_page(mfn);
+            if ( !(l1e_get_flags(l1e[index]) & _PAGE_PRESENT) )
+            {
+                HAP_PRINTK("Level 1 entry not present at index = %d\n", index);
+                success = 0;
+            }
+            gpfn = l1e_get_pfn(l1e[index]);
+            gpa = (l1e_get_intpte(l1e[index]) & PAGE_MASK) + (gva &~PAGE_MASK);
+            unmap_domain_page(l1e);
+        }
+
+        if ( success != 1 ) /* error happened, jump out */
+            break;
+    }
+
+    gpa &= PADDR_MASK;
+    HAP_PRINTK("success = %d, gva = %lx, gpa = %lx\n", success, gva, gpa);
+
+    return (!success ? INVALID_GFN : ((paddr_t)gpa >> PAGE_SHIFT));
+}
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+
diff -r ee7a5ddc1847 -r 45b97e0f2dc8 xen/arch/x86/mm/hap/hap.c
--- a/xen/arch/x86/mm/hap/hap.c Tue Jul 17 10:36:33 2007 +0100
+++ b/xen/arch/x86/mm/hap/hap.c Tue Jul 17 14:09:45 2007 +0100
@@ -290,8 +290,8 @@ void hap_install_xen_entries_in_l2h(stru
             l2e_from_pfn(
                 mfn_x(page_to_mfn(virt_to_page(d->arch.mm_perdomain_pt) + i)),
                 __PAGE_HYPERVISOR);
-    
-    for ( i = 0; i < HAP_L3_PAGETABLE_ENTRIES; i++ )
+
+    for ( i = 0; i < 4; i++ )
         sl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i] =
             l2e_empty();
 
@@ -564,6 +564,7 @@ void hap_vcpu_init(struct vcpu *v)
 {
     v->arch.paging.mode = &hap_paging_real_mode;
 }
+
 /************************************************/
 /*          HAP PAGING MODE FUNCTIONS           */
 /************************************************/
@@ -571,8 +572,8 @@ void hap_vcpu_init(struct vcpu *v)
  * HAP guests can handle page faults (in the guest page tables) without
  * needing any action from Xen, so we should not be intercepting them.
  */
-int hap_page_fault(struct vcpu *v, unsigned long va, 
-                   struct cpu_user_regs *regs)
+static int hap_page_fault(struct vcpu *v, unsigned long va, 
+                          struct cpu_user_regs *regs)
 {
     HAP_ERROR("Intercepted a guest #PF (%u:%u) with HAP enabled.\n",
               v->domain->domain_id, v->vcpu_id);
@@ -584,7 +585,7 @@ int hap_page_fault(struct vcpu *v, unsig
  * HAP guests can handle invlpg without needing any action from Xen, so
  * should not be intercepting it. 
  */
-int hap_invlpg(struct vcpu *v, unsigned long va)
+static int hap_invlpg(struct vcpu *v, unsigned long va)
 {
     HAP_ERROR("Intercepted a guest INVLPG (%u:%u) with HAP enabled.\n",
               v->domain->domain_id, v->vcpu_id);
@@ -596,11 +597,11 @@ int hap_invlpg(struct vcpu *v, unsigned 
  * HAP guests do not need to take any action on CR3 writes (they are still
  * intercepted, so that Xen's copy of the guest's CR3 can be kept in sync.)
  */
-void hap_update_cr3(struct vcpu *v, int do_locking)
-{
-}
-
-void hap_update_paging_modes(struct vcpu *v)
+static void hap_update_cr3(struct vcpu *v, int do_locking)
+{
+}
+
+static void hap_update_paging_modes(struct vcpu *v)
 {
     struct domain *d;
 
@@ -678,7 +679,7 @@ static void p2m_install_entry_in_monitor
 }
 #endif
 
-void 
+static void 
 hap_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p,
                     mfn_t table_mfn, l1_pgentry_t new, unsigned int level)
 {
@@ -696,6 +697,12 @@ hap_write_p2m_entry(struct vcpu *v, unsi
     hap_unlock(v->domain);
 }
 
+static unsigned long hap_gva_to_gfn_real_mode(
+    struct vcpu *v, unsigned long gva)
+{
+    return ((paddr_t)gva >> PAGE_SHIFT);
+}
+
 /* Entry points into this mode of the hap code. */
 struct paging_mode hap_paging_real_mode = {
     .page_fault             = hap_page_fault, 
@@ -710,7 +717,7 @@ struct paging_mode hap_paging_protected_
 struct paging_mode hap_paging_protected_mode = {
     .page_fault             = hap_page_fault, 
     .invlpg                 = hap_invlpg,
-    .gva_to_gfn             = hap_gva_to_gfn_protected_mode,
+    .gva_to_gfn             = hap_gva_to_gfn_2level,
     .update_cr3             = hap_update_cr3,
     .update_paging_modes    = hap_update_paging_modes,
     .write_p2m_entry        = hap_write_p2m_entry,
@@ -720,7 +727,7 @@ struct paging_mode hap_paging_pae_mode =
 struct paging_mode hap_paging_pae_mode = {
     .page_fault             = hap_page_fault, 
     .invlpg                 = hap_invlpg,
-    .gva_to_gfn             = hap_gva_to_gfn_pae_mode,
+    .gva_to_gfn             = hap_gva_to_gfn_3level,
     .update_cr3             = hap_update_cr3,
     .update_paging_modes    = hap_update_paging_modes,
     .write_p2m_entry        = hap_write_p2m_entry,
@@ -730,7 +737,7 @@ struct paging_mode hap_paging_long_mode 
 struct paging_mode hap_paging_long_mode = {
     .page_fault             = hap_page_fault, 
     .invlpg                 = hap_invlpg,
-    .gva_to_gfn             = hap_gva_to_gfn_long_mode,
+    .gva_to_gfn             = hap_gva_to_gfn_4level,
     .update_cr3             = hap_update_cr3,
     .update_paging_modes    = hap_update_paging_modes,
     .write_p2m_entry        = hap_write_p2m_entry,
diff -r ee7a5ddc1847 -r 45b97e0f2dc8 xen/arch/x86/mm/hap/private.h
--- a/xen/arch/x86/mm/hap/private.h     Tue Jul 17 10:36:33 2007 +0100
+++ b/xen/arch/x86/mm/hap/private.h     Tue Jul 17 14:09:45 2007 +0100
@@ -26,10 +26,10 @@
 /********************************************/
 /*          GUEST TRANSLATION FUNCS         */
 /********************************************/
-unsigned long hap_gva_to_gfn_real_mode(struct vcpu *v, unsigned long gva);
-unsigned long hap_gva_to_gfn_protected_mode(struct vcpu *v, unsigned long gva);
-unsigned long hap_gva_to_gfn_pae_mode(struct vcpu *v, unsigned long gva);
-unsigned long hap_gva_to_gfn_long_mode(struct vcpu *v, unsigned long gva);
+unsigned long hap_gva_to_gfn_2level(struct vcpu *v, unsigned long gva);
+unsigned long hap_gva_to_gfn_3level(struct vcpu *v, unsigned long gva);
+unsigned long hap_gva_to_gfn_4level(struct vcpu *v, unsigned long gva);
+
 /********************************************/
 /*            MISC DEFINITIONS              */
 /********************************************/
@@ -62,51 +62,4 @@ static const int PT_ENTRIES[][5] =
     {    0,  512,  512,  512,  512}    /* 4  */
   };
 
-/********************************************/
-/*       PAGING DEFINITION FOR GUEST        */
-/********************************************/
-#define PHYSICAL_PAGE_4K_SIZE (1UL << 12)
-#define PHYSICAL_PAGE_2M_SIZE (1UL << 21)
-#define PHYSICAL_PAGE_4M_SIZE (1UL << 22)
-#define PHYSICAL_PAGE_4K_MASK ( ~(PHYSICAL_PAGE_4K_SIZE - 1) )
-#define PHYSICAL_PAGE_2M_MASK ( ~(PHYSICAL_PAGE_2M_SIZE - 1) )
-#define PHYSICAL_PAGE_4M_MASK ( ~(PHYSICAL_PAGE_4M_SIZE - 1) )
-
-/* long mode physical address mask */
-#define PHYSICAL_ADDR_BITS_LM    52
-#define PHYSICAL_ADDR_MASK_LM    ((1UL << PHYSICAL_ADDR_BITS_LM)-1)
-#define PHYSICAL_ADDR_2M_MASK_LM (PHYSICAL_PAGE_2M_MASK & 
PHYSICAL_ADDR_MASK_LM)
-#define PHYSICAL_ADDR_4K_MASK_LM (PHYSICAL_PAGE_4K_MASK & 
PHYSICAL_ADDR_MASK_LM)
-
-#define PAGE_NX_BIT      (1ULL << 63)
-/************************************************/
-/*        PAGETABLE RELATED VARIABLES           */
-/************************************************/
-#if CONFIG_PAGING_LEVELS == 2
-#define HAP_L1_PAGETABLE_ENTRIES    1024
-#define HAP_L2_PAGETABLE_ENTRIES    1024
-#define HAP_L1_PAGETABLE_SHIFT        12
-#define HAP_L2_PAGETABLE_SHIFT        22
-#endif
-
-#if CONFIG_PAGING_LEVELS == 3
-#define HAP_L1_PAGETABLE_ENTRIES     512
-#define HAP_L2_PAGETABLE_ENTRIES     512
-#define HAP_L3_PAGETABLE_ENTRIES       4
-#define HAP_L1_PAGETABLE_SHIFT        12
-#define HAP_L2_PAGETABLE_SHIFT        21
-#define HAP_L3_PAGETABLE_SHIFT        30
-#endif
-
-#if CONFIG_PAGING_LEVELS == 4
-#define HAP_L1_PAGETABLE_ENTRIES     512
-#define HAP_L2_PAGETABLE_ENTRIES     512
-#define HAP_L3_PAGETABLE_ENTRIES     512
-#define HAP_L4_PAGETABLE_ENTRIES     512
-#define HAP_L1_PAGETABLE_SHIFT        12
-#define HAP_L2_PAGETABLE_SHIFT        21
-#define HAP_L3_PAGETABLE_SHIFT        30
-#define HAP_L4_PAGETABLE_SHIFT        39
-#endif
-
 #endif /* __SVM_NPT_H__ */
diff -r ee7a5ddc1847 -r 45b97e0f2dc8 xen/arch/x86/mm/hap/support.c
--- a/xen/arch/x86/mm/hap/support.c     Tue Jul 17 10:36:33 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-/*
- * arch/x86/mm/hap/support.c
- * 
- * guest page table walker
- * Copyright (c) 2007, AMD Corporation (Wei Huang)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- */
-
-#include <xen/config.h>
-#include <xen/types.h>
-#include <xen/mm.h>
-#include <xen/domain_page.h>
-#include <asm/page.h>
-#include <xen/event.h>
-#include <xen/sched.h>
-#include <asm/hvm/svm/vmcb.h>
-#include <asm/domain.h>
-#include <asm/shadow.h>
-#include <asm/hap.h>
-
-#include "private.h"
-#include "../page-guest32.h"
-
-/*******************************************/
-/*      Platform Specific Functions        */
-/*******************************************/
-
-/* Translate guest virtual address to guest physical address. Specifically
- * for real mode guest. 
- */
-unsigned long hap_gva_to_gfn_real_mode(struct vcpu *v, unsigned long gva)
-{
-    return ((paddr_t)gva >> PAGE_SHIFT);
-}
-
-/* Translate guest virtual address to guest physical address. Specifically
- * for protected guest. 
- */
-unsigned long hap_gva_to_gfn_protected_mode(struct vcpu *v, unsigned long gva)
-{
-    unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3);
-    int mode = 2; /* two-level guest */
-    int lev, index;
-    paddr_t gpa = 0;
-    unsigned long gpfn, mfn;
-    int success = 1;
-    l2_pgentry_32_t *l2e; /* guest page entry size is 32-bit */
-    l1_pgentry_32_t *l1e;
-
-    gpfn = (gcr3 >> PAGE_SHIFT);
-    for ( lev = mode; lev >= 1; lev-- )
-    {
-        mfn = get_mfn_from_gpfn(gpfn);
-        if ( mfn == INVALID_MFN )
-        {
-            HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, 
-                       lev);
-            success = 0;
-            break;
-        }
-        index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1);
-
-        if ( lev == 2 )
-        {
-            l2e = map_domain_page(mfn);
-            HAP_PRINTK("l2 page table entry is %ulx at index = %d\n", 
-                       l2e[index].l2, index);
-            if ( !(l2e_get_flags_32(l2e[index]) & _PAGE_PRESENT) )
-            {
-                HAP_PRINTK("Level 2 entry not present at index = %d\n", index);
-                success = 0;
-            }
-
-            if ( l2e_get_flags_32(l2e[index]) & _PAGE_PSE )
-            {
-                HAP_PRINTK("guest page table is PSE\n");
-                if ( l2e_get_intpte(l2e[index]) & 0x001FE000UL ) /*[13:20] */
-                {
-                    printk("guest physical memory size is too large!\n");
-                    domain_crash(v->domain);
-                }
-                gpa = (l2e_get_intpte(l2e[index]) & PHYSICAL_PAGE_4M_MASK) + 
-                    (gva & ~PHYSICAL_PAGE_4M_MASK);
-                unmap_domain_page(l2e);
-                break; /* last level page table, return from here */
-            }
-
-            gpfn = l2e_get_pfn(l2e[index]);
-            unmap_domain_page(l2e);
-        }
-
-        if ( lev == 1 )
-        {
-            l1e = map_domain_page(mfn);
-            HAP_PRINTK("l1 page table entry is %ulx at index = %d\n", 
-                       l1e[index].l1, index);
-            if ( !(l1e_get_flags_32(l1e[index]) & _PAGE_PRESENT) )
-            {
-                HAP_PRINTK("Level 1 entry not present at index = %d\n", index);
-                success = 0;
-            }
-            gpfn = l1e_get_pfn(l1e[index]);
-            gpa = (l1e_get_intpte(l1e[index]) & PHYSICAL_PAGE_4K_MASK) + 
-                (gva & ~PHYSICAL_PAGE_4K_MASK);    
-            unmap_domain_page(l1e);
-        }
-
-        if ( !success ) /* error happened, jump out */
-            break;
-    }
-
-    HAP_PRINTK("success = %d, gva = %lx, gpa = %lx\n", success, gva, gpa);
-
-    return (!success ? INVALID_GFN : ((paddr_t)gpa >> PAGE_SHIFT));
-}
-
-
-
-/* Translate guest virtual address to guest physical address. Specifically
- * for PAE mode guest. 
- */
-unsigned long hap_gva_to_gfn_pae_mode(struct vcpu *v, unsigned long gva)
-{
-#if CONFIG_PAGING_LEVELS >= 3
-    unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3);
-    int mode = 3; /* three-level guest */
-    int lev, index;
-    paddr_t gpa = 0;
-    unsigned long gpfn, mfn;
-    int success = 1;
-    l1_pgentry_t *l1e;
-    l2_pgentry_t *l2e;
-    l3_pgentry_t *l3e;
-    
-    gpfn = (gcr3 >> PAGE_SHIFT);
-    for ( lev = mode; lev >= 1; lev-- )
-    {
-        mfn = get_mfn_from_gpfn(gpfn);
-        if ( mfn == INVALID_MFN )
-        {
-            HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, 
-                       lev);
-            success = 0;
-            break;
-        }
-        index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1);
-
-        if ( lev == 3 )
-        {
-            l3e = map_domain_page(mfn);
-            index += ((gcr3 >> 5) & 127) * 4;
-            if ( !(l3e_get_flags(l3e[index]) & _PAGE_PRESENT) )
-            {
-                HAP_PRINTK("Level 3 entry not present at index = %d\n", index);
-                success = 0;
-            }
-            gpfn = l3e_get_pfn(l3e[index]);
-            unmap_domain_page(l3e);
-        }
-
-        if ( lev == 2 )
-        {
-            l2e = map_domain_page(mfn);
-            if ( !(l2e_get_flags(l2e[index]) & _PAGE_PRESENT) )
-            {
-                HAP_PRINTK("Level 2 entry not present at index = %d\n", index);
-                success = 0;
-            }
-
-            if ( l2e_get_flags(l2e[index]) & _PAGE_PSE )
-            {
-                HAP_PRINTK("guest page table is PSE\n");
-                gpa = (l2e_get_intpte(l2e[index]) & PHYSICAL_PAGE_2M_MASK) + 
-                    (gva & ~PHYSICAL_PAGE_2M_MASK);
-                unmap_domain_page(l2e);
-                break; /* last level page table, jump out from here */
-            }
-
-            gpfn = l2e_get_pfn(l2e[index]);
-            unmap_domain_page(l2e);
-        }
-
-        if ( lev == 1 )
-        {
-            l1e = map_domain_page(mfn);
-            if ( !(l1e_get_flags(l1e[index]) & _PAGE_PRESENT) )
-            {
-                HAP_PRINTK("Level 1 entry not present at index = %d\n", index);
-                success = 0;
-            }
-            gpfn = l1e_get_pfn(l1e[index]);
-            gpa = (l1e_get_intpte(l1e[index]) & PHYSICAL_PAGE_4K_MASK) + 
-                (gva & ~PHYSICAL_PAGE_4K_MASK);
-            unmap_domain_page(l1e);
-        }
-
-        if ( success != 1 ) /* error happened, jump out */
-            break;
-    }
-
-    gpa &= ~PAGE_NX_BIT; /* clear NX bit of guest physical address */
-    HAP_PRINTK("success = %d, gva = %lx, gpa = %lx\n", success, gva, gpa);
-
-    return (!success ? INVALID_GFN : ((paddr_t)gpa >> PAGE_SHIFT));
-#else
-    printk("guest paging level (3) is greater than host paging level!\n");
-    domain_crash(v->domain);
-    return INVALID_GFN;
-#endif
-}
-
-
-/* Translate guest virtual address to guest physical address. Specifically
- * for long mode guest. 
- */
-unsigned long hap_gva_to_gfn_long_mode(struct vcpu *v, unsigned long gva)
-{
-#if CONFIG_PAGING_LEVELS == 4
-    unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3);
-    int mode = 4; /* four-level guest */
-    int lev, index;
-    paddr_t gpa = 0;
-    unsigned long gpfn, mfn;
-    int success = 1;
-    l4_pgentry_t *l4e;
-    l3_pgentry_t *l3e;
-    l2_pgentry_t *l2e;
-    l1_pgentry_t *l1e;
-
-    gpfn = (gcr3 >> PAGE_SHIFT);
-    for ( lev = mode; lev >= 1; lev-- )
-    {
-        mfn = get_mfn_from_gpfn(gpfn);
-        if ( mfn == INVALID_MFN )
-        {
-            HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, 
-                       lev);
-            success = 0;
-            break;
-        }
-        index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1);
-
-        if ( lev == 4 )
-        {
-            l4e = map_domain_page(mfn);
-            if ( !(l4e_get_flags(l4e[index]) & _PAGE_PRESENT) )
-            {
-                HAP_PRINTK("Level 4 entry not present at index = %d\n", index);
-                success = 0;
-            }
-            gpfn = l4e_get_pfn(l4e[index]);
-            unmap_domain_page(l4e);
-        }
-
-        if ( lev == 3 )
-        {
-            l3e = map_domain_page(mfn);
-            if ( !(l3e_get_flags(l3e[index]) & _PAGE_PRESENT) )
-            {
-                HAP_PRINTK("Level 3 entry not present at index = %d\n", index);
-                success = 0;
-            }
-            gpfn = l3e_get_pfn(l3e[index]);
-            unmap_domain_page(l3e);
-        }
-
-        if ( lev == 2 )
-        {
-            l2e = map_domain_page(mfn);
-            if ( !(l2e_get_flags(l2e[index]) & _PAGE_PRESENT) )
-            {
-                HAP_PRINTK("Level 2 entry not present at index = %d\n", index);
-                success = 0;
-            }
-
-            if ( l2e_get_flags(l2e[index]) & _PAGE_PSE )
-            {
-                HAP_PRINTK("guest page table is PSE\n");
-                gpa = (l2e_get_intpte(l2e[index]) & PHYSICAL_ADDR_2M_MASK_LM) 
-                    + (gva & ~PHYSICAL_PAGE_2M_MASK);
-                unmap_domain_page(l2e);
-                break; /* last level page table, jump out from here */
-            }
-
-            gpfn = l2e_get_pfn(l2e[index]);
-            unmap_domain_page(l2e);
-        }
-
-        if ( lev == 1 )
-        {
-            l1e = map_domain_page(mfn);
-            if ( !(l1e_get_flags(l1e[index]) & _PAGE_PRESENT) )
-            {
-                HAP_PRINTK("Level 1 entry not present at index = %d\n", index);
-                success = 0;
-            }
-            gpfn = l1e_get_pfn(l1e[index]);
-            gpa = (l1e_get_intpte(l1e[index]) & PHYSICAL_ADDR_4K_MASK_LM) + 
-                (gva & ~PHYSICAL_PAGE_4K_MASK);
-            unmap_domain_page(l1e);
-        }
-
-        if ( success != 1 ) /* error happened, jump out */
-            break;
-    }
-
-    gpa &= ~PAGE_NX_BIT; /* clear NX bit of guest physical address */
-    HAP_PRINTK("success = %d, gva = %lx, gpa = %lx\n", success, gva, gpa);
-
-    return (!success ? INVALID_GFN : ((paddr_t)gpa >> PAGE_SHIFT));
-#else
-    printk("guest paging level (4) is greater than host paging level!\n");
-    domain_crash(v->domain);
-    return INVALID_GFN;
-#endif
-}
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-

_______________________________________________
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®.