Commit 58246041 authored by Greg Kurz's avatar Greg Kurz Committed by David Gibson
Browse files

xive/kvm: Trigger interrupts from userspace



When using the XIVE KVM device, the trigger page is directly accessible
in QEMU. Unlike with XICS, no need to ask KVM to fire the interrupt. A
simple store on the trigger page does the job.

Just call xive_esb_trigger().

This may improve performance of emulated devices that go through
qemu_set_irq(), eg. virtio devices created with ioeventfd=off or
configured by the guest to use LSI interrupts, which aren't really
recommended setups.

Signed-off-by: default avatarGreg Kurz <groug@kaod.org>
Message-Id: <157408992731.494439.3405812941731584740.stgit@bahia.lan>
Reviewed-by: default avatarCédric Le Goater <clg@kaod.org>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 7aa22e18
Loading
Loading
Loading
Loading
+2 −14
Original line number Diff line number Diff line
@@ -354,32 +354,20 @@ static void kvmppc_xive_source_get_state(XiveSource *xsrc)
void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val)
{
    XiveSource *xsrc = opaque;
    SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
    struct kvm_irq_level args;
    int rc;

    /* The KVM XIVE device should be in use */
    assert(xive->fd != -1);

    args.irq = srcno;
    if (!xive_source_irq_is_lsi(xsrc, srcno)) {
        if (!val) {
            return;
        }
        args.level = KVM_INTERRUPT_SET;
    } else {
        if (val) {
            xsrc->status[srcno] |= XIVE_STATUS_ASSERTED;
            args.level = KVM_INTERRUPT_SET_LEVEL;
        } else {
            xsrc->status[srcno] &= ~XIVE_STATUS_ASSERTED;
            args.level = KVM_INTERRUPT_UNSET;
        }
    }
    rc = kvm_vm_ioctl(kvm_state, KVM_IRQ_LINE, &args);
    if (rc < 0) {
        error_report("XIVE: kvm_irq_line() failed : %s", strerror(errno));
    }

    xive_esb_trigger(xsrc, srcno);
}

/*