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] x86: Use the shadow-code PT walker from t

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: Use the shadow-code PT walker from the HAP functions
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 19 Nov 2008 08:10:30 -0800
Delivery-date: Wed, 19 Nov 2008 08:11:56 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/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 Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1226581396 0
# Node ID 48879ca5884866c38b99a984ddf2854dfc6f9ff0
# Parent  7fb33d15dc9bc5892e4708011beded66dd756be3
x86: Use the shadow-code PT walker from the HAP functions

Replace the guts of the HAP pagetable walker with a call to the
newly-commonified walker from the shadow code.  This reduces
duplication, and gives HAP guests proper access control and A/D-bit
setting for memory accesses from the emulator

Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---
 xen/arch/x86/mm/page-guest32.h   |  100 ---------------------
 xen/arch/x86/mm/hap/guest_walk.c |  181 +++++++++------------------------------
 xen/arch/x86/mm/hap/private.h    |   34 -------
 3 files changed, 46 insertions(+), 269 deletions(-)

diff -r 7fb33d15dc9b -r 48879ca58848 xen/arch/x86/mm/hap/guest_walk.c
--- a/xen/arch/x86/mm/hap/guest_walk.c  Thu Nov 13 13:02:08 2008 +0000
+++ b/xen/arch/x86/mm/hap/guest_walk.c  Thu Nov 13 13:03:16 2008 +0000
@@ -19,25 +19,58 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
 
+
+#include <xen/domain_page.h>
+#include <xen/paging.h>
 #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/paging.h>
-#include <asm/p2m.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
+#if GUEST_PAGING_LEVELS <= CONFIG_PAGING_LEVELS
+
+#include <asm/guest_pt.h>
+
+unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)(
+    struct vcpu *v, unsigned long gva, uint32_t *pfec)
+{
+    unsigned long cr3;
+    uint32_t missing;
+    mfn_t top_mfn;
+    void *top_map;
+    p2m_type_t p2mt;
+    walk_t gw;
+
+    /* Get the top-level table's MFN */
+    cr3 = v->arch.hvm_vcpu.guest_cr[3];
+    top_mfn = gfn_to_mfn(v->domain, _gfn(cr3 >> PAGE_SHIFT), &p2mt);
+    if ( !p2m_is_ram(p2mt) )
+    {
+        pfec[0] &= ~PFEC_page_present;
+        return INVALID_GFN;
+    }
+
+    /* Map the top-level table and call the tree-walker */
+    ASSERT(mfn_valid(mfn_x(top_mfn)));
+    top_map = map_domain_page(mfn_x(top_mfn));
+#if GUEST_PAGING_LEVELS == 3
+    top_map += (cr3 & ~(PAGE_MASK | 31));
+#endif
+    missing = guest_walk_tables(v, gva, &gw, pfec[0], top_mfn, top_map);
+    unmap_domain_page(top_map);
+
+    /* Interpret the answer */
+    if ( missing == 0 ) 
+        return gfn_x(guest_l1e_get_gfn(gw.l1e));
+    
+    if ( missing & _PAGE_PRESENT )
+        pfec[0] &= ~PFEC_page_present;
+    
+    return INVALID_GFN;
+}
+
+#else
 
 unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)(
     struct vcpu *v, unsigned long gva, uint32_t *pfec)
@@ -48,130 +81,8 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
     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, uint32_t *pfec)
-{
-    unsigned long gcr3 = v->arch.hvm_vcpu.guest_cr[3];
-    int mode = GUEST_PAGING_LEVELS;
-    int lev, index;
-    paddr_t gpa = 0;
-    unsigned long gpfn, mfn;
-    p2m_type_t p2mt;
-    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 = mfn_x(gfn_to_mfn(v->domain, gpfn, &p2mt));
-        if ( !p2m_is_ram(p2mt) )
-        {
-            HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva,
-                       lev);
-            success = 0;
-            break;
-        }
-        ASSERT(mfn_valid(mfn));
-
-        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:
diff -r 7fb33d15dc9b -r 48879ca58848 xen/arch/x86/mm/hap/private.h
--- a/xen/arch/x86/mm/hap/private.h     Thu Nov 13 13:02:08 2008 +0000
+++ b/xen/arch/x86/mm/hap/private.h     Thu Nov 13 13:03:16 2008 +0000
@@ -20,9 +20,6 @@
 #ifndef __HAP_PRIVATE_H__
 #define __HAP_PRIVATE_H__
 
