anolis: module: redirect kmalloc related symbols
ANBZ: #9065 During module loading, when processing relocation symbols, memory allocation symbols such as __kmalloc are specially handled to make them point to symbols dedicated for out-of-tree (OOT) modules, thus obtaining memory from dedicated slabs. Signed-off-by: Yi Tao <escape@linux.alibaba.com> Reviewed-by: Xu Yu <xuyu@linux.alibaba.com> Reviewed-by: Guixin Liu <kanie@linux.alibaba.com> Link: https://gitee.com/anolis/cloud-kernel/pulls/3208
This commit is contained in:
parent
baa47e1aa7
commit
1f31422bb6
|
@ -535,7 +535,7 @@ struct module {
|
|||
struct error_injection_entry *ei_funcs;
|
||||
unsigned int num_ei_funcs;
|
||||
#endif
|
||||
|
||||
unsigned int oot_isolation_index;
|
||||
CK_KABI_RESERVE(1)
|
||||
CK_KABI_RESERVE(2)
|
||||
CK_KABI_RESERVE(3)
|
||||
|
|
|
@ -591,6 +591,54 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
|
|||
return false;
|
||||
}
|
||||
|
||||
#define OOT_POOL_NUM 16
|
||||
|
||||
struct redirect_sym {
|
||||
char *src_name;
|
||||
char *dst_name[OOT_POOL_NUM];
|
||||
};
|
||||
|
||||
#define DEFINE_REDIRECT_SYM(__src_name, __dst_name) \
|
||||
{ \
|
||||
.src_name = __src_name, \
|
||||
.dst_name = { \
|
||||
__dst_name "_0", \
|
||||
__dst_name "_1", \
|
||||
__dst_name "_2", \
|
||||
__dst_name "_3", \
|
||||
__dst_name "_4", \
|
||||
__dst_name "_5", \
|
||||
__dst_name "_6", \
|
||||
__dst_name "_7", \
|
||||
__dst_name "_8", \
|
||||
__dst_name "_9", \
|
||||
__dst_name "_10", \
|
||||
__dst_name "_11", \
|
||||
__dst_name "_12", \
|
||||
__dst_name "_13", \
|
||||
__dst_name "_14", \
|
||||
__dst_name "_15", \
|
||||
} \
|
||||
}
|
||||
|
||||
static struct redirect_sym redirect_syms[] = {
|
||||
DEFINE_REDIRECT_SYM("kmalloc_caches", "oot_kmalloc_caches"),
|
||||
DEFINE_REDIRECT_SYM("__kmalloc", "oot___kmalloc"),
|
||||
DEFINE_REDIRECT_SYM("__kmalloc_node", "oot___kmalloc_node"),
|
||||
{},
|
||||
};
|
||||
|
||||
static const char *find_true_name(const char *name, struct module *mod)
|
||||
{
|
||||
struct redirect_sym *rsym;
|
||||
|
||||
for (rsym = redirect_syms; rsym->src_name; rsym++)
|
||||
if (!strcmp(name, rsym->src_name))
|
||||
return rsym->dst_name[mod->oot_isolation_index];
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/* Find an exported symbol and return it, along with, (optional) crc and
|
||||
* (optional) module which owns it. Needs preempt disabled or module_mutex. */
|
||||
static const struct kernel_symbol *find_symbol(const char *name,
|
||||
|
@ -1330,7 +1378,7 @@ static int check_version(const struct load_info *info,
|
|||
for (i = 0; i < num_versions; i++) {
|
||||
u32 crcval;
|
||||
|
||||
if (strcmp(versions[i].name, symname) != 0)
|
||||
if (strcmp(versions[i].name, find_true_name(symname, mod)) != 0)
|
||||
continue;
|
||||
|
||||
if (IS_ENABLED(CONFIG_MODULE_REL_CRCS))
|
||||
|
@ -1476,7 +1524,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
|||
*/
|
||||
sched_annotate_sleep();
|
||||
mutex_lock(&module_mutex);
|
||||
sym = find_symbol(name, &owner, &crc, &license,
|
||||
sym = find_symbol(find_true_name(name, mod), &owner, &crc, &license,
|
||||
!(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
|
||||
if (!sym)
|
||||
goto unlock;
|
||||
|
@ -2229,6 +2277,39 @@ void __weak module_arch_freeing_init(struct module *mod)
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
struct module *oot_table[OOT_POOL_NUM];
|
||||
|
||||
static void get_oot_mempool(struct module *mod)
|
||||
{
|
||||
int i;
|
||||
|
||||
//TODO: check this mod need oot mempool
|
||||
mutex_lock(&module_mutex);
|
||||
for (i = 0; i < OOT_POOL_NUM; i++) {
|
||||
if (!oot_table[i]) {
|
||||
oot_table[i] = mod;
|
||||
mod->oot_isolation_index = i;
|
||||
pr_info("Module %s use oot-kmalloc-%d.\n", mod->name, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&module_mutex);
|
||||
if (mod->oot_isolation_index == -1)
|
||||
pr_info("Module %s can't use oot-kmalloc because pool exhausted.\n", mod->name);
|
||||
}
|
||||
|
||||
static void put_oot_mempool(struct module *mod)
|
||||
{
|
||||
//TODO: check this mod need oot mempool
|
||||
mutex_lock(&module_mutex);
|
||||
if (oot_table[mod->oot_isolation_index] == mod)
|
||||
oot_table[mod->oot_isolation_index] = NULL;
|
||||
else
|
||||
WARN_ON("oot mempool dismatch with owner!!!\n");
|
||||
mutex_unlock(&module_mutex);
|
||||
}
|
||||
|
||||
/* Free a module, remove from lists, etc. */
|
||||
static void free_module(struct module *mod)
|
||||
{
|
||||
|
@ -2242,6 +2323,8 @@ static void free_module(struct module *mod)
|
|||
mod->state = MODULE_STATE_UNFORMED;
|
||||
mutex_unlock(&module_mutex);
|
||||
|
||||
put_oot_mempool(mod);
|
||||
|
||||
/* Remove dynamic debug info */
|
||||
ddebug_remove_module(mod->name);
|
||||
|
||||
|
@ -4048,6 +4131,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
|
|||
/* Set up MODINFO_ATTR fields */
|
||||
setup_modinfo(mod, info);
|
||||
|
||||
get_oot_mempool(mod);
|
||||
|
||||
/* Fix up syms, so that st_value is a pointer to location. */
|
||||
err = simplify_symbols(mod, info);
|
||||
if (err < 0)
|
||||
|
@ -4138,6 +4223,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
|
|||
free_arch_cleanup:
|
||||
module_arch_cleanup(mod);
|
||||
free_modinfo:
|
||||
put_oot_mempool(mod);
|
||||
free_modinfo(mod);
|
||||
free_unload:
|
||||
module_unload_free(mod);
|
||||
|
|
Loading…
Reference in New Issue