KVM: s390: interprocessor communication via sigp
This patch introduces in-kernel handling of _some_ sigp interprocessor signals (similar to ipi). kvm_s390_handle_sigp() decodes the sigp instruction and calls individual handlers depending on the operation requested: - sigp sense tries to retrieve information such as existence or running state of the remote cpu - sigp emergency sends an external interrupt to the remove cpu - sigp stop stops a remove cpu - sigp stop store status stops a remote cpu, and stores its entire internal state to the cpus lowcore - sigp set arch sets the architecture mode of the remote cpu. setting to ESAME (s390x 64bit) is accepted, setting to ESA/S390 (s390, 31 or 24 bit) is denied, all others are passed to userland - sigp set prefix sets the prefix register of a remote cpu For implementation of this, the stop intercept indication starts to get reused on purpose: a set of action bits defines what to do once a cpu gets stopped: ACTION_STOP_ON_STOP really stops the cpu when a stop intercept is recognized ACTION_STORE_ON_STOP stores the cpu status to lowcore when a stop intercept is recognized Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Carsten Otte <cotte@de.ibm.com> Signed-off-by: Carsten Otte <cotte@de.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
committed by
Avi Kivity
parent
453423dce2
commit
5288fbf0ef
@@ -95,6 +95,7 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
|
||||
static intercept_handler_t instruction_handlers[256] = {
|
||||
[0xae] = kvm_s390_handle_sigp,
|
||||
[0xb2] = kvm_s390_handle_priv,
|
||||
[0xb7] = handle_lctl,
|
||||
[0xeb] = handle_lctg,
|
||||
@@ -117,10 +118,27 @@ static int handle_noop(struct kvm_vcpu *vcpu)
|
||||
|
||||
static int handle_stop(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
int rc;
|
||||
|
||||
vcpu->stat.exit_stop_request++;
|
||||
VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
|
||||
atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
|
||||
return -ENOTSUPP;
|
||||
spin_lock_bh(&vcpu->arch.local_int.lock);
|
||||
if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) {
|
||||
vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP;
|
||||
rc = __kvm_s390_vcpu_store_status(vcpu,
|
||||
KVM_S390_STORE_STATUS_NOADDR);
|
||||
if (rc >= 0)
|
||||
rc = -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) {
|
||||
vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
|
||||
VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
|
||||
rc = -ENOTSUPP;
|
||||
} else
|
||||
rc = 0;
|
||||
spin_unlock_bh(&vcpu->arch.local_int.lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int handle_validity(struct kvm_vcpu *vcpu)
|
||||
|
Reference in New Issue
Block a user