From: Like Xu <likexu@xxxxxxxxxxx> On Intel platforms with TSX feature, pmu users in guest can collect the commited or total transactional cycles for a tsx-enabled workload, adding new test cases to cover them, as they are not strictly the same as normal hardware events from the KVM implementation point of view. Signed-off-by: Like Xu <likexu@xxxxxxxxxxx> --- V1: https://lore.kernel.org/kvm/20221207071506.15733-1-likexu@xxxxxxxxxxx/ V1 -> V2 Changelog: - Drop HLE check; (Weijiang) - Print out the data here for each GP counter; (Weijiang) - Use "unsigned int" for EAX; (Sean) - Use mnemonic for XBEGIN; (Sean) - Drop use of _xend(); (Sean) - Use xbegin inline instead of processor.h to avoid conflicts with vmx_tests; x86/pmu.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/x86/pmu.c b/x86/pmu.c index 72c2c9c..356d589 100644 --- a/x86/pmu.c +++ b/x86/pmu.c @@ -20,7 +20,7 @@ typedef struct { uint32_t ctr; - uint32_t config; + uint64_t config; uint64_t count; int idx; } pmu_counter_t; @@ -547,6 +547,45 @@ static void check_emulated_instr(void) report_prefix_pop(); } +#define XBEGIN_STARTED (~0u) +static void check_tsx_cycles(void) +{ + pmu_counter_t cnt; + unsigned int i, ret = 0; + + if (!this_cpu_has(X86_FEATURE_RTM)) + return; + + report_prefix_push("TSX cycles"); + + for (i = 0; i < pmu.nr_gp_counters; i++) { + cnt.ctr = MSR_GP_COUNTERx(i); + + if (i == 2) + /* Transactional cycles commited only on gp counter 2 */ + cnt.config = EVNTSEL_OS | EVNTSEL_USR | 0x30000003c; + else + /* Transactional cycles */ + cnt.config = EVNTSEL_OS | EVNTSEL_USR | 0x10000003c; + + start_event(&cnt); + + asm volatile("xbegin 1f\n\t" + "1:\n\t" + : "+a" (ret) :: "memory"); + + /* Generate a non-canonical #GP to trigger ABORT. */ + if (ret == XBEGIN_STARTED) + *(int *)NONCANONICAL = 0; + + stop_event(&cnt); + + report(cnt.count > 0, "gp cntr-%d with a value of %" PRId64 "", i, cnt.count); + } + + report_prefix_pop(); +} + static void check_counters(void) { if (is_fep_available()) @@ -559,6 +598,7 @@ static void check_counters(void) check_counter_overflow(); check_gp_counter_cmask(); check_running_counter_wrmsr(); + check_tsx_cycles(); } static void do_unsupported_width_counter_write(void *index) -- 2.39.0