On 22.01.2026 17:47, Oleksii Kurochko wrote:
> Based on Linux kernel v6.16.0.
>
> Add lockless tracking of pending vCPU interrupts using atomic bitops.
> Two bitmaps are introduced:
> - irqs_pending — interrupts currently pending for the vCPU
> - irqs_pending_mask — bits that have changed in irqs_pending
>
> The design follows a multi-producer, single-consumer model, where the
> consumer is the vCPU itself. Producers may set bits in
> irqs_pending_mask without a lock. Clearing bits in irqs_pending_mask is
> performed only by the consumer via xchg_acquire(). The consumer must not
> write to irqs_pending and must not act on bits that are not set in the
> mask. Otherwise, extra synchronization should be provided.
>
> On RISC-V interrupts are not injected via guest registers, so pending
> interrupts must be recorded in irqs_pending (using the new
> vcpu_{un}set_interrupt() helpers) and flushed to the guest by updating
> HVIP before returning control to the guest. The consumer side is
> implemented in a follow-up patch.
>
> A barrier between updating irqs_pending and setting the corresponding
> mask bit in vcpu_set_interrupt() / vcpu_unset_interrupt() guarantees
> that if the consumer observes a mask bit set, the corresponding pending
> bit is also visible. This prevents missed interrupts during the flush.
>
> Signed-off-by: Oleksii Kurochko <[email protected]>
The use of barriers here matches the (Linux) specification, so
Acked-by: Jan Beulich <[email protected]>
However, ...
> @@ -130,3 +131,43 @@ void arch_vcpu_destroy(struct vcpu *v)
> {
> vfree((char *)v->arch.cpu_info + sizeof(struct cpu_info));
> }
> +
> +int vcpu_set_interrupt(struct vcpu *v, unsigned int irq)
> +{
> + /*
> + * We only allow VS-mode software, timer, and external
> + * interrupts when irq is one of the local interrupts
> + * defined by RISC-V privilege specification.
> + */
> + if ( irq != IRQ_VS_SOFT &&
> + irq != IRQ_VS_TIMER &&
> + irq != IRQ_VS_EXT )
> + return -EINVAL;
> +
> + set_bit(irq, v->arch.irqs_pending);
> + smp_mb__before_atomic();
> + set_bit(irq, v->arch.irqs_pending_mask);
... isn't it too heavy a barrier here? You only need ordering of writes,
without any regard to reads, don't you?
Jan