aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorJens Freimann <jfrei@linux.vnet.ibm.com>2014-07-29 07:45:21 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-11-28 07:59:03 -0500
commit0fb97abe050348bf3bc1796329e75ac522de6b14 (patch)
treefddac37a90921b842929a536e8b1ffd27847e28a /arch/s390
parent60f90a14dd3e675adfa5c3e0a153696a0230e725 (diff)
KVM: s390: refactor interrupt delivery code
Move delivery code for cpu-local interrupt from the huge do_deliver_interrupt() to smaller functions which handle one type of interrupt. Signed-off-by: Jens Freimann <jfrei@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.c459
1 files changed, 282 insertions, 177 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 481f1368c6eb..0d7f0a7be2fc 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -30,8 +30,6 @@
30#define PFAULT_DONE 0x0680 30#define PFAULT_DONE 0x0680
31#define VIRTIO_PARAM 0x0d00 31#define VIRTIO_PARAM 0x0d00
32 32
33static int __must_check deliver_ckc_interrupt(struct kvm_vcpu *vcpu);
34
35static int is_ioint(u64 type) 33static int is_ioint(u64 type)
36{ 34{
37 return ((type & 0xfffe0000u) != 0xfffe0000u); 35 return ((type & 0xfffe0000u) != 0xfffe0000u);
@@ -228,12 +226,183 @@ static u16 get_ilc(struct kvm_vcpu *vcpu)
228 } 226 }
229} 227}
230 228
231static int __must_check __deliver_prog_irq(struct kvm_vcpu *vcpu, 229static int __must_check __deliver_cpu_timer(struct kvm_vcpu *vcpu)
232 struct kvm_s390_pgm_info *pgm_info) 230{
231 int rc;
232
233 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER,
234 0, 0);
235
236 rc = put_guest_lc(vcpu, EXT_IRQ_CPU_TIMER,
237 (u16 *)__LC_EXT_INT_CODE);
238 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
239 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
240 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
241 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
242 return rc;
243}
244
245static int __must_check __deliver_ckc(struct kvm_vcpu *vcpu)
246{
247 int rc;
248
249 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP,
250 0, 0);
251
252 rc = put_guest_lc(vcpu, EXT_IRQ_CLK_COMP,
253 (u16 __user *)__LC_EXT_INT_CODE);
254 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
255 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
256 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
257 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
258 return rc;
259}
260
261static int __must_check __deliver_pfault_init(struct kvm_vcpu *vcpu,
262 struct kvm_s390_interrupt_info *inti)
263{
264 struct kvm_s390_ext_info *ext = &inti->ext;
265 int rc;
266
267 VCPU_EVENT(vcpu, 4, "interrupt: pfault init parm:%x,parm64:%llx",
268 0, ext->ext_params2);
269 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
270 KVM_S390_INT_PFAULT_INIT,
271 0, ext->ext_params2);
272
273 rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, (u16 *) __LC_EXT_INT_CODE);
274 rc |= put_guest_lc(vcpu, PFAULT_INIT, (u16 *) __LC_EXT_CPU_ADDR);
275 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
276 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
277 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
278 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
279 rc |= put_guest_lc(vcpu, ext->ext_params2, (u64 *) __LC_EXT_PARAMS2);
280 return rc;
281}
282
283static int __must_check __deliver_machine_check(struct kvm_vcpu *vcpu,
284 struct kvm_s390_interrupt_info *inti)
285{
286 struct kvm_s390_mchk_info *mchk = &inti->mchk;
287 int rc;
288
289 VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx",
290 mchk->mcic);
291 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_MCHK,
292 mchk->cr14, mchk->mcic);
293
294 rc = kvm_s390_vcpu_store_status(vcpu, KVM_S390_STORE_STATUS_PREFIXED);
295 rc |= put_guest_lc(vcpu, mchk->mcic,
296 (u64 __user *) __LC_MCCK_CODE);
297 rc |= put_guest_lc(vcpu, mchk->failing_storage_address,
298 (u64 __user *) __LC_MCCK_FAIL_STOR_ADDR);
299 rc |= write_guest_lc(vcpu, __LC_PSW_SAVE_AREA,
300 &mchk->fixed_logout, sizeof(mchk->fixed_logout));
301 rc |= write_guest_lc(vcpu, __LC_MCK_OLD_PSW,
302 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
303 rc |= read_guest_lc(vcpu, __LC_MCK_NEW_PSW,
304 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
305 return rc;
306}
307
308static int __must_check __deliver_restart(struct kvm_vcpu *vcpu)
309{
310 int rc;
311
312 VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu restart");
313 vcpu->stat.deliver_restart_signal++;
314 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0);
315
316 rc = write_guest_lc(vcpu,
317 offsetof(struct _lowcore, restart_old_psw),
318 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
319 rc |= read_guest_lc(vcpu, offsetof(struct _lowcore, restart_psw),
320 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
321 return rc;
322}
323
324static int __must_check __deliver_stop(struct kvm_vcpu *vcpu)
325{
326 VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop");
327 vcpu->stat.deliver_stop_signal++;
328 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_SIGP_STOP,
329 0, 0);
330
331 __set_cpuflag(vcpu, CPUSTAT_STOP_INT);
332 return 0;
333}
334
335static int __must_check __deliver_set_prefix(struct kvm_vcpu *vcpu,
336 struct kvm_s390_interrupt_info *inti)
337{
338 struct kvm_s390_prefix_info *prefix = &inti->prefix;
339
340 VCPU_EVENT(vcpu, 4, "interrupt: set prefix to %x", prefix->address);
341 vcpu->stat.deliver_prefix_signal++;
342 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
343 KVM_S390_SIGP_SET_PREFIX,
344 prefix->address, 0);
345
346 kvm_s390_set_prefix(vcpu, prefix->address);
347 return 0;
348}
349
350static int __must_check __deliver_emergency_signal(struct kvm_vcpu *vcpu,
351 struct kvm_s390_interrupt_info *inti)
352{
353 struct kvm_s390_emerg_info *emerg = &inti->emerg;
354 int rc;
355
356 VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp emerg");
357 vcpu->stat.deliver_emergency_signal++;
358 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
359 inti->emerg.code, 0);
360
361 rc = put_guest_lc(vcpu, EXT_IRQ_EMERGENCY_SIG,
362 (u16 *)__LC_EXT_INT_CODE);
363 rc |= put_guest_lc(vcpu, emerg->code, (u16 *)__LC_EXT_CPU_ADDR);
364 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
365 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
366 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
367 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
368 return rc;
369}
370
371static int __must_check __deliver_external_call(struct kvm_vcpu *vcpu,
372 struct kvm_s390_interrupt_info *inti)
373{
374 struct kvm_s390_extcall_info *extcall = &inti->extcall;
375 int rc;
376
377 VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp ext call");
378 vcpu->stat.deliver_external_call++;
379 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
380 KVM_S390_INT_EXTERNAL_CALL,
381 extcall->code, 0);
382
383 rc = put_guest_lc(vcpu, EXT_IRQ_EXTERNAL_CALL,
384 (u16 *)__LC_EXT_INT_CODE);
385 rc |= put_guest_lc(vcpu, extcall->code, (u16 *)__LC_EXT_CPU_ADDR);
386 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
387 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
388 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, &vcpu->arch.sie_block->gpsw,
389 sizeof(psw_t));
390 return rc;
391}
392
393static int __must_check __deliver_prog(struct kvm_vcpu *vcpu,
394 struct kvm_s390_interrupt_info *inti)
233{ 395{
396 struct kvm_s390_pgm_info *pgm_info = &inti->pgm;
234 int rc = 0; 397 int rc = 0;
235 u16 ilc = get_ilc(vcpu); 398 u16 ilc = get_ilc(vcpu);
236 399
400 VCPU_EVENT(vcpu, 4, "interrupt: pgm check code:%x, ilc:%x",
401 pgm_info->code, ilc);
402 vcpu->stat.deliver_program_int++;
403 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_PROGRAM_INT,
404 pgm_info->code, 0);
405
237 switch (pgm_info->code & ~PGM_PER) { 406 switch (pgm_info->code & ~PGM_PER) {
238 case PGM_AFX_TRANSLATION: 407 case PGM_AFX_TRANSLATION:
239 case PGM_ASX_TRANSLATION: 408 case PGM_ASX_TRANSLATION:
@@ -306,202 +475,151 @@ static int __must_check __deliver_prog_irq(struct kvm_vcpu *vcpu,
306 &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); 475 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
307 rc |= read_guest_lc(vcpu, __LC_PGM_NEW_PSW, 476 rc |= read_guest_lc(vcpu, __LC_PGM_NEW_PSW,
308 &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); 477 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
478 return rc;
479}
480
481static int __must_check __deliver_service(struct kvm_vcpu *vcpu,
482 struct kvm_s390_interrupt_info *inti)
483{
484 int rc;
485
486 VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x",
487 inti->ext.ext_params);
488 vcpu->stat.deliver_service_signal++;
489 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
490 inti->ext.ext_params, 0);
491
492 rc = put_guest_lc(vcpu, EXT_IRQ_SERVICE_SIG, (u16 *)__LC_EXT_INT_CODE);
493 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
494 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
495 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
496 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
497 rc |= put_guest_lc(vcpu, inti->ext.ext_params,
498 (u32 *)__LC_EXT_PARAMS);
499 return rc;
500}
501
502static int __must_check __deliver_pfault_done(struct kvm_vcpu *vcpu,
503 struct kvm_s390_interrupt_info *inti)
504{
505 int rc;
506
507 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id,
508 KVM_S390_INT_PFAULT_DONE, 0,
509 inti->ext.ext_params2);
309 510
511 rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, (u16 *)__LC_EXT_INT_CODE);
512 rc |= put_guest_lc(vcpu, PFAULT_DONE, (u16 *)__LC_EXT_CPU_ADDR);
513 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
514 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
515 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
516 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
517 rc |= put_guest_lc(vcpu, inti->ext.ext_params2,
518 (u64 *)__LC_EXT_PARAMS2);
519 return rc;
520}
521
522static int __must_check __deliver_virtio(struct kvm_vcpu *vcpu,
523 struct kvm_s390_interrupt_info *inti)
524{
525 int rc;
526
527 VCPU_EVENT(vcpu, 4, "interrupt: virtio parm:%x,parm64:%llx",
528 inti->ext.ext_params, inti->ext.ext_params2);
529 vcpu->stat.deliver_virtio_interrupt++;
530 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
531 inti->ext.ext_params,
532 inti->ext.ext_params2);
533
534 rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE, (u16 *)__LC_EXT_INT_CODE);
535 rc |= put_guest_lc(vcpu, VIRTIO_PARAM, (u16 *)__LC_EXT_CPU_ADDR);
536 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
537 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
538 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
539 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
540 rc |= put_guest_lc(vcpu, inti->ext.ext_params,
541 (u32 *)__LC_EXT_PARAMS);
542 rc |= put_guest_lc(vcpu, inti->ext.ext_params2,
543 (u64 *)__LC_EXT_PARAMS2);
544 return rc;
545}
546
547static int __must_check __deliver_io(struct kvm_vcpu *vcpu,
548 struct kvm_s390_interrupt_info *inti)
549{
550 int rc;
551
552 VCPU_EVENT(vcpu, 4, "interrupt: I/O %llx", inti->type);
553 vcpu->stat.deliver_io_int++;
554 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
555 ((__u32)inti->io.subchannel_id << 16) |
556 inti->io.subchannel_nr,
557 ((__u64)inti->io.io_int_parm << 32) |
558 inti->io.io_int_word);
559
560 rc = put_guest_lc(vcpu, inti->io.subchannel_id,
561 (u16 *)__LC_SUBCHANNEL_ID);
562 rc |= put_guest_lc(vcpu, inti->io.subchannel_nr,
563 (u16 *)__LC_SUBCHANNEL_NR);
564 rc |= put_guest_lc(vcpu, inti->io.io_int_parm,
565 (u32 *)__LC_IO_INT_PARM);
566 rc |= put_guest_lc(vcpu, inti->io.io_int_word,
567 (u32 *)__LC_IO_INT_WORD);
568 rc |= write_guest_lc(vcpu, __LC_IO_OLD_PSW,
569 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
570 rc |= read_guest_lc(vcpu, __LC_IO_NEW_PSW,
571 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
310 return rc; 572 return rc;
311} 573}
312 574
313static int __must_check __do_deliver_interrupt(struct kvm_vcpu *vcpu, 575static int __must_check __do_deliver_interrupt(struct kvm_vcpu *vcpu,
314 struct kvm_s390_interrupt_info *inti) 576 struct kvm_s390_interrupt_info *inti)
315{ 577{
316 const unsigned short table[] = { 2, 4, 4, 6 }; 578 int rc;
317 int rc = 0;
318 579
319 switch (inti->type) { 580 switch (inti->type) {
320 case KVM_S390_INT_EMERGENCY: 581 case KVM_S390_INT_EMERGENCY:
321 VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp emerg"); 582 rc = __deliver_emergency_signal(vcpu, inti);
322 vcpu->stat.deliver_emergency_signal++;
323 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
324 inti->emerg.code, 0);
325 rc = put_guest_lc(vcpu, 0x1201, (u16 *)__LC_EXT_INT_CODE);
326 rc |= put_guest_lc(vcpu, inti->emerg.code,
327 (u16 *)__LC_EXT_CPU_ADDR);
328 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
329 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
330 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
331 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
332 break; 583 break;
333 case KVM_S390_INT_EXTERNAL_CALL: 584 case KVM_S390_INT_EXTERNAL_CALL:
334 VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp ext call"); 585 rc = __deliver_external_call(vcpu, inti);
335 vcpu->stat.deliver_external_call++;
336 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
337 inti->extcall.code, 0);
338 rc = put_guest_lc(vcpu, 0x1202, (u16 *)__LC_EXT_INT_CODE);
339 rc |= put_guest_lc(vcpu, inti->extcall.code,
340 (u16 *)__LC_EXT_CPU_ADDR);
341 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
342 &vcpu->arch.sie_block->gpsw,
343 sizeof(psw_t));
344 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
345 &vcpu->arch.sie_block->gpsw,
346 sizeof(psw_t));
347 break; 586 break;
348 case KVM_S390_INT_CLOCK_COMP: 587 case KVM_S390_INT_CLOCK_COMP:
349 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, 588 rc = __deliver_ckc(vcpu);
350 0, 0);
351 rc = deliver_ckc_interrupt(vcpu);
352 break; 589 break;
353 case KVM_S390_INT_CPU_TIMER: 590 case KVM_S390_INT_CPU_TIMER:
354 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, 591 rc = __deliver_cpu_timer(vcpu);
355 0, 0);
356 rc = put_guest_lc(vcpu, EXT_IRQ_CPU_TIMER,
357 (u16 *)__LC_EXT_INT_CODE);
358 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
359 &vcpu->arch.sie_block->gpsw,
360 sizeof(psw_t));
361 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
362 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
363 break; 592 break;
364 case KVM_S390_INT_SERVICE: 593 case KVM_S390_INT_SERVICE:
365 VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x", 594 rc = __deliver_service(vcpu, inti);
366 inti->ext.ext_params);
367 vcpu->stat.deliver_service_signal++;
368 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
369 inti->ext.ext_params, 0);
370 rc = put_guest_lc(vcpu, 0x2401, (u16 *)__LC_EXT_INT_CODE);
371 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
372 &vcpu->arch.sie_block->gpsw,
373 sizeof(psw_t));
374 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
375 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
376 rc |= put_guest_lc(vcpu, inti->ext.ext_params,
377 (u32 *)__LC_EXT_PARAMS);
378 break; 595 break;
379 case KVM_S390_INT_PFAULT_INIT: 596 case KVM_S390_INT_PFAULT_INIT:
380 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, 0, 597 rc = __deliver_pfault_init(vcpu, inti);
381 inti->ext.ext_params2);
382 rc = put_guest_lc(vcpu, EXT_IRQ_CP_SERVICE,
383 (u16 *) __LC_EXT_INT_CODE);
384 rc |= put_guest_lc(vcpu, PFAULT_INIT, (u16 *) __LC_EXT_CPU_ADDR);
385 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
386 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
387 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
388 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
389 rc |= put_guest_lc(vcpu, inti->ext.ext_params2,
390 (u64 *) __LC_EXT_PARAMS2);
391 break; 598 break;
392 case KVM_S390_INT_PFAULT_DONE: 599 case KVM_S390_INT_PFAULT_DONE:
393 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type, 0, 600 rc = __deliver_pfault_done(vcpu, inti);
394 inti->ext.ext_params2);
395 rc = put_guest_lc(vcpu, 0x2603, (u16 *)__LC_EXT_INT_CODE);
396 rc |= put_guest_lc(vcpu, PFAULT_DONE, (u16 *)__LC_EXT_CPU_ADDR);
397 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
398 &vcpu->arch.sie_block->gpsw,
399 sizeof(psw_t));
400 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
401 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
402 rc |= put_guest_lc(vcpu, inti->ext.ext_params2,
403 (u64 *)__LC_EXT_PARAMS2);
404 break; 601 break;
405 case KVM_S390_INT_VIRTIO: 602 case KVM_S390_INT_VIRTIO:
406 VCPU_EVENT(vcpu, 4, "interrupt: virtio parm:%x,parm64:%llx", 603 rc = __deliver_virtio(vcpu, inti);
407 inti->ext.ext_params, inti->ext.ext_params2);
408 vcpu->stat.deliver_virtio_interrupt++;
409 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
410 inti->ext.ext_params,
411 inti->ext.ext_params2);
412 rc = put_guest_lc(vcpu, 0x2603, (u16 *)__LC_EXT_INT_CODE);
413 rc |= put_guest_lc(vcpu, VIRTIO_PARAM, (u16 *)__LC_EXT_CPU_ADDR);
414 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
415 &vcpu->arch.sie_block->gpsw,
416 sizeof(psw_t));
417 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
418 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
419 rc |= put_guest_lc(vcpu, inti->ext.ext_params,
420 (u32 *)__LC_EXT_PARAMS);
421 rc |= put_guest_lc(vcpu, inti->ext.ext_params2,
422 (u64 *)__LC_EXT_PARAMS2);
423 break; 604 break;
424 case KVM_S390_SIGP_STOP: 605 case KVM_S390_SIGP_STOP:
425 VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop"); 606 rc = __deliver_stop(vcpu);
426 vcpu->stat.deliver_stop_signal++;
427 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
428 0, 0);
429 __set_intercept_indicator(vcpu, inti);
430 break; 607 break;
431
432 case KVM_S390_SIGP_SET_PREFIX: 608 case KVM_S390_SIGP_SET_PREFIX:
433 VCPU_EVENT(vcpu, 4, "interrupt: set prefix to %x", 609 rc = __deliver_set_prefix(vcpu, inti);
434 inti->prefix.address);
435 vcpu->stat.deliver_prefix_signal++;
436 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
437 inti->prefix.address, 0);
438 kvm_s390_set_prefix(vcpu, inti->prefix.address);
439 break; 610 break;
440
441 case KVM_S390_RESTART: 611 case KVM_S390_RESTART:
442 VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu restart"); 612 rc = __deliver_restart(vcpu);
443 vcpu->stat.deliver_restart_signal++;
444 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
445 0, 0);
446 rc = write_guest_lc(vcpu,
447 offsetof(struct _lowcore, restart_old_psw),
448 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
449 rc |= read_guest_lc(vcpu, offsetof(struct _lowcore, restart_psw),
450 &vcpu->arch.sie_block->gpsw,
451 sizeof(psw_t));
452 break; 613 break;
453 case KVM_S390_PROGRAM_INT: 614 case KVM_S390_PROGRAM_INT:
454 VCPU_EVENT(vcpu, 4, "interrupt: pgm check code:%x, ilc:%x", 615 rc = __deliver_prog(vcpu, inti);
455 inti->pgm.code,
456 table[vcpu->arch.sie_block->ipa >> 14]);
457 vcpu->stat.deliver_program_int++;
458 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
459 inti->pgm.code, 0);
460 rc = __deliver_prog_irq(vcpu, &inti->pgm);
461 break; 616 break;
462
463 case KVM_S390_MCHK: 617 case KVM_S390_MCHK:
464 VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx", 618 rc = __deliver_machine_check(vcpu, inti);
465 inti->mchk.mcic);
466 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
467 inti->mchk.cr14,
468 inti->mchk.mcic);
469 rc = kvm_s390_vcpu_store_status(vcpu,
470 KVM_S390_STORE_STATUS_PREFIXED);
471 rc |= put_guest_lc(vcpu, inti->mchk.mcic, (u64 *)__LC_MCCK_CODE);
472 rc |= write_guest_lc(vcpu, __LC_MCK_OLD_PSW,
473 &vcpu->arch.sie_block->gpsw,
474 sizeof(psw_t));
475 rc |= read_guest_lc(vcpu, __LC_MCK_NEW_PSW,
476 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
477 break; 619 break;
478
479 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: 620 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
480 { 621 rc = __deliver_io(vcpu, inti);
481 __u32 param0 = ((__u32)inti->io.subchannel_id << 16) |
482 inti->io.subchannel_nr;
483 __u64 param1 = ((__u64)inti->io.io_int_parm << 32) |
484 inti->io.io_int_word;
485 VCPU_EVENT(vcpu, 4, "interrupt: I/O %llx", inti->type);
486 vcpu->stat.deliver_io_int++;
487 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
488 param0, param1);
489 rc = put_guest_lc(vcpu, inti->io.subchannel_id,
490 (u16 *)__LC_SUBCHANNEL_ID);
491 rc |= put_guest_lc(vcpu, inti->io.subchannel_nr,
492 (u16 *)__LC_SUBCHANNEL_NR);
493 rc |= put_guest_lc(vcpu, inti->io.io_int_parm,
494 (u32 *)__LC_IO_INT_PARM);
495 rc |= put_guest_lc(vcpu, inti->io.io_int_word,
496 (u32 *)__LC_IO_INT_WORD);
497 rc |= write_guest_lc(vcpu, __LC_IO_OLD_PSW,
498 &vcpu->arch.sie_block->gpsw,
499 sizeof(psw_t));
500 rc |= read_guest_lc(vcpu, __LC_IO_NEW_PSW,
501 &vcpu->arch.sie_block->gpsw,
502 sizeof(psw_t));
503 break; 622 break;
504 }
505 default: 623 default:
506 BUG(); 624 BUG();
507 } 625 }
@@ -509,19 +627,6 @@ static int __must_check __do_deliver_interrupt(struct kvm_vcpu *vcpu,
509 return rc; 627 return rc;
510} 628}
511 629
512static int __must_check deliver_ckc_interrupt(struct kvm_vcpu *vcpu)
513{
514 int rc;
515
516 rc = put_guest_lc(vcpu, 0x1004, (u16 __user *)__LC_EXT_INT_CODE);
517 rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW,
518 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
519 rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW,
520 &vcpu->arch.sie_block->gpsw,
521 sizeof(psw_t));
522 return rc;
523}
524
525/* Check whether SIGP interpretation facility has an external call pending */ 630/* Check whether SIGP interpretation facility has an external call pending */
526int kvm_s390_si_ext_call_pending(struct kvm_vcpu *vcpu) 631int kvm_s390_si_ext_call_pending(struct kvm_vcpu *vcpu)
527{ 632{
@@ -691,7 +796,7 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
691 } 796 }
692 797
693 if (!rc && kvm_cpu_has_pending_timer(vcpu)) 798 if (!rc && kvm_cpu_has_pending_timer(vcpu))
694 rc = deliver_ckc_interrupt(vcpu); 799 rc = __deliver_ckc(vcpu);
695 800
696 if (!rc && atomic_read(&fi->active)) { 801 if (!rc && atomic_read(&fi->active)) {
697 do { 802 do {