[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-4.0-testing] x86 hvm: Fix MTRR physaddr-width check.
# HG changeset patch # User Keir Fraser <keir@xxxxxxx> # Date 1289335340 0 # Node ID 750c0c1e4606c91cd800701ca02e9e180e21c4c5 # Parent 31602ac2b5fa80af1669cbab5863baf8a50acd8d x86 hvm: Fix MTRR physaddr-width check. Should be checking against physaddr width presented to teh guest, rather than the host physaddr width. Signed-off-by: Keir Fraser <keir@xxxxxxx> xen-unstable changeset: 22374:9997a1418633 xen-unstable date: Tue Nov 09 11:48:43 2010 +0000 --- xen/arch/x86/hvm/hvm.c | 2 - xen/arch/x86/hvm/mtrr.c | 64 +++++++++++++++++++++------------------------ xen/include/asm-x86/mtrr.h | 5 ++- 3 files changed, 35 insertions(+), 36 deletions(-) diff -r 31602ac2b5fa -r 750c0c1e4606 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Mon Nov 08 15:39:37 2010 +0000 +++ b/xen/arch/x86/hvm/hvm.c Tue Nov 09 20:42:20 2010 +0000 @@ -2120,7 +2120,7 @@ int hvm_msr_write_intercept(struct cpu_u case MSR_IA32_MTRR_PHYSBASE0...MSR_IA32_MTRR_PHYSMASK7: if ( !mtrr ) goto gp_fault; - if ( !mtrr_var_range_msr_set(&v->arch.hvm_vcpu.mtrr, + if ( !mtrr_var_range_msr_set(v->domain, &v->arch.hvm_vcpu.mtrr, regs->ecx, msr_content) ) goto gp_fault; break; diff -r 31602ac2b5fa -r 750c0c1e4606 xen/arch/x86/hvm/mtrr.c --- a/xen/arch/x86/hvm/mtrr.c Mon Nov 08 15:39:37 2010 +0000 +++ b/xen/arch/x86/hvm/mtrr.c Tue Nov 09 20:42:20 2010 +0000 @@ -30,10 +30,7 @@ extern struct mtrr_state mtrr_state; -static uint64_t phys_base_msr_mask; -static uint64_t phys_mask_msr_mask; static uint32_t size_or_mask; -static uint32_t size_and_mask; /* Get page attribute fields (PAn) from PAT MSR. */ #define pat_cr_2_paf(pat_cr,n) ((((uint64_t)pat_cr) >> ((n)<<3)) & 0xff) @@ -181,11 +178,7 @@ static int hvm_mtrr_pat_init(void) if ( cpuid_eax(0x80000000) >= 0x80000008 ) phys_addr = (uint8_t)cpuid_eax(0x80000008); - phys_base_msr_mask = ~((((uint64_t)1) << phys_addr) - 1) | 0xf00UL; - phys_mask_msr_mask = ~((((uint64_t)1) << phys_addr) - 1) | 0x7ffUL; - size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1); - size_and_mask = ~size_or_mask & 0xfff00000; return 0; } @@ -482,34 +475,39 @@ bool_t mtrr_fix_range_msr_set(struct mtr return 1; } -bool_t mtrr_var_range_msr_set(struct mtrr_state *m, uint32_t msr, - uint64_t msr_content) -{ - uint32_t index; +bool_t mtrr_var_range_msr_set( + struct domain *d, struct mtrr_state *m, uint32_t msr, uint64_t msr_content) +{ + uint32_t index, type, phys_addr, eax, ebx, ecx, edx; uint64_t msr_mask; uint64_t *var_range_base = (uint64_t*)m->var_ranges; index = msr - MSR_IA32_MTRR_PHYSBASE0; - - if ( var_range_base[index] != msr_content ) - { - uint32_t type = msr_content & 0xff; - - msr_mask = (index & 1) ? phys_mask_msr_mask : phys_base_msr_mask; - - if ( unlikely(!(type == 0 || type == 1 || - type == 4 || type == 5 || type == 6)) ) - return 0; - - if ( unlikely(msr_content && (msr_content & msr_mask)) ) - { - HVM_DBG_LOG(DBG_LEVEL_MSR, "invalid msr content:%"PRIx64"\n", - msr_content); - return 0; - } - - var_range_base[index] = msr_content; - } + if ( var_range_base[index] == msr_content ) + return 1; + + type = (uint8_t)msr_content; + if ( unlikely(!(type == 0 || type == 1 || + type == 4 || type == 5 || type == 6)) ) + return 0; + + phys_addr = 36; + domain_cpuid(d, 0x80000000, 0, &eax, &ebx, &ecx, &edx); + if ( eax >= 0x80000008 ) + { + domain_cpuid(d, 0x80000008, 0, &eax, &ebx, &ecx, &edx); + phys_addr = (uint8_t)eax; + } + msr_mask = ~((((uint64_t)1) << phys_addr) - 1); + msr_mask |= (index & 1) ? 0x7ffUL : 0xf00UL; + if ( unlikely(msr_content && (msr_content & msr_mask)) ) + { + HVM_DBG_LOG(DBG_LEVEL_MSR, "invalid msr content:%"PRIx64"\n", + msr_content); + return 0; + } + + var_range_base[index] = msr_content; m->overlapped = is_var_mtrr_overlapped(m); @@ -692,9 +690,9 @@ static int hvm_load_mtrr_msr(struct doma for ( i = 0; i < MTRR_VCNT; i++ ) { - mtrr_var_range_msr_set(mtrr_state, + mtrr_var_range_msr_set(d, mtrr_state, MTRRphysBase_MSR(i), hw_mtrr.msr_mtrr_var[i*2]); - mtrr_var_range_msr_set(mtrr_state, + mtrr_var_range_msr_set(d, mtrr_state, MTRRphysMask_MSR(i), hw_mtrr.msr_mtrr_var[i*2+1]); } diff -r 31602ac2b5fa -r 750c0c1e4606 xen/include/asm-x86/mtrr.h --- a/xen/include/asm-x86/mtrr.h Mon Nov 08 15:39:37 2010 +0000 +++ b/xen/include/asm-x86/mtrr.h Tue Nov 09 20:42:20 2010 +0000 @@ -76,8 +76,9 @@ extern void mtrr_aps_sync_end(void); extern void mtrr_aps_sync_end(void); extern void mtrr_bp_restore(void); -extern bool_t mtrr_var_range_msr_set(struct mtrr_state *v, - uint32_t msr, uint64_t msr_content); +extern bool_t mtrr_var_range_msr_set( + struct domain *d, struct mtrr_state *m, + uint32_t msr, uint64_t msr_content); extern bool_t mtrr_fix_range_msr_set(struct mtrr_state *v, uint32_t row, uint64_t msr_content); extern bool_t mtrr_def_type_msr_set(struct mtrr_state *v, uint64_t msr_content); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |