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