| From stable-owner@vger.kernel.org Wed May 9 06:11:16 2012 |
| From: Avi Kivity <avi@redhat.com> |
| Date: Wed, 9 May 2012 16:10:37 +0300 |
| Subject: KVM: s390: do store status after handling STOP_ON_STOP bit |
| To: stable@vger.kernel.org |
| Cc: Marcelo Tosatti <mtosatti@redhat.com>, kvm@vger.kernel.org |
| Message-ID: <1336569047-23576-2-git-send-email-avi@redhat.com> |
| |
| |
| From: Jens Freimann <jfrei@linux.vnet.ibm.com> |
| |
| (cherry picked from commit 9e0d5473e2f0ba2d2fe9dab9408edef3060b710e) |
| |
| In handle_stop() handle the stop bit before doing the store status as |
| described for "Stop and Store Status" in the Principles of Operation. |
| We have to give up the local_int.lock before calling kvm store status |
| since it calls gmap_fault() which might sleep. Since local_int.lock |
| only protects local_int.* and not guest memory we can give up the lock. |
| |
| Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com> |
| Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> |
| Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> |
| Signed-off-by: Avi Kivity <avi@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/s390/kvm/intercept.c | 20 ++++++++++++-------- |
| 1 file changed, 12 insertions(+), 8 deletions(-) |
| |
| --- a/arch/s390/kvm/intercept.c |
| +++ b/arch/s390/kvm/intercept.c |
| @@ -133,13 +133,6 @@ static int handle_stop(struct kvm_vcpu * |
| |
| vcpu->stat.exit_stop_request++; |
| spin_lock_bh(&vcpu->arch.local_int.lock); |
| - if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) { |
| - vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP; |
| - rc = kvm_s390_vcpu_store_status(vcpu, |
| - KVM_S390_STORE_STATUS_NOADDR); |
| - if (rc >= 0) |
| - rc = -EOPNOTSUPP; |
| - } |
| |
| if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) { |
| vcpu->arch.local_int.action_bits &= ~ACTION_RELOADVCPU_ON_STOP; |
| @@ -155,7 +148,18 @@ static int handle_stop(struct kvm_vcpu * |
| rc = -EOPNOTSUPP; |
| } |
| |
| - spin_unlock_bh(&vcpu->arch.local_int.lock); |
| + if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) { |
| + vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP; |
| + /* store status must be called unlocked. Since local_int.lock |
| + * only protects local_int.* and not guest memory we can give |
| + * up the lock here */ |
| + spin_unlock_bh(&vcpu->arch.local_int.lock); |
| + rc = kvm_s390_vcpu_store_status(vcpu, |
| + KVM_S390_STORE_STATUS_NOADDR); |
| + if (rc >= 0) |
| + rc = -EOPNOTSUPP; |
| + } else |
| + spin_unlock_bh(&vcpu->arch.local_int.lock); |
| return rc; |
| } |
| |