// SPDX-License-Identifier: GPL-2.0
/*
 * UEFI Common Platform Error Record (CPER) support
 *
 * Copyright (C) 2010, Intel Corp.
 *	Author: Huang Ying <ying.huang@intel.com>
 *
 * CPER is the format used to describe platform hardware error by
 * various tables, such as ERST, BERT and HEST etc.
 *
 * For more information about CPER, please refer to Appendix N of UEFI
 * Specification version 2.4.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/cper.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <linux/pci.h>
#include <linux/aer.h>
#include <linux/printk.h>
#include <linux/bcd.h>
#include <acpi/ghes.h>
#include <ras/ras_event.h>
#include <cxl/event.h>

/*
 * CPER record ID need to be unique even after reboot, because record
 * ID is used as index for ERST storage, while CPER records from
 * multiple boot may co-exist in ERST.
 */
u64 cper_next_record_id(void)
{
	static atomic64_t seq;

	if (!atomic64_read(&seq)) {
		time64_t time = ktime_get_real_seconds();

		/*
		 * This code is unlikely to still be needed in year 2106,
		 * but just in case, let's use a few more bits for timestamps
		 * after y2038 to be sure they keep increasing monotonically
		 * for the next few hundred years...
		 */
		if (time < 0x80000000)
			atomic64_set(&seq, (ktime_get_real_seconds()) << 32);
		else
			atomic64_set(&seq, 0x8000000000000000ull |
					   ktime_get_real_seconds() << 24);
	}

	return atomic64_inc_return(&seq);
}
EXPORT_SYMBOL_GPL(cper_next_record_id);

static const char * const severity_strs[] = {
	"recoverable",
	"fatal",
	"corrected",
	"info",
};

const char *cper_severity_str(unsigned int severity)
{
	return severity < ARRAY_SIZE(severity_strs) ?
		severity_strs[severity] : "unknown";
}
EXPORT_SYMBOL_GPL(cper_severity_str);

/*
 * cper_print_bits - print strings for set bits
 * @pfx: prefix for each line, including log level and prefix string
 * @bits: bit mask
 * @strs: string array, indexed by bit position
 * @strs_size: size of the string array: @strs
 *
 * For each set bit in @bits, print the corresponding string in @strs.
 * If the output length is longer than 80, multiple line will be
 * printed, with @pfx is printed at the beginning of each line.
 */
void cper_print_bits(const char *pfx, unsigned int bits,
		     const char * const strs[], unsigned int strs_size)
{
	int i, len = 0;
	const char *str;
	char buf[84];

	for (i = 0; i < strs_size; i++) {
		if (!(bits & (1U << i)))
			continue;
		str = strs[i];
		if (!str)
			continue;
		if (len && len + strlen(str) + 2 > 80) {
			printk("%s\n", buf);
			len = 0;
		}
		if (!len)
			len = snprintf(buf, sizeof(buf), "%s%s", pfx, str);
		else
			len += scnprintf(buf+len, sizeof(buf)-len, ", %s", str);
	}
	if (len)
		printk("%s\n", buf);
}

static const char * const proc_type_strs[] = {
	"IA32/X64",
	"IA64",
	"ARM",
};

static const char * const proc_isa_strs[] = {
	"IA32",
	"IA64",
	"X64",
	"ARM A32/T32",
	"ARM A64",
};

const char * const cper_proc_error_type_strs[] = {
	"cache error",
	"TLB error",
	"bus error",
	"micro-architectural error",
};

static const char * const proc_op_strs[] = {
	"unknown or generic",
	"data read",
	"data write",
	"instruction execution",
};

static const char * const proc_flag_strs[] = {
	"restartable",
	"precise IP",
	"overflow",
	"corrected",
};

