1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun #include <linux/init.h>
3*4882a593Smuzhiyun #include <linux/static_call.h>
4*4882a593Smuzhiyun #include <linux/bug.h>
5*4882a593Smuzhiyun #include <linux/smp.h>
6*4882a593Smuzhiyun #include <linux/sort.h>
7*4882a593Smuzhiyun #include <linux/slab.h>
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/cpu.h>
10*4882a593Smuzhiyun #include <linux/processor.h>
11*4882a593Smuzhiyun #include <asm/sections.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun extern struct static_call_site __start_static_call_sites[],
14*4882a593Smuzhiyun __stop_static_call_sites[];
15*4882a593Smuzhiyun extern struct static_call_tramp_key __start_static_call_tramp_key[],
16*4882a593Smuzhiyun __stop_static_call_tramp_key[];
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun static bool static_call_initialized;
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /* mutex to protect key modules/sites */
21*4882a593Smuzhiyun static DEFINE_MUTEX(static_call_mutex);
22*4882a593Smuzhiyun
static_call_lock(void)23*4882a593Smuzhiyun static void static_call_lock(void)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun mutex_lock(&static_call_mutex);
26*4882a593Smuzhiyun }
27*4882a593Smuzhiyun
static_call_unlock(void)28*4882a593Smuzhiyun static void static_call_unlock(void)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun mutex_unlock(&static_call_mutex);
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun
static_call_addr(struct static_call_site * site)33*4882a593Smuzhiyun static inline void *static_call_addr(struct static_call_site *site)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun return (void *)((long)site->addr + (long)&site->addr);
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun
__static_call_key(const struct static_call_site * site)38*4882a593Smuzhiyun static inline unsigned long __static_call_key(const struct static_call_site *site)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun return (long)site->key + (long)&site->key;
41*4882a593Smuzhiyun }
42*4882a593Smuzhiyun
static_call_key(const struct static_call_site * site)43*4882a593Smuzhiyun static inline struct static_call_key *static_call_key(const struct static_call_site *site)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun return (void *)(__static_call_key(site) & ~STATIC_CALL_SITE_FLAGS);
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun /* These assume the key is word-aligned. */
static_call_is_init(struct static_call_site * site)49*4882a593Smuzhiyun static inline bool static_call_is_init(struct static_call_site *site)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun return __static_call_key(site) & STATIC_CALL_SITE_INIT;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun
static_call_is_tail(struct static_call_site * site)54*4882a593Smuzhiyun static inline bool static_call_is_tail(struct static_call_site *site)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun return __static_call_key(site) & STATIC_CALL_SITE_TAIL;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun
static_call_set_init(struct static_call_site * site)59*4882a593Smuzhiyun static inline void static_call_set_init(struct static_call_site *site)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun site->key = (__static_call_key(site) | STATIC_CALL_SITE_INIT) -
62*4882a593Smuzhiyun (long)&site->key;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
static_call_site_cmp(const void * _a,const void * _b)65*4882a593Smuzhiyun static int static_call_site_cmp(const void *_a, const void *_b)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun const struct static_call_site *a = _a;
68*4882a593Smuzhiyun const struct static_call_site *b = _b;
69*4882a593Smuzhiyun const struct static_call_key *key_a = static_call_key(a);
70*4882a593Smuzhiyun const struct static_call_key *key_b = static_call_key(b);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun if (key_a < key_b)
73*4882a593Smuzhiyun return -1;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun if (key_a > key_b)
76*4882a593Smuzhiyun return 1;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun return 0;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
static_call_site_swap(void * _a,void * _b,int size)81*4882a593Smuzhiyun static void static_call_site_swap(void *_a, void *_b, int size)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun long delta = (unsigned long)_a - (unsigned long)_b;
84*4882a593Smuzhiyun struct static_call_site *a = _a;
85*4882a593Smuzhiyun struct static_call_site *b = _b;
86*4882a593Smuzhiyun struct static_call_site tmp = *a;
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun a->addr = b->addr - delta;
89*4882a593Smuzhiyun a->key = b->key - delta;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun b->addr = tmp.addr + delta;
92*4882a593Smuzhiyun b->key = tmp.key + delta;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
static_call_sort_entries(struct static_call_site * start,struct static_call_site * stop)95*4882a593Smuzhiyun static inline void static_call_sort_entries(struct static_call_site *start,
96*4882a593Smuzhiyun struct static_call_site *stop)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun sort(start, stop - start, sizeof(struct static_call_site),
99*4882a593Smuzhiyun static_call_site_cmp, static_call_site_swap);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
static_call_key_has_mods(struct static_call_key * key)102*4882a593Smuzhiyun static inline bool static_call_key_has_mods(struct static_call_key *key)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun return !(key->type & 1);
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun
static_call_key_next(struct static_call_key * key)107*4882a593Smuzhiyun static inline struct static_call_mod *static_call_key_next(struct static_call_key *key)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun if (!static_call_key_has_mods(key))
110*4882a593Smuzhiyun return NULL;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun return key->mods;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
static_call_key_sites(struct static_call_key * key)115*4882a593Smuzhiyun static inline struct static_call_site *static_call_key_sites(struct static_call_key *key)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun if (static_call_key_has_mods(key))
118*4882a593Smuzhiyun return NULL;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun return (struct static_call_site *)(key->type & ~1);
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun
__static_call_update(struct static_call_key * key,void * tramp,void * func)123*4882a593Smuzhiyun void __static_call_update(struct static_call_key *key, void *tramp, void *func)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun struct static_call_site *site, *stop;
126*4882a593Smuzhiyun struct static_call_mod *site_mod, first;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun cpus_read_lock();
129*4882a593Smuzhiyun static_call_lock();
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun if (key->func == func)
132*4882a593Smuzhiyun goto done;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun key->func = func;
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun arch_static_call_transform(NULL, tramp, func, false);
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun /*
139*4882a593Smuzhiyun * If uninitialized, we'll not update the callsites, but they still
140*4882a593Smuzhiyun * point to the trampoline and we just patched that.
141*4882a593Smuzhiyun */
142*4882a593Smuzhiyun if (WARN_ON_ONCE(!static_call_initialized))
143*4882a593Smuzhiyun goto done;
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun first = (struct static_call_mod){
146*4882a593Smuzhiyun .next = static_call_key_next(key),
147*4882a593Smuzhiyun .mod = NULL,
148*4882a593Smuzhiyun .sites = static_call_key_sites(key),
149*4882a593Smuzhiyun };
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun for (site_mod = &first; site_mod; site_mod = site_mod->next) {
152*4882a593Smuzhiyun bool init = system_state < SYSTEM_RUNNING;
153*4882a593Smuzhiyun struct module *mod = site_mod->mod;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun if (!site_mod->sites) {
156*4882a593Smuzhiyun /*
157*4882a593Smuzhiyun * This can happen if the static call key is defined in
158*4882a593Smuzhiyun * a module which doesn't use it.
159*4882a593Smuzhiyun *
160*4882a593Smuzhiyun * It also happens in the has_mods case, where the
161*4882a593Smuzhiyun * 'first' entry has no sites associated with it.
162*4882a593Smuzhiyun */
163*4882a593Smuzhiyun continue;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun stop = __stop_static_call_sites;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun if (mod) {
169*4882a593Smuzhiyun #ifdef CONFIG_MODULES
170*4882a593Smuzhiyun stop = mod->static_call_sites +
171*4882a593Smuzhiyun mod->num_static_call_sites;
172*4882a593Smuzhiyun init = mod->state == MODULE_STATE_COMING;
173*4882a593Smuzhiyun #endif
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun for (site = site_mod->sites;
177*4882a593Smuzhiyun site < stop && static_call_key(site) == key; site++) {
178*4882a593Smuzhiyun void *site_addr = static_call_addr(site);
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun if (!init && static_call_is_init(site))
181*4882a593Smuzhiyun continue;
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun if (!kernel_text_address((unsigned long)site_addr)) {
184*4882a593Smuzhiyun /*
185*4882a593Smuzhiyun * This skips patching built-in __exit, which
186*4882a593Smuzhiyun * is part of init_section_contains() but is
187*4882a593Smuzhiyun * not part of kernel_text_address().
188*4882a593Smuzhiyun *
189*4882a593Smuzhiyun * Skipping built-in __exit is fine since it
190*4882a593Smuzhiyun * will never be executed.
191*4882a593Smuzhiyun */
192*4882a593Smuzhiyun WARN_ONCE(!static_call_is_init(site),
193*4882a593Smuzhiyun "can't patch static call site at %pS",
194*4882a593Smuzhiyun site_addr);
195*4882a593Smuzhiyun continue;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun arch_static_call_transform(site_addr, NULL, func,
199*4882a593Smuzhiyun static_call_is_tail(site));
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun done:
204*4882a593Smuzhiyun static_call_unlock();
205*4882a593Smuzhiyun cpus_read_unlock();
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__static_call_update);
208*4882a593Smuzhiyun
__static_call_init(struct module * mod,struct static_call_site * start,struct static_call_site * stop)209*4882a593Smuzhiyun static int __static_call_init(struct module *mod,
210*4882a593Smuzhiyun struct static_call_site *start,
211*4882a593Smuzhiyun struct static_call_site *stop)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun struct static_call_site *site;
214*4882a593Smuzhiyun struct static_call_key *key, *prev_key = NULL;
215*4882a593Smuzhiyun struct static_call_mod *site_mod;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun if (start == stop)
218*4882a593Smuzhiyun return 0;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun static_call_sort_entries(start, stop);
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun for (site = start; site < stop; site++) {
223*4882a593Smuzhiyun void *site_addr = static_call_addr(site);
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun if ((mod && within_module_init((unsigned long)site_addr, mod)) ||
226*4882a593Smuzhiyun (!mod && init_section_contains(site_addr, 1)))
227*4882a593Smuzhiyun static_call_set_init(site);
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun key = static_call_key(site);
230*4882a593Smuzhiyun if (key != prev_key) {
231*4882a593Smuzhiyun prev_key = key;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun /*
234*4882a593Smuzhiyun * For vmlinux (!mod) avoid the allocation by storing
235*4882a593Smuzhiyun * the sites pointer in the key itself. Also see
236*4882a593Smuzhiyun * __static_call_update()'s @first.
237*4882a593Smuzhiyun *
238*4882a593Smuzhiyun * This allows architectures (eg. x86) to call
239*4882a593Smuzhiyun * static_call_init() before memory allocation works.
240*4882a593Smuzhiyun */
241*4882a593Smuzhiyun if (!mod) {
242*4882a593Smuzhiyun key->sites = site;
243*4882a593Smuzhiyun key->type |= 1;
244*4882a593Smuzhiyun goto do_transform;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun site_mod = kzalloc(sizeof(*site_mod), GFP_KERNEL);
248*4882a593Smuzhiyun if (!site_mod)
249*4882a593Smuzhiyun return -ENOMEM;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun /*
252*4882a593Smuzhiyun * When the key has a direct sites pointer, extract
253*4882a593Smuzhiyun * that into an explicit struct static_call_mod, so we
254*4882a593Smuzhiyun * can have a list of modules.
255*4882a593Smuzhiyun */
256*4882a593Smuzhiyun if (static_call_key_sites(key)) {
257*4882a593Smuzhiyun site_mod->mod = NULL;
258*4882a593Smuzhiyun site_mod->next = NULL;
259*4882a593Smuzhiyun site_mod->sites = static_call_key_sites(key);
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun key->mods = site_mod;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun site_mod = kzalloc(sizeof(*site_mod), GFP_KERNEL);
264*4882a593Smuzhiyun if (!site_mod)
265*4882a593Smuzhiyun return -ENOMEM;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun site_mod->mod = mod;
269*4882a593Smuzhiyun site_mod->sites = site;
270*4882a593Smuzhiyun site_mod->next = static_call_key_next(key);
271*4882a593Smuzhiyun key->mods = site_mod;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun do_transform:
275*4882a593Smuzhiyun arch_static_call_transform(site_addr, NULL, key->func,
276*4882a593Smuzhiyun static_call_is_tail(site));
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun return 0;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
addr_conflict(struct static_call_site * site,void * start,void * end)282*4882a593Smuzhiyun static int addr_conflict(struct static_call_site *site, void *start, void *end)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun unsigned long addr = (unsigned long)static_call_addr(site);
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun if (addr <= (unsigned long)end &&
287*4882a593Smuzhiyun addr + CALL_INSN_SIZE > (unsigned long)start)
288*4882a593Smuzhiyun return 1;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun return 0;
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun
__static_call_text_reserved(struct static_call_site * iter_start,struct static_call_site * iter_stop,void * start,void * end,bool init)293*4882a593Smuzhiyun static int __static_call_text_reserved(struct static_call_site *iter_start,
294*4882a593Smuzhiyun struct static_call_site *iter_stop,
295*4882a593Smuzhiyun void *start, void *end, bool init)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun struct static_call_site *iter = iter_start;
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun while (iter < iter_stop) {
300*4882a593Smuzhiyun if (init || !static_call_is_init(iter)) {
301*4882a593Smuzhiyun if (addr_conflict(iter, start, end))
302*4882a593Smuzhiyun return 1;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun iter++;
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun return 0;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun #ifdef CONFIG_MODULES
311*4882a593Smuzhiyun
__static_call_mod_text_reserved(void * start,void * end)312*4882a593Smuzhiyun static int __static_call_mod_text_reserved(void *start, void *end)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun struct module *mod;
315*4882a593Smuzhiyun int ret;
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun preempt_disable();
318*4882a593Smuzhiyun mod = __module_text_address((unsigned long)start);
319*4882a593Smuzhiyun WARN_ON_ONCE(__module_text_address((unsigned long)end) != mod);
320*4882a593Smuzhiyun if (!try_module_get(mod))
321*4882a593Smuzhiyun mod = NULL;
322*4882a593Smuzhiyun preempt_enable();
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun if (!mod)
325*4882a593Smuzhiyun return 0;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun ret = __static_call_text_reserved(mod->static_call_sites,
328*4882a593Smuzhiyun mod->static_call_sites + mod->num_static_call_sites,
329*4882a593Smuzhiyun start, end, mod->state == MODULE_STATE_COMING);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun module_put(mod);
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun return ret;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
tramp_key_lookup(unsigned long addr)336*4882a593Smuzhiyun static unsigned long tramp_key_lookup(unsigned long addr)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun struct static_call_tramp_key *start = __start_static_call_tramp_key;
339*4882a593Smuzhiyun struct static_call_tramp_key *stop = __stop_static_call_tramp_key;
340*4882a593Smuzhiyun struct static_call_tramp_key *tramp_key;
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun for (tramp_key = start; tramp_key != stop; tramp_key++) {
343*4882a593Smuzhiyun unsigned long tramp;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun tramp = (long)tramp_key->tramp + (long)&tramp_key->tramp;
346*4882a593Smuzhiyun if (tramp == addr)
347*4882a593Smuzhiyun return (long)tramp_key->key + (long)&tramp_key->key;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun return 0;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
static_call_add_module(struct module * mod)353*4882a593Smuzhiyun static int static_call_add_module(struct module *mod)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun struct static_call_site *start = mod->static_call_sites;
356*4882a593Smuzhiyun struct static_call_site *stop = start + mod->num_static_call_sites;
357*4882a593Smuzhiyun struct static_call_site *site;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun for (site = start; site != stop; site++) {
360*4882a593Smuzhiyun unsigned long s_key = __static_call_key(site);
361*4882a593Smuzhiyun unsigned long addr = s_key & ~STATIC_CALL_SITE_FLAGS;
362*4882a593Smuzhiyun unsigned long key;
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun /*
365*4882a593Smuzhiyun * Is the key is exported, 'addr' points to the key, which
366*4882a593Smuzhiyun * means modules are allowed to call static_call_update() on
367*4882a593Smuzhiyun * it.
368*4882a593Smuzhiyun *
369*4882a593Smuzhiyun * Otherwise, the key isn't exported, and 'addr' points to the
370*4882a593Smuzhiyun * trampoline so we need to lookup the key.
371*4882a593Smuzhiyun *
372*4882a593Smuzhiyun * We go through this dance to prevent crazy modules from
373*4882a593Smuzhiyun * abusing sensitive static calls.
374*4882a593Smuzhiyun */
375*4882a593Smuzhiyun if (!kernel_text_address(addr))
376*4882a593Smuzhiyun continue;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun key = tramp_key_lookup(addr);
379*4882a593Smuzhiyun if (!key) {
380*4882a593Smuzhiyun pr_warn("Failed to fixup __raw_static_call() usage at: %ps\n",
381*4882a593Smuzhiyun static_call_addr(site));
382*4882a593Smuzhiyun return -EINVAL;
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun key |= s_key & STATIC_CALL_SITE_FLAGS;
386*4882a593Smuzhiyun site->key = key - (long)&site->key;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun return __static_call_init(mod, start, stop);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
static_call_del_module(struct module * mod)392*4882a593Smuzhiyun static void static_call_del_module(struct module *mod)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun struct static_call_site *start = mod->static_call_sites;
395*4882a593Smuzhiyun struct static_call_site *stop = mod->static_call_sites +
396*4882a593Smuzhiyun mod->num_static_call_sites;
397*4882a593Smuzhiyun struct static_call_key *key, *prev_key = NULL;
398*4882a593Smuzhiyun struct static_call_mod *site_mod, **prev;
399*4882a593Smuzhiyun struct static_call_site *site;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun for (site = start; site < stop; site++) {
402*4882a593Smuzhiyun key = static_call_key(site);
403*4882a593Smuzhiyun if (key == prev_key)
404*4882a593Smuzhiyun continue;
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun prev_key = key;
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun for (prev = &key->mods, site_mod = key->mods;
409*4882a593Smuzhiyun site_mod && site_mod->mod != mod;
410*4882a593Smuzhiyun prev = &site_mod->next, site_mod = site_mod->next)
411*4882a593Smuzhiyun ;
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun if (!site_mod)
414*4882a593Smuzhiyun continue;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun *prev = site_mod->next;
417*4882a593Smuzhiyun kfree(site_mod);
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
static_call_module_notify(struct notifier_block * nb,unsigned long val,void * data)421*4882a593Smuzhiyun static int static_call_module_notify(struct notifier_block *nb,
422*4882a593Smuzhiyun unsigned long val, void *data)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun struct module *mod = data;
425*4882a593Smuzhiyun int ret = 0;
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun cpus_read_lock();
428*4882a593Smuzhiyun static_call_lock();
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun switch (val) {
431*4882a593Smuzhiyun case MODULE_STATE_COMING:
432*4882a593Smuzhiyun ret = static_call_add_module(mod);
433*4882a593Smuzhiyun if (ret) {
434*4882a593Smuzhiyun WARN(1, "Failed to allocate memory for static calls");
435*4882a593Smuzhiyun static_call_del_module(mod);
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun break;
438*4882a593Smuzhiyun case MODULE_STATE_GOING:
439*4882a593Smuzhiyun static_call_del_module(mod);
440*4882a593Smuzhiyun break;
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun static_call_unlock();
444*4882a593Smuzhiyun cpus_read_unlock();
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun return notifier_from_errno(ret);
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun static struct notifier_block static_call_module_nb = {
450*4882a593Smuzhiyun .notifier_call = static_call_module_notify,
451*4882a593Smuzhiyun };
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun #else
454*4882a593Smuzhiyun
__static_call_mod_text_reserved(void * start,void * end)455*4882a593Smuzhiyun static inline int __static_call_mod_text_reserved(void *start, void *end)
456*4882a593Smuzhiyun {
457*4882a593Smuzhiyun return 0;
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun #endif /* CONFIG_MODULES */
461*4882a593Smuzhiyun
static_call_text_reserved(void * start,void * end)462*4882a593Smuzhiyun int static_call_text_reserved(void *start, void *end)
463*4882a593Smuzhiyun {
464*4882a593Smuzhiyun bool init = system_state < SYSTEM_RUNNING;
465*4882a593Smuzhiyun int ret = __static_call_text_reserved(__start_static_call_sites,
466*4882a593Smuzhiyun __stop_static_call_sites, start, end, init);
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun if (ret)
469*4882a593Smuzhiyun return ret;
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun return __static_call_mod_text_reserved(start, end);
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
static_call_init(void)474*4882a593Smuzhiyun int __init static_call_init(void)
475*4882a593Smuzhiyun {
476*4882a593Smuzhiyun int ret;
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun if (static_call_initialized)
479*4882a593Smuzhiyun return 0;
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun cpus_read_lock();
482*4882a593Smuzhiyun static_call_lock();
483*4882a593Smuzhiyun ret = __static_call_init(NULL, __start_static_call_sites,
484*4882a593Smuzhiyun __stop_static_call_sites);
485*4882a593Smuzhiyun static_call_unlock();
486*4882a593Smuzhiyun cpus_read_unlock();
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun if (ret) {
489*4882a593Smuzhiyun pr_err("Failed to allocate memory for static_call!\n");
490*4882a593Smuzhiyun BUG();
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun static_call_initialized = true;
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun #ifdef CONFIG_MODULES
496*4882a593Smuzhiyun register_module_notifier(&static_call_module_nb);
497*4882a593Smuzhiyun #endif
498*4882a593Smuzhiyun return 0;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun early_initcall(static_call_init);
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun #ifdef CONFIG_STATIC_CALL_SELFTEST
503*4882a593Smuzhiyun
func_a(int x)504*4882a593Smuzhiyun static int func_a(int x)
505*4882a593Smuzhiyun {
506*4882a593Smuzhiyun return x+1;
507*4882a593Smuzhiyun }
508*4882a593Smuzhiyun
func_b(int x)509*4882a593Smuzhiyun static int func_b(int x)
510*4882a593Smuzhiyun {
511*4882a593Smuzhiyun return x+2;
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun DEFINE_STATIC_CALL(sc_selftest, func_a);
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun static struct static_call_data {
517*4882a593Smuzhiyun int (*func)(int);
518*4882a593Smuzhiyun int val;
519*4882a593Smuzhiyun int expect;
520*4882a593Smuzhiyun } static_call_data [] __initdata = {
521*4882a593Smuzhiyun { NULL, 2, 3 },
522*4882a593Smuzhiyun { func_b, 2, 4 },
523*4882a593Smuzhiyun { func_a, 2, 3 }
524*4882a593Smuzhiyun };
525*4882a593Smuzhiyun
test_static_call_init(void)526*4882a593Smuzhiyun static int __init test_static_call_init(void)
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun int i;
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun for (i = 0; i < ARRAY_SIZE(static_call_data); i++ ) {
531*4882a593Smuzhiyun struct static_call_data *scd = &static_call_data[i];
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun if (scd->func)
534*4882a593Smuzhiyun static_call_update(sc_selftest, scd->func);
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun WARN_ON(static_call(sc_selftest)(scd->val) != scd->expect);
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun return 0;
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun early_initcall(test_static_call_init);
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun #endif /* CONFIG_STATIC_CALL_SELFTEST */
544