Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * linux/arch/sparc/mm/extable.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/extable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) void sort_extable(struct exception_table_entry *start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 		  struct exception_table_entry *finish)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) /* Caller knows they are in a range if ret->fixup == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) const struct exception_table_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) search_extable(const struct exception_table_entry *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	       const size_t num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	       unsigned long value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	/* Single insn entries are encoded as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	 *	word 1:	insn address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	 *	word 2:	fixup code address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	 * Range entries are encoded as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	 *	word 1: first insn address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	 *	word 2: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	 *	word 3: last insn address + 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	 *	word 4: fixup code address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	 * Deleted entries are encoded as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	 *	word 1: unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	 *	word 2: -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	 * See asm/uaccess.h for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	/* 1. Try to find an exact match. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		if (base[i].fixup == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 			/* A range entry, skip both parts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		/* A deleted entry; see trim_init_extable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		if (base[i].fixup == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		if (base[i].insn == value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			return &base[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	/* 2. Try to find a range match. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	for (i = 0; i < (num - 1); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		if (base[i].fixup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		if (base[i].insn <= value && base[i + 1].insn > value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			return &base[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)         return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #ifdef CONFIG_MODULES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) /* We could memmove them around; easier to mark the trimmed ones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) void trim_init_extable(struct module *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	bool range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	for (i = 0; i < m->num_exentries; i += range ? 2 : 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		range = m->extable[i].fixup == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		if (within_module_init(m->extable[i].insn, m)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			m->extable[i].fixup = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			if (range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 				m->extable[i+1].fixup = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		if (range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #endif /* CONFIG_MODULES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) /* Special extable search, which handles ranges.  Returns fixup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	const struct exception_table_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	entry = search_exception_tables(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	/* Inside range?  Fix g2 and return correct fixup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (!entry->fixup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		*g2 = (addr - entry->insn) / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		return (entry + 1)->fixup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	return entry->fixup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }