[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86emul: support RDPKRU/WRPKRU
Since we support PKU for HVM guests, the respective insns should also be recognized by the emulator. In emul_test_read_cr() instead of further extending the comment to explain the hex numbers, switch to using X86_CR4_* values. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -2399,6 +2399,23 @@ int main(int argc, char **argv) goto fail; printf("okay\n"); + printf("%-40s", "Testing rdpkru / wrpkru..."); + instr[0] = 0x0f; instr[1] = 0x01; + regs.ecx = 0; + for ( i = 0, j = (uint32_t)-__LINE__; i < 3; ++i ) + { + instr[2] = 0xee | (i & 1); + regs.eax = i < 2 ? j : 0; + regs.edx = i & 1 ? 0 : j; + regs.eip = (unsigned long)&instr[0]; + rc = x86_emulate(&ctxt, &emulops); + if ( (rc != X86EMUL_OKAY) || + (!(i & 1) && (regs.eax != (i ? j : 0) || regs.edx)) || + (regs.eip != (unsigned long)&instr[3]) ) + goto fail; + } + printf("okay\n"); + printf("%-40s", "Testing movdiri %edx,(%ecx)..."); if ( stack_exec && cpu_has_movdiri ) { --- a/tools/tests/x86_emulator/x86-emulate.c +++ b/tools/tests/x86_emulator/x86-emulate.c @@ -184,8 +184,8 @@ int emul_test_read_cr( return X86EMUL_OKAY; case 4: - /* OSFXSR, OSXMMEXCPT, and maybe OSXSAVE */ - *val = 0x00000600 | (cpu_has_xsave ? 0x00040000 : 0); + *val = X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT | X86_CR4_PKE | + (cpu_has_xsave ? X86_CR4_OSXSAVE : 0); return X86EMUL_OKAY; } @@ -256,4 +256,16 @@ void emul_test_put_fpu( /* TBD */ } +static uint32_t pkru; + +static unsigned int read_pkru(void) +{ + return pkru; +} + +static void write_pkru(unsigned int val) +{ + pkru = val; +} + #include "x86_emulate/x86_emulate.c" --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -5815,6 +5815,39 @@ x86_emulate( } break; + case 0xee: + switch ( vex.pfx ) + { + case vex_none: /* rdpkru */ + if ( !ops->read_cr || + ops->read_cr(4, &cr4, ctxt) != X86EMUL_OKAY ) + cr4 = 0; + generate_exception_if(!(cr4 & X86_CR4_PKE), EXC_UD); + generate_exception_if(_regs.ecx, EXC_GP, 0); + _regs.r(ax) = read_pkru(); + _regs.r(dx) = 0; + break; + default: + goto unimplemented_insn; + } + break; + + case 0xef: + switch ( vex.pfx ) + { + case vex_none: /* wrpkru */ + if ( !ops->read_cr || + ops->read_cr(4, &cr4, ctxt) != X86EMUL_OKAY ) + cr4 = 0; + generate_exception_if(!(cr4 & X86_CR4_PKE), EXC_UD); + generate_exception_if(_regs.ecx | _regs.edx, EXC_GP, 0); + write_pkru(_regs.eax); + break; + default: + goto unimplemented_insn; + } + break; + case 0xf8: /* swapgs */ generate_exception_if(!mode_64bit(), EXC_UD); generate_exception_if(!mode_ring0(), EXC_GP, 0); --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -385,6 +385,17 @@ static inline unsigned int read_pkru(voi return pkru; } +static inline void write_pkru(unsigned int pkru) +{ + unsigned long cr4 = read_cr4(); + + /* See read_pkru() */ + write_cr4(cr4 | X86_CR4_PKE); + asm volatile ( ".byte 0x0f, 0x01, 0xef" + :: "a" (pkru), "d" (0), "c" (0) ); + write_cr4(cr4); +} + /* Macros for PKRU domain */ #define PKRU_READ (0) #define PKRU_WRITE (1)
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |