From df01e0fc33af5b1247d8ac4bfec5b94466ff69c2 Mon Sep 17 00:00:00 2001 From: balrog Date: Sun, 9 Dec 2007 23:35:27 +0000 Subject: [PATCH] Add rdpmc SVM intercept, by Bernhard Kauer. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3791 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/exec.h | 1 + target-i386/helper.c | 12 ++++++++++++ target-i386/op.c | 5 +++++ target-i386/translate.c | 4 ++++ 4 files changed, 22 insertions(+) diff --git a/target-i386/exec.h b/target-i386/exec.h index 70fac64fc3..20153f7279 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -199,6 +199,7 @@ void helper_sysexit(void); void helper_syscall(int next_eip_addend); void helper_sysret(int dflag); void helper_rdtsc(void); +void helper_rdpmc(void); void helper_rdmsr(void); void helper_wrmsr(void); void helper_lsl(void); diff --git a/target-i386/helper.c b/target-i386/helper.c index a2f465c736..07ff3563cc 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -2743,6 +2743,18 @@ void helper_rdtsc(void) EDX = (uint32_t)(val >> 32); } +void helper_rdpmc(void) +{ + if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { + raise_exception(EXCP0D_GPF); + } + + if (!svm_check_intercept_param(SVM_EXIT_RDPMC, 0)) { + /* currently unimplemented */ + raise_exception_err(EXCP06_ILLOP, 0); + } +} + #if defined(CONFIG_USER_ONLY) void helper_wrmsr(void) { diff --git a/target-i386/op.c b/target-i386/op.c index 7d8950e079..77930db125 100644 --- a/target-i386/op.c +++ b/target-i386/op.c @@ -953,6 +953,11 @@ void OPPROTO op_rdtsc(void) helper_rdtsc(); } +void OPPROTO op_rdpmc(void) +{ + helper_rdpmc(); +} + void OPPROTO op_cpuid(void) { helper_cpuid(); diff --git a/target-i386/translate.c b/target-i386/translate.c index 02dc6cf61c..579831ef7a 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -5658,6 +5658,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_jmp_im(pc_start - s->cs_base); gen_op_rdtsc(); break; + case 0x133: /* rdpmc */ + gen_jmp_im(pc_start - s->cs_base); + gen_op_rdpmc(); + break; case 0x134: /* sysenter */ if (CODE64(s)) goto illegal_op;