^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * handling interprocessor communication
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright IBM Corp. 2008, 2013
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author(s): Carsten Otte <cotte@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Christian Borntraeger <borntraeger@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Christian Ehrhardt <ehrhardt@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kvm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kvm_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/sigp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "gaccess.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "kvm-s390.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int __sigp_sense(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) u64 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) const bool stopped = kvm_s390_test_cpuflags(dst_vcpu, CPUSTAT_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) int ext_call_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ext_call_pending = kvm_s390_ext_call_pending(dst_vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (!stopped && !ext_call_pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) rc = SIGP_CC_ORDER_CODE_ACCEPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (ext_call_pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *reg |= SIGP_STATUS_EXT_CALL_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (stopped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *reg |= SIGP_STATUS_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) rc = SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) VCPU_EVENT(vcpu, 4, "sensed status of cpu %x rc %x", dst_vcpu->vcpu_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int __inject_sigp_emergency(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct kvm_vcpu *dst_vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct kvm_s390_irq irq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .type = KVM_S390_INT_EMERGENCY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .u.emerg.code = vcpu->vcpu_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) rc = kvm_s390_inject_vcpu(dst_vcpu, &irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) dst_vcpu->vcpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int __sigp_emergency(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return __inject_sigp_emergency(vcpu, dst_vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct kvm_vcpu *dst_vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u16 asn, u64 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u16 p_asn, s_asn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) psw_t *psw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bool idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) idle = is_vcpu_idle(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) psw = &dst_vcpu->arch.sie_block->gpsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* Inject the emergency signal? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (!is_vcpu_stopped(vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) || (psw->mask & psw_int_mask) != psw_int_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) || (idle && psw->addr != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) || (!idle && (asn == p_asn || asn == s_asn))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return __inject_sigp_emergency(vcpu, dst_vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *reg |= SIGP_STATUS_INCORRECT_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int __sigp_external_call(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct kvm_vcpu *dst_vcpu, u64 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct kvm_s390_irq irq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .type = KVM_S390_INT_EXTERNAL_CALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .u.extcall.code = vcpu->vcpu_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) rc = kvm_s390_inject_vcpu(dst_vcpu, &irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (rc == -EBUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *reg |= SIGP_STATUS_EXT_CALL_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) } else if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) dst_vcpu->vcpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int __sigp_stop(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct kvm_s390_irq irq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .type = KVM_S390_SIGP_STOP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) rc = kvm_s390_inject_vcpu(dst_vcpu, &irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (rc == -EBUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) rc = SIGP_CC_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) else if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) dst_vcpu->vcpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int __sigp_stop_and_store_status(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct kvm_vcpu *dst_vcpu, u64 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct kvm_s390_irq irq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .type = KVM_S390_SIGP_STOP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .u.stop.flags = KVM_S390_STOP_FLAG_STORE_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) rc = kvm_s390_inject_vcpu(dst_vcpu, &irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (rc == -EBUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) rc = SIGP_CC_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) else if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) VCPU_EVENT(vcpu, 4, "sent sigp stop and store status to cpu %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) dst_vcpu->vcpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u64 *status_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct kvm_vcpu *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) bool all_stopped = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) kvm_for_each_vcpu(i, v, vcpu->kvm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (v == vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (!is_vcpu_stopped(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) all_stopped = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *status_reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* Reject set arch order, with czam we're always in z/Arch mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) *status_reg |= (all_stopped ? SIGP_STATUS_INVALID_PARAMETER :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) SIGP_STATUS_INCORRECT_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u32 address, u64 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct kvm_s390_irq irq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .type = KVM_S390_SIGP_SET_PREFIX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .u.prefix.address = address & 0x7fffe000u,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * Make sure the new value is valid memory. We only need to check the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * first page, since address is 8k aligned and memory pieces are always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * at least 1MB aligned and have at least a size of 1MB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (kvm_is_error_gpa(vcpu->kvm, irq.u.prefix.address)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *reg |= SIGP_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) rc = kvm_s390_inject_vcpu(dst_vcpu, &irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (rc == -EBUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *reg |= SIGP_STATUS_INCORRECT_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct kvm_vcpu *dst_vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u32 addr, u64 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (!kvm_s390_test_cpuflags(dst_vcpu, CPUSTAT_STOPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) *reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *reg |= SIGP_STATUS_INCORRECT_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) addr &= 0x7ffffe00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) rc = kvm_s390_store_status_unloaded(dst_vcpu, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (rc == -EFAULT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) *reg |= SIGP_STATUS_INVALID_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) rc = SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int __sigp_sense_running(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct kvm_vcpu *dst_vcpu, u64 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!test_kvm_facility(vcpu->kvm, 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) *reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *reg |= SIGP_STATUS_INVALID_ORDER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (kvm_s390_test_cpuflags(dst_vcpu, CPUSTAT_RUNNING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) rc = SIGP_CC_ORDER_CODE_ACCEPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* not running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) *reg &= 0xffffffff00000000UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *reg |= SIGP_STATUS_NOT_RUNNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) rc = SIGP_CC_STATUS_STORED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) VCPU_EVENT(vcpu, 4, "sensed running status of cpu %x rc %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dst_vcpu->vcpu_id, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int __prepare_sigp_re_start(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct kvm_vcpu *dst_vcpu, u8 order_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* handle (RE)START in user space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* make sure we don't race with STOP irq injection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) spin_lock(&li->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (kvm_s390_is_stop_irq_pending(dst_vcpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) rc = SIGP_CC_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) spin_unlock(&li->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static int __prepare_sigp_cpu_reset(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct kvm_vcpu *dst_vcpu, u8 order_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* handle (INITIAL) CPU RESET in user space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int __prepare_sigp_unknown(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct kvm_vcpu *dst_vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* handle unknown orders in user space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) u16 cpu_addr, u32 parameter, u64 *status_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct kvm_vcpu *dst_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!dst_vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return SIGP_CC_NOT_OPERATIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * SIGP RESTART, SIGP STOP, and SIGP STOP AND STORE STATUS orders
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * are processed asynchronously. Until the affected VCPU finishes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * its work and calls back into KVM to clear the (RESTART or STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * interrupt, we need to return any new non-reset orders "busy".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * This is important because a single VCPU could issue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * 1) SIGP STOP $DESTINATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * 2) SIGP SENSE $DESTINATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * If the SIGP SENSE would not be rejected as "busy", it could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * return an incorrect answer as to whether the VCPU is STOPPED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * or OPERATING.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (order_code != SIGP_INITIAL_CPU_RESET &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) order_code != SIGP_CPU_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * Lockless check. Both SIGP STOP and SIGP (RE)START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * properly synchronize everything while processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * their orders, while the guest cannot observe a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * difference when issuing other orders from two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * different VCPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (kvm_s390_is_stop_irq_pending(dst_vcpu) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) kvm_s390_is_restart_irq_pending(dst_vcpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return SIGP_CC_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) switch (order_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case SIGP_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) vcpu->stat.instruction_sigp_sense++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) rc = __sigp_sense(vcpu, dst_vcpu, status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) case SIGP_EXTERNAL_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) vcpu->stat.instruction_sigp_external_call++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) rc = __sigp_external_call(vcpu, dst_vcpu, status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) case SIGP_EMERGENCY_SIGNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) vcpu->stat.instruction_sigp_emergency++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) rc = __sigp_emergency(vcpu, dst_vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case SIGP_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) vcpu->stat.instruction_sigp_stop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) rc = __sigp_stop(vcpu, dst_vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case SIGP_STOP_AND_STORE_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) vcpu->stat.instruction_sigp_stop_store_status++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) rc = __sigp_stop_and_store_status(vcpu, dst_vcpu, status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) case SIGP_STORE_STATUS_AT_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) vcpu->stat.instruction_sigp_store_status++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) rc = __sigp_store_status_at_addr(vcpu, dst_vcpu, parameter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case SIGP_SET_PREFIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) vcpu->stat.instruction_sigp_prefix++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) rc = __sigp_set_prefix(vcpu, dst_vcpu, parameter, status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case SIGP_COND_EMERGENCY_SIGNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) vcpu->stat.instruction_sigp_cond_emergency++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) rc = __sigp_conditional_emergency(vcpu, dst_vcpu, parameter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case SIGP_SENSE_RUNNING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) vcpu->stat.instruction_sigp_sense_running++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) rc = __sigp_sense_running(vcpu, dst_vcpu, status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) case SIGP_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) vcpu->stat.instruction_sigp_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case SIGP_RESTART:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) vcpu->stat.instruction_sigp_restart++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case SIGP_INITIAL_CPU_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) vcpu->stat.instruction_sigp_init_cpu_reset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case SIGP_CPU_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) vcpu->stat.instruction_sigp_cpu_reset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) vcpu->stat.instruction_sigp_unknown++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) rc = __prepare_sigp_unknown(vcpu, dst_vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (rc == -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) VCPU_EVENT(vcpu, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) "sigp order %u -> cpu %x: handled in user space",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) order_code, dst_vcpu->vcpu_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static int handle_sigp_order_in_user_space(struct kvm_vcpu *vcpu, u8 order_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) u16 cpu_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!vcpu->kvm->arch.user_sigp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) switch (order_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case SIGP_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) case SIGP_EXTERNAL_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) case SIGP_EMERGENCY_SIGNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) case SIGP_COND_EMERGENCY_SIGNAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) case SIGP_SENSE_RUNNING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* update counters as we're directly dropping to user space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) case SIGP_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) vcpu->stat.instruction_sigp_stop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) case SIGP_STOP_AND_STORE_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) vcpu->stat.instruction_sigp_stop_store_status++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) case SIGP_STORE_STATUS_AT_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) vcpu->stat.instruction_sigp_store_status++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) case SIGP_STORE_ADDITIONAL_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) vcpu->stat.instruction_sigp_store_adtl_status++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) case SIGP_SET_PREFIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) vcpu->stat.instruction_sigp_prefix++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) case SIGP_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) vcpu->stat.instruction_sigp_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case SIGP_RESTART:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) vcpu->stat.instruction_sigp_restart++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case SIGP_INITIAL_CPU_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) vcpu->stat.instruction_sigp_init_cpu_reset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case SIGP_CPU_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) vcpu->stat.instruction_sigp_cpu_reset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) vcpu->stat.instruction_sigp_unknown++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) VCPU_EVENT(vcpu, 3, "SIGP: order %u for CPU %d handled in userspace",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) order_code, cpu_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int r3 = vcpu->arch.sie_block->ipa & 0x000f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) u32 parameter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) u16 cpu_addr = vcpu->run->s.regs.gprs[r3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) u8 order_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /* sigp in userspace can exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) order_code = kvm_s390_get_base_disp_rs(vcpu, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (handle_sigp_order_in_user_space(vcpu, order_code, cpu_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (r1 % 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) parameter = vcpu->run->s.regs.gprs[r1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) parameter = vcpu->run->s.regs.gprs[r1 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) switch (order_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case SIGP_SET_ARCHITECTURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) vcpu->stat.instruction_sigp_arch++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) rc = __sigp_set_arch(vcpu, parameter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) &vcpu->run->s.regs.gprs[r1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) rc = handle_sigp_dst(vcpu, order_code, cpu_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) parameter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) &vcpu->run->s.regs.gprs[r1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) kvm_s390_set_psw_cc(vcpu, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * Handle SIGP partial execution interception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * This interception will occur at the source cpu when a source cpu sends an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * external call to a target cpu and the target cpu has the WAIT bit set in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * its cpuflags. Interception will occurr after the interrupt indicator bits at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * the target cpu have been set. All error cases will lead to instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * interception, therefore nothing is to be checked or prepared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int r3 = vcpu->arch.sie_block->ipa & 0x000f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) u16 cpu_addr = vcpu->run->s.regs.gprs[r3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct kvm_vcpu *dest_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) u8 order_code = kvm_s390_get_base_disp_rs(vcpu, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (order_code == SIGP_EXTERNAL_CALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) BUG_ON(dest_vcpu == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) kvm_s390_vcpu_wakeup(dest_vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) kvm_s390_set_psw_cc(vcpu, SIGP_CC_ORDER_CODE_ACCEPTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }