static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu, struct kvm_s390_interrupt_info *inti) { switch (inti->type) { case KVM_S390_INT_EMERGENCY: if (psw_extint_disabled(vcpu)) return 0; if (vcpu->arch.sie_block->gcr[0] & 0x4000ul) return 1; return 0; case KVM_S390_INT_SERVICE: if (psw_extint_disabled(vcpu)) return 0; if (vcpu->arch.sie_block->gcr[0] & 0x200ul) return 1; return 0; case KVM_S390_INT_VIRTIO: if (psw_extint_disabled(vcpu)) return 0; if (vcpu->arch.sie_block->gcr[0] & 0x200ul) return 1; return 0; case KVM_S390_PROGRAM_INT: case KVM_S390_SIGP_STOP: case KVM_S390_SIGP_SET_PREFIX: case KVM_S390_RESTART: return 1; default: BUG(); } return 0; }
static int __try_deliver_ckc_interrupt(struct kvm_vcpu *vcpu) { int rc, exception = 0; if (psw_extint_disabled(vcpu)) return 0; if (!(vcpu->arch.sie_block->gcr[0] & 0x800ul)) return 0; rc = put_guest_u16(vcpu, __LC_EXT_INT_CODE, 0x1004); if (rc == -EFAULT) exception = 1; rc = copy_to_guest(vcpu, __LC_EXT_OLD_PSW, &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); if (rc == -EFAULT) exception = 1; rc = copy_from_guest(vcpu, &vcpu->arch.sie_block->gpsw, __LC_EXT_NEW_PSW, sizeof(psw_t)); if (rc == -EFAULT) exception = 1; if (exception) { printk("kvm: The guest lowcore is not mapped during interrupt " "delivery, killing userspace\n"); do_exit(SIGKILL); } return 1; }
static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu) { if (psw_extint_disabled(vcpu) || !(vcpu->arch.sie_block->gcr[0] & 0x800ul)) return 0; if (guestdbg_enabled(vcpu) && guestdbg_sstep_enabled(vcpu)) /* No timer interrupts when single stepping */ return 0; return 1; }
static void __set_intercept_indicator(struct kvm_vcpu *vcpu, struct kvm_s390_interrupt_info *inti) { switch (inti->type) { case KVM_S390_INT_EMERGENCY: case KVM_S390_INT_SERVICE: case KVM_S390_INT_VIRTIO: if (psw_extint_disabled(vcpu)) __set_cpuflag(vcpu, CPUSTAT_EXT_INT); else vcpu->arch.sie_block->lctl |= LCTL_CR0; break; case KVM_S390_SIGP_STOP: __set_cpuflag(vcpu, CPUSTAT_STOP_INT); break; default: BUG(); } }