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/pgtable.h> 9 10 static void change_page_attr(unsigned long addr, int numpages, 11 pte_t (*set) (pte_t)) 12 { 13 pte_t *ptep, pte; 14 pmd_t *pmdp; 15 pud_t *pudp; 16 pgd_t *pgdp; 17 int i; 18 19 for (i = 0; i < numpages; i++) { 20 pgdp = pgd_offset(&init_mm, addr); 21 pudp = pud_offset(pgdp, addr); 22 pmdp = pmd_offset(pudp, addr); 23 if (pmd_huge(*pmdp)) { 24 WARN_ON_ONCE(1); 25 continue; 26 } 27 ptep = pte_offset_kernel(pmdp, addr); 28 29 pte = *ptep; 30 pte = set(pte); 31 __ptep_ipte(addr, ptep); 32 *ptep = pte; 33 addr += PAGE_SIZE; 34 } 35 } 36 37 int set_memory_ro(unsigned long addr, int numpages) 38 { 39 change_page_attr(addr, numpages, pte_wrprotect); 40 return 0; 41 } 42 EXPORT_SYMBOL_GPL(set_memory_ro); 43 44 int set_memory_rw(unsigned long addr, int numpages) 45 { 46 change_page_attr(addr, numpages, pte_mkwrite); 47 return 0; 48 } 49 EXPORT_SYMBOL_GPL(set_memory_rw); 50 51 /* not possible */ 52 int set_memory_nx(unsigned long addr, int numpages) 53 { 54 return 0; 55 } 56 EXPORT_SYMBOL_GPL(set_memory_nx); 57 58 int set_memory_x(unsigned long addr, int numpages) 59 { 60 return 0; 61 } 62