-#include <asm/flushtlb.h>
-#include <asm/hvm/support.h>
-
 /********************************************/
 /*          GUEST TRANSLATION FUNCS         */
 /********************************************/
@@ -33,36 +30,5 @@ unsigned long hap_gva_to_gfn_4level(stru
 unsigned long hap_gva_to_gfn_4level(struct vcpu *v, unsigned long gva,
                                     uint32_t *pfec);
 
-/********************************************/
-/*            MISC DEFINITIONS              */
-/********************************************/
-
-/* PT_SHIFT describes the amount by which a virtual address is shifted right 
- * to right justify the portion to be used for indexing into a page 
- * table, given the guest memory model (i.e. number of levels) and the level 
- * of the page table being accessed. The idea is from Virtual Iron's code.
- */
-static const int PT_SHIFT[][5] =
-  {   /*     ------  level ------           nr_levels  */
-    /*         1     2     3     4                   */
-    {    0,    0,    0,    0,    0},   /* 0 not used */
-    {    0,    0,    0,    0,    0},   /* 1 not used */
-    {    0,   12,   22,    0,    0},   /* 2  */
-    {    0,   12,   21,   30,    0},   /* 3  */
-    {    0,   12,   21,   30,   39}    /* 4  */
-  };
-
-/* PT_ENTRIES describes the number of entries in a page table, given the 
- * memory model (i.e. number of levels) and the level of the page table 
- * being considered. This idea from Virtual Iron's shadow code*/
-static const int PT_ENTRIES[][5] =
-  {   /*     ------  level ------           nr_levels  */
-    /*         1     2     3     4                   */
-    {    0,    0,    0,    0,    0},   /* 0 not used */
-    {    0,    0,    0,    0,    0},   /* 1 not used */
-    {    0, 1024, 1024,    0,    0},   /* 2  */
-    {    0,  512,  512,    4,    0},   /* 3  */
-    {    0,  512,  512,  512,  512}    /* 4  */
-  };
 
 #endif /* __SVM_NPT_H__ */
diff -r 7fb33d15dc9b -r 48879ca58848 xen/arch/x86/mm/page-guest32.h
--- a/xen/arch/x86/mm/page-guest32.h    Thu Nov 13 13:02:08 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-
-#ifndef __X86_PAGE_GUEST_H__
-#define __X86_PAGE_GUEST_H__
-
-#ifndef __ASSEMBLY__
-# include <asm/types.h>
-#endif
-
-#define PAGETABLE_ORDER_32         10
-#define L1_PAGETABLE_ENTRIES_32    (1<<PAGETABLE_ORDER_32)
-#define L2_PAGETABLE_ENTRIES_32    (1<<PAGETABLE_ORDER_32)
-#define ROOT_PAGETABLE_ENTRIES_32  L2_PAGETABLE_ENTRIES_32
-
-
-#define L1_PAGETABLE_SHIFT_32 12
-#define L2_PAGETABLE_SHIFT_32 22
-
-/* Extract flags into 12-bit integer, or turn 12-bit flags into a pte mask. */
-
-#ifndef __ASSEMBLY__
-
-typedef u32 intpte_32_t;
-
-typedef struct { intpte_32_t l1; } l1_pgentry_32_t;
-typedef struct { intpte_32_t l2; } l2_pgentry_32_t;
-typedef l2_pgentry_t root_pgentry_32_t;
-#endif
-
-#define get_pte_flags_32(x) ((u32)(x) & 0xFFF)
-#define put_pte_flags_32(x) ((intpte_32_t)(x))
-
-/* Get pte access flags (unsigned int). */
-#define l1e_get_flags_32(x)           (get_pte_flags_32((x).l1))
-#define l2e_get_flags_32(x)           (get_pte_flags_32((x).l2))
-
-#define l1e_get_paddr_32(x)           \
-    ((paddr_t)(((x).l1 & (PADDR_MASK&PAGE_MASK))))
-#define l2e_get_paddr_32(x)           \
-    ((paddr_t)(((x).l2 & (PADDR_MASK&PAGE_MASK))))
-
-/* Construct an empty pte. */
-#define l1e_empty_32()                ((l1_pgentry_32_t) { 0 })
-#define l2e_empty_32()                ((l2_pgentry_32_t) { 0 })
-
-/* Construct a pte from a pfn and access flags. */
-#define l1e_from_pfn_32(pfn, flags)   \
-    ((l1_pgentry_32_t) { ((intpte_32_t)(pfn) << PAGE_SHIFT) | 
put_pte_flags_32(flags) })
-#define l2e_from_pfn_32(pfn, flags)   \
-    ((l2_pgentry_32_t) { ((intpte_32_t)(pfn) << PAGE_SHIFT) | 
put_pte_flags_32(flags) })
-
-/* Construct a pte from a physical address and access flags. */
-#ifndef __ASSEMBLY__
-static inline l1_pgentry_32_t l1e_from_paddr_32(paddr_t pa, unsigned int flags)
-{
-    ASSERT((pa & ~(PADDR_MASK & PAGE_MASK)) == 0);
-    return (l1_pgentry_32_t) { pa | put_pte_flags_32(flags) };
-}
-static inline l2_pgentry_32_t l2e_from_paddr_32(paddr_t pa, unsigned int flags)
-{
-    ASSERT((pa & ~(PADDR_MASK & PAGE_MASK)) == 0);
-    return (l2_pgentry_32_t) { pa | put_pte_flags_32(flags) };
-}
-#endif /* !__ASSEMBLY__ */
-
-
-/* Construct a pte from a page pointer and access flags. */
-#define l1e_from_page_32(page, flags) 
(l1e_from_pfn_32(page_to_mfn(page),(flags)))
-#define l2e_from_page_32(page, flags) 
(l2e_from_pfn_32(page_to_mfn(page),(flags)))
-
-/* Add extra flags to an existing pte. */
-#define l1e_add_flags_32(x, flags)    ((x).l1 |= put_pte_flags_32(flags))
-#define l2e_add_flags_32(x, flags)    ((x).l2 |= put_pte_flags_32(flags))
-
-/* Remove flags from an existing pte. */
-#define l1e_remove_flags_32(x, flags) ((x).l1 &= ~put_pte_flags_32(flags))
-#define l2e_remove_flags_32(x, flags) ((x).l2 &= ~put_pte_flags_32(flags))
-
-/* Check if a pte's page mapping or significant access flags have changed. */
-#define l1e_has_changed_32(x,y,flags) \
-    ( !!(((x).l1 ^ (y).l1) & ((PADDR_MASK&PAGE_MASK)|put_pte_flags_32(flags))) 
)
-#define l2e_has_changed_32(x,y,flags) \
-    ( !!(((x).l2 ^ (y).l2) & ((PADDR_MASK&PAGE_MASK)|put_pte_flags_32(flags))) 
)
-
-/* Given a virtual address, get an entry offset into a page table. */
-#define l1_table_offset_32(a)         \
-    (((a) >> L1_PAGETABLE_SHIFT_32) & (L1_PAGETABLE_ENTRIES_32 - 1))
-#define l2_table_offset_32(a)         \
-    (((a) >> L2_PAGETABLE_SHIFT_32) & (L2_PAGETABLE_ENTRIES_32 - 1))
-
-#endif /* __X86_PAGE_GUEST_H__ */
-
-/*
- * 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] x86: Use the shadow-code PT walker from the HAP functions, Xen patchbot-unstable <=