]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
pseries: Don't test for MSR_PR for hypercalls under KVM
authorDavid Gibson <david@gibson.dropbear.id.au>
Tue, 25 Sep 2012 17:12:20 +0000 (17:12 +0000)
committerMichael Roth <mdroth@linux.vnet.ibm.com>
Fri, 12 Oct 2012 02:44:21 +0000 (21:44 -0500)
PAPR hypercalls should only be invoked from the guest kernel, not guest
user programs, that is, with MSR[PR]=0.  Currently we check this in
spapr_hypercall, returning H_PRIVILEGE if MSR[PR]=1.

However, under KVM the state of MSR[PR] is already checked by the host
kernel before passing the hypercall to qemu, making this check redundant.
Worse, however, we don't generally synchronize KVM and qemu state on the
hypercall path, meaning that qemu could incorrectly reject a hypercall
because it has a stale MSR value.

This patch fixes the problem by moving the privilege test exclusively to
the TCG hypercall path.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
CC: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
(cherry picked from commit efcb9383b974114e5f682e531346006f8f2466c0)

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
hw/spapr.c
hw/spapr_hcall.c

index c34b767c6e910c01bf47d653839c8e6fb1a1d844..5e5543051c788042150d6a2330631ab9bc2bee50 100644 (file)
@@ -556,7 +556,12 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
 
 static void emulate_spapr_hypercall(CPUPPCState *env)
 {
-    env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
+    if (msr_pr) {
+        hcall_dprintf("Hypercall made with MSR[PR]=1\n");
+        env->gpr[3] = H_PRIVILEGE;
+    } else {
+        env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
+    }
 }
 
 static void spapr_reset(void *opaque)
index abd847f96cfd13f94048c1df0bcabcdce829747d..38098f78b03f0e26ce05d47414ae6782dd0d6f93 100644 (file)
@@ -713,11 +713,6 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
 target_ulong spapr_hypercall(CPUPPCState *env, target_ulong opcode,
                              target_ulong *args)
 {
-    if (msr_pr) {
-        hcall_dprintf("Hypercall made with MSR[PR]=1\n");
-        return H_PRIVILEGE;
-    }
-
     if ((opcode <= MAX_HCALL_OPCODE)
         && ((opcode & 0x3) == 0)) {
         spapr_hcall_fn fn = papr_hypercall_table[opcode / 4];