aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/virtual/kvm/api.txt2
-rw-r--r--arch/s390/kvm/interrupt.c32
-rw-r--r--include/uapi/linux/kvm.h2
3 files changed, 36 insertions, 0 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 2014ff12b492..0581f6c40f2b 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2211,6 +2211,8 @@ KVM_S390_SIGP_STOP (vcpu) - sigp restart
2211KVM_S390_PROGRAM_INT (vcpu) - program check; code in parm 2211KVM_S390_PROGRAM_INT (vcpu) - program check; code in parm
2212KVM_S390_SIGP_SET_PREFIX (vcpu) - sigp set prefix; prefix address in parm 2212KVM_S390_SIGP_SET_PREFIX (vcpu) - sigp set prefix; prefix address in parm
2213KVM_S390_RESTART (vcpu) - restart 2213KVM_S390_RESTART (vcpu) - restart
2214KVM_S390_INT_CLOCK_COMP (vcpu) - clock comparator interrupt
2215KVM_S390_INT_CPU_TIMER (vcpu) - CPU timer interrupt
2214KVM_S390_INT_VIRTIO (vm) - virtio external interrupt; external interrupt 2216KVM_S390_INT_VIRTIO (vm) - virtio external interrupt; external interrupt
2215 parameters in parm and parm64 2217 parameters in parm and parm64
2216KVM_S390_INT_SERVICE (vm) - sclp external interrupt; sclp parameter in parm 2218KVM_S390_INT_SERVICE (vm) - sclp external interrupt; sclp parameter in parm
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;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 836e15b7abc8..2b83cf35437a 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -416,6 +416,8 @@ struct kvm_s390_psw {
416#define KVM_S390_INT_PFAULT_INIT 0xfffe0004u 416#define KVM_S390_INT_PFAULT_INIT 0xfffe0004u
417#define KVM_S390_INT_PFAULT_DONE 0xfffe0005u 417#define KVM_S390_INT_PFAULT_DONE 0xfffe0005u
418#define KVM_S390_MCHK 0xfffe1000u 418#define KVM_S390_MCHK 0xfffe1000u
419#define KVM_S390_INT_CLOCK_COMP 0xffff1004u
420#define KVM_S390_INT_CPU_TIMER 0xffff1005u
419#define KVM_S390_INT_VIRTIO 0xffff2603u 421#define KVM_S390_INT_VIRTIO 0xffff2603u
420#define KVM_S390_INT_SERVICE 0xffff2401u 422#define KVM_S390_INT_SERVICE 0xffff2401u
421#define KVM_S390_INT_EMERGENCY 0xffff1201u 423#define KVM_S390_INT_EMERGENCY 0xffff1201u