[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] x86emul: support RDPKRU/WRPKRU
commit d26c277826dbbd64b3e3cb57159e1ecbfad33bc8 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Mon May 3 15:31:43 2021 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Mon May 3 15:31:43 2021 +0200 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> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- tools/tests/x86_emulator/test_x86_emulator.c | 17 ++++++++++++++ tools/tests/x86_emulator/x86-emulate.c | 16 ++++++++++++-- xen/arch/x86/x86_emulate/x86_emulate.c | 33 ++++++++++++++++++++++++++++ xen/include/asm-x86/processor.h | 6 +++++ 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c index cbb8f34f58..9677476db0 100644 --- 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 ) { diff --git a/tools/tests/x86_emulator/x86-emulate.c b/tools/tests/x86_emulator/x86-emulate.c index fb34933e82..07f892dbbb 100644 --- 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 rdpkru(void) +{ + return pkru; +} + +static void wrpkru(unsigned int val) +{ + pkru = val; +} + #include "x86_emulate/x86_emulate.c" diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 4a33fe9613..c25d88d0d8 100644 --- 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) = rdpkru(); + _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); + wrpkru(_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); diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index d8d0dc8034..83143d4df8 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -377,6 +377,12 @@ static inline unsigned int rdpkru(void) return pkru; } +static inline void wrpkru(unsigned int pkru) +{ + asm volatile ( ".byte 0x0f, 0x01, 0xef" + :: "a" (pkru), "d" (0), "c" (0) ); +} + /* Macros for PKRU domain */ #define PKRU_READ (0) #define PKRU_WRITE (1) -- generated by git-patchbot for /home/xen/git/xen.git#staging
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |