1 /* 2 * Copyright IBM Corp. 2011 3 * Author(s): Jan Glauber <jang@linux.vnet.ibm.com> 4 */ 5 #include <linux/module.h> 6 #include <linux/mm.h> 7 #include <linux/hugetlb.h> 8 #include <asm/cacheflush.h> 9 #include <asm/pgtable.h> 10 11 static void change_page_attr(unsigned long addr, int numpages, 12 pte_t (*set) (pte_t)) 13 { 14 pte_t *ptep, pte; 15 pmd_t *pmdp; 16 pud_t *pudp; 17 pgd_t *pgdp; 18 int i; 19 20 for (i = 0; i < numpages; i++) { 21 pgdp = pgd_offset(&init_mm, addr); 22 pudp = pud_offset(pgdp, addr); 23 pmdp = pmd_offset(pudp, addr); 24 if (pmd_huge(*pmdp)) { 25 WARN_ON_ONCE(1); 26 continue; 27 } 28 ptep = pte_offset_kernel(pmdp, addr); 29 30 pte = *ptep; 31 pte = set(pte); 32 __ptep_ipte(addr, ptep); 33 *ptep = pte; 34 addr += PAGE_SIZE; 35 } 36 } 37 38 int set_memory_ro(unsigned long addr, int numpages) 39 { 40 change_page_attr(addr, numpages, pte_wrprotect); 41 return 0; 42 } 43 EXPORT_SYMBOL_GPL(set_memory_ro); 44 45 int set_memory_rw(unsigned long addr, int numpages) 46 { 47 change_page_attr(addr, numpages, pte_mkwrite); 48 return 0; 49 } 50 EXPORT_SYMBOL_GPL(set_memory_rw); 51 52 /* not possible */ 53 int set_memory_nx(unsigned long addr, int numpages) 54 { 55 return 0; 56 } 57 EXPORT_SYMBOL_GPL(set_memory_nx); 58 59 int set_memory_x(unsigned long addr, int numpages) 60 { 61 return 0; 62 } 63