[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 25/25] target/i386: Implement CPUID_EXT_RDRAND
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PULL 25/25] target/i386: Implement CPUID_EXT_RDRAND |
Date: |
Wed, 22 May 2019 14:42:26 -0400 |
We now have an interface for guest visible random numbers.
Reviewed-by: Eduardo Habkost <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---
target/i386/helper.h | 2 ++
target/i386/cpu.c | 5 ++--
target/i386/int_helper.c | 21 ++++++++++++++
target/i386/translate.c | 62 ++++++++++++++++++++++++++++++----------
4 files changed, 73 insertions(+), 17 deletions(-)
diff --git a/target/i386/helper.h b/target/i386/helper.h
index 6fb8fb9b74..8f9e1905c3 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -226,3 +226,5 @@ DEF_HELPER_3(rcrl, tl, env, tl, tl)
DEF_HELPER_3(rclq, tl, env, tl, tl)
DEF_HELPER_3(rcrq, tl, env, tl, tl)
#endif
+
+DEF_HELPER_1(rdrand, tl, env)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 2df56fa977..357d3c43a1 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -730,13 +730,14 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t
vendor1,
CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \
- CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
+ CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \
+ CPUID_EXT_RDRAND)
/* missing:
CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_AVX,
- CPUID_EXT_F16C, CPUID_EXT_RDRAND */
+ CPUID_EXT_F16C */
#ifdef TARGET_X86_64
#define TCG_EXT2_X86_64_FEATURES (CPUID_EXT2_SYSCALL | CPUID_EXT2_LM)
diff --git a/target/i386/int_helper.c b/target/i386/int_helper.c
index 4dc5c65991..334469ca8c 100644
--- a/target/i386/int_helper.c
+++ b/target/i386/int_helper.c
@@ -22,6 +22,8 @@
#include "exec/exec-all.h"
#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
+#include "qapi/error.h"
+#include "qemu/guest-random.h"
//#define DEBUG_MULDIV
@@ -470,3 +472,22 @@ void helper_cr4_testbit(CPUX86State *env, uint32_t bit)
raise_exception_ra(env, EXCP06_ILLOP, GETPC());
}
}
+
+target_ulong HELPER(rdrand)(CPUX86State *env)
+{
+ Error *err = NULL;
+ target_ulong ret;
+
+ if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
+ qemu_log_mask(LOG_UNIMP, "rdrand: Crypto failure: %s",
+ error_get_pretty(err));
+ error_free(err);
+ /* Failure clears CF and all other flags, and returns 0. */
+ env->cc_src = 0;
+ return 0;
+ }
+
+ /* Success sets CF and clears all others. */
+ env->cc_src = CC_C;
+ return ret;
+}
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 77d6b73e42..03150a86e2 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -5332,31 +5332,63 @@ static target_ulong disas_insn(DisasContext *s,
CPUState *cpu)
case 0x1c7: /* cmpxchg8b */
modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3;
- if ((mod == 3) || ((modrm & 0x38) != 0x8))
- goto illegal_op;
-#ifdef TARGET_X86_64
- if (dflag == MO_64) {
- if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
+ switch ((modrm >> 3) & 7) {
+ case 1: /* CMPXCHG8, CMPXCHG16 */
+ if (mod == 3) {
goto illegal_op;
- gen_lea_modrm(env, s, modrm);
- if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) &
CF_PARALLEL)) {
- gen_helper_cmpxchg16b(cpu_env, s->A0);
- } else {
- gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
}
- } else
+#ifdef TARGET_X86_64
+ if (dflag == MO_64) {
+ if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) {
+ goto illegal_op;
+ }
+ gen_lea_modrm(env, s, modrm);
+ if ((s->prefix & PREFIX_LOCK) &&
+ (tb_cflags(s->base.tb) & CF_PARALLEL)) {
+ gen_helper_cmpxchg16b(cpu_env, s->A0);
+ } else {
+ gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
+ }
+ set_cc_op(s, CC_OP_EFLAGS);
+ break;
+ }
#endif
- {
- if (!(s->cpuid_features & CPUID_CX8))
+ if (!(s->cpuid_features & CPUID_CX8)) {
goto illegal_op;
+ }
gen_lea_modrm(env, s, modrm);
- if ((s->prefix & PREFIX_LOCK) && (tb_cflags(s->base.tb) &
CF_PARALLEL)) {
+ if ((s->prefix & PREFIX_LOCK) &&
+ (tb_cflags(s->base.tb) & CF_PARALLEL)) {
gen_helper_cmpxchg8b(cpu_env, s->A0);
} else {
gen_helper_cmpxchg8b_unlocked(cpu_env, s->A0);
}
+ set_cc_op(s, CC_OP_EFLAGS);
+ break;
+
+ case 7: /* RDSEED */
+ case 6: /* RDRAND */
+ if (mod != 3 ||
+ (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) ||
+ !(s->cpuid_ext_features & CPUID_EXT_RDRAND)) {
+ goto illegal_op;
+ }
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+ gen_io_start();
+ }
+ gen_helper_rdrand(s->T0, cpu_env);
+ rm = (modrm & 7) | REX_B(s);
+ gen_op_mov_reg_v(s, dflag, rm, s->T0);
+ set_cc_op(s, CC_OP_EFLAGS);
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+ gen_io_end();
+ gen_jmp(s, s->pc - s->cs_base);
+ }
+ break;
+
+ default:
+ goto illegal_op;
}
- set_cc_op(s, CC_OP_EFLAGS);
break;
/**************************/
--
2.17.1
- [Qemu-devel] [PULL 00/25] Add qemu_getrandom and ARMv8.5-RNG etc, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 19/25] hw/misc/bcm2835_rng: Use qemu_guest_getrandom_nofail, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 09/25] ui/vnc: Use gcrypto_random_bytes for start_auth_vnc, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 03/25] crypto: Reverse code blocks in random-platform.c, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 25/25] target/i386: Implement CPUID_EXT_RDRAND,
Richard Henderson <=
- [Qemu-devel] [PULL 23/25] target/ppc: Use gen_io_start/end around DARN, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 17/25] aspeed/scu: Use qemu_guest_getrandom_nofail, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 11/25] cpus: Initialize pseudo-random seeds for all guest cpus, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 22/25] target/arm: Implement ARMv8.5-RNG, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 15/25] linux-user/aarch64: Use qemu_guest_getrandom for PAUTH keys, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 16/25] linux-user: Remove srand call, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 05/25] crypto: Use O_CLOEXEC in qcrypto_random_init, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 06/25] crypto: Use getrandom for qcrypto_random_bytes, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 08/25] ui/vnc: Split out authentication_failed, Richard Henderson, 2019/05/22
- [Qemu-devel] [PULL 04/25] crypto: Do not fail for EINTR during qcrypto_random_bytes, Richard Henderson, 2019/05/22