Commit 1191c949 authored by Jens Freimann's avatar Jens Freimann Committed by Cornelia Huck
Browse files

s390x/kvm: use ioctl KVM_S390_IRQ for vcpu interrupts



KVM_S390_INT uses only two parameter fields. This is not
enough to pass all required information for certain interrupts.

A new ioctl KVM_S390_IRQ is available which allows us to
inject all local interrupts as defined in the Principles of
Operation. It takes a struct kvm_s390_irq as a parameter
which can store interrupt payload data for all interrupts.

Let's use the new ioctl for injecting vcpu interrupts.

Tested-by: default avatarThomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: default avatarThomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: default avatarDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: default avatarJens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
parent fb846a09
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
static int cap_sync_regs;
static int cap_async_pf;
static int cap_mem_op;
static int cap_s390_irq;

static void *legacy_s390_alloc(size_t size, uint64_t *align);

@@ -249,6 +250,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
    cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
    cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
    cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
    cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);

    kvm_s390_enable_cmma(s);

@@ -827,10 +829,9 @@ static int s390_kvm_irq_to_interrupt(struct kvm_s390_irq *irq,
    return r;
}

void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq)
static void inject_vcpu_irq_legacy(CPUState *cs, struct kvm_s390_irq *irq)
{
    struct kvm_s390_interrupt kvmint = {};
    CPUState *cs = CPU(cpu);
    int r;

    r = s390_kvm_irq_to_interrupt(irq, &kvmint);
@@ -846,6 +847,23 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq)
    }
}

void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq)
{
    CPUState *cs = CPU(cpu);
    int r;

    if (cap_s390_irq) {
        r = kvm_vcpu_ioctl(cs, KVM_S390_IRQ, irq);
        if (!r) {
            return;
        }
        error_report("KVM failed to inject interrupt %llx", irq->type);
        exit(1);
    }

    inject_vcpu_irq_legacy(cs, irq);
}

static void __kvm_s390_floating_interrupt(struct kvm_s390_irq *irq)
{
    struct kvm_s390_interrupt kvmint = {};