ia64/xen-unstable

changeset 18793:b87cc4de3ca6

x86: Move guest_l*e definitions into common code

Move the definitions of guest pagetable types and the guest pagetable
walk record out of the shadow-code headers into asm-x86.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Nov 13 13:01:22 2008 +0000 (2008-11-13)
parents 9f68b6ae6243
children 7fb33d15dc9b
files xen/arch/x86/mm/shadow/multi.c xen/arch/x86/mm/shadow/types.h xen/include/asm-x86/guest_pt.h
line diff
     1.1 --- a/xen/arch/x86/mm/shadow/multi.c	Thu Nov 13 10:50:50 2008 +0000
     1.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Thu Nov 13 13:01:22 2008 +0000
     1.3 @@ -35,6 +35,7 @@
     1.4  #include <asm/hvm/hvm.h>
     1.5  #include <asm/hvm/cacheattr.h>
     1.6  #include <asm/mtrr.h>
     1.7 +#include <asm/guest_pt.h>
     1.8  #include "private.h"
     1.9  #include "types.h"
    1.10  
    1.11 @@ -254,7 +255,7 @@ static uint32_t set_ad_bits(void *guest_
    1.12   * Return 1 to indicate success and 0 for inconsistency
    1.13   */
    1.14  static inline uint32_t
    1.15 -shadow_check_gwalk(struct vcpu *v, unsigned long va, walk_t *gw)
    1.16 +shadow_check_gwalk(struct vcpu *v, unsigned long va, walk_t *gw, int version)
    1.17  {
    1.18      struct domain *d = v->domain;
    1.19      guest_l1e_t *l1p;
    1.20 @@ -267,9 +268,8 @@ shadow_check_gwalk(struct vcpu *v, unsig
    1.21  
    1.22      ASSERT(shadow_locked_by_me(d));
    1.23  
    1.24 -    if ( gw->version ==
    1.25 -         atomic_read(&d->arch.paging.shadow.gtable_dirty_version) )
    1.26 -        return 1;
    1.27 +    if ( version == atomic_read(&d->arch.paging.shadow.gtable_dirty_version) )
    1.28 +         return 1;
    1.29  
    1.30      /* We may consider caching guest page mapping from last
    1.31       * guest table walk. However considering this check happens
    1.32 @@ -402,9 +402,6 @@ guest_walk_tables(struct vcpu *v, unsign
    1.33      memset(gw, 0, sizeof(*gw));
    1.34      gw->va = va;
    1.35  
    1.36 -    gw->version = atomic_read(&d->arch.paging.shadow.gtable_dirty_version);
    1.37 -    rmb();
    1.38 -
    1.39      /* Mandatory bits that must be set in every entry.  We invert NX, to
    1.40       * calculate as if there were an "X" bit that allowed access. 
    1.41       * We will accumulate, in rc, the set of flags that are missing. */
    1.42 @@ -3173,6 +3170,7 @@ static int sh_page_fault(struct vcpu *v,
    1.43      fetch_type_t ft = 0;
    1.44      p2m_type_t p2mt;
    1.45      uint32_t rc;
    1.46 +    int version;
    1.47  #if SHADOW_OPTIMIZATIONS & SHOPT_FAST_EMULATION
    1.48      int fast_emul = 0;
    1.49  #endif
    1.50 @@ -3316,6 +3314,8 @@ static int sh_page_fault(struct vcpu *v,
    1.51      }
    1.52  
    1.53   rewalk:
    1.54 +    version = atomic_read(&d->arch.paging.shadow.gtable_dirty_version);
    1.55 +    rmb();
    1.56      rc = guest_walk_tables(v, va, &gw, regs->error_code);
    1.57  
    1.58  #if (SHADOW_OPTIMIZATIONS & SHOPT_OUT_OF_SYNC)
    1.59 @@ -3392,7 +3392,7 @@ static int sh_page_fault(struct vcpu *v,
    1.60      }
    1.61  #endif /* OOS */
    1.62  
    1.63 -    if ( !shadow_check_gwalk(v, va, &gw) )
    1.64 +    if ( !shadow_check_gwalk(v, va, &gw, version) )
    1.65      {
    1.66          perfc_incr(shadow_inconsistent_gwalk);
    1.67          shadow_unlock(d);
     2.1 --- a/xen/arch/x86/mm/shadow/types.h	Thu Nov 13 10:50:50 2008 +0000
     2.2 +++ b/xen/arch/x86/mm/shadow/types.h	Thu Nov 13 13:01:22 2008 +0000
     2.3 @@ -191,169 +191,13 @@ static inline shadow_l4e_t shadow_l4e_fr
     2.4  })
     2.5  #endif
     2.6  
     2.7 -
     2.8 -/* Type of the guest's frame numbers */
     2.9 -TYPE_SAFE(unsigned long,gfn)
    2.10 -#define SH_PRI_gfn "05lx"
    2.11 -
    2.12 -#define VALID_GFN(m) (m != INVALID_GFN)
    2.13 -
    2.14 -static inline int
    2.15 -valid_gfn(gfn_t m)
    2.16 -{
    2.17 -    return VALID_GFN(gfn_x(m));
    2.18 -}
    2.19 -
    2.20 -static inline paddr_t
    2.21 -gfn_to_paddr(gfn_t gfn)
    2.22 -{
    2.23 -    return ((paddr_t)gfn_x(gfn)) << PAGE_SHIFT;
    2.24 -}
    2.25 -
    2.26 -/* Override gfn_to_mfn to work with gfn_t */
    2.27 -#undef gfn_to_mfn
    2.28 -#define gfn_to_mfn(d, g, t) _gfn_to_mfn((d), gfn_x(g), (t))
    2.29 +/* The shadow types needed for the various levels. */
    2.30  
    2.31  #if GUEST_PAGING_LEVELS == 2
    2.32 -
    2.33 -#include "../page-guest32.h"
    2.34 -
    2.35 -#define GUEST_L1_PAGETABLE_ENTRIES     1024
    2.36 -#define GUEST_L2_PAGETABLE_ENTRIES     1024
    2.37 -#define GUEST_L1_PAGETABLE_SHIFT         12
    2.38 -#define GUEST_L2_PAGETABLE_SHIFT         22
    2.39 -
    2.40 -/* Types of the guest's page tables */
    2.41 -typedef l1_pgentry_32_t guest_l1e_t;
    2.42 -typedef l2_pgentry_32_t guest_l2e_t;
    2.43 -typedef intpte_32_t guest_intpte_t;
    2.44 -
    2.45 -/* Access functions for them */
    2.46 -static inline paddr_t guest_l1e_get_paddr(guest_l1e_t gl1e)
    2.47 -{ return l1e_get_paddr_32(gl1e); }
    2.48 -static inline paddr_t guest_l2e_get_paddr(guest_l2e_t gl2e)
    2.49 -{ return l2e_get_paddr_32(gl2e); }
    2.50 -
    2.51 -static inline gfn_t guest_l1e_get_gfn(guest_l1e_t gl1e)
    2.52 -{ return _gfn(l1e_get_paddr_32(gl1e) >> PAGE_SHIFT); }
    2.53 -static inline gfn_t guest_l2e_get_gfn(guest_l2e_t gl2e)
    2.54 -{ return _gfn(l2e_get_paddr_32(gl2e) >> PAGE_SHIFT); }
    2.55 -
    2.56 -static inline u32 guest_l1e_get_flags(guest_l1e_t gl1e)
    2.57 -{ return l1e_get_flags_32(gl1e); }
    2.58 -static inline u32 guest_l2e_get_flags(guest_l2e_t gl2e)
    2.59 -{ return l2e_get_flags_32(gl2e); }
    2.60 -
    2.61 -static inline guest_l1e_t guest_l1e_add_flags(guest_l1e_t gl1e, u32 flags)
    2.62 -{ l1e_add_flags_32(gl1e, flags); return gl1e; }
    2.63 -static inline guest_l2e_t guest_l2e_add_flags(guest_l2e_t gl2e, u32 flags)
    2.64 -{ l2e_add_flags_32(gl2e, flags); return gl2e; }
    2.65 -
    2.66 -static inline guest_l1e_t guest_l1e_from_gfn(gfn_t gfn, u32 flags)
    2.67 -{ return l1e_from_pfn_32(gfn_x(gfn), flags); }
    2.68 -static inline guest_l2e_t guest_l2e_from_gfn(gfn_t gfn, u32 flags)
    2.69 -{ return l2e_from_pfn_32(gfn_x(gfn), flags); }
    2.70 -
    2.71 -#define guest_l1_table_offset(a) l1_table_offset_32(a)
    2.72 -#define guest_l2_table_offset(a) l2_table_offset_32(a)
    2.73 -
    2.74 -/* The shadow types needed for the various levels. */
    2.75  #define SH_type_l1_shadow  SH_type_l1_32_shadow
    2.76  #define SH_type_l2_shadow  SH_type_l2_32_shadow
    2.77  #define SH_type_fl1_shadow SH_type_fl1_32_shadow
    2.78 -
    2.79 -#else /* GUEST_PAGING_LEVELS != 2 */
    2.80 -
    2.81 -#if GUEST_PAGING_LEVELS == 3
    2.82 -#define GUEST_L1_PAGETABLE_ENTRIES      512
    2.83 -#define GUEST_L2_PAGETABLE_ENTRIES      512
    2.84 -#define GUEST_L3_PAGETABLE_ENTRIES        4
    2.85 -#define GUEST_L1_PAGETABLE_SHIFT         12
    2.86 -#define GUEST_L2_PAGETABLE_SHIFT         21
    2.87 -#define GUEST_L3_PAGETABLE_SHIFT         30
    2.88 -#else /* GUEST_PAGING_LEVELS == 4 */
    2.89 -#define GUEST_L1_PAGETABLE_ENTRIES      512
    2.90 -#define GUEST_L2_PAGETABLE_ENTRIES      512
    2.91 -#define GUEST_L3_PAGETABLE_ENTRIES      512
    2.92 -#define GUEST_L4_PAGETABLE_ENTRIES      512
    2.93 -#define GUEST_L1_PAGETABLE_SHIFT         12
    2.94 -#define GUEST_L2_PAGETABLE_SHIFT         21
    2.95 -#define GUEST_L3_PAGETABLE_SHIFT         30
    2.96 -#define GUEST_L4_PAGETABLE_SHIFT         39
    2.97 -#endif
    2.98 -
    2.99 -/* Types of the guest's page tables */
   2.100 -typedef l1_pgentry_t guest_l1e_t;
   2.101 -typedef l2_pgentry_t guest_l2e_t;
   2.102 -typedef l3_pgentry_t guest_l3e_t;
   2.103 -#if GUEST_PAGING_LEVELS >= 4
   2.104 -typedef l4_pgentry_t guest_l4e_t;
   2.105 -#endif
   2.106 -typedef intpte_t guest_intpte_t;
   2.107 -
   2.108 -/* Access functions for them */
   2.109 -static inline paddr_t guest_l1e_get_paddr(guest_l1e_t gl1e)
   2.110 -{ return l1e_get_paddr(gl1e); }
   2.111 -static inline paddr_t guest_l2e_get_paddr(guest_l2e_t gl2e)
   2.112 -{ return l2e_get_paddr(gl2e); }
   2.113 -static inline paddr_t guest_l3e_get_paddr(guest_l3e_t gl3e)
   2.114 -{ return l3e_get_paddr(gl3e); }
   2.115 -#if GUEST_PAGING_LEVELS >= 4
   2.116 -static inline paddr_t guest_l4e_get_paddr(guest_l4e_t gl4e)
   2.117 -{ return l4e_get_paddr(gl4e); }
   2.118 -#endif
   2.119 -
   2.120 -static inline gfn_t guest_l1e_get_gfn(guest_l1e_t gl1e)
   2.121 -{ return _gfn(l1e_get_paddr(gl1e) >> PAGE_SHIFT); }
   2.122 -static inline gfn_t guest_l2e_get_gfn(guest_l2e_t gl2e)
   2.123 -{ return _gfn(l2e_get_paddr(gl2e) >> PAGE_SHIFT); }
   2.124 -static inline gfn_t guest_l3e_get_gfn(guest_l3e_t gl3e)
   2.125 -{ return _gfn(l3e_get_paddr(gl3e) >> PAGE_SHIFT); }
   2.126 -#if GUEST_PAGING_LEVELS >= 4
   2.127 -static inline gfn_t guest_l4e_get_gfn(guest_l4e_t gl4e)
   2.128 -{ return _gfn(l4e_get_paddr(gl4e) >> PAGE_SHIFT); }
   2.129 -#endif
   2.130 -
   2.131 -static inline u32 guest_l1e_get_flags(guest_l1e_t gl1e)
   2.132 -{ return l1e_get_flags(gl1e); }
   2.133 -static inline u32 guest_l2e_get_flags(guest_l2e_t gl2e)
   2.134 -{ return l2e_get_flags(gl2e); }
   2.135 -static inline u32 guest_l3e_get_flags(guest_l3e_t gl3e)
   2.136 -{ return l3e_get_flags(gl3e); }
   2.137 -#if GUEST_PAGING_LEVELS >= 4
   2.138 -static inline u32 guest_l4e_get_flags(guest_l4e_t gl4e)
   2.139 -{ return l4e_get_flags(gl4e); }
   2.140 -#endif
   2.141 -
   2.142 -static inline guest_l1e_t guest_l1e_add_flags(guest_l1e_t gl1e, u32 flags)
   2.143 -{ l1e_add_flags(gl1e, flags); return gl1e; }
   2.144 -static inline guest_l2e_t guest_l2e_add_flags(guest_l2e_t gl2e, u32 flags)
   2.145 -{ l2e_add_flags(gl2e, flags); return gl2e; }
   2.146 -static inline guest_l3e_t guest_l3e_add_flags(guest_l3e_t gl3e, u32 flags)
   2.147 -{ l3e_add_flags(gl3e, flags); return gl3e; }
   2.148 -#if GUEST_PAGING_LEVELS >= 4
   2.149 -static inline guest_l4e_t guest_l4e_add_flags(guest_l4e_t gl4e, u32 flags)
   2.150 -{ l4e_add_flags(gl4e, flags); return gl4e; }
   2.151 -#endif
   2.152 -
   2.153 -static inline guest_l1e_t guest_l1e_from_gfn(gfn_t gfn, u32 flags)
   2.154 -{ return l1e_from_pfn(gfn_x(gfn), flags); }
   2.155 -static inline guest_l2e_t guest_l2e_from_gfn(gfn_t gfn, u32 flags)
   2.156 -{ return l2e_from_pfn(gfn_x(gfn), flags); }
   2.157 -static inline guest_l3e_t guest_l3e_from_gfn(gfn_t gfn, u32 flags)
   2.158 -{ return l3e_from_pfn(gfn_x(gfn), flags); }
   2.159 -#if GUEST_PAGING_LEVELS >= 4
   2.160 -static inline guest_l4e_t guest_l4e_from_gfn(gfn_t gfn, u32 flags)
   2.161 -{ return l4e_from_pfn(gfn_x(gfn), flags); }
   2.162 -#endif
   2.163 -
   2.164 -#define guest_l1_table_offset(a) l1_table_offset(a)
   2.165 -#define guest_l2_table_offset(a) l2_table_offset(a)
   2.166 -#define guest_l3_table_offset(a) l3_table_offset(a)
   2.167 -#define guest_l4_table_offset(a) l4_table_offset(a)
   2.168 -
   2.169 -/* The shadow types needed for the various levels. */
   2.170 -#if GUEST_PAGING_LEVELS == 3
   2.171 +#elif GUEST_PAGING_LEVELS == 3
   2.172  #define SH_type_l1_shadow  SH_type_l1_pae_shadow
   2.173  #define SH_type_fl1_shadow SH_type_fl1_pae_shadow
   2.174  #define SH_type_l2_shadow  SH_type_l2_pae_shadow
   2.175 @@ -367,35 +211,6 @@ static inline guest_l4e_t guest_l4e_from
   2.176  #define SH_type_l4_shadow  SH_type_l4_64_shadow
   2.177  #endif
   2.178  
   2.179 -#endif /* GUEST_PAGING_LEVELS != 2 */
   2.180 -
   2.181 -
   2.182 -/* Type used for recording a walk through guest pagetables.  It is
   2.183 - * filled in by the pagetable walk function, and also used as a cache
   2.184 - * for later walks.  When we encounter a suporpage l2e, we fabricate an
   2.185 - * l1e for propagation to the shadow (for splintering guest superpages
   2.186 - * into many shadow l1 entries).  */
   2.187 -typedef struct shadow_walk_t walk_t;
   2.188 -struct shadow_walk_t 
   2.189 -{
   2.190 -    unsigned long va;           /* Address we were looking for */
   2.191 -#if GUEST_PAGING_LEVELS >= 3
   2.192 -#if GUEST_PAGING_LEVELS >= 4
   2.193 -    guest_l4e_t l4e;            /* Guest's level 4 entry */
   2.194 -#endif
   2.195 -    guest_l3e_t l3e;            /* Guest's level 3 entry */
   2.196 -#endif
   2.197 -    guest_l2e_t l2e;            /* Guest's level 2 entry */
   2.198 -    guest_l1e_t l1e;            /* Guest's level 1 entry (or fabrication) */
   2.199 -#if GUEST_PAGING_LEVELS >= 4
   2.200 -    mfn_t l4mfn;                /* MFN that the level 4 entry was in */
   2.201 -    mfn_t l3mfn;                /* MFN that the level 3 entry was in */
   2.202 -#endif
   2.203 -    mfn_t l2mfn;                /* MFN that the level 2 entry was in */
   2.204 -    mfn_t l1mfn;                /* MFN that the level 1 entry was in */
   2.205 -    int version;                /* Saved guest dirty version */
   2.206 -};
   2.207 -
   2.208  /* macros for dealing with the naming of the internal function names of the
   2.209   * shadow code's external entry points.
   2.210   */
   2.211 @@ -460,17 +275,9 @@ struct shadow_walk_t
   2.212  #define MFN_FITS_IN_HVM_CR3(_MFN) !(mfn_x(_MFN) >> 20)
   2.213  #endif
   2.214  
   2.215 -#define SH_PRI_pte PRIpte
   2.216 -
   2.217 -#if GUEST_PAGING_LEVELS == 2
   2.218 -#define SH_PRI_gpte "08x"
   2.219 -#else /* GUEST_PAGING_LEVELS >= 3 */
   2.220 -#ifndef __x86_64__
   2.221 -#define SH_PRI_gpte "016llx"
   2.222 -#else
   2.223 -#define SH_PRI_gpte "016lx"
   2.224 -#endif
   2.225 -#endif /* GUEST_PAGING_LEVELS >= 3 */
   2.226 +#define SH_PRI_pte  PRIpte
   2.227 +#define SH_PRI_gpte PRI_gpte
   2.228 +#define SH_PRI_gfn  PRI_gfn
   2.229  
   2.230  
   2.231  #if (SHADOW_OPTIMIZATIONS & SHOPT_FAST_FAULT_PATH)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/include/asm-x86/guest_pt.h	Thu Nov 13 13:01:22 2008 +0000
     3.3 @@ -0,0 +1,202 @@
     3.4 +/******************************************************************************
     3.5 + * xen/asm-x86/guest_pt.h
     3.6 + *
     3.7 + * Types and accessors for guest pagetable entries, as distinct from
     3.8 + * Xen's pagetable types. 
     3.9 + *
    3.10 + * Users must #define GUEST_PAGING_LEVELS to 2, 3 or 4 before including
    3.11 + * this file.
    3.12 + *
    3.13 + * Parts of this code are Copyright (c) 2006 by XenSource Inc.
    3.14 + * Parts of this code are Copyright (c) 2006 by Michael A Fetterman
    3.15 + * Parts based on earlier work by Michael A Fetterman, Ian Pratt et al.
    3.16 + * 
    3.17 + * This program is free software; you can redistribute it and/or modify
    3.18 + * it under the terms of the GNU General Public License as published by
    3.19 + * the Free Software Foundation; either version 2 of the License, or
    3.20 + * (at your option) any later version.
    3.21 + * 
    3.22 + * This program is distributed in the hope that it will be useful,
    3.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.25 + * GNU General Public License for more details.
    3.26 + * 
    3.27 + * You should have received a copy of the GNU General Public License
    3.28 + * along with this program; if not, write to the Free Software
    3.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.30 + */
    3.31 +
    3.32 +#ifndef _XEN_ASM_GUEST_PT_H
    3.33 +#define _XEN_ASM_GUEST_PT_H
    3.34 +
    3.35 +/* Type of the guest's frame numbers */
    3.36 +TYPE_SAFE(unsigned long,gfn)
    3.37 +#define PRI_gfn "05lx"
    3.38 +
    3.39 +#define VALID_GFN(m) (m != INVALID_GFN)
    3.40 +
    3.41 +static inline int
    3.42 +valid_gfn(gfn_t m)
    3.43 +{
    3.44 +    return VALID_GFN(gfn_x(m));
    3.45 +}
    3.46 +
    3.47 +static inline paddr_t
    3.48 +gfn_to_paddr(gfn_t gfn)
    3.49 +{
    3.50 +    return ((paddr_t)gfn_x(gfn)) << PAGE_SHIFT;
    3.51 +}
    3.52 +
    3.53 +/* Override gfn_to_mfn to work with gfn_t */
    3.54 +#undef gfn_to_mfn
    3.55 +#define gfn_to_mfn(d, g, t) _gfn_to_mfn((d), gfn_x(g), (t))
    3.56 +
    3.57 +
    3.58 +/* Types of the guest's page tables and access functions for them */
    3.59 +
    3.60 +#if GUEST_PAGING_LEVELS == 2
    3.61 +
    3.62 +#define GUEST_L1_PAGETABLE_ENTRIES     1024
    3.63 +#define GUEST_L2_PAGETABLE_ENTRIES     1024
    3.64 +#define GUEST_L1_PAGETABLE_SHIFT         12
    3.65 +#define GUEST_L2_PAGETABLE_SHIFT         22
    3.66 +
    3.67 +typedef uint32_t guest_intpte_t;
    3.68 +typedef struct { guest_intpte_t l1; } guest_l1e_t;
    3.69 +typedef struct { guest_intpte_t l2; } guest_l2e_t;
    3.70 +
    3.71 +#define PRI_gpte "08x"
    3.72 +
    3.73 +static inline paddr_t guest_l1e_get_paddr(guest_l1e_t gl1e)
    3.74 +{ return ((paddr_t) gl1e.l1) & (PADDR_MASK & PAGE_MASK); }
    3.75 +static inline paddr_t guest_l2e_get_paddr(guest_l2e_t gl2e)
    3.76 +{ return ((paddr_t) gl2e.l2) & (PADDR_MASK & PAGE_MASK); }
    3.77 +
    3.78 +static inline gfn_t guest_l1e_get_gfn(guest_l1e_t gl1e)
    3.79 +{ return _gfn(guest_l1e_get_paddr(gl1e) >> PAGE_SHIFT); }
    3.80 +static inline gfn_t guest_l2e_get_gfn(guest_l2e_t gl2e)
    3.81 +{ return _gfn(guest_l2e_get_paddr(gl2e) >> PAGE_SHIFT); }
    3.82 +
    3.83 +static inline u32 guest_l1e_get_flags(guest_l1e_t gl1e)
    3.84 +{ return gl1e.l1 & 0xfff; }
    3.85 +static inline u32 guest_l2e_get_flags(guest_l2e_t gl2e)
    3.86 +{ return gl2e.l2 & 0xfff; }
    3.87 +
    3.88 +static inline guest_l1e_t guest_l1e_from_gfn(gfn_t gfn, u32 flags)
    3.89 +{ return (guest_l1e_t) { (gfn_x(gfn) << PAGE_SHIFT) | flags }; }
    3.90 +static inline guest_l2e_t guest_l2e_from_gfn(gfn_t gfn, u32 flags)
    3.91 +{ return (guest_l2e_t) { (gfn_x(gfn) << PAGE_SHIFT) | flags }; }
    3.92 +
    3.93 +#define guest_l1_table_offset(_va)                                           \
    3.94 +    (((_va) >> GUEST_L1_PAGETABLE_SHIFT) & (GUEST_L1_PAGETABLE_ENTRIES - 1))
    3.95 +#define guest_l2_table_offset(_va)                                           \
    3.96 +    (((_va) >> GUEST_L2_PAGETABLE_SHIFT) & (GUEST_L2_PAGETABLE_ENTRIES - 1))
    3.97 +
    3.98 +#else /* GUEST_PAGING_LEVELS != 2 */
    3.99 +
   3.100 +#if GUEST_PAGING_LEVELS == 3
   3.101 +#define GUEST_L1_PAGETABLE_ENTRIES      512
   3.102 +#define GUEST_L2_PAGETABLE_ENTRIES      512
   3.103 +#define GUEST_L3_PAGETABLE_ENTRIES        4
   3.104 +#define GUEST_L1_PAGETABLE_SHIFT         12
   3.105 +#define GUEST_L2_PAGETABLE_SHIFT         21
   3.106 +#define GUEST_L3_PAGETABLE_SHIFT         30
   3.107 +#else /* GUEST_PAGING_LEVELS == 4 */
   3.108 +#define GUEST_L1_PAGETABLE_ENTRIES      512
   3.109 +#define GUEST_L2_PAGETABLE_ENTRIES      512
   3.110 +#define GUEST_L3_PAGETABLE_ENTRIES      512
   3.111 +#define GUEST_L4_PAGETABLE_ENTRIES      512
   3.112 +#define GUEST_L1_PAGETABLE_SHIFT         12
   3.113 +#define GUEST_L2_PAGETABLE_SHIFT         21
   3.114 +#define GUEST_L3_PAGETABLE_SHIFT         30
   3.115 +#define GUEST_L4_PAGETABLE_SHIFT         39
   3.116 +#endif
   3.117 +
   3.118 +typedef l1_pgentry_t guest_l1e_t;
   3.119 +typedef l2_pgentry_t guest_l2e_t;
   3.120 +typedef l3_pgentry_t guest_l3e_t;
   3.121 +#if GUEST_PAGING_LEVELS >= 4
   3.122 +typedef l4_pgentry_t guest_l4e_t;
   3.123 +#endif
   3.124 +typedef intpte_t guest_intpte_t;
   3.125 +
   3.126 +#define PRI_gpte "016"PRIx64
   3.127 +
   3.128 +static inline paddr_t guest_l1e_get_paddr(guest_l1e_t gl1e)
   3.129 +{ return l1e_get_paddr(gl1e); }
   3.130 +static inline paddr_t guest_l2e_get_paddr(guest_l2e_t gl2e)
   3.131 +{ return l2e_get_paddr(gl2e); }
   3.132 +static inline paddr_t guest_l3e_get_paddr(guest_l3e_t gl3e)
   3.133 +{ return l3e_get_paddr(gl3e); }
   3.134 +#if GUEST_PAGING_LEVELS >= 4
   3.135 +static inline paddr_t guest_l4e_get_paddr(guest_l4e_t gl4e)
   3.136 +{ return l4e_get_paddr(gl4e); }
   3.137 +#endif
   3.138 +
   3.139 +static inline gfn_t guest_l1e_get_gfn(guest_l1e_t gl1e)
   3.140 +{ return _gfn(l1e_get_paddr(gl1e) >> PAGE_SHIFT); }
   3.141 +static inline gfn_t guest_l2e_get_gfn(guest_l2e_t gl2e)
   3.142 +{ return _gfn(l2e_get_paddr(gl2e) >> PAGE_SHIFT); }
   3.143 +static inline gfn_t guest_l3e_get_gfn(guest_l3e_t gl3e)
   3.144 +{ return _gfn(l3e_get_paddr(gl3e) >> PAGE_SHIFT); }
   3.145 +#if GUEST_PAGING_LEVELS >= 4
   3.146 +static inline gfn_t guest_l4e_get_gfn(guest_l4e_t gl4e)
   3.147 +{ return _gfn(l4e_get_paddr(gl4e) >> PAGE_SHIFT); }
   3.148 +#endif
   3.149 +
   3.150 +static inline u32 guest_l1e_get_flags(guest_l1e_t gl1e)
   3.151 +{ return l1e_get_flags(gl1e); }
   3.152 +static inline u32 guest_l2e_get_flags(guest_l2e_t gl2e)
   3.153 +{ return l2e_get_flags(gl2e); }
   3.154 +static inline u32 guest_l3e_get_flags(guest_l3e_t gl3e)
   3.155 +{ return l3e_get_flags(gl3e); }
   3.156 +#if GUEST_PAGING_LEVELS >= 4
   3.157 +static inline u32 guest_l4e_get_flags(guest_l4e_t gl4e)
   3.158 +{ return l4e_get_flags(gl4e); }
   3.159 +#endif
   3.160 +
   3.161 +static inline guest_l1e_t guest_l1e_from_gfn(gfn_t gfn, u32 flags)
   3.162 +{ return l1e_from_pfn(gfn_x(gfn), flags); }
   3.163 +static inline guest_l2e_t guest_l2e_from_gfn(gfn_t gfn, u32 flags)
   3.164 +{ return l2e_from_pfn(gfn_x(gfn), flags); }
   3.165 +static inline guest_l3e_t guest_l3e_from_gfn(gfn_t gfn, u32 flags)
   3.166 +{ return l3e_from_pfn(gfn_x(gfn), flags); }
   3.167 +#if GUEST_PAGING_LEVELS >= 4
   3.168 +static inline guest_l4e_t guest_l4e_from_gfn(gfn_t gfn, u32 flags)
   3.169 +{ return l4e_from_pfn(gfn_x(gfn), flags); }
   3.170 +#endif
   3.171 +
   3.172 +#define guest_l1_table_offset(a) l1_table_offset(a)
   3.173 +#define guest_l2_table_offset(a) l2_table_offset(a)
   3.174 +#define guest_l3_table_offset(a) l3_table_offset(a)
   3.175 +#define guest_l4_table_offset(a) l4_table_offset(a)
   3.176 +
   3.177 +#endif /* GUEST_PAGING_LEVELS != 2 */
   3.178 +
   3.179 +
   3.180 +/* Type used for recording a walk through guest pagetables.  It is
   3.181 + * filled in by the pagetable walk function, and also used as a cache
   3.182 + * for later walks.  When we encounter a superpage l2e, we fabricate an
   3.183 + * l1e for propagation to the shadow (for splintering guest superpages
   3.184 + * into many shadow l1 entries).  */
   3.185 +typedef struct guest_pagetable_walk walk_t;
   3.186 +struct guest_pagetable_walk
   3.187 +{
   3.188 +    unsigned long va;           /* Address we were looking for */
   3.189 +#if GUEST_PAGING_LEVELS >= 3
   3.190 +#if GUEST_PAGING_LEVELS >= 4
   3.191 +    guest_l4e_t l4e;            /* Guest's level 4 entry */
   3.192 +#endif
   3.193 +    guest_l3e_t l3e;            /* Guest's level 3 entry */
   3.194 +#endif
   3.195 +    guest_l2e_t l2e;            /* Guest's level 2 entry */
   3.196 +    guest_l1e_t l1e;            /* Guest's level 1 entry (or fabrication) */
   3.197 +#if GUEST_PAGING_LEVELS >= 4
   3.198 +    mfn_t l4mfn;                /* MFN that the level 4 entry was in */
   3.199 +    mfn_t l3mfn;                /* MFN that the level 3 entry was in */
   3.200 +#endif
   3.201 +    mfn_t l2mfn;                /* MFN that the level 2 entry was in */
   3.202 +    mfn_t l1mfn;                /* MFN that the level 1 entry was in */
   3.203 +};
   3.204 +
   3.205 +#endif /* _XEN_ASM_GUEST_PT_H */