target-i386: Implement FSGSBASE
Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
a114d25d5b
commit
07929f2ab2
@ -358,9 +358,9 @@ static const char *cpuid_6_feature_name[] = {
|
||||
#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
|
||||
CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
|
||||
CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT | \
|
||||
CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX)
|
||||
CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE)
|
||||
/* missing:
|
||||
CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
|
||||
CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
|
||||
CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
|
||||
CPUID_7_0_EBX_RDSEED */
|
||||
#define TCG_7_0_ECX_FEATURES 0
|
||||
@ -2730,6 +2730,9 @@ static void x86_cpu_reset(CPUState *s)
|
||||
if (env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) {
|
||||
cr4 |= CR4_OSFXSR_MASK | CR4_OSXSAVE_MASK;
|
||||
}
|
||||
if (env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_FSGSBASE) {
|
||||
cr4 |= CR4_FSGSBASE_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
env->xcr0 = xcr0;
|
||||
|
@ -15,6 +15,7 @@ DEF_HELPER_2(idivl_EAX, void, env, tl)
|
||||
DEF_HELPER_2(divq_EAX, void, env, tl)
|
||||
DEF_HELPER_2(idivq_EAX, void, env, tl)
|
||||
#endif
|
||||
DEF_HELPER_FLAGS_2(cr4_testbit, TCG_CALL_NO_WG, void, env, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_2(bndck, TCG_CALL_NO_WG, void, env, i32)
|
||||
DEF_HELPER_FLAGS_3(bndldx32, TCG_CALL_NO_WG, i64, env, tl, tl)
|
||||
|
@ -470,3 +470,13 @@ target_ulong helper_pext(target_ulong src, target_ulong mask)
|
||||
#include "shift_helper_template.h"
|
||||
#undef SHIFT
|
||||
#endif
|
||||
|
||||
/* Test that BIT is enabled in CR4. If not, raise an illegal opcode
|
||||
exception. This reduces the requirements for rare CR4 bits being
|
||||
mapped into HFLAGS. */
|
||||
void helper_cr4_testbit(CPUX86State *env, uint32_t bit)
|
||||
{
|
||||
if (unlikely((env->cr[4] & bit) == 0)) {
|
||||
raise_exception_ra(env, EXCP06_ILLOP, GETPC());
|
||||
}
|
||||
}
|
||||
|
@ -7902,6 +7902,40 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
||||
gen_nop_modrm(env, s, modrm);
|
||||
break;
|
||||
|
||||
case 0xc0 ... 0xc7: /* rdfsbase (f3 0f ae /0) */
|
||||
case 0xc8 ... 0xc8: /* rdgsbase (f3 0f ae /1) */
|
||||
case 0xd0 ... 0xd7: /* wrfsbase (f3 0f ae /2) */
|
||||
case 0xd8 ... 0xd8: /* wrgsbase (f3 0f ae /3) */
|
||||
if (CODE64(s)
|
||||
&& (prefixes & PREFIX_REPZ)
|
||||
&& !(prefixes & PREFIX_LOCK)
|
||||
&& (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_FSGSBASE)) {
|
||||
TCGv base, treg, src, dst;
|
||||
|
||||
/* Preserve hflags bits by testing CR4 at runtime. */
|
||||
tcg_gen_movi_i32(cpu_tmp2_i32, CR4_FSGSBASE_MASK);
|
||||
gen_helper_cr4_testbit(cpu_env, cpu_tmp2_i32);
|
||||
|
||||
base = cpu_seg_base[modrm & 8 ? R_GS : R_FS];
|
||||
treg = cpu_regs[(modrm & 7) | REX_B(s)];
|
||||
|
||||
if (modrm & 0x10) {
|
||||
/* wr*base */
|
||||
dst = base, src = treg;
|
||||
} else {
|
||||
/* rd*base */
|
||||
dst = treg, src = base;
|
||||
}
|
||||
|
||||
if (s->dflag == MO_32) {
|
||||
tcg_gen_ext32u_tl(dst, src);
|
||||
} else {
|
||||
tcg_gen_mov_tl(dst, src);
|
||||
}
|
||||
break;
|
||||
}
|
||||
goto illegal_op;
|
||||
|
||||
case 0xf8: /* sfence / pcommit */
|
||||
if (prefixes & PREFIX_DATA) {
|
||||
/* pcommit */
|
||||
|
Loading…
Reference in New Issue
Block a user