xref: /kvm-unit-tests/lib/s390x/fault.c (revision cd719531ee2b3aae62a52cfe97aa6aa5286e4051)
11921c4c6SJanosch Frank /* SPDX-License-Identifier: GPL-2.0-only */
21921c4c6SJanosch Frank /*
31921c4c6SJanosch Frank  * Library to decode addressing related exceptions
41921c4c6SJanosch Frank  *
51921c4c6SJanosch Frank  * Copyright 2021 IBM Corp.
61921c4c6SJanosch Frank  *
71921c4c6SJanosch Frank  * Authors:
81921c4c6SJanosch Frank  *    Janosch Frank <frankja@linux.ibm.com>
91921c4c6SJanosch Frank  */
101921c4c6SJanosch Frank #include <libcflat.h>
111921c4c6SJanosch Frank #include <bitops.h>
121921c4c6SJanosch Frank #include <asm/arch_def.h>
131921c4c6SJanosch Frank #include <asm/page.h>
141921c4c6SJanosch Frank #include <fault.h>
151921c4c6SJanosch Frank 
161921c4c6SJanosch Frank /* Decodes the protection exceptions we'll most likely see */
171921c4c6SJanosch Frank static void print_decode_pgm_prot(uint64_t teid)
181921c4c6SJanosch Frank {
191921c4c6SJanosch Frank 	if (prot_is_lap(teid)) {
201921c4c6SJanosch Frank 		printf("Type: LAP\n");
211921c4c6SJanosch Frank 		return;
221921c4c6SJanosch Frank 	}
231921c4c6SJanosch Frank 
241921c4c6SJanosch Frank 	if (prot_is_iep(teid)) {
251921c4c6SJanosch Frank 		printf("Type: IEP\n");
261921c4c6SJanosch Frank 		return;
271921c4c6SJanosch Frank 	}
281921c4c6SJanosch Frank 
291921c4c6SJanosch Frank 	if (prot_is_datp(teid)) {
301921c4c6SJanosch Frank 		printf("Type: DAT\n");
311921c4c6SJanosch Frank 		return;
321921c4c6SJanosch Frank 	}
331921c4c6SJanosch Frank }
341921c4c6SJanosch Frank 
351921c4c6SJanosch Frank void print_decode_teid(uint64_t teid)
361921c4c6SJanosch Frank {
371921c4c6SJanosch Frank 	int asce_id = teid & 3;
38*cd719531SJanis Schoetterl-Glausch 	bool dat = lowcore.pgm_old_psw.mask & PSW_MASK_DAT;
391921c4c6SJanosch Frank 
401921c4c6SJanosch Frank 	printf("Memory exception information:\n");
411921c4c6SJanosch Frank 	printf("DAT: %s\n", dat ? "on" : "off");
421921c4c6SJanosch Frank 
431921c4c6SJanosch Frank 	printf("AS: ");
441921c4c6SJanosch Frank 	switch (asce_id) {
451921c4c6SJanosch Frank 	case AS_PRIM:
461921c4c6SJanosch Frank 		printf("Primary\n");
471921c4c6SJanosch Frank 		break;
481921c4c6SJanosch Frank 	case AS_ACCR:
491921c4c6SJanosch Frank 		printf("Access Register\n");
501921c4c6SJanosch Frank 		break;
511921c4c6SJanosch Frank 	case AS_SECN:
521921c4c6SJanosch Frank 		printf("Secondary\n");
531921c4c6SJanosch Frank 		break;
541921c4c6SJanosch Frank 	case AS_HOME:
551921c4c6SJanosch Frank 		printf("Home\n");
561921c4c6SJanosch Frank 		break;
571921c4c6SJanosch Frank 	}
581921c4c6SJanosch Frank 
59*cd719531SJanis Schoetterl-Glausch 	if (lowcore.pgm_int_code == PGM_INT_CODE_PROTECTION)
601921c4c6SJanosch Frank 		print_decode_pgm_prot(teid);
611921c4c6SJanosch Frank 
621921c4c6SJanosch Frank 	/*
631921c4c6SJanosch Frank 	 * If teid bit 61 is off for these two exception the reported
641921c4c6SJanosch Frank 	 * address is unpredictable.
651921c4c6SJanosch Frank 	 */
66*cd719531SJanis Schoetterl-Glausch 	if ((lowcore.pgm_int_code == PGM_INT_CODE_SECURE_STOR_ACCESS ||
67*cd719531SJanis Schoetterl-Glausch 	     lowcore.pgm_int_code == PGM_INT_CODE_SECURE_STOR_VIOLATION) &&
681921c4c6SJanosch Frank 	    !test_bit_inv(61, &teid)) {
691921c4c6SJanosch Frank 		printf("Address: %lx, unpredictable\n ", teid & PAGE_MASK);
701921c4c6SJanosch Frank 		return;
711921c4c6SJanosch Frank 	}
721921c4c6SJanosch Frank 	printf("TEID: %lx\n", teid);
731921c4c6SJanosch Frank 	printf("Address: %lx\n\n", teid & PAGE_MASK);
741921c4c6SJanosch Frank }
75