static void cper_print_proc_generic(const char *pfx,
				    const struct cper_sec_proc_generic *proc)
{
	if (proc->validation_bits & CPER_PROC_VALID_TYPE)
		printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type,
		       proc->proc_type < ARRAY_SIZE(proc_type_strs) ?
		       proc_type_strs[proc->proc_type] : "unknown");
	if (proc->validation_bits & CPER_PROC_VALID_ISA)
		printk("%s""processor_isa: %d, %s\n", pfx, proc->proc_isa,
		       proc->proc_isa < ARRAY_SIZE(proc_isa_strs) ?
		       proc_isa_strs[proc->proc_isa] : "unknown");
	if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) {
		printk("%s""error_type: 0x%02x\n", pfx, proc->proc_error_type);
		cper_print_bits(pfx, proc->proc_error_type,
				cper_proc_error_type_strs,
				ARRAY_SIZE(cper_proc_error_type_strs));
	}
	if (proc->validation_bits & CPER_PROC_VALID_OPERATION)
		printk("%s""operation: %d, %s\n", pfx, proc->operation,
		       proc->operation < ARRAY_SIZE(proc_op_strs) ?
		       proc_op_strs[proc->operation] : "unknown");
	if (proc->validation_bits & CPER_PROC_VALID_FLAGS) {
		printk("%s""flags: 0x%02x\n", pfx, proc->flags);
		cper_print_bits(pfx, proc->flags, proc_flag_strs,
				ARRAY_SIZE(proc_flag_strs));
	}
	if (proc->validation_bits & CPER_PROC_VALID_LEVEL)
		printk("%s""level: %d\n", pfx, proc->level);
	if (proc->validation_bits & CPER_PROC_VALID_VERSION)
		printk("%s""version_info: 0x%016llx\n", pfx, proc->cpu_version);
	if (proc->validation_bits & CPER_PROC_VALID_ID)
		printk("%s""processor_id: 0x%016llx\n", pfx, proc->proc_id);
	if (proc->validation_bits & CPER_PROC_VALID_TARGET_ADDRESS)
		printk("%s""target_address: 0x%016llx\n",
		       pfx, proc->target_addr);
	if (proc->validation_bits & CPER_PROC_VALID_REQUESTOR_ID)
		printk("%s""requestor_id: 0x%016llx\n",
		       pfx, proc->requestor_id);
	if (proc->validation_bits & CPER_PROC_VALID_RESPONDER_ID)
		printk("%s""responder_id: 0x%016llx\n",
		       pfx, proc->responder_id);
	if (proc->validation_bits & CPER_PROC_VALID_IP)
		printk("%s""IP: 0x%016llx\n", pfx, proc->ip);
}

static const char * const mem_err_type_strs[] = {
	"unknown",
	"no error",
	"single-bit ECC",
	"multi-bit ECC",
	"single-symbol chipkill ECC",
	"multi-symbol chipkill ECC",
	"master abort",
	"target abort",
	"parity error",
	"watchdog timeout",
	"invalid address",
	"mirror Broken",
	"memory sparing",
	"scrub corrected error",
	"scrub uncorrected error",
	"physical memory map-out event",
};

const char *cper_mem_err_type_str(unsigned int etype)
{
	return etype < ARRAY_SIZE(mem_err_type_strs) ?
		mem_err_type_strs[etype] : "unknown";
}
EXPORT_SYMBOL_GPL(cper_mem_err_type_str);

const char *cper_mem_err_status_str(u64 status)
{
	switch ((status >> 8) & 0xff) {
	case  1:	return "Error detected internal to the component";
	case  4:	return "Storage error in DRAM memory";
	case  5:	return "Storage error in TLB";
	case  6:	return "Storage error in cache";
	case  7:	return "Error in one or more functional units";
	case  8:	return "Component failed self test";
	case  9:	return "Overflow or undervalue of internal queue";
	case 16:	return "Error detected in the bus";
	case 17:	return "Virtual address not found on IO-TLB or IO-PDIR";
	case 18:	return "Improper access error";
	case 19:	return "Access to a memory address which is not mapped to any component";
	case 20:	return "Loss of Lockstep";
	case 21:	return "Response not associated with a request";
	case 22:	return "Bus parity error - must also set the A, C, or D Bits";
	case 23:	return "Detection of a protocol error";
	case 24:	return "Detection of a PATH_ERROR";
	case 25:	return "Bus operation timeout";
	case 26:	return "A read was issued to data that has been poisoned";
	default:	return "Reserved";
	}
}
EXPORT_SYMBOL_GPL(cper_mem_err_status_str);

