WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] hap: Merge the guest-walking functions in

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] hap: Merge the guest-walking functions into one.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 27 Jul 2007 03:08:11 -0700
Delivery-date: Fri, 27 Jul 2007 03:06:15 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] hap: Merge the guest-walking functions into one., Xen patchbot-unstable <=