aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/kvm/intercept.c31
-rw-r--r--arch/s390/kvm/kvm-s390.c8
2 files changed, 20 insertions, 19 deletions
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index a0b586c1913c..ac6b32585a36 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -56,32 +56,25 @@ static int handle_noop(struct kvm_vcpu *vcpu)
56static int handle_stop(struct kvm_vcpu *vcpu) 56static int handle_stop(struct kvm_vcpu *vcpu)
57{ 57{
58 int rc = 0; 58 int rc = 0;
59 unsigned int action_bits;
59 60
60 vcpu->stat.exit_stop_request++; 61 vcpu->stat.exit_stop_request++;
61 spin_lock_bh(&vcpu->arch.local_int.lock);
62
63 trace_kvm_s390_stop_request(vcpu->arch.local_int.action_bits); 62 trace_kvm_s390_stop_request(vcpu->arch.local_int.action_bits);
64 63
65 if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { 64 action_bits = vcpu->arch.local_int.action_bits;
66 kvm_s390_vcpu_stop(vcpu);
67 vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
68 VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
69 rc = -EOPNOTSUPP;
70 }
71 65
72 if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) { 66 if (!(action_bits & ACTION_STOP_ON_STOP))
73 vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP; 67 return 0;
74 /* store status must be called unlocked. Since local_int.lock 68
75 * only protects local_int.* and not guest memory we can give 69 if (action_bits & ACTION_STORE_ON_STOP) {
76 * up the lock here */
77 spin_unlock_bh(&vcpu->arch.local_int.lock);
78 rc = kvm_s390_vcpu_store_status(vcpu, 70 rc = kvm_s390_vcpu_store_status(vcpu,
79 KVM_S390_STORE_STATUS_NOADDR); 71 KVM_S390_STORE_STATUS_NOADDR);
80 if (rc >= 0) 72 if (rc)
81 rc = -EOPNOTSUPP; 73 return rc;
82 } else 74 }
83 spin_unlock_bh(&vcpu->arch.local_int.lock); 75
84 return rc; 76 kvm_s390_vcpu_stop(vcpu);
77 return -EOPNOTSUPP;
85} 78}
86 79
87static int handle_validity(struct kvm_vcpu *vcpu) 80static int handle_validity(struct kvm_vcpu *vcpu)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 2f3e14fe91a4..c5077899de5b 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1494,7 +1494,15 @@ void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu)
1494 spin_lock_bh(&vcpu->kvm->arch.start_stop_lock); 1494 spin_lock_bh(&vcpu->kvm->arch.start_stop_lock);
1495 online_vcpus = atomic_read(&vcpu->kvm->online_vcpus); 1495 online_vcpus = atomic_read(&vcpu->kvm->online_vcpus);
1496 1496
1497 /* Need to lock access to action_bits to avoid a SIGP race condition */
1498 spin_lock_bh(&vcpu->arch.local_int.lock);
1497 atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags); 1499 atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
1500
1501 /* SIGP STOP and SIGP STOP AND STORE STATUS has been fully processed */
1502 vcpu->arch.local_int.action_bits &=
1503 ~(ACTION_STOP_ON_STOP | ACTION_STORE_ON_STOP);
1504 spin_unlock_bh(&vcpu->arch.local_int.lock);
1505
1498 __disable_ibs_on_vcpu(vcpu); 1506 __disable_ibs_on_vcpu(vcpu);
1499 1507
1500 for (i = 0; i < online_vcpus; i++) { 1508 for (i = 0; i < online_vcpus; i++) {