aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/interrupt.c
diff options
context:
space:
mode:
authorEugene (jno) Dvurechenski <jno@linux.vnet.ibm.com>2015-04-23 10:09:06 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-11-30 06:47:07 -0500
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 @@
37/* handle external calls via sigp interpretation facility */ 37/* handle external calls via sigp interpretation facility */
38static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id) 38static int sca_ext_call_pending(struct kvm_vcpu *vcpu, int *src_id)
39{ 39{
40 struct sca_block *sca = vcpu->kvm->arch.sca; 40 struct bsca_block *sca = vcpu->kvm->arch.sca;
41 uint8_t sigp_ctrl = sca->cpu[vcpu->vcpu_id].sigp_ctrl; 41 union bsca_sigp_ctrl sigp_ctrl = sca->cpu[vcpu->vcpu_id].sigp_ctrl;
42 42
43 if (src_id) 43 if (src_id)
44 *src_id = sigp_ctrl & SIGP_CTRL_SCN_MASK; 44 *src_id = sigp_ctrl.scn;
45 45
46 return sigp_ctrl & SIGP_CTRL_C && 46 return sigp_ctrl.c &&
47 atomic_read(&vcpu->arch.sie_block->cpuflags) & 47 atomic_read(&vcpu->arch.sie_block->cpuflags) &
48 CPUSTAT_ECALL_PEND; 48 CPUSTAT_ECALL_PEND;
49} 49}
50 50
51static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id) 51static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
52{ 52{
53 struct sca_block *sca = vcpu->kvm->arch.sca; 53 int expect, rc;
54 uint8_t *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); 54 struct bsca_block *sca = vcpu->kvm->arch.sca;
55 uint8_t new_val = SIGP_CTRL_C | (src_id & SIGP_CTRL_SCN_MASK); 55 union bsca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
56 uint8_t old_val = *sigp_ctrl & ~SIGP_CTRL_C; 56 union bsca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl;
57 57
58 if (cmpxchg(sigp_ctrl, old_val, new_val) != old_val) { 58 new_val.scn = src_id;
59 new_val.c = 1;
60 old_val.c = 0;
61
62 expect = old_val.value;
63 rc = cmpxchg(&sigp_ctrl->value, old_val.value, new_val.value);
64
65 if (rc != expect) {
59 /* another external call is pending */ 66 /* another external call is pending */
60 return -EBUSY; 67 return -EBUSY;
61 } 68 }
@@ -65,12 +72,12 @@ static int sca_inject_ext_call(struct kvm_vcpu *vcpu, int src_id)
65 72
66static void sca_clear_ext_call(struct kvm_vcpu *vcpu) 73static void sca_clear_ext_call(struct kvm_vcpu *vcpu)
67{ 74{
68 struct sca_block *sca = vcpu->kvm->arch.sca; 75 struct bsca_block *sca = vcpu->kvm->arch.sca;
69 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; 76 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
70 uint8_t *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); 77 union bsca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl);
71 78
72 atomic_andnot(CPUSTAT_ECALL_PEND, li->cpuflags); 79 atomic_andnot(CPUSTAT_ECALL_PEND, li->cpuflags);
73 *sigp_ctrl = 0; 80 sigp_ctrl->value = 0;
74} 81}
75 82
76int psw_extint_disabled(struct kvm_vcpu *vcpu) 83int psw_extint_disabled(struct kvm_vcpu *vcpu)