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 + i * PAGE_SIZE); 28 29 pte = *ptep; 30 pte = set(pte); 31 ptep_invalidate(&init_mm, addr + i * PAGE_SIZE, ptep); 32 *ptep = pte; 33 } 34 } 35 36 int set_memory_ro(unsigned long addr, int numpages) 37 { 38 change_page_attr(addr, numpages, pte_wrprotect); 39 return 0; 40 } 41 EXPORT_SYMBOL_GPL(set_memory_ro); 42 43 int set_memory_rw(unsigned long addr, int numpages) 44 { 45 change_page_attr(addr, numpages, pte_mkwrite); 46 return 0; 47 } 48 EXPORT_SYMBOL_GPL(set_memory_rw); 49 50 /* not possible */ 51 int set_memory_nx(unsigned long addr, int numpages) 52 { 53 return 0; 54 } 55 EXPORT_SYMBOL_GPL(set_memory_nx); 56