|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] 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.
Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
xen/arch/x86/hvm/vpt.c | 6 ++++++
xen/arch/x86/include/asm/hvm/vpt.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index 50ed738998..dce365f137 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -318,6 +318,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 generation;
int irq, pt_vector = -1;
bool level;
@@ -356,6 +357,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 +413,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 +555,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 f6bcec8090..8914ed6d5c 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 */
+ u64 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 */
--
2.56.0
--
Ngoc Tu Dinh | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |