xref: /kvm-unit-tests/s390x/diag10.c (revision c9a344475cffd9b4de9e5299fb6b2fd6af00003e)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Release pages hypercall tests (DIAG 10)
4  *
5  * Copyright (c) 2018 IBM Corp
6  *
7  * Authors:
8  *  Janosch Frank <frankja@linux.vnet.ibm.com>
9  */
10 
11 #include <libcflat.h>
12 #include <asm/asm-offsets.h>
13 #include <asm/interrupt.h>
14 #include <asm/page.h>
15 
16 static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
17 const unsigned long page0 = (unsigned long)pagebuf;
18 const unsigned long page1 = (unsigned long)(pagebuf + PAGE_SIZE);
19 
20 /* Tells the host to release pages from guest real addresses start to
21  * end. Parameters have to be page aligned, instruction is privileged.
22  */
diag10(unsigned long start,unsigned long end)23 static inline void diag10(unsigned long start, unsigned long end)
24 {
25 	asm volatile (
26 		"diag	%0,%1,0x10\n"
27 		: : "a" (start), "a" (end));
28 }
29 
30 /* Try freeing the prefix */
test_prefix(void)31 static void test_prefix(void)
32 {
33 	report_prefix_push("lowcore freeing");
34 
35 	report_prefix_push("0x0000/0x0000");
36 	expect_pgm_int();
37 	diag10(0, 0);
38 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
39 	report_prefix_pop();
40 
41 
42 	report_prefix_push("0x1000/0x1000");
43 	expect_pgm_int();
44 	diag10(0x1000, 0x1000);
45 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
46 	report_prefix_pop();
47 
48 	report_prefix_push("0x0000/0x1000");
49 	expect_pgm_int();
50 	diag10(0, 0x1000);
51 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
52 	report_prefix_pop();
53 
54 	report_prefix_pop();
55 }
56 
test_params(void)57 static void test_params(void)
58 {
59 	report_prefix_push("start/end");
60 
61 	/* end < start */
62 	report_prefix_push("end < start");
63 	expect_pgm_int();
64 	diag10(page1, page0);
65 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
66 	report_prefix_pop();
67 
68 	/* Unaligned start */
69 	report_prefix_push("unaligned start");
70 	expect_pgm_int();
71 	diag10((unsigned long) pagebuf + 42, page1);
72 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
73 	report_prefix_pop();
74 
75 	/* Unaligned end */
76 	report_prefix_push("unaligned end");
77 	expect_pgm_int();
78 	diag10(page0, (unsigned long) pagebuf + PAGE_SIZE + 42);
79 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
80 	report_prefix_pop();
81 
82 	report_prefix_pop();
83 }
84 
test_priv(void)85 static void test_priv(void)
86 {
87 	report_prefix_push("privileged");
88 	expect_pgm_int();
89 	enter_pstate();
90 	diag10(page0, page0);
91 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
92 	report_prefix_pop();
93 }
94 
main(void)95 int main(void)
96 {
97 	report_prefix_push("diag10");
98 	test_prefix();
99 	test_params();
100 	test_priv();
101 	return report_summary();
102 }
103