Re: [PATCH] KVM: x86/xen: Fix sleeping lock in hard IRQ context on PREEMPT_RT

Steven Rostedt
2026-03-30T14:17:28Z

On Sun, 29 Mar 2026 18:45:43 +0530
"shaikh.kamal" <shaikhkamal2012@gmail.com> wrote:

> --- a/arch/x86/kvm/xen.c
> +++ b/arch/x86/kvm/xen.c
> @@ -122,6 +122,24 @@ void kvm_xen_inject_timer_irqs(struct kvm_vcpu *vcpu)
> }
> }
>
> +static void xen_timer_inject_irqwork(struct irq_work *work)
> +{
> + struct kvm_vcpu_xen *xen = container_of(work, struct kvm_vcpu_xen,
> + timer_inject_irqwork);
> + struct kvm_vcpu *vcpu = container_of(xen, struct kvm_vcpu, arch.xen);
> + struct kvm_xen_evtchn e;
> + int rc;
> +
> + e.vcpu_id = vcpu->vcpu_id;
> + e.vcpu_idx = vcpu->vcpu_idx;
> + e.port = vcpu->arch.xen.timer_virq;
> + e.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL;
> +
> + rc = kvm_xen_set_evtchn_fast(&e, vcpu->kvm);
> + if (rc != -EWOULDBLOCK)
> + vcpu->arch.xen.timer_expires = 0;
> +}

Why duplicate this code and not simply make a static inline helper
function that is used in both places?

-- Steve

> +
> static enum hrtimer_restart xen_timer_callback(struct hrtimer *timer)
> {
> struct kvm_vcpu *vcpu = container_of(timer, struct kvm_vcpu,
> @@ -132,6 +150,17 @@ static enum hrtimer_restart xen_timer_callback(struct hrtimer *timer)
> if (atomic_read(&vcpu->arch.xen.timer_pending))
> return HRTIMER_NORESTART;
>
> + /*
> + * On PREEMPT_RT, this callback runs in hard IRQ context where
> + * kvm_xen_set_evtchn_fast() cannot acquire sleeping locks
> + * (specifically gpc->lock). Defer to irq_work which runs in
> + * thread context on RT.
> + */
> + if (in_hardirq()) {
> + irq_work_queue(&vcpu->arch.xen.timer_inject_irqwork);
> + return HRTIMER_NORESTART;
> + }
> +
> e.vcpu_id = vcpu->vcpu_id;
> e.vcpu_idx = vcpu->vcpu_idx;
> e.port = vcpu->arch.xen.timer_virq;