From: Dapeng Mi <dapeng1.mi@linux.intel.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Jim Mattson <jmattson@google.com>,
Mingwei Zhang <mizhang@google.com>,
Xiong Zhang <xiong.y.zhang@intel.com>,
Zhenyu Wang <zhenyuw@linux.intel.com>,
Like Xu <like.xu.linux@gmail.com>,
Jinrong Liang <cloudliang@tencent.com>,
Yongwei Ma <yongwei.ma@intel.com>,
Dapeng Mi <dapeng1.mi@intel.com>,
Dapeng Mi <dapeng1.mi@linux.intel.com>
Subject: [kvm-unit-tests patch v6 16/18] x86: pmu: Add IBPB indirect jump asm blob
Date: Sat, 14 Sep 2024 10:17:26 +0000 [thread overview]
Message-ID: <20240914101728.33148-17-dapeng1.mi@linux.intel.com> (raw)
In-Reply-To: <20240914101728.33148-1-dapeng1.mi@linux.intel.com>
Currently the lower boundary of branch misses event is set to 0.
Strictly speaking 0 shouldn't be a valid count since it can't tell us if
branch misses event counter works correctly or even disabled. Whereas
it's also possible and reasonable that branch misses event count is 0
especailly for such simple loop() program with advanced branch
predictor.
To eliminate such ambiguity and make branch misses event verification
more acccurately, an extra IBPB indirect jump asm blob is appended and
IBPB command is leveraged to clear the branch target buffer and force to
cause a branch miss for the indirect jump.
Suggested-by: Jim Mattson <jmattson@google.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
x86/pmu.c | 71 +++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 56 insertions(+), 15 deletions(-)
diff --git a/x86/pmu.c b/x86/pmu.c
index 47b6305d..279d418d 100644
--- a/x86/pmu.c
+++ b/x86/pmu.c
@@ -19,25 +19,52 @@
#define EXPECTED_INSTR 17
#define EXPECTED_BRNCH 5
-
-/* Enable GLOBAL_CTRL + disable GLOBAL_CTRL + clflush/mfence instructions */
-#define EXTRA_INSTRNS (3 + 3 + 2)
+#define IBPB_JMP_INSTRNS 9
+#define IBPB_JMP_BRANCHES 2
+
+#if defined(__i386__) || defined(_M_IX86) /* i386 */
+#define IBPB_JMP_ASM(_wrmsr) \
+ "mov $1, %%eax; xor %%edx, %%edx;\n\t" \
+ "mov $73, %%ecx;\n\t" \
+ _wrmsr "\n\t" \
+ "call 1f\n\t" \
+ "1: pop %%eax\n\t" \
+ "add $(2f-1b), %%eax\n\t" \
+ "jmp *%%eax;\n\t" \
+ "nop;\n\t" \
+ "2: nop;\n\t"
+#else /* x86_64 */
+#define IBPB_JMP_ASM(_wrmsr) \
+ "mov $1, %%eax; xor %%edx, %%edx;\n\t" \
+ "mov $73, %%ecx;\n\t" \
+ _wrmsr "\n\t" \
+ "call 1f\n\t" \
+ "1: pop %%rax\n\t" \
+ "add $(2f-1b), %%rax\n\t" \
+ "jmp *%%rax;\n\t" \
+ "nop;\n\t" \
+ "2: nop;\n\t"
+#endif
+
+/* GLOBAL_CTRL enable + disable + clflush/mfence + IBPB_JMP */
+#define EXTRA_INSTRNS (3 + 3 + 2 + IBPB_JMP_INSTRNS)
#define LOOP_INSTRNS (N * 10 + EXTRA_INSTRNS)
-#define LOOP_BRANCHES (N)
-#define LOOP_ASM(_wrmsr, _clflush) \
- _wrmsr "\n\t" \
+#define LOOP_BRANCHES (N + IBPB_JMP_BRANCHES)
+#define LOOP_ASM(_wrmsr1, _clflush, _wrmsr2) \
+ _wrmsr1 "\n\t" \
"mov %%ecx, %%edi; mov %%ebx, %%ecx;\n\t" \
_clflush "\n\t" \
"mfence;\n\t" \
"1: mov (%1), %2; add $64, %1;\n\t" \
"nop; nop; nop; nop; nop; nop; nop;\n\t" \
"loop 1b;\n\t" \
+ IBPB_JMP_ASM(_wrmsr2) \
"mov %%edi, %%ecx; xor %%eax, %%eax; xor %%edx, %%edx;\n\t" \
- _wrmsr "\n\t"
+ _wrmsr1 "\n\t"
-#define _loop_asm(_wrmsr, _clflush) \
+#define _loop_asm(_wrmsr1, _clflush, _wrmsr2) \
do { \
- asm volatile(LOOP_ASM(_wrmsr, _clflush) \
+ asm volatile(LOOP_ASM(_wrmsr1, _clflush, _wrmsr2) \
: "=b"(tmp), "=r"(tmp2), "=r"(tmp3) \
: "a"(eax), "d"(edx), "c"(global_ctl), \
"0"(N), "1"(buf) \
@@ -101,6 +128,12 @@ static struct pmu_event *gp_events;
static unsigned int gp_events_size;
static unsigned int fixed_counters_num;
+static int has_ibpb(void)
+{
+ return this_cpu_has(X86_FEATURE_SPEC_CTRL) ||
+ this_cpu_has(X86_FEATURE_AMD_IBPB);
+}
+
static inline void __loop(void)
{
unsigned long tmp, tmp2, tmp3;
@@ -108,10 +141,14 @@ static inline void __loop(void)
u32 eax = 0;
u32 edx = 0;
- if (this_cpu_has(X86_FEATURE_CLFLUSH))
- _loop_asm("nop", "clflush (%1)");
+ if (this_cpu_has(X86_FEATURE_CLFLUSH) && has_ibpb())
+ _loop_asm("nop", "clflush (%1)", "wrmsr");
+ else if (this_cpu_has(X86_FEATURE_CLFLUSH))
+ _loop_asm("nop", "clflush (%1)", "nop");
+ else if (has_ibpb())
+ _loop_asm("nop", "nop", "wrmsr");
else
- _loop_asm("nop", "nop");
+ _loop_asm("nop", "nop", "nop");
}
/*
@@ -128,10 +165,14 @@ static inline void __precise_loop(u64 cntrs)
u32 eax = cntrs & (BIT_ULL(32) - 1);
u32 edx = cntrs >> 32;
- if (this_cpu_has(X86_FEATURE_CLFLUSH))
- _loop_asm("wrmsr", "clflush (%1)");
+ if (this_cpu_has(X86_FEATURE_CLFLUSH) && has_ibpb())
+ _loop_asm("wrmsr", "clflush (%1)", "wrmsr");
+ else if (this_cpu_has(X86_FEATURE_CLFLUSH))
+ _loop_asm("wrmsr", "clflush (%1)", "nop");
+ else if (has_ibpb())
+ _loop_asm("wrmsr", "nop", "wrmsr");
else
- _loop_asm("wrmsr", "nop");
+ _loop_asm("wrmsr", "nop", "nop");
}
static inline void loop(u64 cntrs)
--
2.40.1
next prev parent reply other threads:[~2024-09-14 7:01 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-14 10:17 [kvm-unit-tests patch v6 00/18] pmu test bugs fix and improvements Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 01/18] x86: pmu: Remove duplicate code in pmu_init() Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 02/18] x86: pmu: Remove blank line and redundant space Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 03/18] x86: pmu: Refine fixed_events[] names Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 04/18] x86: pmu: Fix the issue that pmu_counter_t.config crosses cache line Dapeng Mi
2025-02-14 21:05 ` Sean Christopherson
2025-02-18 9:07 ` Mi, Dapeng
2024-09-14 10:17 ` [kvm-unit-tests patch v6 05/18] x86: pmu: Enlarge cnt[] length to 48 in check_counters_many() Dapeng Mi
2025-02-14 21:06 ` Sean Christopherson
2025-02-18 9:24 ` Mi, Dapeng
2025-02-18 15:56 ` Sean Christopherson
2024-09-14 10:17 ` [kvm-unit-tests patch v6 06/18] x86: pmu: Print measured event count if test fails Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 07/18] x86: pmu: Fix potential out of bound access for fixed events Dapeng Mi
2025-02-14 21:07 ` Sean Christopherson
2025-02-18 9:34 ` Mi, Dapeng
2025-02-18 15:04 ` Sean Christopherson
2024-09-14 10:17 ` [kvm-unit-tests patch v6 08/18] x86: pmu: Fix cycles event validation failure Dapeng Mi
2025-02-14 21:07 ` Sean Christopherson
2025-02-18 9:36 ` Mi, Dapeng
2024-09-14 10:17 ` [kvm-unit-tests patch v6 09/18] x86: pmu: Use macro to replace hard-coded branches event index Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 10/18] x86: pmu: Use macro to replace hard-coded ref-cycles " Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 11/18] x86: pmu: Use macro to replace hard-coded instructions " Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 12/18] x86: pmu: Enable and disable PMCs in loop() asm blob Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 13/18] x86: pmu: Improve instruction and branches events verification Dapeng Mi
2025-02-14 21:08 ` Sean Christopherson
2025-02-18 9:40 ` Mi, Dapeng
2024-09-14 10:17 ` [kvm-unit-tests patch v6 14/18] x86: pmu: Improve LLC misses event verification Dapeng Mi
2024-09-14 10:17 ` [kvm-unit-tests patch v6 15/18] x86: pmu: Adjust lower boundary of llc-misses event to 0 for legacy CPUs Dapeng Mi
2024-09-14 10:17 ` Dapeng Mi [this message]
2024-09-14 10:17 ` [kvm-unit-tests patch v6 17/18] x86: pmu: Adjust lower boundary of branch-misses event Dapeng Mi
2025-02-14 21:09 ` Sean Christopherson
2025-02-18 9:42 ` Mi, Dapeng
2024-09-14 10:17 ` [kvm-unit-tests patch v6 18/18] x86: pmu: Optimize emulated instruction validation Dapeng Mi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240914101728.33148-17-dapeng1.mi@linux.intel.com \
--to=dapeng1.mi@linux.intel.com \
--cc=cloudliang@tencent.com \
--cc=dapeng1.mi@intel.com \
--cc=jmattson@google.com \
--cc=kvm@vger.kernel.org \
--cc=like.xu.linux@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mizhang@google.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=xiong.y.zhang@intel.com \
--cc=yongwei.ma@intel.com \
--cc=zhenyuw@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).