aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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