コード例 #1
0
ファイル: priv.c プロジェクト: A2109devs/lenovo_a2109a_kernel
static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
{
	int base2 = vcpu->arch.sie_block->ipb >> 28;
	int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16);
	u64 useraddr;
	int rc;

	vcpu->stat.instruction_stap++;
	useraddr = disp2;
	if (base2)
		useraddr += vcpu->arch.guest_gprs[base2];

	if (useraddr & 1) {
		kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
		goto out;
	}

	rc = put_guest_u16(vcpu, useraddr, vcpu->vcpu_id);
	if (rc == -EFAULT) {
		kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
		goto out;
	}

	VCPU_EVENT(vcpu, 5, "storing cpu address to %llx", useraddr);
out:
	return 0;
}
コード例 #2
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;
}
コード例 #3
0
ファイル: priv.c プロジェクト: AiWinters/linux
static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
{
	u64 useraddr;
	int rc;

	vcpu->stat.instruction_stap++;

	useraddr = kvm_s390_get_base_disp_s(vcpu);

	if (useraddr & 1) {
		kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
		goto out;
	}

	rc = put_guest_u16(vcpu, useraddr, vcpu->vcpu_id);
	if (rc == -EFAULT) {
		kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
		goto out;
	}

	VCPU_EVENT(vcpu, 5, "storing cpu address to %llx", useraddr);
	trace_kvm_s390_handle_stap(vcpu, useraddr);
out:
	return 0;
}
コード例 #4
0
ファイル: priv.c プロジェクト: AiWinters/linux
static int handle_tpi(struct kvm_vcpu *vcpu)
{
	u64 addr;
	struct kvm_s390_interrupt_info *inti;
	int cc;

	addr = kvm_s390_get_base_disp_s(vcpu);

	inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->run->s.regs.crs[6], 0);
	if (inti) {
		if (addr) {
			/*
			 * Store the two-word I/O interruption code into the
			 * provided area.
			 */
			put_guest_u16(vcpu, addr, inti->io.subchannel_id);
			put_guest_u16(vcpu, addr + 2, inti->io.subchannel_nr);
			put_guest_u32(vcpu, addr + 4, inti->io.io_int_parm);
		} else {
			/*
			 * Store the three-word I/O interruption code into
			 * the appropriate lowcore area.
			 */
			put_guest_u16(vcpu, 184, inti->io.subchannel_id);
			put_guest_u16(vcpu, 186, inti->io.subchannel_nr);
			put_guest_u32(vcpu, 188, inti->io.io_int_parm);
			put_guest_u32(vcpu, 192, inti->io.io_int_word);
		}
		cc = 1;
	} else
		cc = 0;
	kfree(inti);
	/* Set condition code and we're done. */
	vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
	vcpu->arch.sie_block->gpsw.mask |= (cc & 3ul) << 44;
	return 0;
}
コード例 #5
0
static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
                                   struct kvm_s390_interrupt_info *inti)
{
    const unsigned short table[] = { 2, 4, 4, 6 };
    int rc, exception = 0;

    switch (inti->type) {
    case KVM_S390_INT_EMERGENCY:
        VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp emerg");
        vcpu->stat.deliver_emergency_signal++;
        rc = put_guest_u16(vcpu, __LC_EXT_INT_CODE, 0x1201);
        if (rc == -EFAULT)
            exception = 1;

        rc = put_guest_u16(vcpu, __LC_EXT_CPU_ADDR, inti->emerg.code);
        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;
        break;

    case KVM_S390_INT_EXTERNAL_CALL:
        VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp ext call");
        vcpu->stat.deliver_external_call++;
        rc = put_guest_u16(vcpu, __LC_EXT_INT_CODE, 0x1202);
        if (rc == -EFAULT)
            exception = 1;

        rc = put_guest_u16(vcpu, __LC_EXT_CPU_ADDR, inti->extcall.code);
        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;
        break;

    case KVM_S390_INT_SERVICE:
        VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x",
                   inti->ext.ext_params);
        vcpu->stat.deliver_service_signal++;
        rc = put_guest_u16(vcpu, __LC_EXT_INT_CODE, 0x2401);
        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;

        rc = put_guest_u32(vcpu, __LC_EXT_PARAMS, inti->ext.ext_params);
        if (rc == -EFAULT)
            exception = 1;
        break;

    case KVM_S390_INT_VIRTIO:
        VCPU_EVENT(vcpu, 4, "interrupt: virtio parm:%x,parm64:%llx",
                   inti->ext.ext_params, inti->ext.ext_params2);
        vcpu->stat.deliver_virtio_interrupt++;
        rc = put_guest_u16(vcpu, __LC_EXT_INT_CODE, 0x2603);
        if (rc == -EFAULT)
            exception = 1;

        rc = put_guest_u16(vcpu, __LC_EXT_CPU_ADDR, 0x0d00);
        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;

        rc = put_guest_u32(vcpu, __LC_EXT_PARAMS, inti->ext.ext_params);
        if (rc == -EFAULT)
            exception = 1;

        rc = put_guest_u64(vcpu, __LC_EXT_PARAMS2,
                           inti->ext.ext_params2);
        if (rc == -EFAULT)
            exception = 1;
        break;

    case KVM_S390_SIGP_STOP:
        VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop");
        vcpu->stat.deliver_stop_signal++;
        __set_intercept_indicator(vcpu, inti);
        break;

    case KVM_S390_SIGP_SET_PREFIX:
        VCPU_EVENT(vcpu, 4, "interrupt: set prefix to %x",
                   inti->prefix.address);
        vcpu->stat.deliver_prefix_signal++;
        kvm_s390_set_prefix(vcpu, inti->prefix.address);
        break;

    case KVM_S390_RESTART:
        VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu restart");
        vcpu->stat.deliver_restart_signal++;
        rc = copy_to_guest(vcpu, offsetof(struct _lowcore,
                                          restart_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,
                             offsetof(struct _lowcore, restart_psw), sizeof(psw_t));
        if (rc == -EFAULT)
            exception = 1;
        atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
        break;

    case KVM_S390_PROGRAM_INT:
        VCPU_EVENT(vcpu, 4, "interrupt: pgm check code:%x, ilc:%x",
                   inti->pgm.code,
                   table[vcpu->arch.sie_block->ipa >> 14]);
        vcpu->stat.deliver_program_int++;
        rc = put_guest_u16(vcpu, __LC_PGM_INT_CODE, inti->pgm.code);
        if (rc == -EFAULT)
            exception = 1;

        rc = put_guest_u16(vcpu, __LC_PGM_ILC,
                           table[vcpu->arch.sie_block->ipa >> 14]);
        if (rc == -EFAULT)
            exception = 1;

        rc = copy_to_guest(vcpu, __LC_PGM_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_PGM_NEW_PSW, sizeof(psw_t));
        if (rc == -EFAULT)
            exception = 1;
        break;

    default:
        BUG();
    }
    if (exception) {
        printk("kvm: The guest lowcore is not mapped during interrupt "
               "delivery, killing userspace\n");
        do_exit(SIGKILL);
    }
}