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 )
{
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;
}
/* 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"
}
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);
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)