int cper_mem_err_location(struct cper_mem_err_compact *mem, char *msg)
{
	u32 len, n;

	if (!msg)
		return 0;

	n = 0;
	len = CPER_REC_LEN;
	if (mem->validation_bits & CPER_MEM_VALID_NODE)
		n += scnprintf(msg + n, len - n, "node:%d ", mem->node);
	if (mem->validation_bits & CPER_MEM_VALID_CARD)
		n += scnprintf(msg + n, len - n, "card:%d ", mem->card);
	if (mem->validation_bits & CPER_MEM_VALID_MODULE)
		n += scnprintf(msg + n, len - n, "module:%d ", mem->module);
	if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
		n += scnprintf(msg + n, len - n, "rank:%d ", mem->rank);
	if (mem->validation_bits & CPER_MEM_VALID_BANK)
		n += scnprintf(msg + n, len - n, "bank:%d ", mem->bank);
	if (mem->validation_bits & CPER_MEM_VALID_BANK_GROUP)
		n += scnprintf(msg + n, len - n, "bank_group:%d ",
			       mem->bank >> CPER_MEM_BANK_GROUP_SHIFT);
	if (mem->validation_bits & CPER_MEM_VALID_BANK_ADDRESS)
		n += scnprintf(msg + n, len - n, "bank_address:%d ",
			       mem->bank & CPER_MEM_BANK_ADDRESS_MASK);
	if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
		n += scnprintf(msg + n, len - n, "device:%d ", mem->device);
	if (mem->validation_bits & (CPER_MEM_VALID_ROW | CPER_MEM_VALID_ROW_EXT)) {
		u32 row = mem->row;

		row |= cper_get_mem_extension(mem->validation_bits, mem->extended);
		n += scnprintf(msg + n, len - n, "row:%d ", row);
	}
	if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
		n += scnprintf(msg + n, len - n, "column:%d ", mem->column);
	if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
		n += scnprintf(msg + n, len - n, "bit_position:%d ",
			       mem->bit_pos);
	if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
		n += scnprintf(msg + n, len - n, "requestor_id:0x%016llx ",
			       mem->requestor_id);
	if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
		n += scnprintf(msg + n, len - n, "responder_id:0x%016llx ",
			       mem->responder_id);
	if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
		n += scnprintf(msg + n, len - n, "target_id:0x%016llx ",
			       mem->target_id);
	if (mem->validation_bits & CPER_MEM_VALID_CHIP_ID)
		n += scnprintf(msg + n, len - n, "chip_id:%d ",
			       mem->extended >> CPER_MEM_CHIP_ID_SHIFT);

	return n;
}
EXPORT_SYMBOL_GPL(cper_mem_err_location);

int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg)
{
	u32 len, n;
	const char *bank = NULL, *device = NULL;

	if (!msg || !(mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE))
		return 0;

	len = CPER_REC_LEN;
	dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
	if (bank && device)
		n = snprintf(msg, len, "DIMM location: %s %s ", bank, device);
	else
		n = snprintf(msg, len,
			     "DIMM location: not present. DMI handle: 0x%.4x ",
			     mem->mem_dev_handle);

	return n;
}
EXPORT_SYMBOL_GPL(cper_dimm_err_location);

void cper_mem_err_pack(const struct cper_sec_mem_err *mem,
		       struct cper_mem_err_compact *cmem)
{
	cmem->validation_bits = mem->validation_bits;
	cmem->node = mem->node;
	cmem->card = mem->card;
	cmem->module = mem->module;
	cmem->bank = mem->bank;
	cmem->device = mem->device;
	cmem->row = mem->row;
	cmem->column = mem->column;
	cmem->bit_pos = mem->bit_pos;
	cmem->requestor_id = mem->requestor_id;
	cmem->responder_id = mem->responder_id;
	cmem->target_id = mem->target_id;
	cmem->extended = mem->extended;
	cmem->rank = mem->rank;
	cmem->mem_array_handle = mem->mem_array_handle;
	cmem->mem_dev_handle = mem->mem_dev_handle;
}
EXPORT_SYMBOL_GPL(cper_mem_err_pack);

const char *cper_mem_err_unpack(struct trace_seq *p,
				struct cper_mem_err_compact *cmem)
{
	const char *ret = trace_seq_buffer_ptr(p);
	char rcd_decode_str[CPER_REC_LEN];

	if (cper_mem_err_location(cmem, rcd_decode_str))
		trace_seq_printf(p, "%s", rcd_decode_str);
	if (cper_dimm_err_location(cmem, rcd_decode_str))
		trace_seq_printf(p, "%s", rcd_decode_str);
	trace_seq_putc(p, '\0');

	return ret;
}

