8
8
#include <asm/kdebug.h>
9
9
10
10
typedef bool (* ex_handler_t )(const struct exception_table_entry * ,
11
- struct pt_regs * , int );
11
+ struct pt_regs * , int , unsigned long ,
12
+ unsigned long );
12
13
13
14
static inline unsigned long
14
15
ex_fixup_addr (const struct exception_table_entry * x )
@@ -22,15 +23,19 @@ ex_fixup_handler(const struct exception_table_entry *x)
22
23
}
23
24
24
25
__visible bool ex_handler_default (const struct exception_table_entry * fixup ,
25
- struct pt_regs * regs , int trapnr )
26
+ struct pt_regs * regs , int trapnr ,
27
+ unsigned long error_code ,
28
+ unsigned long fault_addr )
26
29
{
27
30
regs -> ip = ex_fixup_addr (fixup );
28
31
return true;
29
32
}
30
33
EXPORT_SYMBOL (ex_handler_default );
31
34
32
35
__visible bool ex_handler_fault (const struct exception_table_entry * fixup ,
33
- struct pt_regs * regs , int trapnr )
36
+ struct pt_regs * regs , int trapnr ,
37
+ unsigned long error_code ,
38
+ unsigned long fault_addr )
34
39
{
35
40
regs -> ip = ex_fixup_addr (fixup );
36
41
regs -> ax = trapnr ;
@@ -43,7 +48,9 @@ EXPORT_SYMBOL_GPL(ex_handler_fault);
43
48
* result of a refcount inc/dec/add/sub.
44
49
*/
45
50
__visible bool ex_handler_refcount (const struct exception_table_entry * fixup ,
46
- struct pt_regs * regs , int trapnr )
51
+ struct pt_regs * regs , int trapnr ,
52
+ unsigned long error_code ,
53
+ unsigned long fault_addr )
47
54
{
48
55
/* First unconditionally saturate the refcount. */
49
56
* (int * )regs -> cx = INT_MIN / 2 ;
@@ -96,7 +103,9 @@ EXPORT_SYMBOL(ex_handler_refcount);
96
103
* out all the FPU registers) if we can't restore from the task's FPU state.
97
104
*/
98
105
__visible bool ex_handler_fprestore (const struct exception_table_entry * fixup ,
99
- struct pt_regs * regs , int trapnr )
106
+ struct pt_regs * regs , int trapnr ,
107
+ unsigned long error_code ,
108
+ unsigned long fault_addr )
100
109
{
101
110
regs -> ip = ex_fixup_addr (fixup );
102
111
@@ -109,15 +118,19 @@ __visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,
109
118
EXPORT_SYMBOL_GPL (ex_handler_fprestore );
110
119
111
120
__visible bool ex_handler_uaccess (const struct exception_table_entry * fixup ,
112
- struct pt_regs * regs , int trapnr )
121
+ struct pt_regs * regs , int trapnr ,
122
+ unsigned long error_code ,
123
+ unsigned long fault_addr )
113
124
{
114
125
regs -> ip = ex_fixup_addr (fixup );
115
126
return true;
116
127
}
117
128
EXPORT_SYMBOL (ex_handler_uaccess );
118
129
119
130
__visible bool ex_handler_ext (const struct exception_table_entry * fixup ,
120
- struct pt_regs * regs , int trapnr )
131
+ struct pt_regs * regs , int trapnr ,
132
+ unsigned long error_code ,
133
+ unsigned long fault_addr )
121
134
{
122
135
/* Special hack for uaccess_err */
123
136
current -> thread .uaccess_err = 1 ;
@@ -127,7 +140,9 @@ __visible bool ex_handler_ext(const struct exception_table_entry *fixup,
127
140
EXPORT_SYMBOL (ex_handler_ext );
128
141
129
142
__visible bool ex_handler_rdmsr_unsafe (const struct exception_table_entry * fixup ,
130
- struct pt_regs * regs , int trapnr )
143
+ struct pt_regs * regs , int trapnr ,
144
+ unsigned long error_code ,
145
+ unsigned long fault_addr )
131
146
{
132
147
if (pr_warn_once ("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pF)\n" ,
133
148
(unsigned int )regs -> cx , regs -> ip , (void * )regs -> ip ))
@@ -142,7 +157,9 @@ __visible bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup
142
157
EXPORT_SYMBOL (ex_handler_rdmsr_unsafe );
143
158
144
159
__visible bool ex_handler_wrmsr_unsafe (const struct exception_table_entry * fixup ,
145
- struct pt_regs * regs , int trapnr )
160
+ struct pt_regs * regs , int trapnr ,
161
+ unsigned long error_code ,
162
+ unsigned long fault_addr )
146
163
{
147
164
if (pr_warn_once ("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pF)\n" ,
148
165
(unsigned int )regs -> cx , (unsigned int )regs -> dx ,
@@ -156,12 +173,14 @@ __visible bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup
156
173
EXPORT_SYMBOL (ex_handler_wrmsr_unsafe );
157
174
158
175
__visible bool ex_handler_clear_fs (const struct exception_table_entry * fixup ,
159
- struct pt_regs * regs , int trapnr )
176
+ struct pt_regs * regs , int trapnr ,
177
+ unsigned long error_code ,
178
+ unsigned long fault_addr )
160
179
{
161
180
if (static_cpu_has (X86_BUG_NULL_SEG ))
162
181
asm volatile ("mov %0, %%fs" : : "rm" (__USER_DS ));
163
182
asm volatile ("mov %0, %%fs" : : "rm" (0 ));
164
- return ex_handler_default (fixup , regs , trapnr );
183
+ return ex_handler_default (fixup , regs , trapnr , error_code , fault_addr );
165
184
}
166
185
EXPORT_SYMBOL (ex_handler_clear_fs );
167
186
@@ -178,7 +197,8 @@ __visible bool ex_has_fault_handler(unsigned long ip)
178
197
return handler == ex_handler_fault ;
179
198
}
180
199
181
- int fixup_exception (struct pt_regs * regs , int trapnr )
200
+ int fixup_exception (struct pt_regs * regs , int trapnr , unsigned long error_code ,
201
+ unsigned long fault_addr )
182
202
{
183
203
const struct exception_table_entry * e ;
184
204
ex_handler_t handler ;
@@ -202,7 +222,7 @@ int fixup_exception(struct pt_regs *regs, int trapnr)
202
222
return 0 ;
203
223
204
224
handler = ex_fixup_handler (e );
205
- return handler (e , regs , trapnr );
225
+ return handler (e , regs , trapnr , error_code , fault_addr );
206
226
}
207
227
208
228
extern unsigned int early_recursion_flag ;
@@ -238,9 +258,9 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
238
258
* result in a hard-to-debug panic.
239
259
*
240
260
* Keep in mind that not all vectors actually get here. Early
241
- * fage faults, for example, are special.
261
+ * page faults, for example, are special.
242
262
*/
243
- if (fixup_exception (regs , trapnr ))
263
+ if (fixup_exception (regs , trapnr , regs -> orig_ax , 0 ))
244
264
return ;
245
265
246
266
if (fixup_bug (regs , trapnr ))
0 commit comments