qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC 1/2] KVM: s390: add and extend interrupt information d


From: Jens Freimann
Subject: [Qemu-devel] [RFC 1/2] KVM: s390: add and extend interrupt information data structs
Date: Fri, 26 Jul 2013 18:47:58 +0200

With the currently available struct kvm_s390_interrupt it is not possible to
inject all kinds of interrupts as defined in the z/Architecture. Add
interruption parameters to the structures to make sure we can inject all kinds
of interrupts and move it to kvm.h

Signed-off-by: Jens Freimann <address@hidden>
---
 arch/s390/include/asm/kvm_host.h |  45 +---------
 arch/s390/kvm/interrupt.c        | 189 +++++++++++++++++++--------------------
 arch/s390/kvm/priv.c             |  22 ++---
 arch/s390/kvm/sigp.c             |  14 +--
 include/uapi/linux/kvm.h         |  62 +++++++++++++
 5 files changed, 175 insertions(+), 157 deletions(-)

diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 3238d40..c755a9d 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -16,6 +16,7 @@
 #include <linux/hrtimer.h>
 #include <linux/interrupt.h>
 #include <linux/kvm_host.h>
+#include <linux/kvm.h>
 #include <asm/debug.h>
 #include <asm/cpu.h>
 
@@ -162,18 +163,6 @@ struct kvm_vcpu_stat {
        u32 diagnose_9c;
 };
 
-struct kvm_s390_io_info {
-       __u16        subchannel_id;            /* 0x0b8 */
-       __u16        subchannel_nr;            /* 0x0ba */
-       __u32        io_int_parm;              /* 0x0bc */
-       __u32        io_int_word;              /* 0x0c0 */
-};
-
-struct kvm_s390_ext_info {
-       __u32 ext_params;
-       __u64 ext_params2;
-};
-
 #define PGM_OPERATION            0x01
 #define PGM_PRIVILEGED_OP       0x02
 #define PGM_EXECUTE              0x03
@@ -182,39 +171,9 @@ struct kvm_s390_ext_info {
 #define PGM_SPECIFICATION        0x06
 #define PGM_DATA                 0x07
 
-struct kvm_s390_pgm_info {
-       __u16 code;
-};
-
-struct kvm_s390_prefix_info {
-       __u32 address;
-};
-
-struct kvm_s390_extcall_info {
-       __u16 code;
-};
-
-struct kvm_s390_emerg_info {
-       __u16 code;
-};
-
-struct kvm_s390_mchk_info {
-       __u64 cr14;
-       __u64 mcic;
-};
-
 struct kvm_s390_interrupt_info {
        struct list_head list;
-       u64     type;
-       union {
-               struct kvm_s390_io_info io;
-               struct kvm_s390_ext_info ext;
-               struct kvm_s390_pgm_info pgm;
-               struct kvm_s390_emerg_info emerg;
-               struct kvm_s390_extcall_info extcall;
-               struct kvm_s390_prefix_info prefix;
-               struct kvm_s390_mchk_info mchk;
-       };
+       struct kvm_s390_irq irq;
 };
 
 /* for local_interrupt.action_flags */
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 7f35cb3..25cf71d 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -65,7 +65,7 @@ static u64 int_word_to_isc_bits(u32 int_word)
 static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu,
                                      struct kvm_s390_interrupt_info *inti)
 {
-       switch (inti->type) {
+       switch (inti->irq.type) {
        case KVM_S390_INT_EXTERNAL_CALL:
                if (psw_extint_disabled(vcpu))
                        return 0;
@@ -97,19 +97,19 @@ static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu,
        case KVM_S390_MCHK:
                if (psw_mchk_disabled(vcpu))
                        return 0;
-               if (vcpu->arch.sie_block->gcr[14] & inti->mchk.cr14)
+               if (vcpu->arch.sie_block->gcr[14] & inti->irq.mchk.cr14)
                        return 1;
                return 0;
        case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
                if (psw_ioint_disabled(vcpu))
                        return 0;
                if (vcpu->arch.sie_block->gcr[6] &
-                   int_word_to_isc_bits(inti->io.io_int_word))
+                   int_word_to_isc_bits(inti->irq.io.io_int_word))
                        return 1;
                return 0;
        default:
                printk(KERN_WARNING "illegal interrupt type %llx\n",
-                      inti->type);
+                      inti->irq.type);
                BUG();
        }
        return 0;
