0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/device.h>
0010 #include <linux/genalloc.h>
0011 #include <linux/mm.h>
0012 #include <linux/sram.h>
0013
0014 #include <asm/fncpy.h>
0015 #include <asm/set_memory.h>
0016
0017 #include "sram.h"
0018
0019 static DEFINE_MUTEX(exec_pool_list_mutex);
0020 static LIST_HEAD(exec_pool_list);
0021
0022 int sram_check_protect_exec(struct sram_dev *sram, struct sram_reserve *block,
0023 struct sram_partition *part)
0024 {
0025 unsigned long base = (unsigned long)part->base;
0026 unsigned long end = base + block->size;
0027
0028 if (!PAGE_ALIGNED(base) || !PAGE_ALIGNED(end)) {
0029 dev_err(sram->dev,
0030 "SRAM pool marked with 'protect-exec' is not page aligned and will not be created.\n");
0031 return -ENOMEM;
0032 }
0033
0034 return 0;
0035 }
0036
0037 int sram_add_protect_exec(struct sram_partition *part)
0038 {
0039 mutex_lock(&exec_pool_list_mutex);
0040 list_add_tail(&part->list, &exec_pool_list);
0041 mutex_unlock(&exec_pool_list_mutex);
0042
0043 return 0;
0044 }
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 void *sram_exec_copy(struct gen_pool *pool, void *dst, void *src,
0074 size_t size)
0075 {
0076 struct sram_partition *part = NULL, *p;
0077 unsigned long base;
0078 int pages;
0079 void *dst_cpy;
0080 int ret;
0081
0082 mutex_lock(&exec_pool_list_mutex);
0083 list_for_each_entry(p, &exec_pool_list, list) {
0084 if (p->pool == pool)
0085 part = p;
0086 }
0087 mutex_unlock(&exec_pool_list_mutex);
0088
0089 if (!part)
0090 return NULL;
0091
0092 if (!gen_pool_has_addr(pool, (unsigned long)dst, size))
0093 return NULL;
0094
0095 base = (unsigned long)part->base;
0096 pages = PAGE_ALIGN(size) / PAGE_SIZE;
0097
0098 mutex_lock(&part->lock);
0099
0100 ret = set_memory_nx((unsigned long)base, pages);
0101 if (ret)
0102 goto error_out;
0103 ret = set_memory_rw((unsigned long)base, pages);
0104 if (ret)
0105 goto error_out;
0106
0107 dst_cpy = fncpy(dst, src, size);
0108
0109 ret = set_memory_ro((unsigned long)base, pages);
0110 if (ret)
0111 goto error_out;
0112 ret = set_memory_x((unsigned long)base, pages);
0113 if (ret)
0114 goto error_out;
0115
0116 mutex_unlock(&part->lock);
0117
0118 return dst_cpy;
0119
0120 error_out:
0121 mutex_unlock(&part->lock);
0122 return NULL;
0123 }
0124 EXPORT_SYMBOL_GPL(sram_exec_copy);