Skip to content

Commit d52a734

Browse files
author
Peter Zijlstra
committed
x86/msr: Remove .fixup usage
Rework the MSR accessors to remove .fixup usage. Add two new extable types (to the 4 already existing msr ones) using the new register infrastructure to record which register should get the error value. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Josh Poimboeuf <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 4b5305d commit d52a734

File tree

3 files changed

+47
-53
lines changed

3 files changed

+47
-53
lines changed

arch/x86/include/asm/extable_fixup_types.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,16 @@
3232
#define EX_TYPE_COPY 4
3333
#define EX_TYPE_CLEAR_FS 5
3434
#define EX_TYPE_FPU_RESTORE 6
35-
#define EX_TYPE_WRMSR 7
36-
#define EX_TYPE_RDMSR 8
37-
#define EX_TYPE_BPF 9
38-
39-
#define EX_TYPE_WRMSR_IN_MCE 10
40-
#define EX_TYPE_RDMSR_IN_MCE 11
41-
42-
#define EX_TYPE_DEFAULT_MCE_SAFE 12
43-
#define EX_TYPE_FAULT_MCE_SAFE 13
44-
45-
#define EX_TYPE_POP_ZERO 14
46-
#define EX_TYPE_IMM_REG 15 /* reg := (long)imm */
35+
#define EX_TYPE_BPF 7
36+
#define EX_TYPE_WRMSR 8
37+
#define EX_TYPE_RDMSR 9
38+
#define EX_TYPE_WRMSR_SAFE 10 /* reg := -EIO */
39+
#define EX_TYPE_RDMSR_SAFE 11 /* reg := -EIO */
40+
#define EX_TYPE_WRMSR_IN_MCE 12
41+
#define EX_TYPE_RDMSR_IN_MCE 13
42+
#define EX_TYPE_DEFAULT_MCE_SAFE 14
43+
#define EX_TYPE_FAULT_MCE_SAFE 15
44+
#define EX_TYPE_POP_ZERO 16
45+
#define EX_TYPE_IMM_REG 17 /* reg := (long)imm */
4746

4847
#endif

arch/x86/include/asm/msr.h

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,11 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
137137
{
138138
DECLARE_ARGS(val, low, high);
139139

140-
asm volatile("2: rdmsr ; xor %[err],%[err]\n"
141-
"1:\n\t"
142-
".section .fixup,\"ax\"\n\t"
143-
"3: mov %[fault],%[err]\n\t"
144-
"xorl %%eax, %%eax\n\t"
145-
"xorl %%edx, %%edx\n\t"
146-
"jmp 1b\n\t"
147-
".previous\n\t"
148-
_ASM_EXTABLE(2b, 3b)
140+
asm volatile("1: rdmsr ; xor %[err],%[err]\n"
141+
"2:\n\t"
142+
_ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_RDMSR_SAFE, %[err])
149143
: [err] "=r" (*err), EAX_EDX_RET(val, low, high)
150-
: "c" (msr), [fault] "i" (-EIO));
144+
: "c" (msr));
151145
if (tracepoint_enabled(read_msr))
152146
do_trace_read_msr(msr, EAX_EDX_VAL(val, low, high), *err);
153147
return EAX_EDX_VAL(val, low, high);
@@ -169,15 +163,11 @@ native_write_msr_safe(unsigned int msr, u32 low, u32 high)
169163
{
170164
int err;
171165

172-
asm volatile("2: wrmsr ; xor %[err],%[err]\n"
173-
"1:\n\t"
174-
".section .fixup,\"ax\"\n\t"
175-
"3: mov %[fault],%[err] ; jmp 1b\n\t"
176-
".previous\n\t"
177-
_ASM_EXTABLE(2b, 3b)
166+
asm volatile("1: wrmsr ; xor %[err],%[err]\n"
167+
"2:\n\t"
168+
_ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_WRMSR_SAFE, %[err])
178169
: [err] "=a" (err)
179-
: "c" (msr), "0" (low), "d" (high),
180-
[fault] "i" (-EIO)
170+
: "c" (msr), "0" (low), "d" (high)
181171
: "memory");
182172
if (tracepoint_enabled(write_msr))
183173
do_trace_write_msr(msr, ((u64)high << 32 | low), err);

arch/x86/mm/extable.c

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -83,28 +83,29 @@ static bool ex_handler_copy(const struct exception_table_entry *fixup,
8383
return ex_handler_fault(fixup, regs, trapnr);
8484
}
8585

86-
static bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
87-
struct pt_regs *regs)
86+
static bool ex_handler_msr(const struct exception_table_entry *fixup,
87+
struct pt_regs *regs, bool wrmsr, bool safe, int reg)
8888
{
89-
if (pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
89+
if (!safe && wrmsr &&
90+
pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
91+
(unsigned int)regs->cx, (unsigned int)regs->dx,
92+
(unsigned int)regs->ax, regs->ip, (void *)regs->ip))
93+
show_stack_regs(regs);
94+
95+
if (!safe && !wrmsr &&
96+
pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
9097
(unsigned int)regs->cx, regs->ip, (void *)regs->ip))
9198
show_stack_regs(regs);
9299

93-
/* Pretend that the read succeeded and returned 0. */
94-
regs->ax = 0;
95-
regs->dx = 0;
96-
return ex_handler_default(fixup, regs);
97-
}
100+
if (!wrmsr) {
101+
/* Pretend that the read succeeded and returned 0. */
102+
regs->ax = 0;
103+
regs->dx = 0;
104+
}
98105

99-
static bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,
100-
struct pt_regs *regs)
101-
{
102-
if (pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
103-
(unsigned int)regs->cx, (unsigned int)regs->dx,
104-
(unsigned int)regs->ax, regs->ip, (void *)regs->ip))
105-
show_stack_regs(regs);
106+
if (safe)
107+
*pt_regs_nr(regs, reg) = -EIO;
106108

107-
/* Pretend that the write succeeded. */
108109
return ex_handler_default(fixup, regs);
109110
}
110111

@@ -186,18 +187,22 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
186187
return ex_handler_clear_fs(e, regs);
187188
case EX_TYPE_FPU_RESTORE:
188189
return ex_handler_fprestore(e, regs);
189-
case EX_TYPE_RDMSR:
190-
return ex_handler_rdmsr_unsafe(e, regs);
191-
case EX_TYPE_WRMSR:
192-
return ex_handler_wrmsr_unsafe(e, regs);
193190
case EX_TYPE_BPF:
194191
return ex_handler_bpf(e, regs);
195-
case EX_TYPE_RDMSR_IN_MCE:
196-
ex_handler_msr_mce(regs, false);
197-
break;
192+
case EX_TYPE_WRMSR:
193+
return ex_handler_msr(e, regs, true, false, reg);
194+
case EX_TYPE_RDMSR:
195+
return ex_handler_msr(e, regs, false, false, reg);
196+
case EX_TYPE_WRMSR_SAFE:
197+
return ex_handler_msr(e, regs, true, true, reg);
198+
case EX_TYPE_RDMSR_SAFE:
199+
return ex_handler_msr(e, regs, false, true, reg);
198200
case EX_TYPE_WRMSR_IN_MCE:
199201
ex_handler_msr_mce(regs, true);
200202
break;
203+
case EX_TYPE_RDMSR_IN_MCE:
204+
ex_handler_msr_mce(regs, false);
205+
break;
201206
case EX_TYPE_POP_ZERO:
202207
return ex_handler_pop_zero(e, regs);
203208
case EX_TYPE_IMM_REG:

0 commit comments

Comments
 (0)