aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2014-04-14 06:40:03 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-07-10 08:09:44 -0400
commit32f5ff63ff9c87195d06896e6ab4086b6369546a (patch)
treef58d782380f402e03dcac5bbbe92776437a0052a /arch/s390
parent7dfc63cf977447e09b1072911c22564f900fc578 (diff)
KVM: s390: move finalization of SIGP STOP orders to kvm_s390_vcpu_stop
Let's move the finalization of SIGP STOP and SIGP STOP AND STORE STATUS orders to the point where the VCPU is actually stopped. This change is needed to prepare for a user space driven VCPU state change. The action_bits may only be cleared when setting the cpu state to STOPPED while holding the local irq lock. Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390')
-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++) {