summaryrefslogtreecommitdiff
path: root/arch/s390/kvm/interrupt.c
diff options
context:
space:
mode:
authorEugene (jno) Dvurechenski <jno@linux.vnet.ibm.com>2015-04-23 16:09:06 +0200
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-11-30 12:47:07 +0100
commitbc784ccee5eb9ae1e737927eb9d8a0fbf7601abc (patch)
treeb436d5a0a238f488c81c054abb4e9ffceed8b882 /arch/s390/kvm/interrupt.c
parenta6e2f683e7691949d33ca9392e7807cfa9aca34e (diff)
KVM: s390: Introduce new structures
This patch adds new structures and updates some existing ones to provide the base for Extended SCA functionality. The old sca_* structures were renamed to bsca_* to keep things uniform. The access to fields of SIGP controls were turned into bitfields instead of hardcoded bitmasks. Signed-off-by: Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm/interrupt.c')
-rw-r--r--arch/s390/kvm/interrupt.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 2a4718af9dcf..aa221a48cc7c 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -37,25 +37,32 @@
/* handle external calls via sigp interpretation facility */
static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id)
{
- struct sca_block *sca = vcpu->kvm->arch.sca;
- uint8_t sigp_ctrl = sca->cpu[vcpu->vcpu_id].sigp_ctrl;
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
+ union bsca_sigp_ctrl sigp_ctrl = sca->cpu[vcpu->vcpu_id].sigp_ctrl;
if (src_id)
- *src_id = sigp_ctrl & SIGP_CTRL_SCN_MASK;
+ *src_id = sigp_ctrl.scn;
- return sigp_ctrl & SIGP_CTRL_C &&
+ return sigp_ctrl.c &&
atomic_read(&vcpu->arch.sie_block->cpuflags) &
CPUSTAT_ECALL_PEND;
}
static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
{
- struct sca_block *sca = vcpu->kvm->arch.sca;
- uint8_t *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
- uint8_t new_val = SIGP_CTRL_C | (src_id & SIGP_CTRL_SCN_MASK);
- uint8_t old_val = *sigp_ctrl & ~SIGP_CTRL_C;
+ int expect, rc;
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
+ union bsca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+ union bsca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl;
- if (cmpxchg(sigp_ctrl, old_val, new_val) != old_val) {
+ new_val.scn = src_id;
+ new_val.c = 1;
+ old_val.c = 0;
+
+ expect = old_val.value;
+ rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value);
+
+ if (rc != expect) {
/* another external call is pending */
return -EBUSY;
}
@@ -65,12 +72,12 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
static void sca_clear_ext_call(struct kvm_vcpu *vcpu)
{
- struct sca_block *sca = vcpu->kvm->arch.sca;
+ struct bsca_block *sca = vcpu->kvm->arch.sca;
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
- uint8_t *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
+ union bsca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
atomic_andnot(CPUSTAT_ECALL_PEND, li->cpuflags);
- *sigp_ctrl = 0;
+ sigp_ctrl->value = 0;
}
int psw_extint_disabled(struct kvm_vcpu *vcpu)