1 /* 2 * SRAM protect-exec region helper functions 3 * 4 * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ 5 * Dave Gerlach 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 12 * kind, whether express or implied; without even the implied warranty 13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include <linux/device.h> 18 #include <linux/genalloc.h> 19 #include <linux/mm.h> 20 #include <linux/sram.h> 21 22 #include <asm/set_memory.h> 23 24 #include "sram.h" 25 26 static DEFINE_MUTEX(exec_pool_list_mutex); 27 static LIST_HEAD(exec_pool_list); 28 29 int sram_check_protect_exec(struct sram_dev *sram, struct sram_reserve *block, 30 struct sram_partition *part) 31 { 32 unsigned long base = (unsigned long)part->base; 33 unsigned long end = base + block->size; 34 35 if (!PAGE_ALIGNED(base) || !PAGE_ALIGNED(end)) { 36 dev_err(sram->dev, 37 "SRAM pool marked with 'protect-exec' is not page aligned and will not be created.\n"); 38 return -ENOMEM; 39 } 40 41 return 0; 42 } 43 44 int sram_add_protect_exec(struct sram_partition *part) 45 { 46 mutex_lock(&exec_pool_list_mutex); 47 list_add_tail(&part->list, &exec_pool_list); 48 mutex_unlock(&exec_pool_list_mutex); 49 50 return 0; 51 } 52 53 /** 54 * sram_exec_copy - copy data to a protected executable region of sram 55 * 56 * @pool: struct gen_pool retrieved that is part of this sram 57 * @dst: Destination address for the copy, that must be inside pool 58 * @src: Source address for the data to copy 59 * @size: Size of copy to perform, which starting from dst, must reside in pool 60 * 61 * This helper function allows sram driver to act as central control location 62 * of 'protect-exec' pools which are normal sram pools but are always set 63 * read-only and executable except when copying data to them, at which point 64 * they are set to read-write non-executable, to make sure no memory is 65 * writeable and executable at the same time. This region must be page-aligned 66 * and is checked during probe, otherwise page attribute manipulation would 67 * not be possible. 68 */ 69 int sram_exec_copy(struct gen_pool *pool, void *dst, void *src, 70 size_t size) 71 { 72 struct sram_partition *part = NULL, *p; 73 unsigned long base; 74 int pages; 75 76 mutex_lock(&exec_pool_list_mutex); 77 list_for_each_entry(p, &exec_pool_list, list) { 78 if (p->pool == pool) 79 part = p; 80 } 81 mutex_unlock(&exec_pool_list_mutex); 82 83 if (!part) 84 return -EINVAL; 85 86 if (!addr_in_gen_pool(pool, (unsigned long)dst, size)) 87 return -EINVAL; 88 89 base = (unsigned long)part->base; 90 pages = PAGE_ALIGN(size) / PAGE_SIZE; 91 92 mutex_lock(&part->lock); 93 94 set_memory_nx((unsigned long)base, pages); 95 set_memory_rw((unsigned long)base, pages); 96 97 memcpy(dst, src, size); 98 99 set_memory_ro((unsigned long)base, pages); 100 set_memory_x((unsigned long)base, pages); 101 102 mutex_unlock(&part->lock); 103 104 return 0; 105 } 106 EXPORT_SYMBOL_GPL(sram_exec_copy); 107