115 lines
3.7 KiB
C
115 lines
3.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2002 Richard Henderson
|
|
* Copyright (C) 2001 Rusty Russell, 2002, 2010 Rusty Russell IBM.
|
|
* Copyright (C) 2021 MediaTek Inc.
|
|
*/
|
|
|
|
#include <linux/of.h>
|
|
#include "mkp_module.h"
|
|
#include "mkp_api.h"
|
|
|
|
#define DRV_NUM_MAX 128
|
|
static const char *drv_skip_list[DRV_NUM_MAX] __ro_after_init;
|
|
static int drv_skip_num __ro_after_init;
|
|
|
|
/* mkp_drv_skip="ko_1", "ko_2", "ko_3", ..., "ko_128"; */
|
|
void __init update_drv_skip_by_dts(struct device_node *node)
|
|
{
|
|
if (!node)
|
|
return;
|
|
|
|
drv_skip_num = of_property_read_string_array(node, "mkp_drv_skip",
|
|
drv_skip_list, DRV_NUM_MAX);
|
|
|
|
if (drv_skip_num < 0 && drv_skip_num >= DRV_NUM_MAX) {
|
|
pr_info("%s: no valid mkp_drv_skip(%d)\n", __func__, drv_skip_num);
|
|
drv_skip_num = 0;
|
|
}
|
|
}
|
|
|
|
bool drv_skip(char *module_name)
|
|
{
|
|
int i = 0;
|
|
|
|
for (i = 0; i < drv_skip_num; i++) {
|
|
if (strcmp(module_name, drv_skip_list[i]) == 0)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static void frob_text(const struct module_layout *layout,
|
|
enum helper_ops ops, uint32_t policy)
|
|
{
|
|
int ret;
|
|
|
|
BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
|
|
BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
|
|
ret = mkp_set_mapping_xxx_helper((unsigned long)layout->base, layout->text_size>>PAGE_SHIFT,
|
|
policy, ops);
|
|
}
|
|
static void frob_rodata(const struct module_layout *layout,
|
|
enum helper_ops ops, uint32_t policy)
|
|
{
|
|
int ret;
|
|
|
|
BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
|
|
BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
|
|
BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
|
|
ret = mkp_set_mapping_xxx_helper((unsigned long)layout->base+layout->text_size,
|
|
(layout->ro_size-layout->text_size)>>PAGE_SHIFT, policy, ops);
|
|
}
|
|
static void frob_ro_after_init(const struct module_layout *layout,
|
|
enum helper_ops ops, uint32_t policy)
|
|
{
|
|
int ret;
|
|
|
|
BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
|
|
BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
|
|
BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1));
|
|
ret = mkp_set_mapping_xxx_helper((unsigned long)layout->base+layout->ro_size,
|
|
(layout->ro_after_init_size-layout->ro_size)>>PAGE_SHIFT, policy, ops);
|
|
}
|
|
static void frob_writable_data(const struct module_layout *layout,
|
|
enum helper_ops ops, uint32_t policy)
|
|
{
|
|
int ret;
|
|
|
|
BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
|
|
BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1));
|
|
BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1));
|
|
ret = mkp_set_mapping_xxx_helper((unsigned long)layout->base+layout->ro_after_init_size,
|
|
(layout->size-layout->ro_after_init_size)>>PAGE_SHIFT, policy, ops);
|
|
}
|
|
|
|
void module_enable_x(const struct module *mod, uint32_t policy)
|
|
{
|
|
frob_text(&mod->core_layout, HELPER_MAPPING_X, policy);
|
|
if (policy == MKP_POLICY_DRV)
|
|
frob_text(&mod->init_layout, HELPER_MAPPING_X, policy);
|
|
}
|
|
void module_enable_ro(const struct module *mod, bool after_init, uint32_t policy)
|
|
{
|
|
/* DO NOT CHANGE THE FOLLOWING ORDER */
|
|
frob_text(&mod->core_layout, HELPER_MAPPING_RO, policy);
|
|
frob_rodata(&mod->core_layout, HELPER_MAPPING_RO, policy);
|
|
if (policy == MKP_POLICY_DRV) {
|
|
frob_text(&mod->init_layout, HELPER_MAPPING_RO, policy);
|
|
frob_rodata(&mod->init_layout, HELPER_MAPPING_RO, policy);
|
|
}
|
|
|
|
if (after_init)
|
|
frob_ro_after_init(&mod->core_layout, HELPER_MAPPING_RO, policy);
|
|
}
|
|
void module_enable_nx(const struct module *mod, uint32_t policy)
|
|
{
|
|
frob_rodata(&mod->core_layout, HELPER_MAPPING_NX, policy);
|
|
/* DO NOT REMOVE THE FOLLOWING STEP */
|
|
frob_ro_after_init(&mod->core_layout, HELPER_MAPPING_NX, policy);
|
|
frob_writable_data(&mod->core_layout, HELPER_MAPPING_NX, policy);
|
|
if (policy == MKP_POLICY_DRV) {
|
|
frob_rodata(&mod->init_layout, HELPER_MAPPING_NX, policy);
|
|
frob_writable_data(&mod->init_layout, HELPER_MAPPING_NX, policy);
|
|
}
|
|
}
|