xref: /kvm-unit-tests/s390x/sck.c (revision 5bf99cb38621d44b0a7d2204ecd9326b3209ab73)
1*adf6cc0cSNico Boehr /* SPDX-License-Identifier: GPL-2.0-only */
2*adf6cc0cSNico Boehr /*
3*adf6cc0cSNico Boehr  * Perform Set Clock tests
4*adf6cc0cSNico Boehr  *
5*adf6cc0cSNico Boehr  * Copyright IBM Corp. 2022
6*adf6cc0cSNico Boehr  *
7*adf6cc0cSNico Boehr  * Authors:
8*adf6cc0cSNico Boehr  *  Nico Boehr <nrb@linux.ibm.com>
9*adf6cc0cSNico Boehr  */
10*adf6cc0cSNico Boehr #include <libcflat.h>
11*adf6cc0cSNico Boehr #include <uv.h>
12*adf6cc0cSNico Boehr #include <asm/interrupt.h>
13*adf6cc0cSNico Boehr #include <asm/time.h>
14*adf6cc0cSNico Boehr 
test_priv(void)15*adf6cc0cSNico Boehr static void test_priv(void)
16*adf6cc0cSNico Boehr {
17*adf6cc0cSNico Boehr 	uint64_t time_to_set_privileged = 0xfacef00dcafe0000,
18*adf6cc0cSNico Boehr 	    time_to_set_nonprivileged = 0xcafe0000,
19*adf6cc0cSNico Boehr 	    time_verify;
20*adf6cc0cSNico Boehr 	int cc;
21*adf6cc0cSNico Boehr 
22*adf6cc0cSNico Boehr 	report_prefix_push("privileged");
23*adf6cc0cSNico Boehr 	cc = sck(&time_to_set_privileged);
24*adf6cc0cSNico Boehr 	report(!cc, "set clock cc=%d", cc);
25*adf6cc0cSNico Boehr 
26*adf6cc0cSNico Boehr 	cc = stck(&time_verify);
27*adf6cc0cSNico Boehr 	report(!cc, "store clock cc=%d", cc);
28*adf6cc0cSNico Boehr 	report(time_verify > time_to_set_privileged,
29*adf6cc0cSNico Boehr 	       "privileged set affected the clock");
30*adf6cc0cSNico Boehr 	report_prefix_pop();
31*adf6cc0cSNico Boehr 
32*adf6cc0cSNico Boehr 	report_prefix_push("unprivileged");
33*adf6cc0cSNico Boehr 	expect_pgm_int();
34*adf6cc0cSNico Boehr 	enter_pstate();
35*adf6cc0cSNico Boehr 	sck(&time_to_set_nonprivileged);
36*adf6cc0cSNico Boehr 	leave_pstate();
37*adf6cc0cSNico Boehr 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
38*adf6cc0cSNico Boehr 
39*adf6cc0cSNico Boehr 	cc = stck(&time_verify);
40*adf6cc0cSNico Boehr 	report(!cc, "store clock cc=%d", cc);
41*adf6cc0cSNico Boehr 	report(time_verify > time_to_set_privileged,
42*adf6cc0cSNico Boehr 	       "unprivileged set did not affect the clock");
43*adf6cc0cSNico Boehr 	report_prefix_pop();
44*adf6cc0cSNico Boehr }
45*adf6cc0cSNico Boehr 
test_align(void)46*adf6cc0cSNico Boehr static void test_align(void)
47*adf6cc0cSNico Boehr {
48*adf6cc0cSNico Boehr 	const int align_to = 8;
49*adf6cc0cSNico Boehr 	char unalign[sizeof(uint64_t) + align_to] __attribute__((aligned(8)));
50*adf6cc0cSNico Boehr 
51*adf6cc0cSNico Boehr 	report_prefix_push("Unaligned operand");
52*adf6cc0cSNico Boehr 	for (int i = 1; i < align_to; i *= 2) {
53*adf6cc0cSNico Boehr 		report_prefix_pushf("%d", i);
54*adf6cc0cSNico Boehr 		expect_pgm_int();
55*adf6cc0cSNico Boehr 		sck((uint64_t *)(unalign + i));
56*adf6cc0cSNico Boehr 		check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
57*adf6cc0cSNico Boehr 		report_prefix_pop();
58*adf6cc0cSNico Boehr 	}
59*adf6cc0cSNico Boehr 	report_prefix_pop();
60*adf6cc0cSNico Boehr }
61*adf6cc0cSNico Boehr 
test_set(void)62*adf6cc0cSNico Boehr static void test_set(void)
63*adf6cc0cSNico Boehr {
64*adf6cc0cSNico Boehr 	uint64_t start = 0, end = 0, time = 0xcafef00dbeef;
65*adf6cc0cSNico Boehr 	const uint64_t ticks_per_ms = 1000 << 12, ms_to_wait = 5;
66*adf6cc0cSNico Boehr 	int cc;
67*adf6cc0cSNico Boehr 
68*adf6cc0cSNico Boehr 	report_prefix_push("set");
69*adf6cc0cSNico Boehr 
70*adf6cc0cSNico Boehr 	cc = sck(&time);
71*adf6cc0cSNico Boehr 	report(!cc, "set clock cc=%d", cc);
72*adf6cc0cSNico Boehr 
73*adf6cc0cSNico Boehr 	cc = stck(&start);
74*adf6cc0cSNico Boehr 	report(!cc, "store start clock cc=%d", cc);
75*adf6cc0cSNico Boehr 	report(start >= time, "start >= set value");
76*adf6cc0cSNico Boehr 
77*adf6cc0cSNico Boehr 	mdelay(ms_to_wait);
78*adf6cc0cSNico Boehr 
79*adf6cc0cSNico Boehr 	cc = stck(&end);
80*adf6cc0cSNico Boehr 	report(!cc, "store end clock cc=%d", cc);
81*adf6cc0cSNico Boehr 	report(end > time, "end > set value");
82*adf6cc0cSNico Boehr 
83*adf6cc0cSNico Boehr 	report(end - start > (ticks_per_ms * ms_to_wait), "Advances");
84*adf6cc0cSNico Boehr 
85*adf6cc0cSNico Boehr 	report_prefix_pop();
86*adf6cc0cSNico Boehr }
87*adf6cc0cSNico Boehr 
main(void)88*adf6cc0cSNico Boehr int main(void)
89*adf6cc0cSNico Boehr {
90*adf6cc0cSNico Boehr 	report_prefix_push("sck");
91*adf6cc0cSNico Boehr 
92*adf6cc0cSNico Boehr 	if (uv_os_is_guest()) {
93*adf6cc0cSNico Boehr 		report_skip("Test unsupported under PV");
94*adf6cc0cSNico Boehr 		goto out;
95*adf6cc0cSNico Boehr 	}
96*adf6cc0cSNico Boehr 
97*adf6cc0cSNico Boehr 	test_align();
98*adf6cc0cSNico Boehr 	test_set();
99*adf6cc0cSNico Boehr 	test_priv();
100*adf6cc0cSNico Boehr 
101*adf6cc0cSNico Boehr out:
102*adf6cc0cSNico Boehr 	report_prefix_pop();
103*adf6cc0cSNico Boehr 	return report_summary();
104*adf6cc0cSNico Boehr }
105