aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorThomas Huth <thuth@linux.vnet.ibm.com>2014-03-26 11:11:54 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-05-06 08:58:05 -0400
commite029ae5b787e08e976a683c6a45fac20fc227447 (patch)
tree3d182479f67f73be675009606c94882091dbf883 /arch/s390
parentfcc9aec3de0a1d00cbce47f7274ec0c62122266b (diff)
KVM: s390: Add clock comparator and CPU timer IRQ injection
Add an interface to inject clock comparator and CPU timer interrupts into the guest. This is needed for handling the external interrupt interception. Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kvm/interrupt.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index d9526bb29194..75cd3217cd5a 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -27,6 +27,8 @@
27#define IOINT_CSSID_MASK 0x03fc0000 27#define IOINT_CSSID_MASK 0x03fc0000
28#define IOINT_AI_MASK 0x04000000 28#define IOINT_AI_MASK 0x04000000
29 29
30static void deliver_ckc_interrupt(struct kvm_vcpu *vcpu);
31
30static int is_ioint(u64 type) 32static int is_ioint(u64 type)
31{ 33{
32 return ((type & 0xfffe0000u) != 0xfffe0000u); 34 return ((type & 0xfffe0000u) != 0xfffe0000u);
@@ -89,6 +91,14 @@ static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu,
89 if (vcpu->arch.sie_block->gcr[0] & 0x4000ul) 91 if (vcpu->arch.sie_block->gcr[0] & 0x4000ul)
90 return 1; 92 return 1;
91 return 0; 93 return 0;
94 case KVM_S390_INT_CLOCK_COMP:
95 return ckc_interrupts_enabled(vcpu);
96 case KVM_S390_INT_CPU_TIMER:
97 if (psw_extint_disabled(vcpu))
98 return 0;
99 if (vcpu->arch.sie_block->gcr[0] & 0x400ul)
100 return 1;
101 return 0;
92 case KVM_S390_INT_SERVICE: 102 case KVM_S390_INT_SERVICE:
93 case KVM_S390_INT_PFAULT_INIT: 103 case KVM_S390_INT_PFAULT_INIT:
94 case KVM_S390_INT_PFAULT_DONE: 104 case KVM_S390_INT_PFAULT_DONE:
@@ -166,6 +176,8 @@ static void __set_intercept_indicator(struct kvm_vcpu *vcpu,
166 case KVM_S390_INT_PFAULT_INIT: 176 case KVM_S390_INT_PFAULT_INIT:
167 case KVM_S390_INT_PFAULT_DONE: 177 case KVM_S390_INT_PFAULT_DONE:
168 case KVM_S390_INT_VIRTIO: 178 case KVM_S390_INT_VIRTIO:
179 case KVM_S390_INT_CLOCK_COMP:
180 case KVM_S390_INT_CPU_TIMER:
169 if (psw_extint_disabled(vcpu)) 181 if (psw_extint_disabled(vcpu))
170 __set_cpuflag(vcpu, CPUSTAT_EXT_INT); 182 __set_cpuflag(vcpu, CPUSTAT_EXT_INT);
171 else 183 else
@@ -326,6 +338,24 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
326 &vcpu->arch.sie_block->gpsw, 338 &vcpu->arch.sie_block->gpsw,
327 sizeof(psw_t)); 339 sizeof(psw_t));
328 break; 340 break;
341 case KVM_S390_INT_CLOCK_COMP:
342 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
343 inti->ext.ext_params, 0);
344 deliver_ckc_interrupt(vcpu);
345 break;
346 case KVM_S390_INT_CPU_TIMER:
347 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
348 inti->ext.ext_params, 0);
349 rc = put_guest_lc(vcpu, EXT_IRQ_CPU_TIMER,
350 (u16 *)__LC_EXT_INT_CODE);
351 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
352 &vcpu->arch.sie_block->gpsw,
353 sizeof(psw_t));
354 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
355 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
356 rc |= put_guest_lc(vcpu, inti->ext.ext_params,
357 (u32 *)__LC_EXT_PARAMS);
358 break;
329 case KVM_S390_INT_SERVICE: 359 case KVM_S390_INT_SERVICE:
330 VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x", 360 VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x",
331 inti->ext.ext_params); 361 inti->ext.ext_params);
@@ -984,6 +1014,8 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
984 break; 1014 break;
985 case KVM_S390_SIGP_STOP: 1015 case KVM_S390_SIGP_STOP:
986 case KVM_S390_RESTART: 1016 case KVM_S390_RESTART:
1017 case KVM_S390_INT_CLOCK_COMP:
1018 case KVM_S390_INT_CPU_TIMER:
987 VCPU_EVENT(vcpu, 3, "inject: type %x", s390int->type); 1019 VCPU_EVENT(vcpu, 3, "inject: type %x", s390int->type);
988 inti->type = s390int->type; 1020 inti->type = s390int->type;
989 break; 1021 break;