diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kvm/interrupt.c | 32 |
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 | ||
30 | static void deliver_ckc_interrupt(struct kvm_vcpu *vcpu); | ||
31 | |||
30 | static int is_ioint(u64 type) | 32 | static 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; |