mirror of
https://github.com/S3NEO/android_kernel_samsung_msm8226.git
synced 2024-11-07 03:47:13 +00:00
scm-mpu: Add additional memory protection options
Add support for a scm call to protect a contiguous physical address range. Add a config option to use this api to protect the kernel text section. Otherwise, the user may specify the region through module parameters. CRs-Fixed: 797891 Change-Id: Ie751ec72deb1a1692093559fe8c6784e8bf912a2 Signed-off-by: Patrick Daly <pdaly@codeaurora.org> [schikk@codeaurora.org: 3.4 kernel doesn't have drivers/soc/qcom folder, new file scm-mpu.c has been added in arch/arm/mach-msm/. 3.4 kernel doesn't support function scm_call2 , so replaced the function call with scm_call which is supported in 3.4 kernel ] Signed-off-by: Swetha Chikkaboraiah <schikk@codeaurora.org>
This commit is contained in:
parent
8aeb0925bc
commit
d6ce51794a
4 changed files with 148 additions and 1 deletions
36
Documentation/arm/msm/scm-mpu.txt
Normal file
36
Documentation/arm/msm/scm-mpu.txt
Normal file
|
@ -0,0 +1,36 @@
|
|||
Introduction
|
||||
============
|
||||
|
||||
The scm-mpu driver allows enabling xpu protection of arbitrary physical memory
|
||||
addresses as a debug mechanism.
|
||||
|
||||
Software description
|
||||
====================
|
||||
|
||||
Several methods of controlling this feature are provided.
|
||||
|
||||
* CONFIG_KERNEL_TEXT_MPU_PROT - Enables protection of the kernel code and
|
||||
read-only sections by default.
|
||||
|
||||
* kernel command line
|
||||
scm_mpu.mpu_start=0x0
|
||||
scm_mpu.mpu_size=0x1000
|
||||
|
||||
* /sys/module/scm_mpu/parameters
|
||||
echo 0x0 > mpu_start
|
||||
echo 0x1000 > mpu_size
|
||||
echo 0x11 > mpu_enable
|
||||
|
||||
The sysfs interface may also be used to unlock previously defined regions.
|
||||
echo 0x0 > mpu_start
|
||||
echo 0x1000 > mpu_size
|
||||
echo 0x10 > mpu_enable
|
||||
|
||||
Limitations
|
||||
===========
|
||||
The number of distinct regions allowed is limited by available resources.
|
||||
|
||||
No provisions are made for "carving out" or otherwise removing xpu protected
|
||||
regions from the linux memory map.
|
||||
|
||||
XPU protection currently uses 4K alignment.
|
|
@ -3044,3 +3044,11 @@ config KRAIT_REGULATOR
|
|||
regulators running in ganged mode inside the PMIC. Enable
|
||||
this option to support such configurations.
|
||||
endif
|
||||
|
||||
config KERNEL_TEXT_MPU_PROT
|
||||
bool "Enable xpu protection of kernel r/o sections"
|
||||
help
|
||||
Enables xpu protection of kernel code and read-only data
|
||||
sections early in boot. Read access is permitted to
|
||||
all masters; Write access is only permited to the
|
||||
secure world.
|
||||
|
|
|
@ -76,7 +76,7 @@ $(obj)/smd_rpc_sym.c: $(src)/smd_rpc_sym $(src)/mkrpcsym.pl
|
|||
obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o remote_spinlock.o smd_private.o smem.o smd_init_dt.o smd_init_plat.o
|
||||
obj-$(CONFIG_MSM_SMP2P) += smp2p.o smp2p_debug.o smp2p_gpio.o
|
||||
obj-$(CONFIG_MSM_SMP2P_TEST) += smp2p_loopback.o smp2p_test.o smp2p_gpio_test.o smp2p_spinlock_test.o
|
||||
obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
|
||||
obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o scm-mpu.o
|
||||
obj-$(CONFIG_MSM_XPU_ERR_FATAL) += scm-xpu.o
|
||||
obj-$(CONFIG_MSM_SECURE_IO) += scm-io.o
|
||||
obj-$(CONFIG_MSM_PIL) += peripheral-loader.o
|
||||
|
|
103
arch/arm/mach-msm/scm-mpu.c
Normal file
103
arch/arm/mach-msm/scm-mpu.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <mach/scm.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/sections.h>
|
||||
|
||||
#define TZ_PROTECT_MEMORY 0x1
|
||||
|
||||
/* filesystem parameters */
|
||||
#define MPU_MAGIC_LOCK 0x11
|
||||
#define MPU_MAGIC_UNLOCK 0x10
|
||||
|
||||
static ulong mpu_start;
|
||||
static ulong mpu_size;
|
||||
static u32 mpu_enable;
|
||||
|
||||
module_param(mpu_start, ulong, 0644);
|
||||
module_param(mpu_size, ulong, 0644);
|
||||
|
||||
static void mem_prot_region(u64 start, u64 size, bool lock);
|
||||
static int set_enabled(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = param_set_int(val, kp);
|
||||
|
||||
if (mpu_enable == MPU_MAGIC_LOCK)
|
||||
mem_prot_region(mpu_start, mpu_size, true);
|
||||
else if (mpu_enable == MPU_MAGIC_UNLOCK)
|
||||
mem_prot_region(mpu_start, mpu_size, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct kernel_param_ops mpu_ops = {
|
||||
.set = set_enabled,
|
||||
.get = param_get_int,
|
||||
};
|
||||
module_param_cb(mpu_enable, &mpu_ops, &mpu_enable, 0644);
|
||||
|
||||
static void mem_prot_region(u64 start, u64 size, bool lock)
|
||||
{
|
||||
int ret;
|
||||
struct req_cmd {
|
||||
u32 address;
|
||||
u32 size;
|
||||
u32 permission;
|
||||
u32 lock;
|
||||
u32 arg;
|
||||
} request;
|
||||
|
||||
request.address = PAGE_ALIGN(start);
|
||||
request.size = PAGE_ALIGN(size);
|
||||
/*
|
||||
* Permissions: Write: Read
|
||||
* 0x1 TZ Anyone
|
||||
* 0x2 TZ Tz, APPS
|
||||
* 0x3 TZ Tz
|
||||
*/
|
||||
request.permission = 0x1;
|
||||
request.lock = lock;
|
||||
request.arg = 0;
|
||||
|
||||
ret = scm_call(SCM_SVC_MP, TZ_PROTECT_MEMORY,
|
||||
&request, sizeof(request), &ret, sizeof(ret));
|
||||
|
||||
if (ret != 0)
|
||||
pr_err("Failed to %s region %llx - %llx\n",
|
||||
lock ? "protect" : "unlock", start, start + size);
|
||||
else
|
||||
pr_debug("SUCCESS to %s region %llx - %llx\n",
|
||||
lock ? "protect" : "unlock", start, start + size);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KERNEL_TEXT_MPU_PROT
|
||||
static int __init mem_prot_init(void)
|
||||
{
|
||||
phys_addr_t phys = virt_to_phys(_stext);
|
||||
mem_prot_region((u64)phys, (u64)(_etext - _stext), true);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(mem_prot_init);
|
||||
#else
|
||||
static int __init mem_prot_init(void)
|
||||
{
|
||||
if (mpu_start && mpu_size)
|
||||
mem_prot_region(mpu_start, mpu_size, true);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(mem_prot_init);
|
||||
#endif
|
Loading…
Reference in a new issue