Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
ACPI/AEST: Initial AEST driver
Browse files Browse the repository at this point in the history
Add support for parsing the ARM Error Source Table and basic handling of
errors reported through both memory mapped and system register interfaces.

This is closely based on this RFC series:
https://lkml.org/lkml/2019/7/2/781
but it has been modified for properly initializing PPIs for each CPU that
works properly with CPU hot plug.

Signed-off-by: Tyler Baicar <[email protected]>
  • Loading branch information
Tyler Baicar authored and adamliyi committed Mar 8, 2022
1 parent 1adef62 commit cd0dba5
Show file tree
Hide file tree
Showing 9 changed files with 591 additions and 1 deletion.
1 change: 1 addition & 0 deletions arch/arm64/configs/altra_5.15_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ CONFIG_ACPI_APEI_GHES=y
CONFIG_ACPI_APEI_PCIEAER=y
CONFIG_ACPI_APEI_MEMORY_FAILURE=y
CONFIG_ACPI_APEI_EINJ=m
CONFIG_ACPI_AEST=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_ARM64_CRYPTO=y
Expand Down
41 changes: 41 additions & 0 deletions arch/arm64/include/asm/ras.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_RAS_H
#define __ASM_RAS_H

#define ERR_STATUS_AV BIT(31)
#define ERR_STATUS_V BIT(30)
#define ERR_STATUS_UE BIT(29)
#define ERR_STATUS_ER BIT(28)
#define ERR_STATUS_OF BIT(27)
#define ERR_STATUS_MV BIT(26)
#define ERR_STATUS_CE_SHIFT 24
#define ERR_STATUS_CE_MASK 0x3
#define ERR_STATUS_DE BIT(23)
#define ERR_STATUS_PN BIT(22)
#define ERR_STATUS_UET_SHIFT 20
#define ERR_STATUS_UET_MASK 0x3
#define ERR_STATUS_IERR_SHIFT 8
#define ERR_STATUS_IERR_MASK 0xff
#define ERR_STATUS_SERR_SHIFT 0
#define ERR_STATUS_SERR_MASK 0xff

#define ERR_FR_CEC_SHIFT 12
#define ERR_FR_CEC_MASK 0x7

#define ERR_FR_8B_CEC BIT(1)
#define ERR_FR_16B_CEC BIT(2)

struct ras_ext_regs {
u64 err_fr;
u64 err_ctlr;
u64 err_status;
u64 err_addr;
u64 err_misc0;
u64 err_misc1;
u64 err_misc2;
u64 err_misc3;
};

void arch_arm_ras_report_error(void);

#endif /* __ASM_RAS_H */
2 changes: 1 addition & 1 deletion arch/arm64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
cpufeature.o alternative.o cacheinfo.o \
smp.o smp_spin_table.o topology.o smccc-call.o \
syscall.o proton-pack.o idreg-override.o idle.o \
patching.o
patching.o ras.o

targets += efi-entry.o

Expand Down
68 changes: 68 additions & 0 deletions arch/arm64/kernel/ras.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: GPL-2.0

#include <linux/kernel.h>
#include <linux/cpu.h>
#include <linux/smp.h>

#include <asm/ras.h>

void arch_arm_ras_report_error(void)
{
u64 num_records;
unsigned int i, cpu_num;
bool fatal = false;
struct ras_ext_regs regs;

if (!this_cpu_has_cap(ARM64_HAS_RAS_EXTN))
return;

cpu_num = get_cpu();
num_records = read_sysreg_s(SYS_ERRIDR_EL1);

for (i = 0; i < num_records; i++) {
write_sysreg_s(i, SYS_ERRSELR_EL1);
regs.err_status = read_sysreg_s(SYS_ERXSTATUS_EL1);

if (!(regs.err_status & ERR_STATUS_V))
continue;

pr_err("CPU%u: ERR%uSTATUS: 0x%llx\n", cpu_num, i,
regs.err_status);

if (regs.err_status & ERR_STATUS_AV) {
regs.err_addr = read_sysreg_s(SYS_ERXSTATUS_EL1);
pr_err("CPU%u: ERR%uADDR: 0x%llx\n", cpu_num, i,
regs.err_addr);
} else {
regs.err_addr = 0;
}

regs.err_fr = read_sysreg_s(SYS_ERXFR_EL1);
pr_err("CPU%u: ERR%uFR: 0x%llx\n", cpu_num, i, regs.err_fr);
regs.err_ctlr = read_sysreg_s(SYS_ERXCTLR_EL1);
pr_err("CPU%u: ERR%uCTLR: 0x%llx\n", cpu_num, i, regs.err_ctlr);

if (regs.err_status & ERR_STATUS_MV) {
regs.err_misc0 = read_sysreg_s(SYS_ERXMISC0_EL1);
pr_err("CPU%u: ERR%uMISC0: 0x%llx\n", cpu_num, i,
regs.err_misc0);
regs.err_misc1 = read_sysreg_s(SYS_ERXMISC1_EL1);
pr_err("CPU%u: ERR%uMISC1: 0x%llx\n", cpu_num, i,
regs.err_misc1);
}

/*
* In the future, we will treat UER conditions as potentially
* recoverable.
*/
if (regs.err_status & ERR_STATUS_UE)
fatal = true;

write_sysreg_s(regs.err_status, SYS_ERXSTATUS_EL1);
}

if (fatal)
panic("uncorrectable error encountered");

put_cpu();
}
3 changes: 3 additions & 0 deletions drivers/acpi/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ config ACPI_IORT

config ACPI_GTDT
bool

config ACPI_AEST
bool "ARM Error Source Table Support"
1 change: 1 addition & 0 deletions drivers/acpi/arm64/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_ACPI_IORT) += iort.o
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
obj-$(CONFIG_ACPI_AEST) += aest.o
obj-y += dma.o
Loading

0 comments on commit cd0dba5

Please sign in to comment.