xref: /kvm-unit-tests/s390x/iep.c (revision c315f52b88b967cfb4cd58f3b4e1987378c47f3b)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Instruction Execution Prevention (IEP) DAT test.
4  *
5  * Copyright (c) 2018 IBM Corp
6  *
7  * Authors:
8  *	Janosch Frank <frankja@linux.ibm.com>
9  */
10 #include <libcflat.h>
11 #include <vmalloc.h>
12 #include <mmu.h>
13 #include <asm/facility.h>
14 #include <asm/interrupt.h>
15 #include <asm/pgtable.h>
16 
test_iep(void)17 static void test_iep(void)
18 {
19 	uint16_t *code;
20 	uint8_t *iepbuf = NULL;
21 	void (*fn)(void);
22 
23 	/* Enable IEP */
24 	ctl_set_bit(0, CTL0_IEP);
25 
26 	/* Get and protect a page with the IEP bit */
27 	iepbuf = alloc_page();
28 	protect_page(iepbuf, PAGE_ENTRY_IEP);
29 
30 	/* Code branches into r14 which contains the return address. */
31 	code = (uint16_t *)iepbuf;
32 	*code = 0x07fe;
33 	fn = (void *)code;
34 
35 	report_prefix_push("iep protection");
36 	expect_pgm_int();
37 	/* Jump into protected page */
38 	fn();
39 	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
40 	report_prefix_pop();
41 	unprotect_page(iepbuf, PAGE_ENTRY_IEP);
42 	ctl_clear_bit(0, CTL0_IEP);
43 	free_page(iepbuf);
44 }
45 
main(void)46 int main(void)
47 {
48 	bool has_iep = test_facility(130);
49 
50 	report_prefix_push("iep");
51 	if (!has_iep) {
52 		report_skip("DAT IEP is not available");
53 		goto done;
54 	}
55 
56 	/* Setup DAT 1:1 mapping and memory management */
57 	setup_vm();
58 	test_iep();
59 
60 done:
61 	report_prefix_pop();
62 	return report_summary();
63 }
64