Skip to content

Commit

Permalink
KVM: s390: move finalization of SIGP STOP orders to kvm_s390_vcpu_stop
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David Hildenbrand authored and Christian Borntraeger committed Jul 10, 2014
1 parent 7dfc63c commit 32f5ff6
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 19 deletions.
31 changes: 12 additions & 19 deletions arch/s390/kvm/intercept.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,32 +56,25 @@ static int handle_noop(struct kvm_vcpu *vcpu)
static int handle_stop(struct kvm_vcpu *vcpu)
{
int rc = 0;
unsigned int action_bits;

vcpu->stat.exit_stop_request++;
spin_lock_bh(&vcpu->arch.local_int.lock);

trace_kvm_s390_stop_request(vcpu->arch.local_int.action_bits);

if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) {
kvm_s390_vcpu_stop(vcpu);
vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
rc = -EOPNOTSUPP;
}
action_bits = vcpu->arch.local_int.action_bits;

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);
if (!(action_bits & ACTION_STOP_ON_STOP))
return 0;

if (action_bits & ACTION_STORE_ON_STOP) {
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;
if (rc)
return rc;
}

kvm_s390_vcpu_stop(vcpu);
return -EOPNOTSUPP;
}

static int handle_validity(struct kvm_vcpu *vcpu)
Expand Down
8 changes: 8 additions & 0 deletions arch/s390/kvm/kvm-s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,15 @@ void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu)
spin_lock_bh(&vcpu->kvm->arch.start_stop_lock);
online_vcpus = atomic_read(&vcpu->kvm->online_vcpus);

/* Need to lock access to action_bits to avoid a SIGP race condition */
spin_lock_bh(&vcpu->arch.local_int.lock);
atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);

/* SIGP STOP and SIGP STOP AND STORE STATUS has been fully processed */
vcpu->arch.local_int.action_bits &=
~(ACTION_STOP_ON_STOP | ACTION_STORE_ON_STOP);
spin_unlock_bh(&vcpu->arch.local_int.lock);

__disable_ibs_on_vcpu(vcpu);

for (i = 0; i < online_vcpus; i++) {
Expand Down

0 comments on commit 32f5ff6

Please sign in to comment.