@@ -146,7 +146,7 @@ static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag)
 static void __set_intercept_indicator(struct kvm_vcpu *vcpu,
                                      struct kvm_s390_interrupt_info *inti)
 {
-       switch (inti->type) {
+       switch (inti->irq.type) {
        case KVM_S390_INT_EXTERNAL_CALL:
        case KVM_S390_INT_EMERGENCY:
        case KVM_S390_INT_SERVICE:
@@ -182,14 +182,14 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
        const unsigned short table[] = { 2, 4, 4, 6 };
        int rc = 0;
 
-       switch (inti->type) {
+       switch (inti->irq.type) {
        case KVM_S390_INT_EMERGENCY:
                VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp emerg");
                vcpu->stat.deliver_emergency_signal++;
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
-                                                inti->emerg.code, 0);
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
+                                                inti->irq.emerg.code, 0);
                rc  = put_guest(vcpu, 0x1201, (u16 __user *)__LC_EXT_INT_CODE);
-               rc |= put_guest(vcpu, inti->emerg.code,
+               rc |= put_guest(vcpu, inti->irq.emerg.code,
                                (u16 __user *)__LC_EXT_CPU_ADDR);
                rc |= copy_to_guest(vcpu, __LC_EXT_OLD_PSW,
                                    &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
@@ -199,10 +199,10 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
        case KVM_S390_INT_EXTERNAL_CALL:
                VCPU_EVENT(vcpu, 4, "%s", "interrupt: sigp ext call");
                vcpu->stat.deliver_external_call++;
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
-                                                inti->extcall.code, 0);
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
+                                                inti->irq.extcall.code, 0);
                rc  = put_guest(vcpu, 0x1202, (u16 __user *)__LC_EXT_INT_CODE);
-               rc |= put_guest(vcpu, inti->extcall.code,
+               rc |= put_guest(vcpu, inti->irq.extcall.code,
                                (u16 __user *)__LC_EXT_CPU_ADDR);
                rc |= copy_to_guest(vcpu, __LC_EXT_OLD_PSW,
                                    &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
@@ -211,57 +211,57 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
                break;
        case KVM_S390_INT_SERVICE:
                VCPU_EVENT(vcpu, 4, "interrupt: sclp parm:%x",
-                          inti->ext.ext_params);
+                          inti->irq.ext.ext_params);
                vcpu->stat.deliver_service_signal++;
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
-                                                inti->ext.ext_params, 0);
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
+                                                inti->irq.ext.ext_params, 0);
                rc  = put_guest(vcpu, 0x2401, (u16 __user *)__LC_EXT_INT_CODE);
                rc |= copy_to_guest(vcpu, __LC_EXT_OLD_PSW,
                                    &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
                rc |= copy_from_guest(vcpu, &vcpu->arch.sie_block->gpsw,
                                      __LC_EXT_NEW_PSW, sizeof(psw_t));
-               rc |= put_guest(vcpu, inti->ext.ext_params,
+               rc |= put_guest(vcpu, inti->irq.ext.ext_params,
                                (u32 __user *)__LC_EXT_PARAMS);
                break;
        case KVM_S390_INT_VIRTIO:
                VCPU_EVENT(vcpu, 4, "interrupt: virtio parm:%x,parm64:%llx",
-                          inti->ext.ext_params, inti->ext.ext_params2);
+                          inti->irq.ext.ext_params, inti->irq.ext.ext_params2);
                vcpu->stat.deliver_virtio_interrupt++;
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
-                                                inti->ext.ext_params,
-                                                inti->ext.ext_params2);
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
+                                                inti->irq.ext.ext_params,
+                                                inti->irq.ext.ext_params2);
                rc  = put_guest(vcpu, 0x2603, (u16 __user *)__LC_EXT_INT_CODE);
                rc |= put_guest(vcpu, 0x0d00, (u16 __user *)__LC_EXT_CPU_ADDR);
                rc |= copy_to_guest(vcpu, __LC_EXT_OLD_PSW,
                                    &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
                rc |= copy_from_guest(vcpu, &vcpu->arch.sie_block->gpsw,
                                      __LC_EXT_NEW_PSW, sizeof(psw_t));
-               rc |= put_guest(vcpu, inti->ext.ext_params,
+               rc |= put_guest(vcpu, inti->irq.ext.ext_params,
                                (u32 __user *)__LC_EXT_PARAMS);
-               rc |= put_guest(vcpu, inti->ext.ext_params2,
+               rc |= put_guest(vcpu, inti->irq.ext.ext_params2,
                                (u64 __user *)__LC_EXT_PARAMS2);
                break;
        case KVM_S390_SIGP_STOP:
                VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu stop");
                vcpu->stat.deliver_stop_signal++;
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
                                                 0, 0);
                __set_intercept_indicator(vcpu, inti);
                break;
 
        case KVM_S390_SIGP_SET_PREFIX:
                VCPU_EVENT(vcpu, 4, "interrupt: set prefix to %x",
-                          inti->prefix.address);
+                          inti->irq.prefix.address);
                vcpu->stat.deliver_prefix_signal++;
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
-                                                inti->prefix.address, 0);
-               kvm_s390_set_prefix(vcpu, inti->prefix.address);
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
+                                                inti->irq.prefix.address, 0);
+               kvm_s390_set_prefix(vcpu, inti->irq.prefix.address);
                break;
 
        case KVM_S390_RESTART:
                VCPU_EVENT(vcpu, 4, "%s", "interrupt: cpu restart");
                vcpu->stat.deliver_restart_signal++;
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
                                                 0, 0);
                rc  = copy_to_guest(vcpu,
                                    offsetof(struct _lowcore, restart_old_psw),
@@ -273,12 +273,12 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
                break;
        case KVM_S390_PROGRAM_INT:
                VCPU_EVENT(vcpu, 4, "interrupt: pgm check code:%x, ilc:%x",
-                          inti->pgm.code,
+                          inti->irq.pgm.code,
                           table[vcpu->arch.sie_block->ipa >> 14]);
                vcpu->stat.deliver_program_int++;
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
-                                                inti->pgm.code, 0);
-               rc  = put_guest(vcpu, inti->pgm.code, (u16 __user 
*)__LC_PGM_INT_CODE);
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
+                                                inti->irq.pgm.code, 0);
+               rc  = put_guest(vcpu, inti->irq.pgm.code, (u16 __user 
*)__LC_PGM_INT_CODE);
                rc |= put_guest(vcpu, table[vcpu->arch.sie_block->ipa >> 14],
                                (u16 __user *)__LC_PGM_ILC);
                rc |= copy_to_guest(vcpu, __LC_PGM_OLD_PSW,
@@ -289,13 +289,13 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
 
        case KVM_S390_MCHK:
                VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx",
-                          inti->mchk.mcic);
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
-                                                inti->mchk.cr14,
-                                                inti->mchk.mcic);
+                          inti->irq.mchk.mcic);
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
+                                                inti->irq.mchk.cr14,
+                                                inti->irq.mchk.mcic);
                rc  = kvm_s390_vcpu_store_status(vcpu,
                                                 
KVM_S390_STORE_STATUS_PREFIXED);
-               rc |= put_guest(vcpu, inti->mchk.mcic, (u64 __user *) 
__LC_MCCK_CODE);
+               rc |= put_guest(vcpu, inti->irq.mchk.mcic, (u64 __user *) 
__LC_MCCK_CODE);
                rc |= copy_to_guest(vcpu, __LC_MCK_OLD_PSW,
                                    &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
                rc |= copy_from_guest(vcpu, &vcpu->arch.sie_block->gpsw,
@@ -304,21 +304,21 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
 
        case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
        {
-               __u32 param0 = ((__u32)inti->io.subchannel_id << 16) |
-                       inti->io.subchannel_nr;
-               __u64 param1 = ((__u64)inti->io.io_int_parm << 32) |
-                       inti->io.io_int_word;
-               VCPU_EVENT(vcpu, 4, "interrupt: I/O %llx", inti->type);
+               __u32 param0 = ((__u32)inti->irq.io.subchannel_id << 16) |
+                       inti->irq.io.subchannel_nr;
+               __u64 param1 = ((__u64)inti->irq.io.io_int_parm << 32) |
+                       inti->irq.io.io_int_word;
+               VCPU_EVENT(vcpu, 4, "interrupt: I/O %llx", inti->irq.type);
                vcpu->stat.deliver_io_int++;
-               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
+               trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->irq.type,
                                                 param0, param1);
-               rc  = put_guest(vcpu, inti->io.subchannel_id,
+               rc  = put_guest(vcpu, inti->irq.io.subchannel_id,
                                (u16 __user *) __LC_SUBCHANNEL_ID);
-               rc |= put_guest(vcpu, inti->io.subchannel_nr,
+               rc |= put_guest(vcpu, inti->irq.io.subchannel_nr,
                                (u16 __user *) __LC_SUBCHANNEL_NR);
-               rc |= put_guest(vcpu, inti->io.io_int_parm,
+               rc |= put_guest(vcpu, inti->irq.io.io_int_parm,
                                (u32 __user *) __LC_IO_INT_PARM);
-               rc |= put_guest(vcpu, inti->io.io_int_word,
+               rc |= put_guest(vcpu, inti->irq.io.io_int_word,
                                (u32 __user *) __LC_IO_INT_WORD);
                rc |= copy_to_guest(vcpu, __LC_IO_OLD_PSW,
                                    &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
@@ -554,7 +554,7 @@ void kvm_s390_deliver_pending_machine_checks(struct 
kvm_vcpu *vcpu)
                        deliver = 0;
                        spin_lock_bh(&li->lock);
                        list_for_each_entry_safe(inti, n, &li->list, list) {
-                               if ((inti->type == KVM_S390_MCHK) &&
+                               if ((inti->irq.type == KVM_S390_MCHK) &&
                                    __interrupt_is_deliverable(vcpu, inti)) {
                                        list_del(&inti->list);
                                        deliver = 1;
@@ -577,7 +577,7 @@ void kvm_s390_deliver_pending_machine_checks(struct 
kvm_vcpu *vcpu)
                        deliver = 0;
                        spin_lock(&fi->lock);
                        list_for_each_entry_safe(inti, n, &fi->list, list) {
-                               if ((inti->type == KVM_S390_MCHK) &&
+                               if ((inti->irq.type == KVM_S390_MCHK) &&
                                    __interrupt_is_deliverable(vcpu, inti)) {
                                        list_del(&inti->list);
                                        deliver = 1;
@@ -605,11 +605,11 @@ int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, 
u16 code)
        if (!inti)
                return -ENOMEM;
 
-       inti->type = KVM_S390_PROGRAM_INT;
-       inti->pgm.code = code;
+       inti->irq.type = KVM_S390_PROGRAM_INT;
+       inti->irq.pgm.code = code;
 
        VCPU_EVENT(vcpu, 3, "inject: program check %d (from kernel)", code);
-       trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, inti->type, code, 0, 1);
+       trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, inti->irq.type, code, 0, 1);
        spin_lock_bh(&li->lock);
        list_add(&inti->list, &li->list);
        atomic_set(&li->active, 1);
@@ -631,17 +631,17 @@ struct kvm_s390_interrupt_info 
*kvm_s390_get_io_int(struct kvm *kvm,
        spin_lock(&fi->lock);
        inti = NULL;
        list_for_each_entry(iter, &fi->list, list) {
-               if (!is_ioint(iter->type))
+               if (!is_ioint(iter->irq.type))
                        continue;
                if (cr6 &&
-                   ((cr6 & int_word_to_isc_bits(iter->io.io_int_word)) == 0))
+                   ((cr6 & int_word_to_isc_bits(iter->irq.io.io_int_word)) == 
0))
                        continue;
                if (schid) {
                        if (((schid & 0x00000000ffff0000) >> 16) !=
-                           iter->io.subchannel_id)
+                           iter->irq.io.subchannel_id)
                                continue;
                        if ((schid & 0x000000000000ffff) !=
-                           iter->io.subchannel_nr)
+                           iter->irq.io.subchannel_nr)
                                continue;
                }
                inti = iter;
@@ -662,72 +662,69 @@ int kvm_s390_inject_vm(struct kvm *kvm,
        struct kvm_s390_local_interrupt *li;
        struct kvm_s390_float_interrupt *fi;
        struct kvm_s390_interrupt_info *inti, *iter;
+       struct kvm_s390_irq *irq;
        int sigcpu;
 
        inti = kzalloc(sizeof(*inti), GFP_KERNEL);
        if (!inti)
                return -ENOMEM;
 
-       switch (s390int->type) {
+       irq = &inti->irq;
+
+       irq->type = s390int->type;
+       switch (irq->type) {
        case KVM_S390_INT_VIRTIO:
                VM_EVENT(kvm, 5, "inject: virtio parm:%x,parm64:%llx",
                         s390int->parm, s390int->parm64);
-               inti->type = s390int->type;
-               inti->ext.ext_params = s390int->parm;
-               inti->ext.ext_params2 = s390int->parm64;
+               irq->ext.ext_params = s390int->parm;
+               irq->ext.ext_params2 = s390int->parm64;
                break;
        case KVM_S390_INT_SERVICE:
                VM_EVENT(kvm, 5, "inject: sclp parm:%x", s390int->parm);
-               inti->type = s390int->type;
-               inti->ext.ext_params = s390int->parm;
+               irq->ext.ext_params = s390int->parm;
                break;
-       case KVM_S390_PROGRAM_INT:
-       case KVM_S390_SIGP_STOP:
-       case KVM_S390_INT_EXTERNAL_CALL:
-       case KVM_S390_INT_EMERGENCY:
-               kfree(inti);
-               return -EINVAL;
        case KVM_S390_MCHK:
                VM_EVENT(kvm, 5, "inject: machine check parm64:%llx",
                         s390int->parm64);
-               inti->type = s390int->type;
-               inti->mchk.cr14 = s390int->parm; /* upper bits are not used */
-               inti->mchk.mcic = s390int->parm64;
+               irq->mchk.cr14 = s390int->parm; /* upper bits are not used */
+               irq->mchk.mcic = s390int->parm64;
                break;
        case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
-               if (s390int->type & IOINT_AI_MASK)
+               if (irq->type & IOINT_AI_MASK)
                        VM_EVENT(kvm, 5, "%s", "inject: I/O (AI)");
                else
                        VM_EVENT(kvm, 5, "inject: I/O css %x ss %x schid %04x",
                                 s390int->type & IOINT_CSSID_MASK,
                                 s390int->type & IOINT_SSID_MASK,
                                 s390int->type & IOINT_SCHID_MASK);
-               inti->type = s390int->type;
-               inti->io.subchannel_id = s390int->parm >> 16;
-               inti->io.subchannel_nr = s390int->parm & 0x0000ffffu;
-               inti->io.io_int_parm = s390int->parm64 >> 32;
-               inti->io.io_int_word = s390int->parm64 & 0x00000000ffffffffull;
+               irq->io.subchannel_id = s390int->parm >> 16;
+               irq->io.subchannel_nr = s390int->parm & 0x0000ffffu;
+               irq->io.io_int_parm = s390int->parm64 >> 32;
+               irq->io.io_int_word = s390int->parm64 & 0x00000000ffffffffull;
                break;
+       case KVM_S390_PROGRAM_INT:
+       case KVM_S390_SIGP_STOP:
+       case KVM_S390_INT_EXTERNAL_CALL:
+       case KVM_S390_INT_EMERGENCY:
        default:
                kfree(inti);
                return -EINVAL;
        }
-       trace_kvm_s390_inject_vm(s390int->type, s390int->parm, s390int->parm64,
-                                2);
+       trace_kvm_s390_inject_vm(s390int->type, s390int->parm, s390int->parm64, 
2);
 
        mutex_lock(&kvm->lock);
        fi = &kvm->arch.float_int;
        spin_lock(&fi->lock);
-       if (!is_ioint(inti->type))
+       if (!is_ioint(inti->irq.type))
                list_add_tail(&inti->list, &fi->list);
        else {
-               u64 isc_bits = int_word_to_isc_bits(inti->io.io_int_word);
+               u64 isc_bits = int_word_to_isc_bits(inti->irq.io.io_int_word);
 
                /* Keep I/O interrupts sorted in isc order. */
                list_for_each_entry(iter, &fi->list, list) {
-                       if (!is_ioint(iter->type))
+                       if (!is_ioint(iter->irq.type))
                                continue;
-                       if (int_word_to_isc_bits(iter->io.io_int_word)
+                       if (int_word_to_isc_bits(iter->irq.io.io_int_word)
                            <= isc_bits)
                                continue;
                        break;
@@ -770,21 +767,21 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
                        kfree(inti);
                        return -EINVAL;
                }
-               inti->type = s390int->type;
-               inti->pgm.code = s390int->parm;
+               inti->irq.type = s390int->type;
+               inti->irq.pgm.code = s390int->parm;
                VCPU_EVENT(vcpu, 3, "inject: program check %d (from user)",
                           s390int->parm);
                break;
        case KVM_S390_SIGP_SET_PREFIX:
-               inti->prefix.address = s390int->parm;
-               inti->type = s390int->type;
+               inti->irq.prefix.address = s390int->parm;
+               inti->irq.type = s390int->type;
                VCPU_EVENT(vcpu, 3, "inject: set prefix to %x (from user)",
                           s390int->parm);
                break;
        case KVM_S390_SIGP_STOP:
        case KVM_S390_RESTART:
                VCPU_EVENT(vcpu, 3, "inject: type %x", s390int->type);
-               inti->type = s390int->type;
+               inti->irq.type = s390int->type;
                break;
        case KVM_S390_INT_EXTERNAL_CALL:
                if (s390int->parm & 0xffff0000) {
@@ -793,8 +790,8 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
                }
                VCPU_EVENT(vcpu, 3, "inject: external call source-cpu:%u",
                           s390int->parm);
-               inti->type = s390int->type;
-               inti->extcall.code = s390int->parm;
+               inti->irq.type = s390int->type;
+               inti->irq.extcall.code = s390int->parm;
                break;
        case KVM_S390_INT_EMERGENCY:
                if (s390int->parm & 0xffff0000) {
@@ -802,14 +799,14 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
                        return -EINVAL;
                }
                VCPU_EVENT(vcpu, 3, "inject: emergency %u\n", s390int->parm);
-               inti->type = s390int->type;
-               inti->emerg.code = s390int->parm;
+               inti->irq.type = s390int->type;
+               inti->irq.emerg.code = s390int->parm;
                break;
        case KVM_S390_MCHK:
                VCPU_EVENT(vcpu, 5, "inject: machine check parm64:%llx",
                           s390int->parm64);
-               inti->type = s390int->type;
-               inti->mchk.mcic = s390int->parm64;
+               inti->irq.type = s390int->type;
+               inti->irq.mchk.mcic = s390int->parm64;
                break;
        case KVM_S390_INT_VIRTIO:
        case KVM_S390_INT_SERVICE:
@@ -824,12 +821,12 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
        mutex_lock(&vcpu->kvm->lock);
        li = &vcpu->arch.local_int;
        spin_lock_bh(&li->lock);
-       if (inti->type == KVM_S390_PROGRAM_INT)
+       if (inti->irq.type == KVM_S390_PROGRAM_INT)
                list_add(&inti->list, &li->list);
        else
                list_add_tail(&inti->list, &li->list);
        atomic_set(&li->active, 1);
-       if (inti->type == KVM_S390_SIGP_STOP)
+       if (inti->irq.type == KVM_S390_SIGP_STOP)
                li->action_bits |= ACTION_STOP_ON_STOP;
        atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags);
        if (waitqueue_active(&vcpu->wq))
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 0da3e6e..897fff2 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -146,19 +146,19 @@ static int handle_tpi(struct kvm_vcpu *vcpu)
                 * Store the two-word I/O interruption code into the
                 * provided area.
                 */
-               if (put_guest(vcpu, inti->io.subchannel_id, (u16 __user *)addr)
-                   || put_guest(vcpu, inti->io.subchannel_nr, (u16 __user 
*)(addr + 2))
-                   || put_guest(vcpu, inti->io.io_int_parm, (u32 __user 
*)(addr + 4)))
+               if (put_guest(vcpu, inti->irq.io.subchannel_id, (u16 __user 
*)addr)
+                   || put_guest(vcpu, inti->irq.io.subchannel_nr, (u16 __user 
*)(addr + 2))
+                   || put_guest(vcpu, inti->irq.io.io_int_parm, (u32 __user 
*)(addr + 4)))
                        return kvm_s390_inject_program_int(vcpu, 
PGM_ADDRESSING);
        } else {
                /*
                 * Store the three-word I/O interruption code into
                 * the appropriate lowcore area.
                 */
-               put_guest(vcpu, inti->io.subchannel_id, (u16 __user *) 
__LC_SUBCHANNEL_ID);
-               put_guest(vcpu, inti->io.subchannel_nr, (u16 __user *) 
__LC_SUBCHANNEL_NR);
-               put_guest(vcpu, inti->io.io_int_parm, (u32 __user *) 
__LC_IO_INT_PARM);
-               put_guest(vcpu, inti->io.io_int_word, (u32 __user *) 
__LC_IO_INT_WORD);
+               put_guest(vcpu, inti->irq.io.subchannel_id, (u16 __user *) 
__LC_SUBCHANNEL_ID);
+               put_guest(vcpu, inti->irq.io.subchannel_nr, (u16 __user *) 
__LC_SUBCHANNEL_NR);
+               put_guest(vcpu, inti->irq.io.io_int_parm, (u32 __user *) 
__LC_IO_INT_PARM);
+               put_guest(vcpu, inti->irq.io.io_int_word, (u32 __user *) 
__LC_IO_INT_WORD);
        }
        kfree(inti);
 no_interrupt:
@@ -186,10 +186,10 @@ static int handle_tsch(struct kvm_vcpu *vcpu)
        vcpu->run->exit_reason = KVM_EXIT_S390_TSCH;
        vcpu->run->s390_tsch.dequeued = !!inti;
        if (inti) {
-               vcpu->run->s390_tsch.subchannel_id = inti->io.subchannel_id;
-               vcpu->run->s390_tsch.subchannel_nr = inti->io.subchannel_nr;
-               vcpu->run->s390_tsch.io_int_parm = inti->io.io_int_parm;
-               vcpu->run->s390_tsch.io_int_word = inti->io.io_int_word;
+               vcpu->run->s390_tsch.subchannel_id = inti->irq.io.subchannel_id;
+               vcpu->run->s390_tsch.subchannel_nr = inti->irq.io.subchannel_nr;
+               vcpu->run->s390_tsch.io_int_parm = inti->irq.io.io_int_parm;
+               vcpu->run->s390_tsch.io_int_word = inti->irq.io.io_int_word;
        }
        vcpu->run->s390_tsch.ipb = vcpu->arch.sie_block->ipb;
        kfree(inti);
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index bec398c..a8cd912 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -65,8 +65,8 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 
cpu_addr)
        if (!inti)
                return -ENOMEM;
 
-       inti->type = KVM_S390_INT_EMERGENCY;
-       inti->emerg.code = vcpu->vcpu_id;
+       inti->irq.type = KVM_S390_INT_EMERGENCY;
+       inti->irq.emerg.code = vcpu->vcpu_id;
 
        spin_lock(&fi->lock);
        li = fi->local_int[cpu_addr];
@@ -103,8 +103,8 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 
cpu_addr)
        if (!inti)
                return -ENOMEM;
 
-       inti->type = KVM_S390_INT_EXTERNAL_CALL;
-       inti->extcall.code = vcpu->vcpu_id;
+       inti->irq.type = KVM_S390_INT_EXTERNAL_CALL;
+       inti->irq.extcall.code = vcpu->vcpu_id;
 
        spin_lock(&fi->lock);
        li = fi->local_int[cpu_addr];
@@ -134,7 +134,7 @@ static int __inject_sigp_stop(struct 
kvm_s390_local_interrupt *li, int action)
        inti = kzalloc(sizeof(*inti), GFP_ATOMIC);
        if (!inti)
                return -ENOMEM;
-       inti->type = KVM_S390_SIGP_STOP;
+       inti->irq.type = KVM_S390_SIGP_STOP;
 
        spin_lock_bh(&li->lock);
        if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
@@ -245,8 +245,8 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 
cpu_addr, u32 address,
                goto out_li;
        }
 
-       inti->type = KVM_S390_SIGP_SET_PREFIX;
-       inti->prefix.address = address;
+       inti->irq.type = KVM_S390_SIGP_SET_PREFIX;
+       inti->irq.prefix.address = address;
 
        list_add_tail(&inti->list, &li->list);
        atomic_set(&li->active, 1);
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index acccd08..d6a1584 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -434,6 +434,68 @@ struct kvm_s390_interrupt {
        __u64 parm64;
 };
 
+struct kvm_s390_io_info {
+       __u16 subchannel_id;
+       __u16 subchannel_nr;
+       __u32 io_int_parm;
+       __u32 io_int_word;
+};
+
+struct kvm_s390_ext_info {
+       __u32 ext_params;
+       __u64 ext_params2;
+};
+
+struct kvm_s390_pgm_info {
+       __u64 trans_exc_code;
+       __u64 mon_code;
+       __u64 per_address;
+       __u32 data_exc_code;
+       __u16 code;
+       __u16 mon_class_nr;
+       __u8 per_code;
+       __u8 per_atmid;
+       __u8 exc_access_id;
+       __u8 per_access_id;
+       __u8 op_access_id;
+       __u8 pad[3];
+};
+
+struct kvm_s390_prefix_info {
+       __u32 address;
+};
+
+struct kvm_s390_extcall_info {
+       __u16 code;
+};
+
+struct kvm_s390_emerg_info {
+       __u16 code;
+};
+
+struct kvm_s390_mchk_info {
+       __u64 cr14;
+       __u64 mcic;
+       __u64 failing_storage_address;
+       __u32 ext_damage_code;
+       __u32 pad;
+       __u8 fixed_logout[16];
+};
+
+struct kvm_s390_irq {
+       __u64 type;
+       union {
+               struct kvm_s390_io_info io;
+               struct kvm_s390_ext_info ext;
+               struct kvm_s390_pgm_info pgm;
+               struct kvm_s390_emerg_info emerg;
+               struct kvm_s390_extcall_info extcall;
+               struct kvm_s390_prefix_info prefix;
+               struct kvm_s390_mchk_info mchk;
+       };
+       char reserved[64];
+};
+
 /* for KVM_SET_GUEST_DEBUG */
 
 #define KVM_GUESTDBG_ENABLE            0x00000001
-- 
1.8.0.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]