aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorLuden <luden@ghostmail.com>2016-02-18 21:22:02 +0100
committerZiyan <jaraidaniel@gmail.com>2016-05-01 23:35:58 +0200
commitf3ccb5a5514a8b6a87b77b2ee4c146886ff6d104 (patch)
tree37f67436647f3b66a5c89105cca1148b0e7a32d1 /security
parent7a27a75e1ce7be1cd4a3c524e58d6be5a902de93 (diff)
downloadkernel_samsung_tuna-f3ccb5a5514a8b6a87b77b2ee4c146886ff6d104.zip
kernel_samsung_tuna-f3ccb5a5514a8b6a87b77b2ee4c146886ff6d104.tar.gz
kernel_samsung_tuna-f3ccb5a5514a8b6a87b77b2ee4c146886ff6d104.tar.bz2
SMC: switch workspace allocation to CMA
Diffstat (limited to 'security')
-rw-r--r--security/smc/tf_device_mshield.c79
1 files changed, 76 insertions, 3 deletions
diff --git a/security/smc/tf_device_mshield.c b/security/smc/tf_device_mshield.c
index 0bd30ad..4765d31 100644
--- a/security/smc/tf_device_mshield.c
+++ b/security/smc/tf_device_mshield.c
@@ -30,6 +30,9 @@
#include <linux/device.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#ifdef CONFIG_CMA
+#include <linux/dma-contiguous.h>
+#endif
#include "tf_protocol.h"
#include "tf_defs.h"
@@ -45,6 +48,15 @@
static struct class *tf_ctrl_class;
+#ifdef CONFIG_CMA
+// Dummy device for CMA
+static struct device smc_cma_device = { 0, };
+
+static phys_addr_t omap4_smc_cma_addr;
+static struct page* omap4_smc_cma_pages;
+static size_t omap4_smc_cma_pages_count;
+#endif
+
#define TF_DEVICE_CTRL_BASE_NAME "tf_ctrl"
struct tf_pa_ctrl {
@@ -57,6 +69,31 @@ struct tf_pa_ctrl {
u8 *conf_buffer;
};
+#ifdef CONFIG_CMA
+static bool omap_smc_allocate_memory(void)
+{
+ omap4_smc_cma_pages = dma_alloc_from_contiguous_fixed_addr(&smc_cma_device,
+ omap4_smc_cma_addr, omap4_smc_cma_pages_count);
+ if (!omap4_smc_cma_pages) {
+ pr_err("CMA SMC pages allocation failed\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool omap_smc_free_memory(void)
+{
+ if (!dma_release_from_contiguous(&smc_cma_device, omap4_smc_cma_pages,
+ omap4_smc_cma_pages_count)) {
+ pr_err("CMA SMC pages release failed\n");
+ return false;
+ }
+
+ return true;
+}
+#endif
+
static int tf_ctrl_check_omap_type(void)
{
/* No need to do anything on a GP device */
@@ -150,6 +187,13 @@ static long tf_ctrl_device_ioctl(struct file *file, unsigned int ioctl_num,
goto start_exit;
}
+#ifdef CONFIG_CMA
+ if (!omap_smc_allocate_memory()) {
+ result = -ENOMEM;
+ goto start_exit;
+ }
+#endif
+
result = tf_start(&dev->sm,
dev->workspace_addr,
dev->workspace_size,
@@ -157,8 +201,12 @@ static long tf_ctrl_device_ioctl(struct file *file, unsigned int ioctl_num,
pa_ctrl.pa_size,
pa_ctrl.conf_buffer,
pa_ctrl.conf_size);
- if (result)
+ if (result) {
+#ifdef CONFIG_CMA
+ omap_smc_free_memory();
+#endif
dpr_err("SMC: start failed\n");
+ }
else
dpr_info("SMC: started\n");
@@ -173,8 +221,12 @@ start_exit:
TF_POWER_OPERATION_SHUTDOWN);
if (result)
dpr_err("SMC: stop failed [0x%x]\n", result);
- else
+ else {
dpr_info("SMC: stopped\n");
+#ifdef CONFIG_CMA
+ omap_smc_free_memory();
+#endif
+ }
break;
default:
@@ -280,6 +332,11 @@ static int __initdata smc_address;
void __init tf_allocate_workspace(void)
{
struct tf_device *dev = tf_get_device();
+#ifdef CONFIG_CMA
+ const size_t cma_alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order);
+ phys_addr_t cma_region_addr;
+ size_t cma_region_size;
+#endif
tf_clock_timer_init();
@@ -300,9 +357,25 @@ void __init tf_allocate_workspace(void)
else
dev->workspace_addr = smc_address;
- pr_info("SMC: Allocated workspace of 0x%x Bytes at (0x%x)\n",
+#ifdef CONFIG_CMA
+ omap4_smc_cma_addr = dev->workspace_addr;
+ omap4_smc_cma_pages_count = dev->workspace_size / PAGE_SIZE;
+ cma_region_addr = round_down(omap4_smc_cma_addr, cma_alignment);
+ cma_region_size = round_up(dev->workspace_size, cma_alignment);
+
+ pr_info("Reserving CMA SMC region at address = 0x%x with size = 0x%x\n",
+ cma_region_addr, cma_region_size);
+ dma_declare_contiguous(&smc_cma_device, cma_region_size,
+ cma_region_addr, 0);
+
+ pr_info("SMC: will allocate workspace of 0x%x Bytes at (0x%x) once requested\n",
dev->workspace_size,
dev->workspace_addr);
+#else
+ pr_info("SMC: Allocated workspace of 0x%x Bytes at (0x%x)\n",
+ dev->workspace_size,
+ dev->workspace_addr);
+#endif
}
static int __init tf_mem_setup(char *str)