diff options
-rw-r--r-- | arch/s390/kvm/intercept.c | 31 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 8 |
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) | |||
56 | static int handle_stop(struct kvm_vcpu *vcpu) | 56 | static 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 | ||
87 | static int handle_validity(struct kvm_vcpu *vcpu) | 80 | static 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++) { |