mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-29 17:22:07 +00:00
kprobes: add testcases for s390
Add a few testcases to make sure that it's not possible to place a kprobe in the mid of an instruction on s390. Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
f768a20c0a
commit
d340d28a96
@ -946,4 +946,16 @@ config S390_UNWIND_SELFTEST
|
||||
|
||||
Say N if you are unsure.
|
||||
|
||||
config S390_KPROBES_SANITY_TEST
|
||||
def_tristate n
|
||||
prompt "Enable s390 specific kprobes tests"
|
||||
depends on KPROBES
|
||||
depends on KUNIT
|
||||
help
|
||||
This option enables an s390 specific kprobes test module. This option
|
||||
is not useful for distributions or general kernels, but only for kernel
|
||||
developers working on architecture code.
|
||||
|
||||
Say N if you are unsure.
|
||||
|
||||
endmenu
|
||||
|
@ -62,6 +62,7 @@ CONFIG_CMM=m
|
||||
CONFIG_APPLDATA_BASE=y
|
||||
CONFIG_KVM=m
|
||||
CONFIG_S390_UNWIND_SELFTEST=y
|
||||
CONFIG_S390_KPROBES_SANITY_TEST=y
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_JUMP_LABEL=y
|
||||
CONFIG_STATIC_KEYS_SELFTEST=y
|
||||
|
@ -7,6 +7,8 @@ lib-y += delay.o string.o uaccess.o find.o spinlock.o
|
||||
obj-y += mem.o xor.o
|
||||
lib-$(CONFIG_KPROBES) += probes.o
|
||||
lib-$(CONFIG_UPROBES) += probes.o
|
||||
obj-$(CONFIG_S390_KPROBES_SANITY_TEST) += test_kprobes_s390.o
|
||||
test_kprobes_s390-objs += test_kprobes_asm.o test_kprobes.o
|
||||
|
||||
# Instrumenting memory accesses to __user data (in different address space)
|
||||
# produce false positives
|
||||
|
75
arch/s390/lib/test_kprobes.c
Normal file
75
arch/s390/lib/test_kprobes.c
Normal file
@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/random.h>
|
||||
#include <kunit/test.h>
|
||||
#include "test_kprobes.h"
|
||||
|
||||
static struct kprobe kp;
|
||||
|
||||
static void setup_kprobe(struct kunit *test, struct kprobe *kp,
|
||||
const char *symbol, int offset)
|
||||
{
|
||||
kp->offset = offset;
|
||||
kp->addr = NULL;
|
||||
kp->symbol_name = symbol;
|
||||
}
|
||||
|
||||
static void test_kprobe_offset(struct kunit *test, struct kprobe *kp,
|
||||
const char *target, int offset)
|
||||
{
|
||||
int ret;
|
||||
|
||||
setup_kprobe(test, kp, target, 0);
|
||||
ret = register_kprobe(kp);
|
||||
if (!ret)
|
||||
unregister_kprobe(kp);
|
||||
KUNIT_EXPECT_EQ(test, 0, ret);
|
||||
setup_kprobe(test, kp, target, offset);
|
||||
ret = register_kprobe(kp);
|
||||
KUNIT_EXPECT_EQ(test, -EINVAL, ret);
|
||||
if (!ret)
|
||||
unregister_kprobe(kp);
|
||||
}
|
||||
|
||||
static void test_kprobe_odd(struct kunit *test)
|
||||
{
|
||||
test_kprobe_offset(test, &kp, "kprobes_target_odd",
|
||||
kprobes_target_odd_offs);
|
||||
}
|
||||
|
||||
static void test_kprobe_in_insn4(struct kunit *test)
|
||||
{
|
||||
test_kprobe_offset(test, &kp, "kprobes_target_in_insn4",
|
||||
kprobes_target_in_insn4_offs);
|
||||
}
|
||||
|
||||
static void test_kprobe_in_insn6_lo(struct kunit *test)
|
||||
{
|
||||
test_kprobe_offset(test, &kp, "kprobes_target_in_insn6_lo",
|
||||
kprobes_target_in_insn6_lo_offs);
|
||||
}
|
||||
|
||||
static void test_kprobe_in_insn6_hi(struct kunit *test)
|
||||
{
|
||||
test_kprobe_offset(test, &kp, "kprobes_target_in_insn6_hi",
|
||||
kprobes_target_in_insn6_hi_offs);
|
||||
}
|
||||
|
||||
static struct kunit_case kprobes_testcases[] = {
|
||||
KUNIT_CASE(test_kprobe_odd),
|
||||
KUNIT_CASE(test_kprobe_in_insn4),
|
||||
KUNIT_CASE(test_kprobe_in_insn6_lo),
|
||||
KUNIT_CASE(test_kprobe_in_insn6_hi),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite kprobes_test_suite = {
|
||||
.name = "kprobes_test_s390",
|
||||
.test_cases = kprobes_testcases,
|
||||
};
|
||||
|
||||
kunit_test_suites(&kprobes_test_suite);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
10
arch/s390/lib/test_kprobes.h
Normal file
10
arch/s390/lib/test_kprobes.h
Normal file
@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
#ifndef TEST_KPROBES_H
|
||||
#define TEST_KPROBES_H
|
||||
|
||||
extern unsigned long kprobes_target_odd_offs;
|
||||
extern unsigned long kprobes_target_in_insn4_offs;
|
||||
extern unsigned long kprobes_target_in_insn6_lo_offs;
|
||||
extern unsigned long kprobes_target_in_insn6_hi_offs;
|
||||
|
||||
#endif
|
45
arch/s390/lib/test_kprobes_asm.S
Normal file
45
arch/s390/lib/test_kprobes_asm.S
Normal file
@ -0,0 +1,45 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
#define KPROBES_TARGET_START(name) \
|
||||
SYM_FUNC_START(name); \
|
||||
FTRACE_GEN_NOP_ASM(name)
|
||||
|
||||
#define KPROBES_TARGET_END(name) \
|
||||
SYM_FUNC_END(name); \
|
||||
SYM_DATA(name##_offs, .quad 1b - name)
|
||||
|
||||
KPROBES_TARGET_START(kprobes_target_in_insn4)
|
||||
.word 0x4700 // bc 0,0
|
||||
1: .word 0x0000
|
||||
br %r14
|
||||
KPROBES_TARGET_END(kprobes_target_in_insn4)
|
||||
|
||||
KPROBES_TARGET_START(kprobes_target_in_insn6_lo)
|
||||
.word 0xe310 // ly 1,0
|
||||
1: .word 0x0000
|
||||
.word 0x0058
|
||||
br %r14
|
||||
KPROBES_TARGET_END(kprobes_target_in_insn6_lo)
|
||||
|
||||
KPROBES_TARGET_START(kprobes_target_in_insn6_hi)
|
||||
.word 0xe310 // ly 1,0
|
||||
.word 0x0000
|
||||
1: .word 0x0058
|
||||
br %r14
|
||||
KPROBES_TARGET_END(kprobes_target_in_insn6_hi)
|
||||
|
||||
KPROBES_TARGET_START(kprobes_target_bp)
|
||||
nop
|
||||
.word 0x0000
|
||||
nop
|
||||
1: br %r14
|
||||
KPROBES_TARGET_END(kprobes_target_bp)
|
||||
|
||||
KPROBES_TARGET_START(kprobes_target_odd)
|
||||
.byte 0x07
|
||||
1: .byte 0x07
|
||||
br %r14
|
||||
KPROBES_TARGET_END(kprobes_target_odd)
|
Loading…
Reference in New Issue
Block a user