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