summary refs log tree commit diff
path: root/arch/s390/kernel/kprobes.c
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2020-09-18 10:26:19 +0200
committerVasily Gorbik <gor@linux.ibm.com>2020-10-09 23:45:30 +0200
commitb61e1f3281c5a53f24f47849873463514f58c1b8 (patch)
tree73623ca152797153f08cddc9bca78cb8f619869f /arch/s390/kernel/kprobes.c
parenteefc69a09ca5b441ee136f9fb68ab5970cfc2d51 (diff)
downloadlinux-b61e1f3281c5a53f24f47849873463514f58c1b8.tar.gz
s390/kprobes: move insn_page to text segment
Move the in-kernel kprobes insn page to text segment. Rationale:
having that page in rw data segment is suboptimal, since as soon as a
kprobe is set, this will split the 1:1 kernel mapping for a single
page which get new permissions.

Note: there is always at least one kprobe present for the kretprobe
trampoline; so the mapping will always be split into smaller 4k
mappings because of this.

Moving the kprobes insn page into text segment makes sure that the
page is mapped RO/X in any case, and avoids that the 1:1 mapping is
split.

The kprobe insn_page is defined as a dummy function which is filled
with "br %r14" instructions.

Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel/kprobes.c')
-rw-r--r--arch/s390/kernel/kprobes.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index b34fa4eef742..6574774d404e 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -22,6 +22,7 @@
 #include <asm/set_memory.h>
 #include <asm/sections.h>
 #include <asm/dis.h>
+#include "entry.h"
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe);
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@@ -31,7 +32,6 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = { };
 DEFINE_INSN_CACHE_OPS(s390_insn);
 
 static int insn_page_in_use;
-static char insn_page[PAGE_SIZE] __aligned(PAGE_SIZE);
 
 void *alloc_insn_page(void)
 {
@@ -53,13 +53,11 @@ static void *alloc_s390_insn_page(void)
 {
 	if (xchg(&insn_page_in_use, 1) == 1)
 		return NULL;
-	__set_memory((unsigned long) &insn_page, 1, SET_MEMORY_RO | SET_MEMORY_X);
-	return &insn_page;
+	return &kprobes_insn_page;
 }
 
 static void free_s390_insn_page(void *page)
 {
-	__set_memory((unsigned long) page, 1, SET_MEMORY_RW | SET_MEMORY_NX);
 	xchg(&insn_page_in_use, 0);
 }