xref: /kvm-unit-tests/s390x/css.c (revision 610c15284a537484682adfb4b6d6313991ab954f)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Channel Subsystem tests
4  *
5  * Copyright (c) 2020 IBM Corp
6  *
7  * Authors:
8  *  Pierre Morel <pmorel@linux.ibm.com>
9  */
10 
11 #include <libcflat.h>
12 #include <interrupt.h>
13 #include <hardware.h>
14 
15 #include <asm/arch_def.h>
16 #include <asm/page.h>
17 
18 #include <malloc_io.h>
19 #include <css.h>
20 
21 #define DEFAULT_CU_TYPE		0x3832 /* virtio-ccw */
22 static unsigned long cu_type = DEFAULT_CU_TYPE;
23 
24 static int test_device_sid;
25 static struct senseid *senseid;
26 struct ccw1 *ccw;
27 
28 char alignment_test_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
29 
test_enumerate(void)30 static void test_enumerate(void)
31 {
32 	test_device_sid = css_enumerate();
33 	if (test_device_sid & SCHID_ONE) {
34 		report_pass("Schid of first I/O device: 0x%08x", test_device_sid);
35 		return;
36 	}
37 	report_fail("No I/O device found");
38 }
39 
test_enable(void)40 static void test_enable(void)
41 {
42 	int cc;
43 
44 	if (!test_device_sid) {
45 		report_skip("No device");
46 		return;
47 	}
48 
49 	cc = css_enable(test_device_sid, IO_SCH_ISC);
50 
51 	report(cc == 0, "Enable subchannel %08x", test_device_sid);
52 }
53 
54 /*
55  * test_sense
56  * Pre-requisites:
57  * - We need the test device as the first recognized
58  *   device by the enumeration.
59  */
test_sense(void)60 static void test_sense(void)
61 {
62 	int ret;
63 	int len;
64 
65 	if (!test_device_sid) {
66 		report_skip("No device");
67 		return;
68 	}
69 
70 	ret = css_enable(test_device_sid, IO_SCH_ISC);
71 	if (ret) {
72 		report_fail("Could not enable the subchannel: %08x",
73 			    test_device_sid);
74 		return;
75 	}
76 
77 	lowcore.io_int_param = 0;
78 
79 	senseid = alloc_io_mem(sizeof(*senseid), 0);
80 	if (!senseid) {
81 		report_fail("Allocation of senseid");
82 		return;
83 	}
84 
85 	ccw = ccw_alloc(CCW_CMD_SENSE_ID, senseid, sizeof(*senseid), CCW_F_SLI);
86 	if (!ccw) {
87 		report_fail("Allocation of CCW");
88 		goto error_ccw;
89 	}
90 
91 	ret = start_ccw1_chain(test_device_sid, ccw);
92 	if (ret) {
93 		report_fail("Starting CCW chain");
94 		goto error;
95 	}
96 
97 	if (wait_and_check_io_completion(test_device_sid) < 0)
98 		goto error;
99 
100 	/* Test transfer completion */
101 	report_prefix_push("ssch transfer completion");
102 
103 	ret = css_residual_count(test_device_sid);
104 
105 	if (ret < 0) {
106 		report_info("no valid residual count");
107 	} else if (ret != 0) {
108 		len = sizeof(*senseid) - ret;
109 		if (ret && len < CSS_SENSEID_COMMON_LEN) {
110 			report_fail("transferred a too short length: %d", ret);
111 			goto error;
112 		} else if (ret && len)
113 			report_info("transferred a shorter length: %d", len);
114 	}
115 
116 	if (senseid->reserved != 0xff) {
117 		report_fail("transferred garbage: 0x%02x", senseid->reserved);
118 		goto error;
119 	}
120 
121 	report_prefix_pop();
122 
123 	report_info("reserved 0x%02x cu_type 0x%04x cu_model 0x%02x dev_type 0x%04x dev_model 0x%02x",
124 		    senseid->reserved, senseid->cu_type, senseid->cu_model,
125 		    senseid->dev_type, senseid->dev_model);
126 
127 	report(senseid->cu_type == cu_type, "cu_type expected 0x%04x got 0x%04x",
128 	       (uint16_t)cu_type, senseid->cu_type);
129 
130 error:
131 	free_io_mem(ccw, sizeof(*ccw));
132 error_ccw:
133 	free_io_mem(senseid, sizeof(*senseid));
134 }
135 
sense_id(void)136 static void sense_id(void)
137 {
138 	assert(!start_ccw1_chain(test_device_sid, ccw));
139 
140 	assert(wait_and_check_io_completion(test_device_sid) >= 0);
141 }
142 
css_init(void)143 static void css_init(void)
144 {
145 	assert(register_io_int_func(css_irq_io) == 0);
146 	lowcore.io_int_param = 0;
147 
148 	report(get_chsc_scsc(), "Store Channel Characteristics");
149 }
150 
test_schm(void)151 static void test_schm(void)
152 {
153 	if (css_test_general_feature(CSSC_EXTENDED_MEASUREMENT_BLOCK))
154 		report_info("Extended measurement block available");
155 
156 	/* bits 59-63 of MB address must be 0  if MBU is defined */
157 	report_prefix_push("Unaligned operand");
158 	expect_pgm_int();
159 	schm((void *)0x01, SCHM_MBU);
160 	check_pgm_int_code(PGM_INT_CODE_OPERAND);
161 	report_prefix_pop();
162 
163 	/* bits 36-61 of register 1 (flags) must be 0 */
164 	report_prefix_push("Bad flags");
165 	expect_pgm_int();
166 	schm(NULL, 0xfffffffc);
167 	check_pgm_int_code(PGM_INT_CODE_OPERAND);
168 	report_prefix_pop();
169 
170 	/* SCHM is a privilege operation */
171 	report_prefix_push("Privilege");
172 	enter_pstate();
173 	expect_pgm_int();
174 	schm(NULL, SCHM_MBU);
175 	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
176 	report_prefix_pop();
177 
178 	/* Normal operation */
179 	report_prefix_push("Normal operation");
180 	schm(NULL, SCHM_MBU);
181 	report_pass("SCHM call without address");
182 	report_prefix_pop();
183 }
184 
185 #define SCHM_UPDATE_CNT 10
start_measuring(uint64_t mbo,uint16_t mbi,bool fmt1)186 static bool start_measuring(uint64_t mbo, uint16_t mbi, bool fmt1)
187 {
188 	int i;
189 
190 	senseid = alloc_io_mem(sizeof(*senseid), 0);
191 	assert(senseid);
192 
193 	ccw = ccw_alloc(CCW_CMD_SENSE_ID, senseid, sizeof(*senseid), CCW_F_SLI);
194 	assert(ccw);
195 
196 	if (!css_enable_mb(test_device_sid, mbo, mbi, PMCW_MBUE, fmt1)) {
197 		report_abort("Enabling measurement block failed");
198 		return false;
199 	}
200 
201 	for (i = 0; i < SCHM_UPDATE_CNT; i++)
202 		sense_id();
203 
204 	free_io_mem(ccw, sizeof(*ccw));
205 	free_io_mem(senseid, sizeof(*senseid));
206 
207 	return true;
208 }
209 
210 /*
211  * test_schm_fmt0:
212  * With measurement block format 0 a memory space is shared
213  * by all subchannels, each subchannel can provide an index
214  * for the measurement block facility to store the measurements.
215  */
test_schm_fmt0(void)216 static void test_schm_fmt0(void)
217 {
218 	struct measurement_block_format0 *mb0;
219 	int shared_mb_size = 2 * sizeof(struct measurement_block_format0);
220 
221 	if (!test_device_sid) {
222 		report_skip("No device");
223 		return;
224 	}
225 
226 	/* Allocate zeroed Measurement block */
227 	mb0 = alloc_io_mem(shared_mb_size, 0);
228 	if (!mb0) {
229 		report_abort("measurement_block_format0 allocation failed");
230 		return;
231 	}
232 
233 	schm(NULL, 0); /* Stop any previous measurement */
234 	schm(mb0, SCHM_MBU);
235 
236 	/* Expect success */
237 	report_prefix_push("Valid MB address and index 0");
238 	report(start_measuring(0, 0, false) &&
239 	       mb0->ssch_rsch_count == SCHM_UPDATE_CNT,
240 	       "SSCH measured %d", mb0->ssch_rsch_count);
241 	report_prefix_pop();
242 
243 	/* Clear the measurement block for the next test */
244 	memset(mb0, 0, shared_mb_size);
245 
246 	/* Expect success */
247 	report_prefix_push("Valid MB address and index 1");
248 	if (start_measuring(0, 1, false))
249 		report(mb0[1].ssch_rsch_count == SCHM_UPDATE_CNT,
250 		       "SSCH measured %d", mb0[1].ssch_rsch_count);
251 	report_prefix_pop();
252 
253 	/* Stop the measurement */
254 	css_disable_mb(test_device_sid);
255 	schm(NULL, 0);
256 
257 	free_io_mem(mb0, shared_mb_size);
258 }
259 
msch_with_wrong_fmt1_mbo(unsigned int schid,uint64_t mb)260 static void msch_with_wrong_fmt1_mbo(unsigned int schid, uint64_t mb)
261 {
262 	struct pmcw *pmcw = &schib.pmcw;
263 	int cc;
264 
265 	/* Read the SCHIB for this subchannel */
266 	cc = stsch(schid, &schib);
267 	if (cc) {
268 		report_fail("stsch: sch %08x failed with cc=%d", schid, cc);
269 		return;
270 	}
271 
272 	/* Update the SCHIB to enable the measurement block */
273 	pmcw->flags |= PMCW_MBUE;
274 	pmcw->flags2 |= PMCW_MBF1;
275 	schib.mbo = mb;
276 
277 	/* Tell the CSS we want to modify the subchannel */
278 	expect_pgm_int();
279 	cc = msch(schid, &schib);
280 	check_pgm_int_code(PGM_INT_CODE_OPERAND);
281 }
282 
283 /*
284  * test_schm_fmt1:
285  * With measurement block format 1 the measurement block is
286  * dedicated to a subchannel.
287  */
test_schm_fmt1(void)288 static void test_schm_fmt1(void)
289 {
290 	struct measurement_block_format1 *mb1;
291 
292 	if (!test_device_sid) {
293 		report_skip("No device");
294 		return;
295 	}
296 
297 	if (!css_test_general_feature(CSSC_EXTENDED_MEASUREMENT_BLOCK)) {
298 		report_skip("Extended measurement block not available");
299 		return;
300 	}
301 
302 	/* Allocate zeroed Measurement block */
303 	mb1 = alloc_io_mem(sizeof(struct measurement_block_format1), 0);
304 	if (!mb1) {
305 		report_abort("measurement_block_format1 allocation failed");
306 		return;
307 	}
308 
309 	schm(NULL, 0); /* Stop any previous measurement */
310 	schm(0, SCHM_MBU);
311 
312 	/* Expect error for non aligned MB */
313 	report_prefix_push("Unaligned MB origin");
314 	msch_with_wrong_fmt1_mbo(test_device_sid, (uint64_t)mb1 + 1);
315 	report_prefix_pop();
316 
317 	/* Clear the measurement block for the next test */
318 	memset(mb1, 0, sizeof(*mb1));
319 
320 	/* Expect success */
321 	report_prefix_push("Valid MB origin");
322 	if (start_measuring((u64)mb1, 0, true))
323 		report(mb1->ssch_rsch_count == SCHM_UPDATE_CNT,
324 		       "SSCH measured %d", mb1->ssch_rsch_count);
325 	report_prefix_pop();
326 
327 	/* Stop the measurement */
328 	css_disable_mb(test_device_sid);
329 	schm(NULL, 0);
330 
331 	free_io_mem(mb1, sizeof(struct measurement_block_format1));
332 }
333 
test_msch(void)334 static void test_msch(void)
335 {
336 	int invalid_pmcw_flags[] = {0, 1, 6, 7};
337 	struct schib test_schib;
338 	uint16_t old_pmcw_flags;
339 	const int align_to = 4;
340 	int invalid_flag;
341 	int cc;
342 
343 	if (!test_device_sid) {
344 		report_skip("No device");
345 		return;
346 	}
347 
348 	cc = stsch(test_device_sid, &schib);
349 	if (cc) {
350 		report_fail("stsch: sch %08x failed with cc=%d", test_device_sid, cc);
351 		return;
352 	}
353 
354 	report_prefix_push("Unaligned");
355 	for (int i = 1; i < align_to; i *= 2) {
356 		report_prefix_pushf("%d", i);
357 
358 		expect_pgm_int();
359 		msch(test_device_sid, (struct schib *)(alignment_test_page + i));
360 		check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
361 
362 		report_prefix_pop();
363 	}
364 	report_prefix_pop();
365 
366 	report_prefix_push("Invalid SCHIB");
367 	old_pmcw_flags = schib.pmcw.flags;
368 	for (int i = 0; i < ARRAY_SIZE(invalid_pmcw_flags); i++) {
369 		invalid_flag = invalid_pmcw_flags[i];
370 
371 		report_prefix_pushf("PMCW flag bit %d set", invalid_flag);
372 
373 		schib.pmcw.flags = old_pmcw_flags | BIT(15 - invalid_flag);
374 		expect_pgm_int();
375 		msch(test_device_sid, &schib);
376 		check_pgm_int_code(PGM_INT_CODE_OPERAND);
377 
378 		cc = stsch(test_device_sid, &test_schib);
379 		report(!cc, "STSCH succeeded");
380 		report(!(test_schib.pmcw.flags & BIT(15 - invalid_flag)), "Clear on STSCH");
381 
382 		report_prefix_pop();
383 	}
384 	report_prefix_pop();
385 
386 	schib.pmcw.flags = old_pmcw_flags;
387 }
388 
check_stcrw_no_crw_available(void)389 static void check_stcrw_no_crw_available(void)
390 {
391 	uint32_t crw = 0xfeedc0fe;
392 	int cc;
393 
394 	report_prefix_push("No CRW available");
395 	cc = stcrw(&crw);
396 	report(cc == 1, "cc == 1");
397 	report(!crw, "stored zeroes in crw");
398 	report_prefix_pop();
399 }
400 
check_stcrw_crw_available(void)401 static int check_stcrw_crw_available(void)
402 {
403 	const uint32_t magic = 0xfeedc0fe;
404 	uint32_t crw = magic;
405 	int cc;
406 
407 	report_prefix_push("CRW available");
408 	cc = stcrw(&crw);
409 	report(!cc, "cc is zero");
410 	report(crw != magic, "stored crw");
411 	report_prefix_pop();
412 
413 	return crw;
414 }
415 
crw_get_rsc(uint32_t crw)416 static uint32_t crw_get_rsc(uint32_t crw)
417 {
418 	const int rsc_begin = 4;
419 	const int rsc_end = 8;
420 
421 	return (crw & GENMASK(31 - rsc_begin, 31 - rsc_end)) >> 24;
422 }
423 
424 #define CRW_RSC_CHP 4
test_stcrw(void)425 static void test_stcrw(void)
426 {
427 	const int align_to = 4;
428 	int res;
429 	uint32_t crw;
430 
431 	if (!test_device_sid) {
432 		report_skip("No device");
433 		return;
434 	}
435 
436 	report_prefix_push("Unaligned");
437 	for (int i = 1; i < align_to; i *= 2) {
438 		report_prefix_pushf("%d", i);
439 
440 		expect_pgm_int();
441 		stcrw((uint32_t *)(alignment_test_page + i));
442 		check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
443 
444 		report_prefix_pop();
445 	}
446 	report_prefix_pop();
447 
448 	report_prefix_push("No CRW available initally");
449 	check_stcrw_no_crw_available();
450 	report_prefix_pop();
451 
452 	res = css_generate_crw(test_device_sid);
453 	if (res) {
454 		report_skip("Couldn't generate CRW");
455 		report_prefix_pop();
456 		return;
457 	}
458 
459 	crw = check_stcrw_crw_available();
460 
461 	report_prefix_push("CRW available");
462 	report(crw_get_rsc(crw) == CRW_RSC_CHP, "CRW has Channel Path RSC");
463 	report_prefix_pop();
464 
465 	report_prefix_push("No more CRWs pending");
466 	check_stcrw_no_crw_available();
467 	report_prefix_pop();
468 }
469 
test_ssch(void)470 static void test_ssch(void)
471 {
472 	const int align_to = 4;
473 	struct orb orb;
474 
475 	if (!test_device_sid) {
476 		report_skip("No device");
477 		return;
478 	}
479 
480 	report_prefix_push("Unaligned");
481 	for (int i = 1; i < align_to; i *= 2) {
482 		report_prefix_pushf("%d", i);
483 
484 		expect_pgm_int();
485 		ssch(test_device_sid, (struct orb *)(alignment_test_page + i));
486 		check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
487 
488 		report_prefix_pop();
489 	}
490 	report_prefix_pop();
491 
492 	report_prefix_push("Invalid ORB");
493 
494 	memset(&orb, 0xff, sizeof(orb));
495 	expect_pgm_int();
496 	ssch(test_device_sid, &orb);
497 	check_pgm_int_code(PGM_INT_CODE_OPERAND);
498 
499 	report_prefix_pop();
500 }
501 
test_stsch(void)502 static void test_stsch(void)
503 {
504 	const int align_to = 4;
505 	struct schib schib;
506 	int cc;
507 
508 	if (!test_device_sid) {
509 		report_skip("No device");
510 		return;
511 	}
512 
513 	report_prefix_push("Unaligned");
514 	for (int i = 1; i < align_to; i *= 2) {
515 		report_prefix_pushf("%d", i);
516 
517 		expect_pgm_int();
518 		stsch(test_device_sid, (struct schib *)(alignment_test_page + i));
519 		check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
520 
521 		report_prefix_pop();
522 	}
523 	report_prefix_pop();
524 
525 	report_prefix_push("Invalid subchannel number");
526 	cc = stsch(0x0001ffff, &schib);
527 	report(cc == 3, "Channel not operational");
528 	report_prefix_pop();
529 
530 	/*
531 	 * No matter if multiple-subchannel-set facility is installed, bit 47
532 	 * always needs to be 1.
533 	 */
534 	report_prefix_push("Bit 47 in SID is zero");
535 	expect_pgm_int();
536 	stsch(0x0000ffff, &schib);
537 	check_pgm_int_code(PGM_INT_CODE_OPERAND);
538 	report_prefix_pop();
539 }
540 
541 /*
542  * According to architecture MSCH does ignore bit 5 of the second word
543  * but STSCH will store bit 5 as zero.
544  */
test_pmcw_bit5(void)545 static void test_pmcw_bit5(void)
546 {
547 	int cc;
548 	uint16_t old_pmcw_flags;
549 
550 	cc = stsch(test_device_sid, &schib);
551 	if (cc) {
552 		report_fail("stsch: sch %08x failed with cc=%d", test_device_sid, cc);
553 		return;
554 	}
555 	old_pmcw_flags = schib.pmcw.flags;
556 
557 	report_prefix_push("Bit 5 set");
558 
559 	schib.pmcw.flags = old_pmcw_flags | BIT(15 - 5);
560 	cc = msch(test_device_sid, &schib);
561 	report(!cc, "MSCH cc == 0");
562 
563 	cc = stsch(test_device_sid, &schib);
564 	report(!cc, "STSCH cc == 0");
565 	report(!(schib.pmcw.flags & BIT(15 - 5)), "STSCH PMCW Bit 5 is clear");
566 
567 	report_prefix_pop();
568 
569 	report_prefix_push("Bit 5 clear");
570 
571 	schib.pmcw.flags = old_pmcw_flags & ~BIT(15 - 5);
572 	cc = msch(test_device_sid, &schib);
573 	report(!cc, "MSCH cc == 0");
574 
575 	cc = stsch(test_device_sid, &schib);
576 	report(!cc, "STSCH cc == 0");
577 	report(!(schib.pmcw.flags & BIT(15 - 5)), "STSCH PMCW Bit 5 is clear");
578 
579 	report_prefix_pop();
580 }
581 
test_tsch(void)582 static void test_tsch(void)
583 {
584 	const int align_to = 4;
585 	struct irb irb;
586 	int cc;
587 
588 	if (!test_device_sid) {
589 		report_skip("No device");
590 		return;
591 	}
592 
593 	report_prefix_push("Unaligned");
594 	for (int i = 1; i < align_to; i *= 2) {
595 		report_prefix_pushf("%d", i);
596 
597 		expect_pgm_int();
598 		tsch(test_device_sid, (struct irb *)(alignment_test_page + i));
599 		check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
600 
601 		report_prefix_pop();
602 	}
603 	report_prefix_pop();
604 
605 	report_prefix_push("Invalid subchannel number");
606 	cc = tsch(0x0001ffff, &irb);
607 	report(cc == 3, "Channel not operational");
608 	report_prefix_pop();
609 
610 	report_prefix_push("Bit 47 in SID is zero");
611 	expect_pgm_int();
612 	tsch(0x0000ffff, &irb);
613 	check_pgm_int_code(PGM_INT_CODE_OPERAND);
614 	report_prefix_pop();
615 }
616 
617 static struct {
618 	const char *name;
619 	void (*func)(void);
620 } tests[] = {
621 	/* The css_init test is needed to initialize the CSS Characteristics */
622 	{ "initialize CSS (chsc)", css_init },
623 	{ "enumerate (stsch)", test_enumerate },
624 	{ "enable (msch)", test_enable },
625 	{ "sense (ssch/tsch)", test_sense },
626 	{ "measurement block (schm)", test_schm },
627 	{ "measurement block format0", test_schm_fmt0 },
628 	{ "measurement block format1", test_schm_fmt1 },
629 	{ "msch", test_msch },
630 	{ "stcrw", test_stcrw },
631 	{ "ssch", test_ssch },
632 	{ "stsch", test_stsch },
633 	{ "pmcw bit 5 ignored", test_pmcw_bit5 },
634 	{ "tsch", test_tsch },
635 	{ NULL, NULL }
636 };
637 
main(int argc,char * argv[])638 int main(int argc, char *argv[])
639 {
640 	int i;
641 
642 	report_prefix_push("Channel Subsystem");
643 
644 	/* There's no guarantee where our devices are without qemu */
645 	if (!host_is_qemu()) {
646 		report_skip("Not running under QEMU");
647 		goto done;
648 	}
649 
650 	enable_io_isc(0x80 >> IO_SCH_ISC);
651 	for (i = 0; tests[i].name; i++) {
652 		report_prefix_push(tests[i].name);
653 		tests[i].func();
654 		report_prefix_pop();
655 	}
656 
657 done:
658 	report_prefix_pop();
659 	return report_summary();
660 }
661