aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Freimann <jfrei@linux.vnet.ibm.com>2012-02-06 04:59:03 -0500
committerAvi Kivity <avi@redhat.com>2012-03-08 07:10:14 -0500
commit9e0d5473e2f0ba2d2fe9dab9408edef3060b710e (patch)
tree3ca883cc0c44a68480f691e1c62e3a51f7732ce2
parent851755871c1f3184f4124c466e85881f17fa3226 (diff)
KVM: s390: do store status after handling STOP_ON_STOP bit
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>
-rw-r--r--arch/s390/kvm/intercept.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 776ef83c2771..361456577c6f 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -133,13 +133,6 @@ static int handle_stop(struct kvm_vcpu *vcpu)
133 133
134 vcpu->stat.exit_stop_request++; 134 vcpu->stat.exit_stop_request++;
135 spin_lock_bh(&vcpu->arch.local_int.lock); 135 spin_lock_bh(&vcpu->arch.local_int.lock);
136 if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) {
137 vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP;
138 rc = kvm_s390_vcpu_store_status(vcpu,
139 KVM_S390_STORE_STATUS_NOADDR);
140 if (rc >= 0)
141 rc = -EOPNOTSUPP;
142 }
143 136
144 if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) { 137 if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) {
145 vcpu->arch.local_int.action_bits &= ~ACTION_RELOADVCPU_ON_STOP; 138 vcpu->arch.local_int.action_bits &= ~ACTION_RELOADVCPU_ON_STOP;
@@ -155,7 +148,18 @@ static int handle_stop(struct kvm_vcpu *vcpu)
155 rc = -EOPNOTSUPP; 148 rc = -EOPNOTSUPP;
156 } 149 }
157 150
158 spin_unlock_bh(&vcpu->arch.local_int.lock); 151 if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) {
152 vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP;
153 /* store status must be called unlocked. Since local_int.lock
154 * only protects local_int.* and not guest memory we can give
155 * up the lock here */
156 spin_unlock_bh(&vcpu->arch.local_int.lock);
157 rc = kvm_s390_vcpu_store_status(vcpu,
158 KVM_S390_STORE_STATUS_NOADDR);
159 if (rc >= 0)
160 rc = -EOPNOTSUPP;
161 } else
162 spin_unlock_bh(&vcpu->arch.local_int.lock);
159 return rc; 163 return rc;
160} 164}
161 165