Loading target/i386/cpu.c +3 −2 Original line number Diff line number Diff line Loading @@ -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) Loading target/i386/helper.h +2 −0 Original line number Diff line number Diff line Loading @@ -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) target/i386/int_helper.c +21 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; } target/i386/translate.c +47 −15 Original line number Diff line number Diff line Loading @@ -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)) switch ((modrm >> 3) & 7) { case 1: /* CMPXCHG8, CMPXCHG16 */ if (mod == 3) { goto illegal_op; } #ifdef TARGET_X86_64 if (dflag == MO_64) { if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) 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)) { 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 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; } break; /**************************/ Loading Loading
target/i386/cpu.c +3 −2 Original line number Diff line number Diff line Loading @@ -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) Loading
target/i386/helper.h +2 −0 Original line number Diff line number Diff line Loading @@ -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)
target/i386/int_helper.c +21 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; }
target/i386/translate.c +47 −15 Original line number Diff line number Diff line Loading @@ -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)) switch ((modrm >> 3) & 7) { case 1: /* CMPXCHG8, CMPXCHG16 */ if (mod == 3) { goto illegal_op; } #ifdef TARGET_X86_64 if (dflag == MO_64) { if (!(s->cpuid_ext_features & CPUID_EXT_CX16)) 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)) { 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 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; } break; /**************************/ Loading