Other architectures define various set_memory functions to allow attributes to be changed (e.g. set_memory_x, set_memory_rw, etc.) Currently, these functions are missing on ARM. Define these in an appropriate manner for ARM. Signed-off-by: Laura Abbott <lauraa@xxxxxxxxxxxxxx> --- arch/arm/include/asm/cacheflush.h | 5 ++ arch/arm/mm/mmu.c | 86 +++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 0 deletions(-) diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index bff7138..55ed26b 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -438,4 +438,9 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size) #define sync_cache_w(ptr) __sync_cache_range_w(ptr, sizeof *(ptr)) #define sync_cache_r(ptr) __sync_cache_range_r(ptr, sizeof *(ptr)) +int set_memory_ro(unsigned long addr, int numpages); +int set_memory_rw(unsigned long addr, int numpages); +int set_memory_x(unsigned long addr, int numpages); +int set_memory_nx(unsigned long addr, int numpages); + #endif diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e0d8565..1dc14a3 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -335,6 +335,92 @@ const struct mem_type *get_mem_type(unsigned int type) } EXPORT_SYMBOL(get_mem_type); +static int pte_set_ro(pte_t *ptep, pgtable_t token, unsigned long addr, + void *data) +{ + pte_t pte = pte_wrprotect(*ptep); + + set_pte_ext(ptep, pte, 0); + return 0; +} + +int set_memory_ro(unsigned long addr, int numpages) +{ + unsigned long start = addr; + unsigned long size = PAGE_SIZE*numpages; + unsigned end = start + size; + + apply_to_page_range(&init_mm, start, size, pte_set_ro, NULL); + dsb(); + flush_tlb_kernel_range(start, end); + return 0; +} + +static int pte_set_rw(pte_t *ptep, pgtable_t token, unsigned long addr, + void *data) +{ + pte_t pte = pte_mkwrite(*ptep); + + set_pte_ext(ptep, pte, 0); + return 0; +} + +int set_memory_rw(unsigned long addr, int numpages) +{ + unsigned long start = addr; + unsigned long size = PAGE_SIZE*numpages; + unsigned end = start + size; + + apply_to_page_range(&init_mm, start, size, pte_set_rw, NULL); + dsb(); + flush_tlb_kernel_range(start, end); + return 0; + +} + +static int pte_set_x(pte_t *ptep, pgtable_t token, unsigned long addr, + void *data) +{ + pte_t pte = pte_mkexec(*ptep); + + set_pte_ext(ptep, pte, 0); + return 0; +} + +int set_memory_x(unsigned long addr, int numpages) +{ + unsigned long start = addr; + unsigned long size = PAGE_SIZE*numpages; + unsigned end = start + size; + + apply_to_page_range(&init_mm, start, size, pte_set_x, NULL); + dsb(); + flush_tlb_kernel_range(start, end); + return 0; +} + +static int pte_set_nx(pte_t *ptep, pgtable_t token, unsigned long addr, + void *data) +{ + pte_t pte = pte_mknexec(*ptep); + + set_pte_ext(ptep, pte, 0); + return 0; +} + +int set_memory_nx(unsigned long addr, int numpages) +{ + unsigned long start = addr; + unsigned long size = PAGE_SIZE*numpages; + unsigned end = start + size; + + apply_to_page_range(&init_mm, start, size, pte_set_nx, NULL); + dsb(); + flush_tlb_kernel_range(start, end); + + return 0; +} + /* * Adjust the PMD section entries according to the CPU in use. */ -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html