diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2023-06-21 00:47:31 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2023-06-26 10:23:56 +0200 |
commit | 6750485bf42a9917a29487aec899687669104e07 (patch) | |
tree | f3041f5dcd012248e81091fb384e28767fe12195 /target/i386/tcg/translate.c | |
parent | 53b9b4cc9fb956279c6494bfa7d7ea61f07bb214 (diff) |
target/i386: implement RDPID in TCG
RDPID corresponds to a RDMSR(TSC_AUX); however, it is unprivileged
so for user-mode emulation we must provide the value that the kernel
places in the MSR. For Linux, it is a combination of the current CPU
and the current NUMA node, both of which can be retrieved with getcpu(2).
Also try sched_getcpu(), which might be there on the BSDs. If there is
no portable way to retrieve the current CPU id from userspace, return 0.
RDTSCP is reimplemented as RDTSC + RDPID ECX; the differences in terms
of serializability are not relevant to QEMU.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target/i386/tcg/translate.c')
-rw-r--r-- | target/i386/tcg/translate.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 66800392bb..a6c2424133 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -3924,13 +3924,25 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) gen_cmpxchg8b(s, env, modrm); break; - case 7: /* RDSEED */ + case 7: /* RDSEED, RDPID with f3 prefix */ if (mod != 3 || - (s->prefix & (PREFIX_LOCK | PREFIX_REPZ | PREFIX_REPNZ)) || - !(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) { + (s->prefix & (PREFIX_LOCK | PREFIX_REPNZ))) { goto illegal_op; } - goto do_rdrand; + if (s->prefix & PREFIX_REPZ) { + if (!(s->cpuid_ext_features & CPUID_7_0_ECX_RDPID)) { + goto illegal_op; + } + gen_helper_rdpid(s->T0, cpu_env); + rm = (modrm & 7) | REX_B(s); + gen_op_mov_reg_v(s, dflag, rm, s->T0); + break; + } else { + if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_RDSEED)) { + goto illegal_op; + } + goto do_rdrand; + } case 6: /* RDRAND */ if (mod != 3 || @@ -6125,7 +6137,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) gen_update_cc_op(s); gen_update_eip_cur(s); translator_io_start(&s->base); - gen_helper_rdtscp(cpu_env); + gen_helper_rdtsc(cpu_env); + gen_helper_rdpid(s->T0, cpu_env); + gen_op_mov_reg_v(s, dflag, R_ECX, s->T0); break; default: |