diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-06-19 16:47:21 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-06-19 16:47:21 +0100 |
commit | a4f314d74337066bd81a2eb774844b6578904f62 (patch) | |
tree | 4651f2f36a20043f1d3296c35f7336fac6297feb /xen/include/asm-x86/shadow.h | |
parent | 2be827a77339c739fb0352876a41c362c01e5f5c (diff) | |
download | xen-a4f314d74337066bd81a2eb774844b6578904f62.tar.gz xen-a4f314d74337066bd81a2eb774844b6578904f62.tar.bz2 xen-a4f314d74337066bd81a2eb774844b6578904f62.zip |
[HVM][VMX][PAE] Enable PAE VMX guest on PAE host.
The PAE VMX guest supports NX bit and can do kernel build successfully.
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
Signed-off-by: Xiaohui Xin <xiaohui.xin@intel.com>
Diffstat (limited to 'xen/include/asm-x86/shadow.h')
-rw-r--r-- | xen/include/asm-x86/shadow.h | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index 32ac908464..397d4beb6b 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -112,6 +112,30 @@ do { \ } while (0) #endif +#if CONFIG_PAGING_LEVELS >= 3 +static inline u64 get_cr3_idxval(struct vcpu *v) +{ + u64 pae_cr3; + + if ( v->domain->arch.ops->guest_paging_levels == PAGING_L3 && + !shadow_mode_log_dirty(v->domain) ) + { + pae_cr3 = hvm_get_guest_ctrl_reg(v, 3); /* get CR3 */ + return (pae_cr3 >> PAE_CR3_ALIGN) & PAE_CR3_IDX_MASK; + } + else + return 0; +} + +#define shadow_key_t u64 +#define index_to_key(x) ((x) << 32) +#else +#define get_cr3_idxval(v) (0) +#define shadow_key_t unsigned long +#define index_to_key(x) (0) +#endif + + #define SHADOW_ENCODE_MIN_MAX(_min, _max) ((((GUEST_L1_PAGETABLE_ENTRIES - 1) - (_max)) << 16) | (_min)) #define SHADOW_MIN(_encoded) ((_encoded) & ((1u<<16) - 1)) #define SHADOW_MAX(_encoded) ((GUEST_L1_PAGETABLE_ENTRIES - 1) - ((_encoded) >> 16)) @@ -309,7 +333,7 @@ extern unsigned long get_mfn_from_gpfn_foreign( struct shadow_status { struct shadow_status *next; /* Pull-to-front list per hash bucket. */ - unsigned long gpfn_and_flags; /* Guest pfn plus flags. */ + shadow_key_t gpfn_and_flags; /* Guest pfn plus flags. */ unsigned long smfn; /* Shadow mfn. */ }; @@ -1180,7 +1204,13 @@ static inline unsigned long __shadow_status( struct domain *d, unsigned long gpfn, unsigned long stype) { struct shadow_status *p, *x, *head; - unsigned long key = gpfn | stype; + shadow_key_t key; +#if CONFIG_PAGING_LEVELS >= 3 + if ( d->arch.ops->guest_paging_levels == PAGING_L3 && stype == PGT_l4_shadow ) + key = gpfn | stype | index_to_key(get_cr3_idxval(current)); + else +#endif + key = gpfn | stype; ASSERT(shadow_lock_is_acquired(d)); ASSERT(gpfn == (gpfn & PGT_mfn_mask)); @@ -1295,10 +1325,11 @@ shadow_max_pgtable_type(struct domain *d, unsigned long gpfn, } static inline void delete_shadow_status( - struct domain *d, unsigned long gpfn, unsigned long gmfn, unsigned int stype) + struct domain *d, unsigned long gpfn, unsigned long gmfn, unsigned int stype, u64 index) { struct shadow_status *p, *x, *n, *head; - unsigned long key = gpfn | stype; + + shadow_key_t key = gpfn | stype | index_to_key(index); ASSERT(shadow_lock_is_acquired(d)); ASSERT(!(gpfn & ~PGT_mfn_mask)); @@ -1374,11 +1405,12 @@ static inline void delete_shadow_status( static inline void set_shadow_status( struct domain *d, unsigned long gpfn, unsigned long gmfn, - unsigned long smfn, unsigned long stype) + unsigned long smfn, unsigned long stype, u64 index) { struct shadow_status *x, *head, *extra; int i; - unsigned long key = gpfn | stype; + + shadow_key_t key = gpfn | stype | index_to_key(index); SH_VVLOG("set gpfn=%lx gmfn=%lx smfn=%lx t=%lx", gpfn, gmfn, smfn, stype); |