xref: /kvm-unit-tests/lib/s390x/fault.c (revision a63889fe244838b7c13051227d5ea5f7cc325ed0)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Library to decode addressing related exceptions
4  *
5  * Copyright 2021 IBM Corp.
6  *
7  * Authors:
8  *    Janosch Frank <frankja@linux.ibm.com>
9  */
10 #include <libcflat.h>
11 #include <bitops.h>
12 #include <asm/arch_def.h>
13 #include <asm/page.h>
14 #include <fault.h>
15 
16 
print_decode_pgm_prot(union teid teid)17 static void print_decode_pgm_prot(union teid teid)
18 {
19 	switch (get_supp_on_prot_facility()) {
20 	case SOP_NONE:
21 	case SOP_BASIC:
22 		printf("Type: ?\n"); /* modern/relevant machines have ESOP */
23 		break;
24 	case SOP_ENHANCED_1:
25 		if (teid.sop_teid_predictable) {/* implies access list or DAT */
26 			if (teid.sop_acc_list)
27 				printf("Type: ACC\n");
28 			else
29 				printf("Type: DAT\n");
30 		} else {
31 			printf("Type: KEY or LAP\n");
32 		}
33 		break;
34 	case SOP_ENHANCED_2: {
35 		static const char * const prot_str[] = {
36 			"KEY or LAP",
37 			"DAT",
38 			"KEY",
39 			"ACC",
40 			"LAP",
41 			"IEP",
42 		};
43 		_Static_assert(ARRAY_SIZE(prot_str) == PROT_NUM_CODES, "ESOP2 prot codes");
44 		int prot_code = teid_esop2_prot_code(teid);
45 
46 		printf("Type: %s\n", prot_str[prot_code]);
47 		}
48 	}
49 }
50 
print_decode_teid(uint64_t raw_teid)51 void print_decode_teid(uint64_t raw_teid)
52 {
53 	union teid teid = { .val = raw_teid };
54 	bool dat = lowcore.pgm_old_psw.mask & PSW_MASK_DAT;
55 
56 	printf("Memory exception information:\n");
57 	printf("DAT: %s\n", dat ? "on" : "off");
58 
59 	printf("AS: ");
60 	switch (teid.asce_id) {
61 	case AS_PRIM:
62 		printf("Primary\n");
63 		break;
64 	case AS_ACCR:
65 		printf("Access Register\n");
66 		break;
67 	case AS_SECN:
68 		printf("Secondary\n");
69 		break;
70 	case AS_HOME:
71 		printf("Home\n");
72 		break;
73 	}
74 
75 	if (lowcore.pgm_int_code == PGM_INT_CODE_PROTECTION)
76 		print_decode_pgm_prot(teid);
77 
78 	/*
79 	 * If teid bit 61 is off for these two exception the reported
80 	 * address is unpredictable.
81 	 */
82 	if ((lowcore.pgm_int_code == PGM_INT_CODE_SECURE_STOR_ACCESS ||
83 	     lowcore.pgm_int_code == PGM_INT_CODE_SECURE_STOR_VIOLATION) &&
84 	    !teid.sop_teid_predictable) {
85 		printf("Address: %lx, unpredictable\n ", raw_teid & PAGE_MASK);
86 		return;
87 	}
88 	printf("TEID: %lx\n", raw_teid);
89 	printf("Address: %lx\n\n", raw_teid & PAGE_MASK);
90 }
91