aboutsummaryrefslogtreecommitdiff
path: root/target/i386/tcg/sysemu/misc_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-05-14 10:13:33 -0500
committerRichard Henderson <richard.henderson@linaro.org>2021-05-19 12:17:11 -0500
commit4ea2449b5818a2bb73ea5ac259279e58e4e11a20 (patch)
tree94edb3737f02fae955e48aef9c61dedd4dde06e0 /target/i386/tcg/sysemu/misc_helper.c
parenteb26784fe128d1369056bd708c89c2c327b333e9 (diff)
target/i386: Move invlpg, hlt, monitor, mwait to sysemu
These instructions are all privileged. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20210514151342.384376-42-richard.henderson@linaro.org>
Diffstat (limited to 'target/i386/tcg/sysemu/misc_helper.c')
-rw-r--r--target/i386/tcg/sysemu/misc_helper.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c
index c7381ef7e8..803c39e2fb 100644
--- a/target/i386/tcg/sysemu/misc_helper.c
+++ b/target/i386/tcg/sysemu/misc_helper.c
@@ -438,3 +438,56 @@ void helper_rdmsr(CPUX86State *env)
env->regs[R_EAX] = (uint32_t)(val);
env->regs[R_EDX] = (uint32_t)(val >> 32);
}
+
+void helper_invlpg(CPUX86State *env, target_ulong addr)
+{
+ X86CPU *cpu = env_archcpu(env);
+
+ cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0, GETPC());
+ tlb_flush_page(CPU(cpu), addr);
+}
+
+static void QEMU_NORETURN do_hlt(CPUX86State *env)
+{
+ CPUState *cs = env_cpu(env);
+
+ env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
+ cs->halted = 1;
+ cs->exception_index = EXCP_HLT;
+ cpu_loop_exit(cs);
+}
+
+void QEMU_NORETURN helper_hlt(CPUX86State *env, int next_eip_addend)
+{
+ cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC());
+ env->eip += next_eip_addend;
+
+ do_hlt(env);
+}
+
+void helper_monitor(CPUX86State *env, target_ulong ptr)
+{
+ if ((uint32_t)env->regs[R_ECX] != 0) {
+ raise_exception_ra(env, EXCP0D_GPF, GETPC());
+ }
+ /* XXX: store address? */
+ cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC());
+}
+
+void QEMU_NORETURN helper_mwait(CPUX86State *env, int next_eip_addend)
+{
+ CPUState *cs = env_cpu(env);
+
+ if ((uint32_t)env->regs[R_ECX] != 0) {
+ raise_exception_ra(env, EXCP0D_GPF, GETPC());
+ }
+ cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC());
+ env->eip += next_eip_addend;
+
+ /* XXX: not complete but not completely erroneous */
+ if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
+ do_pause(env);
+ } else {
+ do_hlt(env);
+ }
+}