• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * linux/arch/frv/mm/extable.c
3  */
4 
5 #include <linux/module.h>
6 #include <linux/spinlock.h>
7 #include <asm/uaccess.h>
8 
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 
13 
14 /*****************************************************************************/
15 /*
16  * see if there's a fixup handler available to deal with a kernel fault
17  */
search_exception_table(unsigned long pc)18 unsigned long search_exception_table(unsigned long pc)
19 {
20 	const struct exception_table_entry *extab;
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 	}
32 
33 	if (__frame->lr == (unsigned long) &__memcpy_user_error_lr &&
34 	    (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end
35 	    ) {
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 
43 	extab = search_exception_tables(pc);
44 	if (extab)
45 		return extab->fixup;
46 
47 	return 0;
48 
49 } /* end search_exception_table() */
50