xref: /kvm-unit-tests/s390x/diag10.c (revision 2352e986e4599bc4842c225762c78fa49f18648d)
1 /*
2  * Release pages hypercall tests (DIAG 10)
3  *
4  * Copyright (c) 2018 IBM Corp
5  *
6  * Authors:
7  *  Janosch Frank <frankja@linux.vnet.ibm.com>
8  *
9  * This code is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Library General Public License version 2.
11  */
12 
13 #include <libcflat.h>
14 #include <asm/asm-offsets.h>
15 #include <asm/interrupt.h>
16 #include <asm/page.h>
17 
18 static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
19 const unsigned long page0 = (unsigned long)pagebuf;
20 const unsigned long page1 = (unsigned long)(pagebuf + PAGE_SIZE);
21 
22 /* Tells the host to release pages from guest real addresses start to
23  * end. Parameters have to be page aligned, instruction is privileged.
24  */
25 static inline void diag10(unsigned long start, unsigned long end)
26 {
27 	asm volatile (
28 		"diag	%0,%1,0x10\n"
29 		: : "a" (start), "a" (end));
30 }
31 
32 /* Try freeing the prefix */
33 static void test_prefix(void)
34 {
35 	expect_pgm_int();
36 	diag10(0, 0);
37 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
38 
39 	expect_pgm_int();
40 	diag10(0x1000, 0x1000);
41 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
42 
43 	expect_pgm_int();
44 	diag10(0, 0x1000);
45 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
46 }
47 
48 static void test_params(void)
49 {
50 	/* end < start */
51 	expect_pgm_int();
52 	diag10(page1, page0);
53 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
54 
55 	/* Unaligned start */
56 	expect_pgm_int();
57 	diag10((unsigned long) pagebuf + 42, page1);
58 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
59 
60 	/* Unaligned end */
61 	expect_pgm_int();
62 	diag10(page0, (unsigned long) pagebuf + PAGE_SIZE + 42);
63 	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
64 }
65 
66 static void test_priv(void)
67 {
68 	expect_pgm_int();
69 	enter_pstate();
70 	diag10(page0, page0);
71 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
72 }
73 
74 int main(void)
75 {
76 	report_prefix_push("diag10");
77 	test_prefix();
78 	test_params();
79 	test_priv();
80 	return report_summary();
81 }
82