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