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: Greg Kurz <groug@kaod.org>
Message-Id: <157408992731.494439.3405812941731584740.stgit@bahia.lan>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Greg Kurz 2019-11-18 16:12:07 +01:00 committed by David Gibson
parent 7aa22e1809
commit 58246041d3
1 changed files with 2 additions and 14 deletions

View File

@ -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);
}
/*