aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/interrupt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kvm/interrupt.c')
-rw-r--r--arch/s390/kvm/interrupt.c123
1 files changed, 79 insertions, 44 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index aabf46f5f883..b04616b57a94 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -169,8 +169,15 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
169 169
170static int ckc_irq_pending(struct kvm_vcpu *vcpu) 170static int ckc_irq_pending(struct kvm_vcpu *vcpu)
171{ 171{
172 if (vcpu->arch.sie_block->ckc >= kvm_s390_get_tod_clock_fast(vcpu->kvm)) 172 const u64 now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
173 const u64 ckc = vcpu->arch.sie_block->ckc;
174
175 if (vcpu->arch.sie_block->gcr[0] & 0x0020000000000000ul) {
176 if ((s64)ckc >= (s64)now)
177 return 0;
178 } else if (ckc >= now) {
173 return 0; 179 return 0;
180 }
174 return ckc_interrupts_enabled(vcpu); 181 return ckc_interrupts_enabled(vcpu);
175} 182}
176 183
@@ -187,12 +194,6 @@ static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)
187 return kvm_s390_get_cpu_timer(vcpu) >> 63; 194 return kvm_s390_get_cpu_timer(vcpu) >> 63;
188} 195}
189 196
190static inline int is_ioirq(unsigned long irq_type)
191{
192 return ((irq_type >= IRQ_PEND_IO_ISC_7) &&
193 (irq_type <= IRQ_PEND_IO_ISC_0));
194}
195
196static uint64_t isc_to_isc_bits(int isc) 197static uint64_t isc_to_isc_bits(int isc)
197{ 198{
198 return (0x80 >> isc) << 24; 199 return (0x80 >> isc) << 24;
@@ -236,10 +237,15 @@ static inline int kvm_s390_gisa_tac_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gis
236 return test_and_clear_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa); 237 return test_and_clear_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa);
237} 238}
238 239
239static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu) 240static inline unsigned long pending_irqs_no_gisa(struct kvm_vcpu *vcpu)
240{ 241{
241 return vcpu->kvm->arch.float_int.pending_irqs | 242 return vcpu->kvm->arch.float_int.pending_irqs |
242 vcpu->arch.local_int.pending_irqs | 243 vcpu->arch.local_int.pending_irqs;
244}
245
246static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
247{
248 return pending_irqs_no_gisa(vcpu) |
243 kvm_s390_gisa_get_ipm(vcpu->kvm->arch.gisa) << IRQ_PEND_IO_ISC_7; 249 kvm_s390_gisa_get_ipm(vcpu->kvm->arch.gisa) << IRQ_PEND_IO_ISC_7;
244} 250}
245 251
@@ -337,7 +343,7 @@ static void __reset_intercept_indicators(struct kvm_vcpu *vcpu)
337 343
338static void set_intercept_indicators_io(struct kvm_vcpu *vcpu) 344static void set_intercept_indicators_io(struct kvm_vcpu *vcpu)
339{ 345{
340 if (!(pending_irqs(vcpu) & IRQ_PEND_IO_MASK)) 346 if (!(pending_irqs_no_gisa(vcpu) & IRQ_PEND_IO_MASK))
341 return; 347 return;
342 else if (psw_ioint_disabled(vcpu)) 348 else if (psw_ioint_disabled(vcpu))
343 kvm_s390_set_cpuflags(vcpu, CPUSTAT_IO_INT); 349 kvm_s390_set_cpuflags(vcpu, CPUSTAT_IO_INT);
@@ -1011,24 +1017,6 @@ out:
1011 return rc; 1017 return rc;
1012} 1018}
1013 1019
1014typedef int (*deliver_irq_t)(struct kvm_vcpu *vcpu);
1015
1016static const deliver_irq_t deliver_irq_funcs[] = {
1017 [IRQ_PEND_MCHK_EX] = __deliver_machine_check,
1018 [IRQ_PEND_MCHK_REP] = __deliver_machine_check,
1019 [IRQ_PEND_PROG] = __deliver_prog,
1020 [IRQ_PEND_EXT_EMERGENCY] = __deliver_emergency_signal,
1021 [IRQ_PEND_EXT_EXTERNAL] = __deliver_external_call,
1022 [IRQ_PEND_EXT_CLOCK_COMP] = __deliver_ckc,
1023 [IRQ_PEND_EXT_CPU_TIMER] = __deliver_cpu_timer,
1024 [IRQ_PEND_RESTART] = __deliver_restart,
1025 [IRQ_PEND_SET_PREFIX] = __deliver_set_prefix,
1026 [IRQ_PEND_PFAULT_INIT] = __deliver_pfault_init,
1027 [IRQ_PEND_EXT_SERVICE] = __deliver_service,
1028 [IRQ_PEND_PFAULT_DONE] = __deliver_pfault_done,
1029 [IRQ_PEND_VIRTIO] = __deliver_virtio,
1030};
1031
1032/* Check whether an external call is pending (deliverable or not) */ 1020/* Check whether an external call is pending (deliverable or not) */
1033int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu) 1021int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu)
1034{ 1022{
@@ -1066,13 +1054,19 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
1066 1054
1067static u64 __calculate_sltime(struct kvm_vcpu *vcpu) 1055static u64 __calculate_sltime(struct kvm_vcpu *vcpu)
1068{ 1056{
1069 u64 now, cputm, sltime = 0; 1057 const u64 now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
1058 const u64 ckc = vcpu->arch.sie_block->ckc;
1059 u64 cputm, sltime = 0;
1070 1060
1071 if (ckc_interrupts_enabled(vcpu)) { 1061 if (ckc_interrupts_enabled(vcpu)) {
1072 now = kvm_s390_get_tod_clock_fast(vcpu->kvm); 1062 if (vcpu->arch.sie_block->gcr[0] & 0x0020000000000000ul) {
1073 sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now); 1063 if ((s64)now < (s64)ckc)
1074 /* already expired or overflow? */ 1064 sltime = tod_to_ns((s64)ckc - (s64)now);
1075 if (!sltime || vcpu->arch.sie_block->ckc <= now) 1065 } else if (now < ckc) {
1066 sltime = tod_to_ns(ckc - now);
1067 }
1068 /* already expired */
1069 if (!sltime)
1076 return 0; 1070 return 0;
1077 if (cpu_timer_interrupts_enabled(vcpu)) { 1071 if (cpu_timer_interrupts_enabled(vcpu)) {
1078 cputm = kvm_s390_get_cpu_timer(vcpu); 1072 cputm = kvm_s390_get_cpu_timer(vcpu);
@@ -1192,7 +1186,6 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)
1192int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) 1186int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
1193{ 1187{
1194 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; 1188 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
1195 deliver_irq_t func;
1196 int rc = 0; 1189 int rc = 0;
1197 unsigned long irq_type; 1190 unsigned long irq_type;
1198 unsigned long irqs; 1191 unsigned long irqs;
@@ -1212,16 +1205,57 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
1212 while ((irqs = deliverable_irqs(vcpu)) && !rc) { 1205 while ((irqs = deliverable_irqs(vcpu)) && !rc) {
1213 /* bits are in the reverse order of interrupt priority */ 1206 /* bits are in the reverse order of interrupt priority */
1214 irq_type = find_last_bit(&irqs, IRQ_PEND_COUNT); 1207 irq_type = find_last_bit(&irqs, IRQ_PEND_COUNT);
1215 if (is_ioirq(irq_type)) { 1208 switch (irq_type) {
1209 case IRQ_PEND_IO_ISC_0:
1210 case IRQ_PEND_IO_ISC_1:
1211 case IRQ_PEND_IO_ISC_2:
1212 case IRQ_PEND_IO_ISC_3:
1213 case IRQ_PEND_IO_ISC_4:
1214 case IRQ_PEND_IO_ISC_5:
1215 case IRQ_PEND_IO_ISC_6:
1216 case IRQ_PEND_IO_ISC_7:
1216 rc = __deliver_io(vcpu, irq_type); 1217 rc = __deliver_io(vcpu, irq_type);
1217 } else { 1218 break;
1218 func = deliver_irq_funcs[irq_type]; 1219 case IRQ_PEND_MCHK_EX:
1219 if (!func) { 1220 case IRQ_PEND_MCHK_REP:
1220 WARN_ON_ONCE(func == NULL); 1221 rc = __deliver_machine_check(vcpu);
1221 clear_bit(irq_type, &li->pending_irqs); 1222 break;
1222 continue; 1223 case IRQ_PEND_PROG:
1223 } 1224 rc = __deliver_prog(vcpu);
1224 rc = func(vcpu); 1225 break;
1226 case IRQ_PEND_EXT_EMERGENCY:
1227 rc = __deliver_emergency_signal(vcpu);
1228 break;
1229 case IRQ_PEND_EXT_EXTERNAL:
1230 rc = __deliver_external_call(vcpu);
1231 break;
1232 case IRQ_PEND_EXT_CLOCK_COMP:
1233 rc = __deliver_ckc(vcpu);
1234 break;
1235 case IRQ_PEND_EXT_CPU_TIMER:
1236 rc = __deliver_cpu_timer(vcpu);
1237 break;
1238 case IRQ_PEND_RESTART:
1239 rc = __deliver_restart(vcpu);
1240 break;
1241 case IRQ_PEND_SET_PREFIX:
1242 rc = __deliver_set_prefix(vcpu);
1243 break;
1244 case IRQ_PEND_PFAULT_INIT:
1245 rc = __deliver_pfault_init(vcpu);
1246 break;
1247 case IRQ_PEND_EXT_SERVICE:
1248 rc = __deliver_service(vcpu);
1249 break;
1250 case IRQ_PEND_PFAULT_DONE:
1251 rc = __deliver_pfault_done(vcpu);
1252 break;
1253 case IRQ_PEND_VIRTIO:
1254 rc = __deliver_virtio(vcpu);
1255 break;
1256 default:
1257 WARN_ONCE(1, "Unknown pending irq type %ld", irq_type);
1258 clear_bit(irq_type, &li->pending_irqs);
1225 } 1259 }
1226 } 1260 }
1227 1261
@@ -1701,7 +1735,8 @@ static void __floating_irq_kick(struct kvm *kvm, u64 type)
1701 kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_STOP_INT); 1735 kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_STOP_INT);
1702 break; 1736 break;
1703 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: 1737 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
1704 kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT); 1738 if (!(type & KVM_S390_INT_IO_AI_MASK && kvm->arch.gisa))
1739 kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT);
1705 break; 1740 break;
1706 default: 1741 default:
1707 kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_EXT_INT); 1742 kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_EXT_INT);