[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 4/4] TCG x86: add RDTSCP support
From: |
Aurelien Jarno |
Subject: |
Re: [Qemu-devel] [PATCH 4/4] TCG x86: add RDTSCP support |
Date: |
Sun, 4 Oct 2009 14:47:22 +0200 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
On Sat, Sep 19, 2009 at 12:30:49AM +0200, Andre Przywara wrote:
> RDTSCP reads the time stamp counter and atomically also the content
> of a 32-bit MSR, which can be freely set by the OS. This allows CPU
> local data to be queried by userspace.
> Linux uses this to allow a fast implementation of the getcpu()
> syscall, which uses the vsyscall page to avoid a context switch.
> AMD CPUs since K8RevF and Intel CPUs since Nehalem support this
> instruction.
> RDTSCP is guarded by the RDTSCP CPUID bit (Fn8000_0001:EDX[27]).
Thanks, applied.
> Signed-off-by: Andre Przywara <address@hidden>
> ---
> target-i386/cpu.h | 5 +++-
> target-i386/helper.h | 1 +
> target-i386/machine.c | 4 +++
> target-i386/op_helper.c | 12 ++++++++++
> target-i386/translate.c | 57 ++++++++++++++++++++++++++++++++++------------
> 5 files changed, 63 insertions(+), 16 deletions(-)
>
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index b9a6392..f318942 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -322,6 +322,7 @@
> #define MSR_FSBASE 0xc0000100
> #define MSR_GSBASE 0xc0000101
> #define MSR_KERNELGSBASE 0xc0000102
> +#define MSR_TSC_AUX 0xc0000103
>
> #define MSR_VM_HSAVE_PA 0xc0010117
>
> @@ -694,6 +695,8 @@ typedef struct CPUX86State {
> uint64 mcg_status;
> uint64 mcg_ctl;
> uint64 *mce_banks;
> +
> + uint64_t tsc_aux;
> } CPUX86State;
>
> CPUX86State *cpu_x86_init(const char *cpu_model);
> @@ -854,7 +857,7 @@ uint64_t cpu_get_tsc(CPUX86State *env);
> #define cpu_signal_handler cpu_x86_signal_handler
> #define cpu_list x86_cpu_list
>
> -#define CPU_SAVE_VERSION 10
> +#define CPU_SAVE_VERSION 11
>
> /* MMU modes definitions */
> #define MMU_MODE0_SUFFIX _kernel
> diff --git a/target-i386/helper.h b/target-i386/helper.h
> index 38d0708..ef8d4e1 100644
> --- a/target-i386/helper.h
> +++ b/target-i386/helper.h
> @@ -80,6 +80,7 @@ DEF_HELPER_1(cmpxchg16b, void, tl)
> DEF_HELPER_0(single_step, void)
> DEF_HELPER_0(cpuid, void)
> DEF_HELPER_0(rdtsc, void)
> +DEF_HELPER_0(rdtscp, void)
> DEF_HELPER_0(rdpmc, void)
> DEF_HELPER_0(rdmsr, void)
> DEF_HELPER_0(wrmsr, void)
> diff --git a/target-i386/machine.c b/target-i386/machine.c
> index ab31329..e5a060f 100644
> --- a/target-i386/machine.c
> +++ b/target-i386/machine.c
> @@ -171,6 +171,7 @@ void cpu_save(QEMUFile *f, void *opaque)
> qemu_put_be64s(f, &env->mce_banks[4*i + 3]);
> }
> }
> + qemu_put_be64s(f, &env->tsc_aux);
> }
>
> #ifdef USE_X86LDOUBLE
> @@ -377,6 +378,9 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
> }
> }
>
> + if (version_id >= 11) {
> + qemu_get_be64s(f, &env->tsc_aux);
> + }
> /* XXX: ensure compatiblity for halted bit ? */
> /* XXX: compute redundant hflags bits */
> env->hflags = hflags;
> diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
> index 9ffda36..a457bdd 100644
> --- a/target-i386/op_helper.c
> +++ b/target-i386/op_helper.c
> @@ -2969,6 +2969,12 @@ void helper_rdtsc(void)
> EDX = (uint32_t)(val >> 32);
> }
>
> +void helper_rdtscp(void)
> +{
> + helper_rdtsc();
> + ECX = (uint32_t)(env->tsc_aux);
> +}
> +
> void helper_rdpmc(void)
> {
> if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
> @@ -3107,6 +3113,9 @@ void helper_wrmsr(void)
> && (val == 0 || val == ~(uint64_t)0))
> env->mcg_ctl = val;
> break;
> + case MSR_TSC_AUX:
> + env->tsc_aux = val;
> + break;
> default:
> if ((uint32_t)ECX >= MSR_MC0_CTL
> && (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
> @@ -3177,6 +3186,9 @@ void helper_rdmsr(void)
> case MSR_KERNELGSBASE:
> val = env->kernelgsbase;
> break;
> + case MSR_TSC_AUX:
> + val = env->tsc_aux;
> + break;
> #endif
> case MSR_MTRRphysBase(0):
> case MSR_MTRRphysBase(1):
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index 5cbcf07..306685d 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -7217,31 +7217,58 @@ static target_ulong disas_insn(DisasContext *s,
> target_ulong pc_start)
> gen_eob(s);
> }
> break;
> - case 7: /* invlpg */
> - if (s->cpl != 0) {
> - gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> + case 7:
> + if (mod != 3) { /* invlpg */
> + if (s->cpl != 0) {
> + gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> + } else {
> + if (s->cc_op != CC_OP_DYNAMIC)
> + gen_op_set_cc_op(s->cc_op);
> + gen_jmp_im(pc_start - s->cs_base);
> + gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
> + gen_helper_invlpg(cpu_A0);
> + gen_jmp_im(s->pc - s->cs_base);
> + gen_eob(s);
> + }
> } else {
> - if (mod == 3) {
> + switch (rm) {
> + case 0: /* swapgs */
> #ifdef TARGET_X86_64
> - if (CODE64(s) && rm == 0) {
> - /* swapgs */
> - tcg_gen_ld_tl(cpu_T[0], cpu_env,
> offsetof(CPUX86State,segs[R_GS].base));
> - tcg_gen_ld_tl(cpu_T[1], cpu_env,
> offsetof(CPUX86State,kernelgsbase));
> - tcg_gen_st_tl(cpu_T[1], cpu_env,
> offsetof(CPUX86State,segs[R_GS].base));
> - tcg_gen_st_tl(cpu_T[0], cpu_env,
> offsetof(CPUX86State,kernelgsbase));
> + if (CODE64(s)) {
> + if (s->cpl != 0) {
> + gen_exception(s, EXCP0D_GPF, pc_start -
> s->cs_base);
> + } else {
> + tcg_gen_ld_tl(cpu_T[0], cpu_env,
> + offsetof(CPUX86State,segs[R_GS].base));
> + tcg_gen_ld_tl(cpu_T[1], cpu_env,
> + offsetof(CPUX86State,kernelgsbase));
> + tcg_gen_st_tl(cpu_T[1], cpu_env,
> + offsetof(CPUX86State,segs[R_GS].base));
> + tcg_gen_st_tl(cpu_T[0], cpu_env,
> + offsetof(CPUX86State,kernelgsbase));
> + }
> } else
> #endif
> {
> goto illegal_op;
> }
> - } else {
> + break;
> + case 1: /* rdtscp */
> + if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
> + goto illegal_op;
> if (s->cc_op != CC_OP_DYNAMIC)
> gen_op_set_cc_op(s->cc_op);
> gen_jmp_im(pc_start - s->cs_base);
> - gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
> - gen_helper_invlpg(cpu_A0);
> - gen_jmp_im(s->pc - s->cs_base);
> - gen_eob(s);
> + if (use_icount)
> + gen_io_start();
> + gen_helper_rdtscp();
> + if (use_icount) {
> + gen_io_end();
> + gen_jmp(s, s->pc - s->cs_base);
> + }
> + break;
> + default:
> + goto illegal_op;
> }
> }
> break;
> --
> 1.6.1.3
>
>
>
>
>
--
Aurelien Jarno GPG: 1024D/F1BCDB73
address@hidden http://www.aurel32.net
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Qemu-devel] [PATCH 4/4] TCG x86: add RDTSCP support,
Aurelien Jarno <=