@@ -83,28 +83,29 @@ static bool ex_handler_copy(const struct exception_table_entry *fixup,
83
83
return ex_handler_fault (fixup , regs , trapnr );
84
84
}
85
85
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 )
88
88
{
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" ,
90
97
(unsigned int )regs -> cx , regs -> ip , (void * )regs -> ip ))
91
98
show_stack_regs (regs );
92
99
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
+ }
98
105
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 ;
106
108
107
- /* Pretend that the write succeeded. */
108
109
return ex_handler_default (fixup , regs );
109
110
}
110
111
@@ -186,18 +187,22 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
186
187
return ex_handler_clear_fs (e , regs );
187
188
case EX_TYPE_FPU_RESTORE :
188
189
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 );
193
190
case EX_TYPE_BPF :
194
191
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 );
198
200
case EX_TYPE_WRMSR_IN_MCE :
199
201
ex_handler_msr_mce (regs , true);
200
202
break ;
203
+ case EX_TYPE_RDMSR_IN_MCE :
204
+ ex_handler_msr_mce (regs , false);
205
+ break ;
201
206
case EX_TYPE_POP_ZERO :
202
207
return ex_handler_pop_zero (e , regs );
203
208
case EX_TYPE_IMM_REG :
0 commit comments