xref: /kvm-unit-tests/s390x/skey.c (revision f6b354fb16ebd5e47da775f6eb1b3a9ed87ad683)
1*f6b354fbSJanosch Frank /*
2*f6b354fbSJanosch Frank  * Storage key tests
3*f6b354fbSJanosch Frank  *
4*f6b354fbSJanosch Frank  * Copyright (c) 2018 IBM Corp
5*f6b354fbSJanosch Frank  *
6*f6b354fbSJanosch Frank  * Authors:
7*f6b354fbSJanosch Frank  *  Janosch Frank <frankja@linux.vnet.ibm.com>
8*f6b354fbSJanosch Frank  *
9*f6b354fbSJanosch Frank  * This code is free software; you can redistribute it and/or modify it
10*f6b354fbSJanosch Frank  * under the terms of the GNU Library General Public License version 2.
11*f6b354fbSJanosch Frank  */
12*f6b354fbSJanosch Frank #include <libcflat.h>
13*f6b354fbSJanosch Frank #include <asm/asm-offsets.h>
14*f6b354fbSJanosch Frank #include <asm/interrupt.h>
15*f6b354fbSJanosch Frank #include <asm/page.h>
16*f6b354fbSJanosch Frank #include <asm/facility.h>
17*f6b354fbSJanosch Frank #include <asm/mem.h>
18*f6b354fbSJanosch Frank 
19*f6b354fbSJanosch Frank 
20*f6b354fbSJanosch Frank static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
21*f6b354fbSJanosch Frank const unsigned long page0 = (unsigned long)pagebuf;
22*f6b354fbSJanosch Frank const unsigned long page1 = (unsigned long)(pagebuf + PAGE_SIZE);
23*f6b354fbSJanosch Frank 
24*f6b354fbSJanosch Frank static void test_set_mb(void)
25*f6b354fbSJanosch Frank {
26*f6b354fbSJanosch Frank 	union skey skey, ret1, ret2;
27*f6b354fbSJanosch Frank 	unsigned long addr = 0x10000 - 2 * PAGE_SIZE;
28*f6b354fbSJanosch Frank 	unsigned long end = 0x10000;
29*f6b354fbSJanosch Frank 
30*f6b354fbSJanosch Frank 	/* Multi block support came with EDAT 1 */
31*f6b354fbSJanosch Frank 	if (!test_facility(8))
32*f6b354fbSJanosch Frank 		return;
33*f6b354fbSJanosch Frank 
34*f6b354fbSJanosch Frank 	skey.val = 0x30;
35*f6b354fbSJanosch Frank 	while (addr < end)
36*f6b354fbSJanosch Frank 		addr = set_storage_key_mb(addr, skey.val);
37*f6b354fbSJanosch Frank 
38*f6b354fbSJanosch Frank 	ret1.val = get_storage_key(end - PAGE_SIZE);
39*f6b354fbSJanosch Frank 	ret2.val = get_storage_key(end - PAGE_SIZE * 2);
40*f6b354fbSJanosch Frank 	report("multi block", ret1.val == ret2.val && ret1.val == skey.val);
41*f6b354fbSJanosch Frank }
42*f6b354fbSJanosch Frank 
43*f6b354fbSJanosch Frank static void test_chg(void)
44*f6b354fbSJanosch Frank {
45*f6b354fbSJanosch Frank 	union skey skey1, skey2;
46*f6b354fbSJanosch Frank 
47*f6b354fbSJanosch Frank 	skey1.val = 0x30;
48*f6b354fbSJanosch Frank 	set_storage_key(page0, skey1.val, 0);
49*f6b354fbSJanosch Frank 	skey1.val = get_storage_key(page0);
50*f6b354fbSJanosch Frank 	pagebuf[0] = 3;
51*f6b354fbSJanosch Frank 	skey2.val = get_storage_key(page0);
52*f6b354fbSJanosch Frank 	report("chg bit test", !skey1.str.ch && skey2.str.ch);
53*f6b354fbSJanosch Frank }
54*f6b354fbSJanosch Frank 
55*f6b354fbSJanosch Frank static void test_set(void)
56*f6b354fbSJanosch Frank {
57*f6b354fbSJanosch Frank 	union skey skey, ret;
58*f6b354fbSJanosch Frank 
59*f6b354fbSJanosch Frank 	skey.val = 0x30;
60*f6b354fbSJanosch Frank 	ret.val = get_storage_key(page0);
61*f6b354fbSJanosch Frank 	set_storage_key(page0, skey.val, 0);
62*f6b354fbSJanosch Frank 	ret.val = get_storage_key(page0);
63*f6b354fbSJanosch Frank 	report("set key test", skey.val == ret.val);
64*f6b354fbSJanosch Frank }
65*f6b354fbSJanosch Frank 
66*f6b354fbSJanosch Frank static void test_priv(void)
67*f6b354fbSJanosch Frank {
68*f6b354fbSJanosch Frank 	union skey skey;
69*f6b354fbSJanosch Frank 
70*f6b354fbSJanosch Frank 	memset(pagebuf, 0, PAGE_SIZE * 2);
71*f6b354fbSJanosch Frank 	expect_pgm_int();
72*f6b354fbSJanosch Frank 	enter_pstate();
73*f6b354fbSJanosch Frank 	set_storage_key(page0, 0x30, 0);
74*f6b354fbSJanosch Frank 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
75*f6b354fbSJanosch Frank 
76*f6b354fbSJanosch Frank 	skey.val = get_storage_key(page0);
77*f6b354fbSJanosch Frank 	report("skey did not change on exception", skey.str.acc != 3);
78*f6b354fbSJanosch Frank 
79*f6b354fbSJanosch Frank 	expect_pgm_int();
80*f6b354fbSJanosch Frank 	enter_pstate();
81*f6b354fbSJanosch Frank 	get_storage_key(page0);
82*f6b354fbSJanosch Frank 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
83*f6b354fbSJanosch Frank }
84*f6b354fbSJanosch Frank 
85*f6b354fbSJanosch Frank int main(void)
86*f6b354fbSJanosch Frank {
87*f6b354fbSJanosch Frank 	report_prefix_push("skey");
88*f6b354fbSJanosch Frank 	test_priv();
89*f6b354fbSJanosch Frank 	test_set();
90*f6b354fbSJanosch Frank 	test_set_mb();
91*f6b354fbSJanosch Frank 	test_chg();
92*f6b354fbSJanosch Frank 	report_prefix_pop();
93*f6b354fbSJanosch Frank 	return report_summary();
94*f6b354fbSJanosch Frank }
95