static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem,
	int len)
{
	struct cper_mem_err_compact cmem;
	char rcd_decode_str[CPER_REC_LEN];

	/* Don't trust UEFI 2.1/2.2 structure with bad validation bits */
	if (len == sizeof(struct cper_sec_mem_err_old) &&
	    (mem->validation_bits & ~(CPER_MEM_VALID_RANK_NUMBER - 1))) {
		pr_err(FW_WARN "valid bits set for fields beyond structure\n");
		return;
	}
	if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
		printk("%s error_status: %s (0x%016llx)\n",
		       pfx, cper_mem_err_status_str(mem->error_status),
		       mem->error_status);
	if (mem->validation_bits & CPER_MEM_VALID_PA)
		printk("%s""physical_address: 0x%016llx\n",
		       pfx, mem->physical_addr);
	if (mem->validation_bits & CPER_MEM_VALID_PA_MASK)
		printk("%s""physical_address_mask: 0x%016llx\n",
		       pfx, mem->physical_addr_mask);
	cper_mem_err_pack(mem, &cmem);
	if (cper_mem_err_location(&cmem, rcd_decode_str))
		printk("%s%s\n", pfx, rcd_decode_str);
	if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
		u8 etype = mem->error_type;
		printk("%s""error_type: %d, %s\n", pfx, etype,
		       cper_mem_err_type_str(etype));
	}
	if (cper_dimm_err_location(&cmem, rcd_decode_str))
		printk("%s%s\n", pfx, rcd_decode_str);
}

static const char * const pcie_port_type_strs[] = {
	"PCIe end point",
	"legacy PCI end point",
	"unknown",
	"unknown",
	"root port",
	"upstream switch port",
	"downstream switch port",
	"PCIe to PCI/PCI-X bridge",
	"PCI/PCI-X to PCIe bridge",
	"root complex integrated endpoint device",
	"root complex event collector",
};

static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
			    const struct acpi_hest_generic_data *gdata)
{
	if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
		printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
		       pcie->port_type < ARRAY_SIZE(pcie_port_type_strs) ?
		       pcie_port_type_strs[pcie->port_type] : "unknown");
	if (pcie->validation_bits & CPER_PCIE_VALID_VERSION)
		printk("%s""version: %d.%d\n", pfx,
		       pcie->version.major, pcie->version.minor);
	if (pcie->validation_bits & CPER_PCIE_VALID_COMMAND_STATUS)
		printk("%s""command: 0x%04x, status: 0x%04x\n", pfx,
		       pcie->command, pcie->status);
	if (pcie->validation_bits & CPER_PCIE_VALID_DEVICE_ID) {
		const __u8 *p;
		printk("%s""device_id: %04x:%02x:%02x.%x\n", pfx,
		       pcie->device_id.segment, pcie->device_id.bus,
		       pcie->device_id.device, pcie->device_id.function);
		printk("%s""slot: %d\n", pfx,
		       pcie->device_id.slot >> CPER_PCIE_SLOT_SHIFT);
		printk("%s""secondary_bus: 0x%02x\n", pfx,
		       pcie->device_id.secondary_bus);
		printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx,
		       pcie->device_id.vendor_id, pcie->device_id.device_id);
		p = pcie->device_id.class_code;
		printk("%s""class_code: %02x%02x%02x\n", pfx, p[2], p[1], p[0]);
	}
	if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER)
		printk("%s""serial number: 0x%04x, 0x%04x\n", pfx,
		       pcie->serial_number.lower, pcie->serial_number.upper);
	if (pcie->validation_bits & CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS)
		printk(
	"%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
	pfx, pcie->bridge.secondary_status, pcie->bridge.control);

	/*
	 * Print all valid AER info. Record may be from BERT (boot-time) or GHES (run-time).
	 *
	 * Fatal errors call __ghes_panic() before AER handler prints this.
	 */
	if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) {
		struct aer_capability_regs *aer;

		aer = (struct aer_capability_regs *)pcie->aer_info;
		printk("%saer_cor_status: 0x%08x, aer_cor_mask: 0x%08x\n",
		       pfx, aer->cor_status, aer->cor_mask);
		printk("%saer_uncor_status: 0x%08x, aer_uncor_mask: 0x%08x\n",
		       pfx, aer->uncor_status, aer->uncor_mask);
		printk("%saer_uncor_severity: 0x%08x\n",
		       pfx, aer->uncor_severity);
		printk("%sTLP Header: %08x %08x %08x %08x\n", pfx,
		       aer->header_log.dw[0], aer->header_log.dw[1],
		       aer->header_log.dw[2], aer->header_log.dw[3]);
	}
}

static const char * const fw_err_rec_type_strs[] = {
	"IPF SAL Error Record",
	"SOC Firmware Error Record Type1 (Legacy CrashLog Support)",
	"SOC Firmware Error Record Type2",
};

static void cper_print_fw_err(const char *pfx,
			      struct acpi_hest_generic_data *gdata,
			      const struct cper_sec_fw_err_rec_ref *fw_err)
{
	void *buf = acpi_hest_get_payload(gdata);
	u32 offset, length = gdata->error_data_length;

	printk("%s""Firmware Error Record Type: %s\n", pfx,
	       fw_err->record_type < ARRAY_SIZE(fw_err_rec_type_strs) ?
	       fw_err_rec_type_strs[fw_err->record_type] : "unknown");
	printk("%s""Revision: %d\n", pfx, fw_err->revision);

	/* Record Type based on UEFI 2.7 */
	if (fw_err->revision == 0) {
		printk("%s""Record Identifier: %08llx\n", pfx,
		       fw_err->record_identifier);
	} else if (fw_err->revision == 2) {
		printk("%s""Record Identifier: %pUl\n", pfx,
		       &fw_err->record_identifier_guid);
	}

	/*
	 * The FW error record may contain trailing data beyond the
	 * structure defined by the specification. As the fields
	 * defined (and hence the offset of any trailing data) vary
	 * with the revision, set the offset to account for this
	 * variation.
	 */
	if (fw_err->revision == 0) {
		/* record_identifier_guid not defined */
		offset = offsetof(struct cper_sec_fw_err_rec_ref,
				  record_identifier_guid);
	} else if (fw_err->revision == 1) {
		/* record_identifier not defined */
		offset = offsetof(struct cper_sec_fw_err_rec_ref,
				  record_identifier);
	} else {
		offset = sizeof(*fw_err);
	}

	buf += offset;
	length -= offset;

	print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, buf, length, true);
}

static void cper_print_tstamp(const char *pfx,
				   struct acpi_hest_generic_data_v300 *gdata)
{
	__u8 hour, min, sec, day, mon, year, century, *timestamp;

	if (gdata->validation_bits & ACPI_HEST_GEN_VALID_TIMESTAMP) {
		timestamp = (__u8 *)&(gdata->time_stamp);
		sec       = bcd2bin(timestamp[0]);
		min       = bcd2bin(timestamp[1]);
		hour      = bcd2bin(timestamp[2]);
		day       = bcd2bin(timestamp[4]);
		mon       = bcd2bin(timestamp[5]);
		year      = bcd2bin(timestamp[6]);
		century   = bcd2bin(timestamp[7]);

		printk("%s%ststamp: %02d%02d-%02d-%02d %02d:%02d:%02d\n", pfx,
		       (timestamp[3] & 0x1 ? "precise " : "imprecise "),
		       century, year, mon, day, hour, min, sec);
	}
}

struct ignore_section {
	guid_t guid;
	const char *name;
};

static const struct ignore_section ignore_sections[] = {
	{ .guid = CPER_SEC_CXL_GEN_MEDIA_GUID, .name = "CXL General Media Event" },
	{ .guid = CPER_SEC_CXL_DRAM_GUID, .name = "CXL DRAM Event" },
	{ .guid = CPER_SEC_CXL_MEM_MODULE_GUID, .name = "CXL Memory Module Event" },
};

static void
cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata,
			   int sec_no)
{
	guid_t *sec_type = (guid_t *)gdata->section_type;
	__u16 severity;
	char newpfx[64];

	if (acpi_hest_get_version(gdata) >= 3)
		cper_print_tstamp(pfx, (struct acpi_hest_generic_data_v300 *)gdata);

	severity = gdata->error_severity;
	printk("%s""Error %d, type: %s\n", pfx, sec_no,
	       cper_severity_str(severity));
	if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
		printk("%s""fru_id: %pUl\n", pfx, gdata->fru_id);
	if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
		printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text);

	snprintf(newpfx, sizeof(newpfx), "%s ", pfx);

	for (int i = 0; i < ARRAY_SIZE(ignore_sections); i++) {
		if (guid_equal(sec_type, &ignore_sections[i].guid)) {
			printk("%ssection_type: %s\n", newpfx, ignore_sections[i].name);
			return;
		}
	}

	if (guid_equal(sec_type, &CPER_SEC_PROC_GENERIC)) {
		struct cper_sec_proc_generic *proc_err = acpi_hest_get_payload(gdata);

		printk("%s""section_type: general processor error\n", newpfx);
		if (gdata->error_data_length >= sizeof(*proc_err))
			cper_print_proc_generic(newpfx, proc_err);
		else
			goto err_section_too_small;
	} else if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
		struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);

		printk("%s""section_type: memory error\n", newpfx);
		if (gdata->error_data_length >=
		    sizeof(struct cper_sec_mem_err_old))
			cper_print_mem(newpfx, mem_err,
				       gdata->error_data_length);
		else
			goto err_section_too_small;
	} else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
		struct cper_sec_pcie *pcie = acpi_hest_get_payload(gdata);

		printk("%s""section_type: PCIe error\n", newpfx);
		if (gdata->error_data_length >= sizeof(*pcie))
			cper_print_pcie(newpfx, pcie, gdata);
		else
			goto err_section_too_small;
