History

mshv: Fix level-triggered check on uninitialized data

In mshv_irqfd_assign(), the level-triggered validation for resample irqfds checks irqfd_lapic_irq.lapic_control.level_triggered before mshv_irqfd_update() has populated the field. Since the irqfd struct is zero-allocated, level_triggered is always 0 at that point, causing the check to always reject resample irqfds with -EINVAL. This makes level-triggered interrupt resampling — used to avoid interrupt storms with assigned devices — completely non-functional. Move the check after the mshv_irqfd_update() call, which resolves the IRQ routing entry and populates irqfd_lapic_irq with the actual trigger mode.

Stanislav Kinsburskii committed 6 months ago

Commit 0289a671 parent 07622621 file · +14 −11Browse files

Unified · Split

drivers/hv/mshv_eventfd.c+14−11
@@ -473,6 +473,19 @@ static int mshv_irqfd_assign(struct mshv_partition *pt, · 472 unmodified lines
473 init_poll_funcptr(&irqfd->irqfd_polltbl, mshv_irqfd_queue_proc);473 init_poll_funcptr(&irqfd->irqfd_polltbl, mshv_irqfd_queue_proc);
474 474
475 spin_lock_irq(&pt->pt_irqfds_lock);475 spin_lock_irq(&pt->pt_irqfds_lock);
476 ret = 0;
477 hlist_for_each_entry(tmp, &pt->pt_irqfds_list, irqfd_hnode) {
478 if (irqfd->irqfd_eventfd_ctx != tmp->irqfd_eventfd_ctx)
479 continue;
480 /* This fd is used for another irq already. */
481 ret = -EBUSY;
482 spin_unlock_irq(&pt->pt_irqfds_lock);
483 goto fail;
484 }
485
486 idx = srcu_read_lock(&pt->pt_irq_srcu);
487 mshv_irqfd_update(pt, irqfd);
488
476#if IS_ENABLED(CONFIG_X86)489#if IS_ENABLED(CONFIG_X86)
477 if (args->flags & BIT(MSHV_IRQFD_BIT_RESAMPLE) &&490 if (args->flags & BIT(MSHV_IRQFD_BIT_RESAMPLE) &&
478 !irqfd->irqfd_lapic_irq.lapic_control.level_triggered) {491 !irqfd->irqfd_lapic_irq.lapic_control.level_triggered) {
@@ -481,22 +494,12 @@ static int mshv_irqfd_assign(struct mshv_partition *pt, · 2 unmodified lines
481 * Otherwise return with failure494 * Otherwise return with failure
482 */495 */
483 spin_unlock_irq(&pt->pt_irqfds_lock);496 spin_unlock_irq(&pt->pt_irqfds_lock);
497 srcu_read_unlock(&pt->pt_irq_srcu, idx);
484 ret = -EINVAL;498 ret = -EINVAL;
485 goto fail;499 goto fail;
486 }500 }
487#endif501#endif
488 ret = 0;
489 hlist_for_each_entry(tmp, &pt->pt_irqfds_list, irqfd_hnode) {
490 if (irqfd->irqfd_eventfd_ctx != tmp->irqfd_eventfd_ctx)
491 continue;
492 /* This fd is used for another irq already. */
493 ret = -EBUSY;
494 spin_unlock_irq(&pt->pt_irqfds_lock);
495 goto fail;
496 }
497 502
498 idx = srcu_read_lock(&pt->pt_irq_srcu);
499 mshv_irqfd_update(pt, irqfd);
500 hlist_add_head(&irqfd->irqfd_hnode, &pt->pt_irqfds_list);503 hlist_add_head(&irqfd->irqfd_hnode, &pt->pt_irqfds_list);
501 spin_unlock_irq(&pt->pt_irqfds_lock);504 spin_unlock_irq(&pt->pt_irqfds_lock);
502 505

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t