From: BitKeeper B. <ri...@su...> - 2005-02-19 02:53:38
|
ChangeSet 1.1223, 2005/02/18 13:34:28+00:00, ka...@sc... Change priv-op emulation behaviour to fail silently in some cases rather than propagate the fault (still non-silent in debug builds!). Also be careful in running user-specified RDMSR/WRMSR: an invalid MSR index causes a GP(0) fault. Signed-off-by: Keir Fraser <ke...@xe...> arch/x86/dom0_ops.c | 4 ++-- arch/x86/traps.c | 23 +++++++++++------------ include/asm-x86/config.h | 12 ++++++++---- include/asm-x86/msr.h | 43 ++++++++++++++++++++++++++++++------------- 4 files changed, 51 insertions(+), 31 deletions(-) diff -Nru a/xen/arch/x86/dom0_ops.c b/xen/arch/x86/dom0_ops.c --- a/xen/arch/x86/dom0_ops.c 2005-02-18 09:03:18 -05:00 +++ b/xen/arch/x86/dom0_ops.c 2005-02-18 09:03:18 -05:00 @@ -36,13 +36,13 @@ static void write_msr_for(void *unused) { if (((1 << current->processor) & msr_cpu_mask)) - wrmsr(msr_addr, msr_lo, msr_hi); + (void)wrmsr_user(msr_addr, msr_lo, msr_hi); } static void read_msr_for(void *unused) { if (((1 << current->processor) & msr_cpu_mask)) - rdmsr(msr_addr, msr_lo, msr_hi); + (void)rdmsr_user(msr_addr, msr_lo, msr_hi); } long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op) diff -Nru a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c 2005-02-18 09:03:18 -05:00 +++ b/xen/arch/x86/traps.c 2005-02-18 09:03:18 -05:00 @@ -375,12 +375,11 @@ break; case 0x09: /* WBINVD */ + /* Ignore the instruction if unprivileged. */ if ( !IS_CAPABLE_PHYSDEV(ed->domain) ) - { DPRINTK("Non-physdev domain attempted WBINVD.\n"); - goto fail; - } - wbinvd(); + else + wbinvd(); break; case 0x20: /* MOV CR?,<reg> */ @@ -441,21 +440,21 @@ break; case 0x30: /* WRMSR */ + /* Ignore the instruction if unprivileged. */ if ( !IS_PRIV(ed->domain) ) - { - DPRINTK("Non-priv domain attempted WRMSR.\n"); + DPRINTK("Non-priv domain attempted WRMSR(%p,%08lx,%08lx).\n", + regs->ecx, (long)regs->eax, (long)regs->edx); + else if ( wrmsr_user(regs->ecx, regs->eax, regs->edx) ) goto fail; - } - wrmsr(regs->ecx, regs->eax, regs->edx); break; case 0x32: /* RDMSR */ if ( !IS_PRIV(ed->domain) ) - { - DPRINTK("Non-priv domain attempted RDMSR.\n"); + DPRINTK("Non-priv domain attempted RDMSR(%p,%08lx,%08lx).\n", + regs->ecx, (long)regs->eax, (long)regs->edx); + /* Everyone can read the MSR space. */ + if ( rdmsr_user(regs->ecx, regs->eax, regs->edx) ) goto fail; - } - rdmsr(regs->ecx, regs->eax, regs->edx); break; default: diff -Nru a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h --- a/xen/include/asm-x86/config.h 2005-02-18 09:03:18 -05:00 +++ b/xen/include/asm-x86/config.h 2005-02-18 09:03:18 -05:00 @@ -206,8 +206,10 @@ #define __GUEST_SS 0x082b /* For generic assembly code: use macros to define operation/operand sizes. */ -#define __OS "q" /* Operation Suffix */ -#define __OP "r" /* Operand Prefix */ +#define __OS "q" /* Operation Suffix */ +#define __OP "r" /* Operand Prefix */ +#define __FIXUP_ALIGN ".align 8" +#define __FIXUP_WORD ".quad" #elif defined(__i386__) @@ -264,8 +266,10 @@ #define __HYPERVISOR_DS 0x0810 /* For generic assembly code: use macros to define operation/operand sizes. */ -#define __OS "l" /* Operation Suffix */ -#define __OP "e" /* Operand Prefix */ +#define __OS "l" /* Operation Suffix */ +#define __OP "e" /* Operand Prefix */ +#define __FIXUP_ALIGN ".align 4" +#define __FIXUP_WORD ".long" #endif /* __i386__ */ diff -Nru a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h --- a/xen/include/asm-x86/msr.h 2005-02-18 09:03:18 -05:00 +++ b/xen/include/asm-x86/msr.h 2005-02-18 09:03:18 -05:00 @@ -1,28 +1,45 @@ #ifndef __ASM_MSR_H #define __ASM_MSR_H -/* - * Access to machine-specific registers (available on 586 and better only) - * Note: the rd* operations modify the parameters directly (without using - * pointer indirection), this allows gcc to optimize better - */ - #define rdmsr(msr,val1,val2) \ __asm__ __volatile__("rdmsr" \ : "=a" (val1), "=d" (val2) \ : "c" (msr)) -#define rdmsrl(msr,val) do { unsigned long a__,b__; \ - __asm__ __volatile__("rdmsr" \ - : "=a" (a__), "=d" (b__) \ - : "c" (msr)); \ - val = a__ | (b__<<32); \ -} while(0); - #define wrmsr(msr,val1,val2) \ __asm__ __volatile__("wrmsr" \ : /* no outputs */ \ : "c" (msr), "a" (val1), "d" (val2)) + +#define rdmsr_user(msr,val1,val2) ({\ + int _rc = 0; \ + __asm__ __volatile__( \ + "1: rdmsr\n2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl $1,%2\n; jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " "__FIXUP_ALIGN"\n" \ + " "__FIXUP_WORD" 1b,3b\n" \ + ".previous\n" \ + : "=a" (val1), "=d" (val2), "=r" (_rc) \ + : "c" (msr)); \ + _rc; }) + +#define wrmsr_user(msr,val1,val2) ({\ + int _rc = 0; \ + __asm__ __volatile__( \ + "1: wrmsr\n2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl $1,%0\n; jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " "__FIXUP_ALIGN"\n" \ + " "__FIXUP_WORD" 1b,3b\n" \ + ".previous\n" \ + : "=r" (_rc) \ + : "c" (msr), "a" (val1), "d" (val2)); \ + _rc; }) #define rdtsc(low,high) \ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) |