From 02e0de01155508425430a733440570e464f2b57d Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Fri, 17 Nov 2017 12:46:41 +0000 Subject: [PATCH] x86: APIC timer calibration when running as a guest The timer calibration currently depends on PIT. Introduce a variant to wait for a tick's worth of time to elapse when running as a PVH guest. Signed-off-by: Wei Liu Reviewed-by: Jan Beulich --- xen/arch/x86/apic.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index ed59440c45..5039173827 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include static bool __read_mostly tdt_enabled; static bool __initdata tdt_enable = true; @@ -1091,6 +1093,20 @@ static void setup_APIC_timer(void) local_irq_restore(flags); } +static void wait_tick_pvh(void) +{ + u64 lapse_ns = 1000000000ULL / HZ; + s_time_t start, curr_time; + + start = NOW(); + + /* Won't wrap around */ + do { + cpu_relax(); + curr_time = NOW(); + } while ( curr_time - start < lapse_ns ); +} + /* * In this function we calibrate APIC bus clocks to the external * timer. Unfortunately we cannot use jiffies and the timer irq @@ -1123,12 +1139,15 @@ static int __init calibrate_APIC_clock(void) */ __setup_APIC_LVTT(1000000000); - /* - * The timer chip counts down to zero. Let's wait - * for a wraparound to start exact measurement: - * (the current tick might have been already half done) - */ - wait_8254_wraparound(); + if ( !xen_guest ) + /* + * The timer chip counts down to zero. Let's wait + * for a wraparound to start exact measurement: + * (the current tick might have been already half done) + */ + wait_8254_wraparound(); + else + wait_tick_pvh(); /* * We wrapped around just now. Let's start: @@ -1137,10 +1156,13 @@ static int __init calibrate_APIC_clock(void) tt1 = apic_read(APIC_TMCCT); /* - * Let's wait LOOPS wraprounds: + * Let's wait LOOPS ticks: */ for (i = 0; i < LOOPS; i++) - wait_8254_wraparound(); + if ( !xen_guest ) + wait_8254_wraparound(); + else + wait_tick_pvh(); tt2 = apic_read(APIC_TMCCT); t2 = rdtsc_ordered(); -- 2.39.5