summary refs log tree commit diff stats
path: root/target-i386/misc_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-i386/misc_helper.c')
-rw-r--r--target-i386/misc_helper.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 93933fd162..b6307ca386 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -566,6 +566,15 @@ void helper_rdmsr(CPUX86State *env)
 }
 #endif
 
+static void do_pause(X86CPU *cpu)
+{
+    CPUX86State *env = &cpu->env;
+
+    /* Just let another CPU run.  */
+    env->exception_index = EXCP_INTERRUPT;
+    cpu_loop_exit(env);
+}
+
 static void do_hlt(X86CPU *cpu)
 {
     CPUState *cs = CPU(cpu);
@@ -611,13 +620,22 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
     cs = CPU(cpu);
     /* XXX: not complete but not completely erroneous */
     if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
-        /* more than one CPU: do not sleep because another CPU may
-           wake this one */
+        do_pause(cpu);
     } else {
         do_hlt(cpu);
     }
 }
 
+void helper_pause(CPUX86State *env, int next_eip_addend)
+{
+    X86CPU *cpu = x86_env_get_cpu(env);
+
+    cpu_svm_check_intercept_param(env, SVM_EXIT_PAUSE, 0);
+    env->eip += next_eip_addend;
+
+    do_pause(cpu);
+}
+
 void helper_debug(CPUX86State *env)
 {
     env->exception_index = EXCP_DEBUG;