mirror of https://gitee.com/openkylin/qemu.git
hw/vfio/platform: do not set resamplefd for edge-sensitive IRQS
In irqfd mode, current code attempts to set a resamplefd whatever the type of the IRQ. For an edge-sensitive IRQ this attempt fails and as a consequence, the whole irqfd setup fails and we fall back to the slow mode. This patch bypasses the resamplefd setting for non level-sentive IRQs. Signed-off-by: Eric Auger <eric.auger@linaro.org> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
a22313deca
commit
a5b39cd3f6
|
@ -32,6 +32,11 @@
|
|||
* Functions used whatever the injection method
|
||||
*/
|
||||
|
||||
static inline bool vfio_irq_is_automasked(VFIOINTp *intp)
|
||||
{
|
||||
return intp->flags & VFIO_IRQ_INFO_AUTOMASKED;
|
||||
}
|
||||
|
||||
/**
|
||||
* vfio_init_intp - allocate, initialize the IRQ struct pointer
|
||||
* and add it into the list of IRQs
|
||||
|
@ -65,15 +70,17 @@ static VFIOINTp *vfio_init_intp(VFIODevice *vbasedev,
|
|||
error_report("vfio: Error: trigger event_notifier_init failed ");
|
||||
return NULL;
|
||||
}
|
||||
/* Get an eventfd for resample/unmask */
|
||||
intp->unmask = g_malloc0(sizeof(EventNotifier));
|
||||
ret = event_notifier_init(intp->unmask, 0);
|
||||
if (ret) {
|
||||
g_free(intp->interrupt);
|
||||
g_free(intp->unmask);
|
||||
g_free(intp);
|
||||
error_report("vfio: Error: resamplefd event_notifier_init failed");
|
||||
return NULL;
|
||||
if (vfio_irq_is_automasked(intp)) {
|
||||
/* Get an eventfd for resample/unmask */
|
||||
intp->unmask = g_malloc0(sizeof(EventNotifier));
|
||||
ret = event_notifier_init(intp->unmask, 0);
|
||||
if (ret) {
|
||||
g_free(intp->interrupt);
|
||||
g_free(intp->unmask);
|
||||
g_free(intp);
|
||||
error_report("vfio: Error: resamplefd event_notifier_init failed");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
QLIST_INSERT_HEAD(&vdev->intp_list, intp, next);
|
||||
|
@ -294,7 +301,7 @@ static void vfio_platform_eoi(VFIODevice *vbasedev)
|
|||
/* deassert the virtual IRQ */
|
||||
qemu_set_irq(intp->qemuirq, 0);
|
||||
|
||||
if (intp->flags & VFIO_IRQ_INFO_AUTOMASKED) {
|
||||
if (vfio_irq_is_automasked(intp)) {
|
||||
/* unmasks the physical level-sensitive IRQ */
|
||||
vfio_unmask_single_irqindex(vbasedev, intp->pin);
|
||||
}
|
||||
|
@ -409,15 +416,20 @@ static void vfio_start_irqfd_injection(SysBusDevice *sbdev, qemu_irq irq)
|
|||
if (vfio_set_trigger_eventfd(intp, NULL) < 0) {
|
||||
goto fail_vfio;
|
||||
}
|
||||
if (vfio_set_resample_eventfd(intp) < 0) {
|
||||
goto fail_vfio;
|
||||
if (vfio_irq_is_automasked(intp)) {
|
||||
if (vfio_set_resample_eventfd(intp) < 0) {
|
||||
goto fail_vfio;
|
||||
}
|
||||
trace_vfio_platform_start_level_irqfd_injection(intp->pin,
|
||||
event_notifier_get_fd(intp->interrupt),
|
||||
event_notifier_get_fd(intp->unmask));
|
||||
} else {
|
||||
trace_vfio_platform_start_edge_irqfd_injection(intp->pin,
|
||||
event_notifier_get_fd(intp->interrupt));
|
||||
}
|
||||
|
||||
intp->kvm_accel = true;
|
||||
|
||||
trace_vfio_platform_start_irqfd_injection(intp->pin,
|
||||
event_notifier_get_fd(intp->interrupt),
|
||||
event_notifier_get_fd(intp->unmask));
|
||||
return;
|
||||
fail_vfio:
|
||||
kvm_irqchip_remove_irqfd_notifier(kvm_state, intp->interrupt, irq);
|
||||
|
|
|
@ -1624,7 +1624,9 @@ vfio_platform_intp_interrupt(int pin, int fd) "Inject IRQ #%d (fd = %d)"
|
|||
vfio_platform_intp_inject_pending_lockheld(int pin, int fd) "Inject pending IRQ #%d (fd = %d)"
|
||||
vfio_platform_populate_interrupts(int pin, int count, int flags) "- IRQ index %d: count %d, flags=0x%x"
|
||||
vfio_intp_interrupt_set_pending(int index) "irq %d is set PENDING"
|
||||
vfio_platform_start_irqfd_injection(int index, int fd, int resamplefd) "IRQ index=%d, fd = %d, resamplefd = %d"
|
||||
vfio_platform_start_level_irqfd_injection(int index, int fd, int resamplefd) "IRQ index=%d, fd = %d, resamplefd = %d"
|
||||
vfio_platform_start_edge_irqfd_injection(int index, int fd) "IRQ index=%d, fd = %d"
|
||||
|
||||
|
||||
#hw/acpi/memory_hotplug.c
|
||||
mhp_acpi_invalid_slot_selected(uint32_t slot) "0x%"PRIx32
|
||||
|
|
Loading…
Reference in New Issue