fix(loongarch64): make SMP IPI and Virtio IRQ delivery stateful - #380
Conversation
enkerewpo
left a comment
There was a problem hiding this comment.
Nice cleanup of the LoongArch interrupt path — the SMP CPU-ID mapping, the level-triggered HWI lines, and the per-IRQ deassert are all clear improvements over the previous UP assumptions.
One thing worth calling out because it is easy to get wrong: the doorbell coalescing in arch_notify_event looks correct to me. The drain loop in handle_interrupt clears the doorbell bit before each fetch, never after the last one, so a doorbell that lands mid-drain still leaves the bit set and re-fires — the "sender skipped the doorbell because the queue was non-empty" case cannot lose an event. Might be worth a comment there, since the ordering is load-bearing and a later refactor that moves the clear after the fetch would silently break it.
A few smaller things inline. Note also that syswonder/hvisor-tool#111 as it stands still has HVISOR_HC_CLEAR_INJECT_IRQ 20 and an ioctl number that collides with HVISOR_SET_BOOT_MODE, so the two PRs are not yet consistent — I left details on that PR.
Added a comment in |
Merge guest IPI action bits, publish blocking sends before return, and keep the virtual IPI line asserted until all pending actions are cleared.
Maintain asserted HWI bits per physical CPU, update only GINTC.VIP, preserve PIP and HC, and remove timer-driven global injection cleanup.
Pass the target zone and IRQ through HvClearInjectIrq so backends can deassert one guest interrupt line without clearing unrelated pending interrupts.
fix(loongarch64): make SMP IPI and Virtio IRQ delivery stateful
fix(loongarch64): make SMP IPI and Virtio IRQ delivery stateful
Summary
This PR fixes LoongArch SMP guest startup and interrupt delivery issues by introducing explicit virtualization state for guest CPUs, IPIs, event notifications, and HWI interrupt lines.
The main changes are:
Motivation
The previous LoongArch implementation relied on UP guest assumptions, which caused incorrect behavior for SMP guests:
GCSR.CPUIDwas always initialized as zero, preventing correct secondary CPU startup.These issues resulted in secondary CPU boot failures, lost reschedule/call-function IPIs, spurious interrupts, and Virtio console/block stalls.
Public API Changes
Hypercall ABI
This PR introduces a breaking change to
HvClearInjectIrq:20to11. The mandatory number change is caused by an ioctl command collision.HVISOR_SET_BOOT_MODEalready uses ioctl command number9:Linux ioctl values encode the direction, type, command number, and argument size. On a 64-bit platform,
struct hv_zone_boot_mode *is 8 bytes andstruct hvisor_irq_line_argsis also 8 bytes. The two definitions therefore produce the same ioctl value, causing duplicate switch cases in the driver.Virtio IRQ Deassert ABI
This PR replaces the previous broadcast interrupt-clear operation with a precise per-IRQ deassert interface.
The previous implementation ignored the IRQ identifier and broadcast a clear event to all running non-root CPUs. This behavior is incorrect for SMP guests because multiple interrupt sources may be pending simultaneously, and clearing global interrupt state can remove unrelated interrupts. The arguments for
HvClearInjectIrqchange to:arg0: target zone_id,arg1: target irq_id. The operation now deasserts only the specified guest interrupt line.A matching hvisor-tool update(syswonder/hvisor-tool#111) is required : The driver must pass
(zone_id, irq_id)to Hvisor.Event Notification
This PR replaces the previous two-stage event notification interface:
with
The new interface moves event queue state handling into the common event layer. The event is enqueued first, and the architecture layer is informed whether the target queue was previously empty.
This allows different architectures to apply architecture-specific notification strategies: