x86emul: support RDRAND/RDSEED

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Jan Beulich committed 2017-01-19 10:32:13 +01:00
1 parent c4afd683f9
commit a8fe4ec532
3 files changed
+77 -2

No files matched your search

+2
View File
@@ -14,7 +14,9 @@ $(call cc-option-add,CFLAGS,CC,-Wnested-externs)
$(call as-insn-check,CFLAGS,CC,"vmcall",-DHAVE_GAS_VMX)
$(call as-insn-check,CFLAGS,CC,"crc32 %eax$$(comma)%eax",-DHAVE_GAS_SSE4_2)
$(call as-insn-check,CFLAGS,CC,"invept (%rax)$$(comma)%rax",-DHAVE_GAS_EPT)
$(call as-insn-check,CFLAGS,CC,"rdrand %eax",-DHAVE_GAS_RDRAND)
$(call as-insn-check,CFLAGS,CC,"rdfsbase %rax",-DHAVE_GAS_FSGSBASE)
$(call as-insn-check,CFLAGS,CC,"rdseed %eax",-DHAVE_GAS_RDSEED)
$(call as-insn-check,CFLAGS,CC,".equ \"x\"$$(comma)1", \
-U__OBJECT_LABEL__ -DHAVE_GAS_QUOTED_SYM \
'-D__OBJECT_LABEL__=$(subst $(BASEDIR)/,,$(CURDIR))/$$@')
+73 -2
View File
@@ -1351,6 +1351,7 @@ static bool vcpu_has(
#define vcpu_has_movbe() vcpu_has( 1, ECX, 22, ctxt, ops)
#define vcpu_has_popcnt() vcpu_has( 1, ECX, 23, ctxt, ops)
#define vcpu_has_avx() vcpu_has( 1, ECX, 28, ctxt, ops)
#define vcpu_has_rdrand() vcpu_has( 1, ECX, 30, ctxt, ops)
#define vcpu_has_lahf_lm() vcpu_has(0x80000001, ECX, 0, ctxt, ops)
#define vcpu_has_cr8_legacy() vcpu_has(0x80000001, ECX, 4, ctxt, ops)
#define vcpu_has_lzcnt() vcpu_has(0x80000001, ECX, 5, ctxt, ops)
@@ -1361,6 +1362,7 @@ static bool vcpu_has(
#define vcpu_has_bmi2() vcpu_has( 7, EBX, 8, ctxt, ops)
#define vcpu_has_rtm() vcpu_has( 7, EBX, 11, ctxt, ops)
#define vcpu_has_mpx() vcpu_has( 7, EBX, 14, ctxt, ops)
#define vcpu_has_rdseed() vcpu_has( 7, EBX, 18, ctxt, ops)
#define vcpu_has_adx() vcpu_has( 7, EBX, 19, ctxt, ops)
#define vcpu_has_smap() vcpu_has( 7, EBX, 20, ctxt, ops)
#define vcpu_has_clflushopt() vcpu_has( 7, EBX, 23, ctxt, ops)
@@ -5754,14 +5756,83 @@ x86_emulate(
dst.val = src.val;
break;
case X86EMUL_OPC(0x0f, 0xc7): /* Grp9 (cmpxchg8b/cmpxchg16b) */ {
case X86EMUL_OPC(0x0f, 0xc7): /* Grp9 */
{
union {
uint32_t u32[2];
uint64_t u64[2];
} *old, *aux;
if ( ea.type == OP_REG )
{
bool __maybe_unused carry;
switch ( modrm_reg & 7 )
{
default:
goto cannot_emulate;
#ifdef HAVE_GAS_RDRAND
case 6: /* rdrand */
generate_exception_if(rep_prefix(), EXC_UD);
host_and_vcpu_must_have(rdrand);
dst = ea;
switch ( op_bytes )
{
case 2:
asm ( "rdrand %w0" ASM_FLAG_OUT(, "; setc %1")
: "=r" (dst.val), ASM_FLAG_OUT("=@ccc", "=qm") (carry) );
break;
default:
# ifdef __x86_64__
asm ( "rdrand %k0" ASM_FLAG_OUT(, "; setc %1")
: "=r" (dst.val), ASM_FLAG_OUT("=@ccc", "=qm") (carry) );
break;
case 8:
# endif
asm ( "rdrand %0" ASM_FLAG_OUT(, "; setc %1")
: "=r" (dst.val), ASM_FLAG_OUT("=@ccc", "=qm") (carry) );
break;
}
_regs._eflags &= ~EFLAGS_MASK;
if ( carry )
_regs._eflags |= EFLG_CF;
break;
#endif
#ifdef HAVE_GAS_RDSEED
case 7: /* rdseed */
generate_exception_if(rep_prefix(), EXC_UD);
host_and_vcpu_must_have(rdseed);
dst = ea;
switch ( op_bytes )
{
case 2:
asm ( "rdseed %w0" ASM_FLAG_OUT(, "; setc %1")
: "=r" (dst.val), ASM_FLAG_OUT("=@ccc", "=qm") (carry) );
break;
default:
# ifdef __x86_64__
asm ( "rdseed %k0" ASM_FLAG_OUT(, "; setc %1")
: "=r" (dst.val), ASM_FLAG_OUT("=@ccc", "=qm") (carry) );
break;
case 8:
# endif
asm ( "rdseed %0" ASM_FLAG_OUT(, "; setc %1")
: "=r" (dst.val), ASM_FLAG_OUT("=@ccc", "=qm") (carry) );
break;
}
_regs._eflags &= ~EFLAGS_MASK;
if ( carry )
_regs._eflags |= EFLG_CF;
break;
#endif
}
break;
}
/* cmpxchg8b/cmpxchg16b */
generate_exception_if((modrm_reg & 7) != 1, EXC_UD);
generate_exception_if(ea.type != OP_MEM, EXC_UD);
fail_if(!ops->cmpxchg);
if ( rex_prefix & REX_W )
{
+2
View File
@@ -73,6 +73,8 @@
#define cpu_has_monitor boot_cpu_has(X86_FEATURE_MONITOR)
#define cpu_has_eist boot_cpu_has(X86_FEATURE_EIST)
#define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR)
#define cpu_has_rdrand boot_cpu_has(X86_FEATURE_RDRAND)
#define cpu_has_rdseed boot_cpu_has(X86_FEATURE_RDSEED)
#define cpu_has_cmp_legacy boot_cpu_has(X86_FEATURE_CMP_LEGACY)
#define cpu_has_tbm boot_cpu_has(X86_FEATURE_TBM)
#define cpu_has_itsc boot_cpu_has(X86_FEATURE_ITSC)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.