diff --git a/doc/acrn.doxyfile b/doc/acrn.doxyfile index e9a51ca34..d103e1689 100644 --- a/doc/acrn.doxyfile +++ b/doc/acrn.doxyfile @@ -809,7 +809,6 @@ INPUT = custom-doxygen/mainpage.md \ ../hypervisor/include/arch/x86/asm/guest/vcpu.h \ ../hypervisor/include/arch/x86/asm/guest/virtual_cr.h \ ../hypervisor/include/arch/x86/asm/tsc.h \ - ../hypervisor/include/arch/x86/asm/timer.h \ ../hypervisor/include/arch/x86/asm/ioapic.h \ ../hypervisor/include/arch/x86/asm/lapic.h \ ../hypervisor/include/lib/crypto/crypto_api.h \ @@ -820,6 +819,7 @@ INPUT = custom-doxygen/mainpage.md \ ../hypervisor/include/common/irq.h \ ../hypervisor/include/common/ticks.h \ ../hypervisor/include/common/delay.h \ + ../hypervisor/include/common/timer.h \ ../hypervisor/include/common/ptdev.h \ ../hypervisor/include/public/acrn_common.h \ ../hypervisor/include/public/acrn_hv_defs.h \ diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 77cfcacf6..dd1948134 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -220,7 +220,7 @@ HW_C_SRCS += arch/x86/nmi.c HW_C_SRCS += arch/x86/exception.c HW_C_SRCS += arch/x86/irq.c HW_C_SRCS += arch/x86/tsc.c -HW_C_SRCS += arch/x86/timer.c +HW_C_SRCS += arch/x86/tsc_deadline_timer.c HW_C_SRCS += arch/x86/vmx.c HW_C_SRCS += arch/x86/cpu_state_tbl.c HW_C_SRCS += arch/x86/pm.c @@ -231,6 +231,7 @@ HW_C_SRCS += arch/x86/rdt.c HW_C_SRCS += arch/x86/sgx.c HW_C_SRCS += common/ticks.c HW_C_SRCS += common/delay.c +HW_C_SRCS += common/timer.c HW_C_SRCS += common/irq.c HW_C_SRCS += common/softirq.c HW_C_SRCS += common/schedule.c diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index abd867bdd..772567196 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/hypervisor/arch/x86/pm.c b/hypervisor/arch/x86/pm.c index 800d50df1..7b54e14fd 100644 --- a/hypervisor/arch/x86/pm.c +++ b/hypervisor/arch/x86/pm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include struct cpu_context cpu_ctx; diff --git a/hypervisor/arch/x86/tsc_deadline_timer.c b/hypervisor/arch/x86/tsc_deadline_timer.c new file mode 100644 index 000000000..f26ffbcbe --- /dev/null +++ b/hypervisor/arch/x86/tsc_deadline_timer.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2021 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* run in interrupt context */ +static void timer_expired_handler(__unused uint32_t irq, __unused void *data) +{ + fire_softirq(SOFTIRQ_TIMER); +} + +void set_hw_timeout(uint64_t timeout) +{ + msr_write(MSR_IA32_TSC_DEADLINE, timeout); +} + +void init_hw_timer(void) +{ + int32_t retval = 0; + + if (get_pcpu_id() == BSP_CPU_ID) { + retval = request_irq(TIMER_IRQ, (irq_action_t)timer_expired_handler, NULL, IRQF_NONE); + if (retval < 0) { + pr_err("Timer setup failed"); + } + } + + if (retval >= 0) { + uint32_t val = TIMER_VECTOR; + val |= APIC_LVTT_TM_TSCDLT; /* TSC deadline and unmask */ + msr_write(MSR_IA32_EXT_APIC_LVT_TIMER, val); + /* SDM 10.5.4.1: In x2APIC mode, the processor ensures the + ordering of this write and any subsequent WRMSR to the + deadline; no fencing is required. */ + + /* disarm timer */ + msr_write(MSR_IA32_TSC_DEADLINE, 0UL); + } +} diff --git a/hypervisor/arch/x86/timer.c b/hypervisor/common/timer.c similarity index 85% rename from hypervisor/arch/x86/timer.c rename to hypervisor/common/timer.c index 2c73efda1..7ca613318 100644 --- a/hypervisor/arch/x86/timer.c +++ b/hypervisor/common/timer.c @@ -15,6 +15,7 @@ #include #include #include +#include #define MAX_TIMER_ACTIONS 32U #define MIN_TIMER_PERIOD_US 500U @@ -29,12 +30,6 @@ static void run_timer(const struct hv_timer *timer) TRACE_2L(TRACE_TIMER_ACTION_PCKUP, timer->fire_tsc, 0UL); } -/* run in interrupt context */ -static void tsc_deadline_handler(__unused uint32_t irq, __unused void *data) -{ - fire_softirq(SOFTIRQ_TIMER); -} - static inline void update_physical_timer(struct per_cpu_timers *cpu_timer) { struct hv_timer *timer = NULL; @@ -127,26 +122,13 @@ static void init_percpu_timer(uint16_t pcpu_id) INIT_LIST_HEAD(&cpu_timer->timer_list); } -static void init_tsc_deadline_timer(void) -{ - uint32_t val; - - val = TIMER_VECTOR; - val |= APIC_LVTT_TM_TSCDLT; /* TSC deadline and unmask */ - msr_write(MSR_IA32_EXT_APIC_LVT_TIMER, val); - cpu_memory_barrier(); - - /* disarm timer */ - msr_write(MSR_IA32_TSC_DEADLINE, 0UL); -} - static void timer_softirq(uint16_t pcpu_id) { struct per_cpu_timers *cpu_timer; struct hv_timer *timer; const struct list_head *pos, *n; uint32_t tries = MAX_TIMER_ACTIONS; - uint64_t current_tsc = rdtsc(); + uint64_t current_tsc = cpu_ticks(); /* handle passed timer */ cpu_timer = &per_cpu(cpu_timers, pcpu_id); @@ -183,20 +165,12 @@ static void timer_softirq(uint16_t pcpu_id) void timer_init(void) { uint16_t pcpu_id = get_pcpu_id(); - int32_t retval = 0; init_percpu_timer(pcpu_id); if (pcpu_id == BSP_CPU_ID) { register_softirq(SOFTIRQ_TIMER, timer_softirq); - - retval = request_irq(TIMER_IRQ, (irq_action_t)tsc_deadline_handler, NULL, IRQF_NONE); - if (retval < 0) { - pr_err("Timer setup failed"); - } } - if (retval >= 0) { - init_tsc_deadline_timer(); - } + init_hw_timer(); } diff --git a/hypervisor/debug/console.c b/hypervisor/debug/console.c index 40b6e0825..811cc7ad3 100644 --- a/hypervisor/debug/console.c +++ b/hypervisor/debug/console.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/hypervisor/include/arch/x86/asm/guest/vlapic.h b/hypervisor/include/arch/x86/asm/guest/vlapic.h index 0235ec988..60cefae62 100644 --- a/hypervisor/include/arch/x86/asm/guest/vlapic.h +++ b/hypervisor/include/arch/x86/asm/guest/vlapic.h @@ -31,7 +31,7 @@ #define VLAPIC_H #include -#include +#include #include /** diff --git a/hypervisor/include/arch/x86/asm/per_cpu.h b/hypervisor/include/arch/x86/asm/per_cpu.h index 2ccf6bc44..f9d2da7b9 100644 --- a/hypervisor/include/arch/x86/asm/per_cpu.h +++ b/hypervisor/include/arch/x86/asm/per_cpu.h @@ -10,12 +10,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include diff --git a/hypervisor/include/common/ptdev.h b/hypervisor/include/common/ptdev.h index 27a7ae204..2bc8d1146 100644 --- a/hypervisor/include/common/ptdev.h +++ b/hypervisor/include/common/ptdev.h @@ -8,7 +8,7 @@ #define PTDEV_H #include #include -#include +#include enum intx_ctlr { diff --git a/hypervisor/include/common/schedule.h b/hypervisor/include/common/schedule.h index 86e07f7a1..b848b4b42 100644 --- a/hypervisor/include/common/schedule.h +++ b/hypervisor/include/common/schedule.h @@ -8,7 +8,7 @@ #define SCHEDULE_H #include #include -#include +#include #define NEED_RESCHEDULE (1U) diff --git a/hypervisor/include/arch/x86/asm/timer.h b/hypervisor/include/common/timer.h similarity index 94% rename from hypervisor/include/arch/x86/asm/timer.h rename to hypervisor/include/common/timer.h index 51f9da1aa..340498aa3 100644 --- a/hypervisor/include/arch/x86/asm/timer.h +++ b/hypervisor/include/common/timer.h @@ -4,11 +4,11 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef TIMER_H -#define TIMER_H +#ifndef COMMON_TIMER_H +#define COMMON_TIMER_H #include -#include +#include /** * @brief Timer @@ -86,7 +86,7 @@ static inline void initialize_timer(struct hv_timer *timer, */ static inline bool timer_expired(const struct hv_timer *timer) { - return ((timer->fire_tsc == 0UL) || (rdtsc() >= timer->fire_tsc)); + return ((timer->fire_tsc == 0UL) || (cpu_ticks() >= timer->fire_tsc)); } /** @@ -135,4 +135,4 @@ void timer_init(void); * @} */ -#endif /* TIMER_H */ +#endif /* COMMON_TIMER_H */ diff --git a/hypervisor/include/hw/hw_timer.h b/hypervisor/include/hw/hw_timer.h new file mode 100644 index 000000000..fa8db0f4e --- /dev/null +++ b/hypervisor/include/hw/hw_timer.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2021 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef HW_TIMER_H +#define HW_TIMER_H + +#include + +void set_hw_timeout(uint64_t timeout); +void init_hw_timer(void); + +#endif