[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging-4.22] x86/vpt: Validate timer object with generation number



commit 00e5a9ff05a4e30c261532eefc73ad9592e30772
Author:     Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
AuthorDate: Thu Oct 29 13:19:30 2026 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Oct 29 13:19:30 2026 +0100

    x86/vpt: Validate timer object with generation number
    
    The remote completion path of pt_update_irq removes timers from tm_list
    by checking that their addresses match the previous iteration. However,
    if the guest rearms a timer during the gap between two list iterations,
    the resulting timer object is no longer the same, even if their
    addresses match. Removing the timer from the list will then lose the
    armed timer object.
    
    Record a generation number in each timer object upon arming, and check
    that the generation number matches before removing it from the list.
    
    Fixes: 0bcbc971feaa ("x86/vpt: add support for level interrupts")
    Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    master commit: ad987b59ba7b434c1ebcd927328ff3cef24a193a
    master date: 2026-10-29 09:12:03 +0100
---
 xen/arch/x86/hvm/vpt.c             | 7 ++++++-
 xen/arch/x86/include/asm/hvm/vpt.h | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index 50ed738998..c38bf5329e 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -317,7 +317,7 @@ int pt_update_irq(struct vcpu *v)
 {
     struct list_head *head = &v->arch.hvm.tm_list;
     struct periodic_time *pt, *temp, *earliest_pt;
-    uint64_t max_lag;
+    uint64_t max_lag, generation;
     int irq, pt_vector = -1;
     bool level;
 
@@ -356,6 +356,7 @@ int pt_update_irq(struct vcpu *v)
     }
 
     earliest_pt->irq_issued = 1;
+    generation = earliest_pt->generation;
     irq = earliest_pt->irq;
     level = earliest_pt->level;
 
@@ -411,6 +412,9 @@ int pt_update_irq(struct vcpu *v)
                 list_for_each_entry ( pt, &v->arch.hvm.tm_list, list )
                     if ( pt == earliest_pt )
                     {
+                        if ( pt->generation != generation )
+                            break;
+
                         pt_irq_fired(v, pt);
                         cb = pt->cb;
                         cb_priv = pt->priv;
@@ -550,6 +554,7 @@ void create_periodic_time(
     set_timer(&pt->timer, pt->scheduled);
 
     pt_vcpu_lock(v);
+    pt->generation++;
     pt->on_list = 1;
     list_add(&pt->list, &v->arch.hvm.tm_list);
     pt_vcpu_unlock(v);
diff --git a/xen/arch/x86/include/asm/hvm/vpt.h 
b/xen/arch/x86/include/asm/hvm/vpt.h
index 24f0918280..689f175752 100644
--- a/xen/arch/x86/include/asm/hvm/vpt.h
+++ b/xen/arch/x86/include/asm/hvm/vpt.h
@@ -34,6 +34,7 @@ struct periodic_time {
     u8 irq;
     struct vcpu *vcpu;          /* vcpu timer interrupt delivers to */
     u32 pending_intr_nr;        /* pending timer interrupts */
+    uint64_t generation;        /* distinguish two armings of the same timer */
     u64 period;                 /* frequency in ns */
     s_time_t scheduled;         /* scheduled timer interrupt */
     u64 last_plt_gtime;         /* platform time when last IRQ is injected */
--
generated by git-patchbot for /home/xen/git/xen.git#staging-4.22



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.