#if defined(CONFIG_ARM64) || defined(CONFIG_ARM)
	} else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
		struct cper_sec_proc_arm *arm_err = acpi_hest_get_payload(gdata);

		printk("%ssection_type: ARM processor error\n", newpfx);
		if (gdata->error_data_length >= sizeof(*arm_err))
			cper_print_proc_arm(newpfx, arm_err);
		else
			goto err_section_too_small;
#endif
#if defined(CONFIG_UEFI_CPER_X86)
	} else if (guid_equal(sec_type, &CPER_SEC_PROC_IA)) {
		struct cper_sec_proc_ia *ia_err = acpi_hest_get_payload(gdata);

		printk("%ssection_type: IA32/X64 processor error\n", newpfx);
		if (gdata->error_data_length >= sizeof(*ia_err))
			cper_print_proc_ia(newpfx, ia_err);
		else
			goto err_section_too_small;
#endif
	} else if (guid_equal(sec_type, &CPER_SEC_FW_ERR_REC_REF)) {
		struct cper_sec_fw_err_rec_ref *fw_err = acpi_hest_get_payload(gdata);

		printk("%ssection_type: Firmware Error Record Reference\n",
		       newpfx);
		/* The minimal FW Error Record contains 16 bytes */
		if (gdata->error_data_length >= SZ_16)
			cper_print_fw_err(newpfx, gdata, fw_err);
		else
			goto err_section_too_small;
	} else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) {
		struct cxl_cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata);

		printk("%ssection_type: CXL Protocol Error\n", newpfx);
		if (gdata->error_data_length >= sizeof(*prot_err))
			cxl_cper_print_prot_err(newpfx, prot_err);
		else
			goto err_section_too_small;
	} else {
		const void *err = acpi_hest_get_payload(gdata);

		printk("%ssection type: unknown, %pUl\n", newpfx, sec_type);
		printk("%ssection length: %#x\n", newpfx,
		       gdata->error_data_length);
		print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, 4, err,
			       gdata->error_data_length, true);
	}

	return;

err_section_too_small:
	pr_err(FW_WARN "error section length is too small\n");
}

void cper_estatus_print(const char *pfx,
			const struct acpi_hest_generic_status *estatus)
{
	struct acpi_hest_generic_data *gdata;
	int sec_no = 0;
	char newpfx[64];
	__u16 severity;

	severity = estatus->error_severity;
	if (severity == CPER_SEV_CORRECTED)
		printk("%s%s\n", pfx,
		       "It has been corrected by h/w "
		       "and requires no further action");
	printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
	snprintf(newpfx, sizeof(newpfx), "%s ", pfx);

	apei_estatus_for_each_section(estatus, gdata) {
		cper_estatus_print_section(newpfx, gdata, sec_no);
		sec_no++;
	}
}
EXPORT_SYMBOL_GPL(cper_estatus_print);

int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus)
{
	if (estatus->data_length &&
	    estatus->data_length < sizeof(struct acpi_hest_generic_data))
		return -EINVAL;
	if (estatus->raw_data_length &&
	    estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
		return -EINVAL;

	return 0;
}
EXPORT_SYMBOL_GPL(cper_estatus_check_header);

int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
{
	struct acpi_hest_generic_data *gdata;
	unsigned int data_len, record_size;
	int rc;

	rc = cper_estatus_check_header(estatus);
	if (rc)
		return rc;

	data_len = estatus->data_length;

	apei_estatus_for_each_section(estatus, gdata) {
		if (acpi_hest_get_size(gdata) > data_len)
			return -EINVAL;

		record_size = acpi_hest_get_record_size(gdata);
		if (record_size > data_len)
			return -EINVAL;

		data_len -= record_size;
	}
	if (data_len)
		return -EINVAL;

	return 0;
}
EXPORT_SYMBOL_GPL(cper_estatus_check);
