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>
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" \