]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/arch/frv/mm/extable.c | |
3 | */ | |
4 | ||
1da177e4 LT |
5 | #include <linux/module.h> |
6 | #include <linux/spinlock.h> | |
7 | #include <asm/uaccess.h> | |
8 | ||
1da177e4 LT |
9 | extern const void __memset_end, __memset_user_error_lr, __memset_user_error_handler; |
10 | extern const void __memcpy_end, __memcpy_user_error_lr, __memcpy_user_error_handler; | |
11 | extern spinlock_t modlist_lock; | |
12 | ||
1da177e4 LT |
13 | |
14 | /*****************************************************************************/ | |
15 | /* | |
16 | * see if there's a fixup handler available to deal with a kernel fault | |
17 | */ | |
18 | unsigned long search_exception_table(unsigned long pc) | |
19 | { | |
018b8d12 | 20 | const struct exception_table_entry *extab; |
1da177e4 LT |
21 | |
22 | /* determine if the fault lay during a memcpy_user or a memset_user */ | |
23 | if (__frame->lr == (unsigned long) &__memset_user_error_lr && | |
24 | (unsigned long) &memset <= pc && pc < (unsigned long) &__memset_end | |
25 | ) { | |
26 | /* the fault occurred in a protected memset | |
27 | * - we search for the return address (in LR) instead of the program counter | |
28 | * - it was probably during a clear_user() | |
29 | */ | |
30 | return (unsigned long) &__memset_user_error_handler; | |
31 | } | |
018b8d12 DH |
32 | |
33 | if (__frame->lr == (unsigned long) &__memcpy_user_error_lr && | |
34 | (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end | |
35 | ) { | |
1da177e4 LT |
36 | /* the fault occurred in a protected memset |
37 | * - we search for the return address (in LR) instead of the program counter | |
38 | * - it was probably during a copy_to/from_user() | |
39 | */ | |
40 | return (unsigned long) &__memcpy_user_error_handler; | |
41 | } | |
42 | ||
018b8d12 DH |
43 | extab = search_exception_tables(pc); |
44 | if (extab) | |
45 | return extab->fixup; | |
1da177e4 | 46 | |
018b8d12 | 47 | return 0; |
1da177e4 | 48 | |
1da177e4 | 49 | } /* end search_exception_table() */ |