aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2011-03-15 12:08:22 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-03-15 12:08:23 -0400
commit305b1523250faf9675919def94906775992ce52d (patch)
tree2dcbe253cf463eca3c0dfcc9ee8ac7b97cfa5021 /arch/s390
parentd54cddb620fa493968111f479029dcd910fcb921 (diff)
[S390] Write protect module text and RO data
Implement write protection for kernel modules text and read-only data sections by implementing set_memory_[ro|rw] on s390. Since s390 has no execute bit in the pte's NX is not supported. set_memory_[ro|rw] will only work on normal pages and not on large pages, so in case a large page should be modified bail out with a warning. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/Kconfig.debug3
-rw-r--r--arch/s390/include/asm/cacheflush.h4
-rw-r--r--arch/s390/mm/Makefile1
-rw-r--r--arch/s390/mm/pageattr.c55
4 files changed, 63 insertions, 0 deletions
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index 2b380df95606..d76cef3fef37 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -31,4 +31,7 @@ config DEBUG_STRICT_USER_COPY_CHECKS
31 31
32 If unsure, or if you run an older (pre 4.4) gcc, say N. 32 If unsure, or if you run an older (pre 4.4) gcc, say N.
33 33
34config DEBUG_SET_MODULE_RONX
35 def_bool y
36 depends on MODULES
34endmenu 37endmenu
diff --git a/arch/s390/include/asm/cacheflush.h b/arch/s390/include/asm/cacheflush.h
index 7e1f77620624..43a5c78046db 100644
--- a/arch/s390/include/asm/cacheflush.h
+++ b/arch/s390/include/asm/cacheflush.h
@@ -8,4 +8,8 @@
8void kernel_map_pages(struct page *page, int numpages, int enable); 8void kernel_map_pages(struct page *page, int numpages, int enable);
9#endif 9#endif
10 10
11int set_memory_ro(unsigned long addr, int numpages);
12int set_memory_rw(unsigned long addr, int numpages);
13int set_memory_nx(unsigned long addr, int numpages);
14
11#endif /* _S390_CACHEFLUSH_H */ 15#endif /* _S390_CACHEFLUSH_H */
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index 6fbc6f3fbdf2..d98fe9004a52 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -6,3 +6,4 @@ obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \
6 page-states.o gup.o 6 page-states.o gup.o
7obj-$(CONFIG_CMM) += cmm.o 7obj-$(CONFIG_CMM) += cmm.o
8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
9obj-$(CONFIG_DEBUG_SET_MODULE_RONX) += pageattr.o
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
new file mode 100644
index 000000000000..122ffbd08ce0
--- /dev/null
+++ b/arch/s390/mm/pageattr.c
@@ -0,0 +1,55 @@
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
10static 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
36int set_memory_ro(unsigned long addr, int numpages)
37{
38 change_page_attr(addr, numpages, pte_wrprotect);
39 return 0;
40}
41EXPORT_SYMBOL_GPL(set_memory_ro);
42
43int set_memory_rw(unsigned long addr, int numpages)
44{
45 change_page_attr(addr, numpages, pte_mkwrite);
46 return 0;
47}
48EXPORT_SYMBOL_GPL(set_memory_rw);
49
50/* not possible */
51int set_memory_nx(unsigned long addr, int numpages)
52{
53 return 0;
54}
55EXPORT_SYMBOL_GPL(set_memory_nx);