]> Pileus Git - ~andy/linux/commitdiff
KVM: PPC: Move prepare_to_enter call site into subarch code
authorScott Wood <scottwood@freescale.com>
Wed, 9 Nov 2011 00:23:23 +0000 (18:23 -0600)
committerAvi Kivity <avi@redhat.com>
Mon, 5 Mar 2012 12:52:26 +0000 (14:52 +0200)
This function should be called with interrupts disabled, to avoid
a race where an exception is delivered after we check, but the
resched kick is received before we disable interrupts (and thus doesn't
actually trigger the exit code that would recheck exceptions).

booke already does this properly in the lightweight exit case, but
not on initial entry.

For now, move the call of prepare_to_enter into subarch-specific code so
that booke can do the right thing here.  Ideally book3s would do the same
thing, but I'm having a hard time seeing where it does any interrupt
disabling of this sort (plus it has several additional call sites), so
I'm deferring the book3s fix to someone more familiar with that code.
book3s behavior should be unchanged by this patch.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/booke.c
arch/powerpc/kvm/powerpc.c

index 536adee59c0768f6e40f21596429e04d1c1b8eab..b1e3b9c1326a013a8df44f27795dd5af22b826fb 100644 (file)
@@ -836,6 +836,8 @@ int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu)
                return -EINVAL;
        }
 
+       kvmppc_core_prepare_to_enter(vcpu);
+
        /* No need to go into the guest when all we'll do is come back out */
        if (signal_pending(current)) {
                run->exit_reason = KVM_EXIT_INTR;
index f3628581fb7c9d3f4effd700b9e61528ca55ce4e..203a7b7b58b98ef4f6dfacc52a5747e4264f2893 100644 (file)
@@ -929,6 +929,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
                return -EINVAL;
        }
 
+       kvmppc_core_prepare_to_enter(vcpu);
+
        /* No need to go into the guest when all we do is going out */
        if (signal_pending(current)) {
                kvm_run->exit_reason = KVM_EXIT_INTR;
index e082e348c88200a36acc5f4a10f3a5ff1a7772a1..feaefc433276cb78863604622084fd83818708d7 100644 (file)
@@ -295,6 +295,8 @@ void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
        unsigned long old_pending = vcpu->arch.pending_exceptions;
        unsigned int priority;
 
+       WARN_ON_ONCE(!irqs_disabled());
+
        priority = __ffs(*pending);
        while (priority <= BOOKE_IRQPRIO_MAX) {
                if (kvmppc_booke_irqprio_deliver(vcpu, priority))
@@ -323,6 +325,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 
        local_irq_disable();
 
+       kvmppc_core_prepare_to_enter(vcpu);
+
        if (signal_pending(current)) {
                kvm_run->exit_reason = KVM_EXIT_INTR;
                ret = -EINTR;
index 6186ec0d939b7fe619901bcdf345572c1ccc8514..7411bdd8ff6f0d79778c3f2db091c9b9ec64d9b6 100644 (file)
@@ -559,8 +559,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
                vcpu->arch.hcall_needed = 0;
        }
 
-       kvmppc_core_prepare_to_enter(vcpu);
-
        r = kvmppc_vcpu_run(run, vcpu);
 
        if (vcpu->sigset_active)