[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 6/8] x86emul: support RDRAND/RDSEED



Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -14,7 +14,9 @@ $(call cc-option-add,CFLAGS,CC,-Wnested-
 $(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))/$$@')
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -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)
@@ -5737,14 +5739,82 @@ 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 )
         {
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -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)
 


Attachment: x86emul-RDRAND.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.