From c4f6681045ec7d4f0fc9958646da0e936a9633fa Mon Sep 17 00:00:00 2001 From: Conghui Chen Date: Wed, 31 Jul 2019 10:23:04 +0000 Subject: [PATCH] softirq: disable interrupt when modify timer_list In current code, the timer_list for per cpu can be accessed both in vmexit and softirq handler. There is a case that, the timer_list is modifying in vmexit, but an interrupt occur, the timer_list is also modified in softirq handler. So the time_list may in unpredictable state. In some platforms, the hv console may hang as its timer handler is not invoked because of the corruption for timer_list. So, to fix the issue, disable the interrupt before modifying the timer_list. Tracked-On: #3512 Signed-off-by: Yin Fengwei Signed-off-by: Conghui Chen Reviewed-by: Li, Fei1 --- hypervisor/arch/x86/timer.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hypervisor/arch/x86/timer.c b/hypervisor/arch/x86/timer.c index 6fe728dda..36eaa2673 100644 --- a/hypervisor/arch/x86/timer.c +++ b/hypervisor/arch/x86/timer.c @@ -89,6 +89,7 @@ int32_t add_timer(struct hv_timer *timer) struct per_cpu_timers *cpu_timer; uint16_t pcpu_id; int32_t ret = 0; + uint64_t rflags; if ((timer == NULL) || (timer->func == NULL) || (timer->fire_tsc == 0UL)) { ret = -EINVAL; @@ -103,10 +104,12 @@ int32_t add_timer(struct hv_timer *timer) pcpu_id = get_pcpu_id(); cpu_timer = &per_cpu(cpu_timers, pcpu_id); + CPU_INT_ALL_DISABLE(&rflags); /* update the physical timer if we're on the timer_list head */ if (local_add_timer(cpu_timer, timer)) { update_physical_timer(cpu_timer); } + CPU_INT_ALL_RESTORE(rflags); TRACE_2L(TRACE_TIMER_ACTION_ADDED, timer->fire_tsc, 0UL); } @@ -117,9 +120,13 @@ int32_t add_timer(struct hv_timer *timer) void del_timer(struct hv_timer *timer) { + uint64_t rflags; + + CPU_INT_ALL_DISABLE(&rflags); if ((timer != NULL) && !list_empty(&timer->node)) { list_del_init(&timer->node); } + CPU_INT_ALL_RESTORE(rflags); } static void init_percpu_timer(uint16_t pcpu_id)