xref: /kvm-unit-tests/powerpc/spapr_vpa.c (revision e7324a48acdf3776e9bd9d727e0c2319bc5bf356)
1*e7324a48SNicholas Piggin /*
2*e7324a48SNicholas Piggin  * Test sPAPR "Per Virtual Processor Area" and H_REGISTER_VPA hypervisor call
3*e7324a48SNicholas Piggin  * (also known as VPA, also known as lppaca in the Linux pseries kernel).
4*e7324a48SNicholas Piggin  *
5*e7324a48SNicholas Piggin  * This work is licensed under the terms of the GNU LGPL, version 2.
6*e7324a48SNicholas Piggin  */
7*e7324a48SNicholas Piggin #include <libcflat.h>
8*e7324a48SNicholas Piggin #include <libfdt/libfdt.h>
9*e7324a48SNicholas Piggin #include <devicetree.h>
10*e7324a48SNicholas Piggin #include <util.h>
11*e7324a48SNicholas Piggin #include <alloc.h>
12*e7324a48SNicholas Piggin #include <asm/processor.h>
13*e7324a48SNicholas Piggin #include <asm/setup.h>
14*e7324a48SNicholas Piggin #include <asm/hcall.h>
15*e7324a48SNicholas Piggin #include <asm/vpa.h>
16*e7324a48SNicholas Piggin #include <asm/io.h> /* for endian accessors */
17*e7324a48SNicholas Piggin 
18*e7324a48SNicholas Piggin static int verbose;
19*e7324a48SNicholas Piggin 
20*e7324a48SNicholas Piggin static void print_vpa(struct vpa *vpa)
21*e7324a48SNicholas Piggin {
22*e7324a48SNicholas Piggin 	printf("VPA\n");
23*e7324a48SNicholas Piggin 	printf("descriptor:			0x%08x\n", be32_to_cpu(vpa->descriptor));
24*e7324a48SNicholas Piggin 	printf("size:				    0x%04x\n", be16_to_cpu(vpa->size));
25*e7324a48SNicholas Piggin 	printf("status:				      0x%02x\n", vpa->status);
26*e7324a48SNicholas Piggin 	printf("fru_node_id:			0x%08x\n", be32_to_cpu(vpa->fru_node_id));
27*e7324a48SNicholas Piggin 	printf("fru_proc_id:			0x%08x\n", be32_to_cpu(vpa->fru_proc_id));
28*e7324a48SNicholas Piggin 	printf("vhpn_change_counters:		0x%02x %02x %02x %02x %02x %02x %02x %02x\n", vpa->vhpn_change_counters[0], vpa->vhpn_change_counters[1], vpa->vhpn_change_counters[2], vpa->vhpn_change_counters[3], vpa->vhpn_change_counters[4], vpa->vhpn_change_counters[5], vpa->vhpn_change_counters[6], vpa->vhpn_change_counters[7]);
29*e7324a48SNicholas Piggin 	printf("vp_dispatch_count:		0x%08x\n", be32_to_cpu(vpa->vp_dispatch_count));
30*e7324a48SNicholas Piggin 	printf("vp_dispatch_dispersion:		0x%08x\n", be32_to_cpu(vpa->vp_dispatch_dispersion));
31*e7324a48SNicholas Piggin 	printf("vp_fault_count:			0x%08lx\n", be64_to_cpu(vpa->vp_fault_count));
32*e7324a48SNicholas Piggin 	printf("vp_fault_tb:			0x%08lx\n", be64_to_cpu(vpa->vp_fault_tb));
33*e7324a48SNicholas Piggin 	printf("purr_exprop_idle:		0x%08lx\n", be64_to_cpu(vpa->purr_exprop_idle));
34*e7324a48SNicholas Piggin 	printf("spurr_exprop_idle:		0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_idle));
35*e7324a48SNicholas Piggin 	printf("purr_exprop_busy:		0x%08lx\n", be64_to_cpu(vpa->purr_exprop_busy));
36*e7324a48SNicholas Piggin 	printf("spurr_exprop_busy:		0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_busy));
37*e7324a48SNicholas Piggin 	printf("purr_donate_idle:		0x%08lx\n", be64_to_cpu(vpa->purr_donate_idle));
38*e7324a48SNicholas Piggin 	printf("spurr_donate_idle:		0x%08lx\n", be64_to_cpu(vpa->spurr_donate_idle));
39*e7324a48SNicholas Piggin 	printf("purr_donate_busy:		0x%08lx\n", be64_to_cpu(vpa->purr_donate_busy));
40*e7324a48SNicholas Piggin 	printf("spurr_donate_busy:		0x%08lx\n", be64_to_cpu(vpa->spurr_donate_busy));
41*e7324a48SNicholas Piggin 	printf("vp_wait3_tb:			0x%08lx\n", be64_to_cpu(vpa->vp_wait3_tb));
42*e7324a48SNicholas Piggin 	printf("vp_wait2_tb:			0x%08lx\n", be64_to_cpu(vpa->vp_wait2_tb));
43*e7324a48SNicholas Piggin 	printf("vp_wait1_tb:			0x%08lx\n", be64_to_cpu(vpa->vp_wait1_tb));
44*e7324a48SNicholas Piggin 	printf("purr_exprop_adjunct_busy:	0x%08lx\n", be64_to_cpu(vpa->purr_exprop_adjunct_busy));
45*e7324a48SNicholas Piggin 	printf("spurr_exprop_adjunct_busy:	0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_adjunct_busy));
46*e7324a48SNicholas Piggin 	printf("purr_exprop_adjunct_idle:	0x%08lx\n", be64_to_cpu(vpa->purr_exprop_adjunct_idle));
47*e7324a48SNicholas Piggin 	printf("spurr_exprop_adjunct_idle:	0x%08lx\n", be64_to_cpu(vpa->spurr_exprop_adjunct_idle));
48*e7324a48SNicholas Piggin 	printf("adjunct_insns_executed:		0x%08lx\n", be64_to_cpu(vpa->adjunct_insns_executed));
49*e7324a48SNicholas Piggin 	printf("dtl_index:			0x%08lx\n", be64_to_cpu(vpa->dtl_index));
50*e7324a48SNicholas Piggin }
51*e7324a48SNicholas Piggin 
52*e7324a48SNicholas Piggin #define SUBFUNC_RESERVED	(0ULL << 45)
53*e7324a48SNicholas Piggin #define SUBFUNC_REGISTER	(1ULL << 45)
54*e7324a48SNicholas Piggin #define SUBFUNC_DEREGISTER	(5ULL << 45)
55*e7324a48SNicholas Piggin 
56*e7324a48SNicholas Piggin /**
57*e7324a48SNicholas Piggin  * Test the H_REGISTER_VPA h-call register/deregister calls.
58*e7324a48SNicholas Piggin  */
59*e7324a48SNicholas Piggin static void test_register_vpa(void)
60*e7324a48SNicholas Piggin {
61*e7324a48SNicholas Piggin 	struct vpa *vpa;
62*e7324a48SNicholas Piggin 	uint32_t cpuid = fdt_boot_cpuid_phys(dt_fdt());
63*e7324a48SNicholas Piggin 	int rc;
64*e7324a48SNicholas Piggin 
65*e7324a48SNicholas Piggin 	report_prefix_push("H_REGISTER_VPA");
66*e7324a48SNicholas Piggin 
67*e7324a48SNicholas Piggin 	vpa = memalign(4096, sizeof(*vpa));
68*e7324a48SNicholas Piggin 
69*e7324a48SNicholas Piggin 	memset(vpa, 0, sizeof(*vpa));
70*e7324a48SNicholas Piggin 
71*e7324a48SNicholas Piggin 	vpa->size = cpu_to_be16(sizeof(*vpa));
72*e7324a48SNicholas Piggin 
73*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_RESERVED, cpuid, vpa);
74*e7324a48SNicholas Piggin 	report(rc == H_PARAMETER, "Reserved sub-function fails with H_PARAMETER");
75*e7324a48SNicholas Piggin 
76*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, 0xbadbad, vpa);
77*e7324a48SNicholas Piggin 	report(rc == H_PARAMETER, "Register with invalid proc-no fails");
78*e7324a48SNicholas Piggin 
79*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, (void *)vpa + 8);
80*e7324a48SNicholas Piggin 	report(rc == H_PARAMETER, "Register with VPA not cacheline aligned fails");
81*e7324a48SNicholas Piggin 
82*e7324a48SNicholas Piggin 
83*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, (void *)vpa + 4096 - 128);
84*e7324a48SNicholas Piggin 	report(rc == H_PARAMETER, "Register with VPA spanning 4096 bytes fails");
85*e7324a48SNicholas Piggin 
86*e7324a48SNicholas Piggin 	vpa->size = cpu_to_be16(632);
87*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, (void *)vpa);
88*e7324a48SNicholas Piggin 	report(rc == H_PARAMETER, "Register with VPA size < 640 bytes fails");
89*e7324a48SNicholas Piggin 	vpa->size = cpu_to_be16(sizeof(*vpa));
90*e7324a48SNicholas Piggin 
91*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, PHYSICAL_END);
92*e7324a48SNicholas Piggin 	report(rc == H_PARAMETER, "Register with VPA outside guest real memory fails");
93*e7324a48SNicholas Piggin 
94*e7324a48SNicholas Piggin 
95*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, vpa);
96*e7324a48SNicholas Piggin 	report(rc == H_SUCCESS, "VPA registered");
97*e7324a48SNicholas Piggin 
98*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, cpuid, NULL);
99*e7324a48SNicholas Piggin 	report(rc == H_SUCCESS, "VPA deregistered");
100*e7324a48SNicholas Piggin 
101*e7324a48SNicholas Piggin 	/*
102*e7324a48SNicholas Piggin 	 * From PAPR: "note no check is made that a valid VPA registration
103*e7324a48SNicholas Piggin 	 * exists".
104*e7324a48SNicholas Piggin 	 */
105*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, cpuid, NULL);
106*e7324a48SNicholas Piggin 	report(rc == H_SUCCESS, "Deregister succeeds with no VPA registered");
107*e7324a48SNicholas Piggin 
108*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, 0xbadbad, NULL);
109*e7324a48SNicholas Piggin 	report(rc == H_PARAMETER, "Deregister with invalid proc-no fails");
110*e7324a48SNicholas Piggin 
111*e7324a48SNicholas Piggin 	report_prefix_pop();
112*e7324a48SNicholas Piggin }
113*e7324a48SNicholas Piggin 
114*e7324a48SNicholas Piggin /**
115*e7324a48SNicholas Piggin  * Test some VPA fields.
116*e7324a48SNicholas Piggin  */
117*e7324a48SNicholas Piggin static void test_vpa(void)
118*e7324a48SNicholas Piggin {
119*e7324a48SNicholas Piggin 	struct vpa *vpa;
120*e7324a48SNicholas Piggin 	uint32_t cpuid = fdt_boot_cpuid_phys(dt_fdt());
121*e7324a48SNicholas Piggin 	int disp_count1, disp_count2;
122*e7324a48SNicholas Piggin 	int rc;
123*e7324a48SNicholas Piggin 
124*e7324a48SNicholas Piggin 	report_prefix_push("VPA");
125*e7324a48SNicholas Piggin 
126*e7324a48SNicholas Piggin 	vpa = memalign(4096, sizeof(*vpa));
127*e7324a48SNicholas Piggin 
128*e7324a48SNicholas Piggin 	memset(vpa, 0, sizeof(*vpa));
129*e7324a48SNicholas Piggin 
130*e7324a48SNicholas Piggin 	vpa->size = cpu_to_be16(sizeof(*vpa));
131*e7324a48SNicholas Piggin 
132*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_REGISTER, cpuid, vpa);
133*e7324a48SNicholas Piggin 	if (rc != H_SUCCESS) {
134*e7324a48SNicholas Piggin 		report_skip("VPA could not be registered");
135*e7324a48SNicholas Piggin 		return;
136*e7324a48SNicholas Piggin 	}
137*e7324a48SNicholas Piggin 
138*e7324a48SNicholas Piggin 	if (verbose)
139*e7324a48SNicholas Piggin 		print_vpa(vpa);
140*e7324a48SNicholas Piggin 
141*e7324a48SNicholas Piggin 	disp_count1 = be32_to_cpu(vpa->vp_dispatch_count);
142*e7324a48SNicholas Piggin 	report(disp_count1 % 2 == 0, "Dispatch count is even while running");
143*e7324a48SNicholas Piggin 	msleep(100);
144*e7324a48SNicholas Piggin 	disp_count2 = be32_to_cpu(vpa->vp_dispatch_count);
145*e7324a48SNicholas Piggin 	report(disp_count1 != disp_count2, "Dispatch count increments over H_CEDE");
146*e7324a48SNicholas Piggin 
147*e7324a48SNicholas Piggin 	rc = hcall(H_REGISTER_VPA, SUBFUNC_DEREGISTER, cpuid, vpa);
148*e7324a48SNicholas Piggin 	if (rc != H_SUCCESS)
149*e7324a48SNicholas Piggin 		report_fail("Could not deregister after registration");
150*e7324a48SNicholas Piggin 
151*e7324a48SNicholas Piggin 	disp_count1 = be32_to_cpu(vpa->vp_dispatch_count);
152*e7324a48SNicholas Piggin 	report(disp_count1 % 2 == 1, "Dispatch count is odd after deregister");
153*e7324a48SNicholas Piggin 
154*e7324a48SNicholas Piggin 	report_prefix_pop();
155*e7324a48SNicholas Piggin }
156*e7324a48SNicholas Piggin 
157*e7324a48SNicholas Piggin int main(int argc, char *argv[])
158*e7324a48SNicholas Piggin {
159*e7324a48SNicholas Piggin 	int i;
160*e7324a48SNicholas Piggin 
161*e7324a48SNicholas Piggin 	for (i = 1; i < argc; i++) {
162*e7324a48SNicholas Piggin 		if (strcmp(argv[i], "-v") == 0) {
163*e7324a48SNicholas Piggin 			verbose = 1;
164*e7324a48SNicholas Piggin 		}
165*e7324a48SNicholas Piggin 	}
166*e7324a48SNicholas Piggin 
167*e7324a48SNicholas Piggin 	test_register_vpa();
168*e7324a48SNicholas Piggin 
169*e7324a48SNicholas Piggin 	test_vpa();
170*e7324a48SNicholas Piggin 
171*e7324a48SNicholas Piggin 	return report_summary();
172*e7324a48SNicholas Piggin }
173