diff options
-rw-r--r-- | arch/x86/kernel/tsc.c | 28 | ||||
-rw-r--r-- | include/linux/clocksource_ids.h | 2 |
2 files changed, 23 insertions, 7 deletions
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 7978f31c86f0..fd567a0ac90e 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -54,6 +54,7 @@ static u32 art_to_tsc_numerator; static u32 art_to_tsc_denominator; static u64 art_to_tsc_offset; static struct clocksource *art_related_clocksource; +static bool have_art; struct cyc2ns { struct cyc2ns_data data[2]; /* 0 + 2*16 = 32 */ @@ -1168,6 +1169,7 @@ static struct clocksource clocksource_tsc_early = { .mask = CLOCKSOURCE_MASK(64), .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_MUST_VERIFY, + .id = CSID_X86_TSC_EARLY, .vdso_clock_mode = VDSO_CLOCKMODE_TSC, .enable = tsc_cs_enable, .resume = tsc_resume, @@ -1190,6 +1192,7 @@ static struct clocksource clocksource_tsc = { CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_MUST_VERIFY | CLOCK_SOURCE_VERIFY_PERCPU, + .id = CSID_X86_TSC, .vdso_clock_mode = VDSO_CLOCKMODE_TSC, .enable = tsc_cs_enable, .resume = tsc_resume, @@ -1309,8 +1312,11 @@ struct system_counterval_t convert_art_to_tsc(u64 art) do_div(tmp, art_to_tsc_denominator); res += tmp + art_to_tsc_offset; - return (struct system_counterval_t) {.cs = art_related_clocksource, - .cycles = res}; + return (struct system_counterval_t) { + .cs = art_related_clocksource, + .cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC, + .cycles = res, + }; } EXPORT_SYMBOL(convert_art_to_tsc); @@ -1327,9 +1333,10 @@ EXPORT_SYMBOL(convert_art_to_tsc); * that this flag is set before conversion to TSC is attempted. * * Return: - * struct system_counterval_t - system counter value with the pointer to the + * struct system_counterval_t - system counter value with the ID of the * corresponding clocksource: * cycles: System counter value + * cs_id: The clocksource ID for validating comparability * cs: Clocksource corresponding to system counter value. Used * by timekeeping code to verify comparability of two cycle * values. @@ -1347,8 +1354,11 @@ struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns) do_div(tmp, USEC_PER_SEC); res += tmp; - return (struct system_counterval_t) { .cs = art_related_clocksource, - .cycles = res}; + return (struct system_counterval_t) { + .cs = art_related_clocksource, + .cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC, + .cycles = res, + }; } EXPORT_SYMBOL(convert_art_ns_to_tsc); @@ -1454,8 +1464,10 @@ out: if (tsc_unstable) goto unreg; - if (boot_cpu_has(X86_FEATURE_ART)) + if (boot_cpu_has(X86_FEATURE_ART)) { art_related_clocksource = &clocksource_tsc; + have_art = true; + } clocksource_register_khz(&clocksource_tsc, tsc_khz); unreg: clocksource_unregister(&clocksource_tsc_early); @@ -1480,8 +1492,10 @@ static int __init init_tsc_clocksource(void) * the refined calibration and directly register it as a clocksource. */ if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) { - if (boot_cpu_has(X86_FEATURE_ART)) + if (boot_cpu_has(X86_FEATURE_ART)) { art_related_clocksource = &clocksource_tsc; + have_art = true; + } clocksource_register_khz(&clocksource_tsc, tsc_khz); clocksource_unregister(&clocksource_tsc_early); diff --git a/include/linux/clocksource_ids.h b/include/linux/clocksource_ids.h index 16775d7d8f8d..f8467946e9ee 100644 --- a/include/linux/clocksource_ids.h +++ b/include/linux/clocksource_ids.h @@ -6,6 +6,8 @@ enum clocksource_ids { CSID_GENERIC = 0, CSID_ARM_ARCH_COUNTER, + CSID_X86_TSC_EARLY, + CSID_X86_TSC, CSID_MAX, }; |