Skip to content

Commit a1a5482

Browse files
author
Peter Zijlstra
committed
x86/extable: Fix ex_handler_msr() print condition
On Fri, Jun 17, 2022 at 02:08:52PM +0300, Stephane Eranian wrote: > Some changes to the way invalid MSR accesses are reported by the > kernel is causing some problems with messages printed on the > console. > > We have seen several cases of ex_handler_msr() printing invalid MSR > accesses once but the callstack multiple times causing confusion on > the console. > The problem here is that another earlier commit (5.13): > > a358f40 ("once: implement DO_ONCE_LITE for non-fast-path "do once" functionality") > > Modifies all the pr_*_once() calls to always return true claiming > that no caller is ever checking the return value of the functions. > > This is why we are seeing the callstack printed without the > associated printk() msg. Extract the ONCE_IF(cond) part into __ONCE_LTE_IF() and use that to implement DO_ONCE_LITE_IF() and fix the extable code. Fixes: a358f40 ("once: implement DO_ONCE_LITE for non-fast-path "do once" functionality") Reported-by: Stephane Eranian <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Tested-by: Stephane Eranian <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 09d0953 commit a1a5482

File tree

2 files changed

+25
-11
lines changed

2 files changed

+25
-11
lines changed

arch/x86/mm/extable.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,18 @@ static bool ex_handler_copy(const struct exception_table_entry *fixup,
9494
static bool ex_handler_msr(const struct exception_table_entry *fixup,
9595
struct pt_regs *regs, bool wrmsr, bool safe, int reg)
9696
{
97-
if (!safe && wrmsr &&
98-
pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
99-
(unsigned int)regs->cx, (unsigned int)regs->dx,
100-
(unsigned int)regs->ax, regs->ip, (void *)regs->ip))
97+
if (__ONCE_LITE_IF(!safe && wrmsr)) {
98+
pr_warn("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
99+
(unsigned int)regs->cx, (unsigned int)regs->dx,
100+
(unsigned int)regs->ax, regs->ip, (void *)regs->ip);
101101
show_stack_regs(regs);
102+
}
102103

103-
if (!safe && !wrmsr &&
104-
pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
105-
(unsigned int)regs->cx, regs->ip, (void *)regs->ip))
104+
if (__ONCE_LITE_IF(!safe && !wrmsr)) {
105+
pr_warn("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
106+
(unsigned int)regs->cx, regs->ip, (void *)regs->ip);
106107
show_stack_regs(regs);
108+
}
107109

108110
if (!wrmsr) {
109111
/* Pretend that the read succeeded and returned 0. */

include/linux/once_lite.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,27 @@
99
*/
1010
#define DO_ONCE_LITE(func, ...) \
1111
DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__)
12-
#define DO_ONCE_LITE_IF(condition, func, ...) \
12+
13+
#define __ONCE_LITE_IF(condition) \
1314
({ \
1415
static bool __section(".data.once") __already_done; \
15-
bool __ret_do_once = !!(condition); \
16+
bool __ret_cond = !!(condition); \
17+
bool __ret_once = false; \
1618
\
17-
if (unlikely(__ret_do_once && !__already_done)) { \
19+
if (unlikely(__ret_cond && !__already_done)) { \
1820
__already_done = true; \
19-
func(__VA_ARGS__); \
21+
__ret_once = true; \
2022
} \
23+
unlikely(__ret_once); \
24+
})
25+
26+
#define DO_ONCE_LITE_IF(condition, func, ...) \
27+
({ \
28+
bool __ret_do_once = !!(condition); \
29+
\
30+
if (__ONCE_LITE_IF(__ret_do_once)) \
31+
func(__VA_ARGS__); \
32+
\
2133
unlikely(__ret_do_once); \
2234
})
2335

0 commit comments

Comments
 (0)