debuggers.hg
changeset 22260:71f836615ea2
x86: adjust MSR_IA32_MISC_ENABLE handling
In the warning message issued on writes, the Xen-modified value should
be printed (and used to determine whether anything needs to be printed
at all), as the guest kernel will usually do a read-modify-write
cycle.
A question is whether Dom0 shouldn't be allowed control over some
bits, or whether some bits shouldn't be fully virtualized. I'm
particularly thinking of MSR_IA32_MISC_ENABLE_FAST_STRING, which
recent Linux kernels want to disable for CONFIG_KMEMCHECK.
While putting this together I also noticed that rdmsr_safe() failed to
initialize its output registers in the failure path, thus leading to
printing of uninitialized data in the guest WRMSR warning message.
Further, the default case value-changed check can be simplified.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
In the warning message issued on writes, the Xen-modified value should
be printed (and used to determine whether anything needs to be printed
at all), as the guest kernel will usually do a read-modify-write
cycle.
A question is whether Dom0 shouldn't be allowed control over some
bits, or whether some bits shouldn't be fully virtualized. I'm
particularly thinking of MSR_IA32_MISC_ENABLE_FAST_STRING, which
recent Linux kernels want to disable for CONFIG_KMEMCHECK.
While putting this together I also noticed that rdmsr_safe() failed to
initialize its output registers in the failure path, thus leading to
printing of uninitialized data in the guest WRMSR warning message.
Further, the default case value-changed check can be simplified.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
author | Keir Fraser <keir@xen.org> |
---|---|
date | Fri Sep 24 15:54:39 2010 +0100 (2010-09-24) |
parents | eb247ea9db8c |
children | c8331262efe6 |
files | xen/arch/x86/traps.c xen/include/asm-x86/msr.h |
line diff
1.1 --- a/xen/arch/x86/traps.c Fri Sep 24 15:53:31 2010 +0100 1.2 +++ b/xen/arch/x86/traps.c Fri Sep 24 15:54:39 2010 +0100 1.3 @@ -1670,6 +1670,16 @@ unsigned long guest_to_host_gpr_switch(u 1.4 1.5 void (*pv_post_outb_hook)(unsigned int port, u8 value); 1.6 1.7 +static inline uint64_t guest_misc_enable(uint64_t val) 1.8 +{ 1.9 + val &= ~(MSR_IA32_MISC_ENABLE_PERF_AVAIL | 1.10 + MSR_IA32_MISC_ENABLE_MONITOR_ENABLE); 1.11 + val |= MSR_IA32_MISC_ENABLE_BTS_UNAVAIL | 1.12 + MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL | 1.13 + MSR_IA32_MISC_ENABLE_XTPR_DISABLE; 1.14 + return val; 1.15 +} 1.16 + 1.17 /* Instruction fetch with error handling. */ 1.18 #define insn_fetch(type, base, eip, limit) \ 1.19 ({ unsigned long _rc, _ptr = (base) + (eip); \ 1.20 @@ -2266,6 +2276,13 @@ static int emulate_privileged_op(struct 1.21 if ( wrmsr_safe(MSR_FAM10H_MMIO_CONF_BASE, msr_content) != 0 ) 1.22 goto fail; 1.23 break; 1.24 + case MSR_IA32_MISC_ENABLE: 1.25 + if ( rdmsr_safe(regs->ecx, val) ) 1.26 + goto invalid; 1.27 + val = guest_misc_enable(val); 1.28 + if ( msr_content != val ) 1.29 + goto invalid; 1.30 + break; 1.31 case MSR_IA32_MPERF: 1.32 case MSR_IA32_APERF: 1.33 if (( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ) && 1.34 @@ -2302,8 +2319,7 @@ static int emulate_privileged_op(struct 1.35 if ( rc ) 1.36 break; 1.37 1.38 - if ( (rdmsr_safe(regs->ecx, val) != 0) || 1.39 - (eax != (uint32_t)val) || (edx != (uint32_t)(val >> 32)) ) 1.40 + if ( (rdmsr_safe(regs->ecx, val) != 0) || (msr_content != val) ) 1.41 invalid: 1.42 gdprintk(XENLOG_WARNING, "Domain attempted WRMSR %p from " 1.43 "0x%016"PRIx64" to 0x%016"PRIx64".\n", 1.44 @@ -2374,13 +2390,9 @@ static int emulate_privileged_op(struct 1.45 case MSR_IA32_MISC_ENABLE: 1.46 if ( rdmsr_safe(regs->ecx, msr_content) ) 1.47 goto fail; 1.48 + msr_content = guest_misc_enable(msr_content); 1.49 regs->eax = (uint32_t)msr_content; 1.50 regs->edx = (uint32_t)(msr_content >> 32); 1.51 - regs->eax &= ~(MSR_IA32_MISC_ENABLE_PERF_AVAIL | 1.52 - MSR_IA32_MISC_ENABLE_MONITOR_ENABLE); 1.53 - regs->eax |= MSR_IA32_MISC_ENABLE_BTS_UNAVAIL | 1.54 - MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL | 1.55 - MSR_IA32_MISC_ENABLE_XTPR_DISABLE; 1.56 break; 1.57 case MSR_EFER: 1.58 case MSR_AMD_PATCHLEVEL:
2.1 --- a/xen/include/asm-x86/msr.h Fri Sep 24 15:53:31 2010 +0100 2.2 +++ b/xen/include/asm-x86/msr.h Fri Sep 24 15:54:39 2010 +0100 2.3 @@ -41,7 +41,8 @@ static inline void wrmsrl(unsigned int m 2.4 __asm__ __volatile__( \ 2.5 "1: rdmsr\n2:\n" \ 2.6 ".section .fixup,\"ax\"\n" \ 2.7 - "3: movl %5,%2\n; jmp 2b\n" \ 2.8 + "3: xorl %0,%0\n; xorl %1,%1\n" \ 2.9 + " movl %5,%2\n; jmp 2b\n" \ 2.10 ".previous\n" \ 2.11 ".section __ex_table,\"a\"\n" \ 2.12 " "__FIXUP_ALIGN"\n" \