xref: /kvm-unit-tests/s390x/tprot.c (revision 4c8a99ca02252d4a2bee43f4558fe47ce5ab7ec0)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * TEST PROTECTION tests
4  *
5  * Copyright IBM Corp. 2022
6  *
7  * Authors:
8  *  Nico Boehr <nrb@linux.ibm.com>
9  */
10 
11 #include <libcflat.h>
12 #include <bitops.h>
13 #include <asm/pgtable.h>
14 #include <asm/interrupt.h>
15 #include <mmu.h>
16 #include <vmalloc.h>
17 #include <sclp.h>
18 
19 static uint8_t pagebuf[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
20 
21 static void test_tprot_rw(void)
22 {
23 	enum tprot_permission permission;
24 
25 	report_prefix_push("Page read/writeable");
26 
27 	permission = tprot((unsigned long)pagebuf, 0);
28 	report(permission == TPROT_READ_WRITE, "CC = 0");
29 
30 	report_prefix_pop();
31 }
32 
33 static void test_tprot_ro(void)
34 {
35 	enum tprot_permission permission;
36 
37 	report_prefix_push("Page readonly");
38 
39 	protect_dat_entry(pagebuf, PAGE_ENTRY_P, 5);
40 
41 	permission = tprot((unsigned long)pagebuf, 0);
42 	report(permission == TPROT_READ, "CC = 1");
43 
44 	unprotect_dat_entry(pagebuf, PAGE_ENTRY_P, 5);
45 
46 	report_prefix_pop();
47 }
48 
49 static void test_tprot_low_addr_prot(void)
50 {
51 	enum tprot_permission permission;
52 
53 	report_prefix_push("low-address protection");
54 
55 	low_prot_enable();
56 	permission = tprot(0, 0);
57 	low_prot_disable();
58 	report(permission == TPROT_READ, "CC = 1");
59 
60 	report_prefix_pop();
61 }
62 
63 static void test_tprot_transl_unavail(void)
64 {
65 	enum tprot_permission permission;
66 
67 	report_prefix_push("Page translation unavailable");
68 
69 	protect_dat_entry(pagebuf, PAGE_ENTRY_I, 5);
70 
71 	permission = tprot((unsigned long)pagebuf, 0);
72 	report(permission == TPROT_TRANSL_UNAVAIL, "CC = 3");
73 
74 	unprotect_dat_entry(pagebuf, PAGE_ENTRY_I, 5);
75 
76 	report_prefix_pop();
77 }
78 
79 static void test_tprot_transl_pte_bit52_set(void)
80 {
81 	report_prefix_push("PTE Bit 52 set");
82 
83 	protect_dat_entry(pagebuf, BIT(63 - 52), 5);
84 
85 	expect_pgm_int();
86 	tprot((unsigned long)pagebuf, 0);
87 	check_pgm_int_code(PGM_INT_CODE_TRANSLATION_SPEC);
88 
89 	unprotect_dat_entry(pagebuf, BIT(63 - 52), 5);
90 
91 	report_prefix_pop();
92 }
93 
94 int main(void)
95 {
96 	report_prefix_push("tprot");
97 
98 	setup_vm();
99 
100 	test_tprot_rw();
101 	test_tprot_ro();
102 	test_tprot_low_addr_prot();
103 	test_tprot_transl_unavail();
104 	test_tprot_transl_pte_bit52_set();
105 
106 	report_prefix_pop();
107 	return report_summary();
108 }
109