Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1497556 > unrolled thread
| Started by | Tyler Baicar <tbaicar@codeaurora.org> |
|---|---|
| First post | 2016-10-07 23:40 +0200 |
| Last post | 2016-10-14 01:50 +0200 |
| Articles | 20 on this page of 41 — 10 participants |
Back to article view | Back to linux.kernel
[PATCH V3 00/10] Add UEFI 2.6 and ACPI 6.1 updates for RAS on ARM64 Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
[PATCH V3 07/10] efi: print unrecognized CPER section Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
[PATCH V3 08/10] ras: acpi / apei: generate trace event for unrecognized CPER section Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
Re: [PATCH V3 08/10] ras: acpi / apei: generate trace event for unrecognized CPER section Punit Agrawal <punit.agrawal@arm.com> - 2016-10-13 13:00 +0200
Re: [PATCH V3 08/10] ras: acpi / apei: generate trace event for unrecognized CPER section "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-13 22:20 +0200
[PATCH V3 10/10] arm64: KVM: add guest SEA support Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
Re: [PATCH V3 10/10] arm64: KVM: add guest SEA support Punit Agrawal <punit.agrawal@arm.com> - 2016-10-13 15:20 +0200
Re: [PATCH V3 10/10] arm64: KVM: add guest SEA support "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-13 22:20 +0200
Re: [PATCH V3 10/10] arm64: KVM: add guest SEA support Punit Agrawal <punit.agrawal@arm.com> - 2016-10-14 11:50 +0200
Re: [PATCH V3 10/10] arm64: KVM: add guest SEA support "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-15 00:00 +0200
[PATCH V3 03/10] efi: parse ARMv8 processor error Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
[PATCH V3 01/10] acpi: apei: read ack upon ghes record consumption Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
Re: [PATCH V3 01/10] acpi: apei: read ack upon ghes record consumption Punit Agrawal <punit.agrawal@arm.com> - 2016-10-12 20:20 +0200
Re: [PATCH V3 01/10] acpi: apei: read ack upon ghes record consumption "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-13 16:00 +0200
[PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 Punit Agrawal <punit.agrawal@arm.com> - 2016-10-12 20:10 +0200
Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-13 16:10 +0200
Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 Punit Agrawal <punit.agrawal@arm.com> - 2016-10-14 11:50 +0200
Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 Hanjun Guo <hanjun.guo@linaro.org> - 2016-10-18 14:50 +0200
Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 "Abdulhamid, Harb" <harba@codeaurora.org> - 2016-10-19 19:00 +0200
Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 Hanjun Guo <guohanjun@huawei.com> - 2016-10-23 11:20 +0200
Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 Hanjun Guo <hanjun.guo@linaro.org> - 2016-10-18 15:10 +0200
Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 "Abdulhamid, Harb" <harba@codeaurora.org> - 2016-10-19 19:20 +0200
[PATCH V3 04/10] arm64: exception: handle Synchronous External Abort Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
Re: [PATCH V3 04/10] arm64: exception: handle Synchronous External Abort Punit Agrawal <punit.agrawal@arm.com> - 2016-10-12 19:50 +0200
Re: [PATCH V3 04/10] arm64: exception: handle Synchronous External Abort "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-13 16:00 +0200
[PATCH V3 09/10] trace, ras: add ARM processor error trace event Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
Re: [PATCH V3 09/10] trace, ras: add ARM processor error trace event Steven Rostedt <rostedt@goodmis.org> - 2016-10-07 23:50 +0200
Re: [PATCH V3 09/10] trace, ras: add ARM processor error trace event "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-12 23:30 +0200
[PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 Suzuki K Poulose <Suzuki.Poulose@arm.com> - 2016-10-11 19:40 +0200
Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-13 00:30 +0200
Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 Suzuki K Poulose <Suzuki.Poulose@arm.com> - 2016-10-13 11:00 +0200
Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-13 21:50 +0200
Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 Suzuki K Poulose <Suzuki.Poulose@arm.com> - 2016-10-14 18:30 +0200
Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 Mark Rutland <mark.rutland@arm.com> - 2016-10-14 18:50 +0200
Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 Russell King - ARM Linux <linux@armlinux.org.uk> - 2016-10-11 21:10 +0200
Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-13 00:20 +0200
[PATCH V3 06/10] acpi: apei: panic OS with fatal error status block Tyler Baicar <tbaicar@codeaurora.org> - 2016-10-07 23:40 +0200
Re: [PATCH V3 06/10] acpi: apei: panic OS with fatal error status block Suzuki K Poulose <Suzuki.Poulose@arm.com> - 2016-10-13 15:10 +0200
Re: [PATCH V3 06/10] acpi: apei: panic OS with fatal error status block "Baicar, Tyler" <tbaicar@codeaurora.org> - 2016-10-14 01:50 +0200
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Hanjun Guo <guohanjun@huawei.com> |
|---|---|
| Date | 2016-10-23 11:20 +0200 |
| Subject | Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 |
| Message-ID | <svn6F-7u1-3@gated-at.bofh.it> |
| In reply to | #1504135 |
Hi Harb, On 2016/10/20 0:59, Abdulhamid, Harb wrote: > On 10/18/2016 8:44 AM, Hanjun Guo wrote: >> Hi Tyler, >> >> On 2016/10/8 5:31, Tyler Baicar wrote: >>> ARM APEI extension proposal added SEA (Synchrounous External >>> Abort) notification type for ARMv8. >>> Add a new GHES error source handling function for SEA. If an error >>> source's notification type is SEA, then this function can be registered >>> into the SEA exception handler. That way GHES will parse and report >>> SEA exceptions when they occur. >> Does this SEA is replayed by the firmware (firmware first handling) >> or directly triggered by the hardware when error is happened? > Architecturally, an SEA must be synchronous and *precise*, so if you > take an SEA on a particular load instruction, firmware/hardware should > not be corrupting the context/state of the PE to allow software to > determine which thread/process encountered the abort. GHES error status That's my concern too, and that's why I raised my question :) > block will be expose to software with information about the type, > severity, physical address impacted. > > Generally the error status block is populated by firmware. However, as > long as the above requirement is met, I don't think the spec precludes > error status block being populated by hardware. Those details must be > completely transparent to software. > > Finally, to answer your more specific question: If the implementation > of firmware-first involves trapping the SEA in EL3 to do some firmware > first handling, firmware must maintain the context of the offending ELx, > generate an error record, and then "replay" the exception to normal > (non-secure) software at the appropriate vector base address. > Thank you for your answer, it clears my confusion now, I will try something similar on ARM64 platform, will get back to you if I get blocks. Thanks Hanjun
[toc] | [prev] | [next] | [standalone]
| From | Hanjun Guo <hanjun.guo@linaro.org> |
|---|---|
| Date | 2016-10-18 15:10 +0200 |
| Subject | Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 |
| Message-ID | <stCjv-25f-15@gated-at.bofh.it> |
| In reply to | #1497563 |
On 2016/10/8 5:31, Tyler Baicar wrote:
> ARM APEI extension proposal added SEA (Synchrounous External
> Abort) notification type for ARMv8.
> Add a new GHES error source handling function for SEA. If an error
> source's notification type is SEA, then this function can be registered
> into the SEA exception handler. That way GHES will parse and report
> SEA exceptions when they occur.
>
> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
> ---
> arch/arm64/Kconfig | 1 +
> drivers/acpi/apei/Kconfig | 15 +++++++++
> drivers/acpi/apei/ghes.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 99 insertions(+)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b380c87..ae34349 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -53,6 +53,7 @@ config ARM64
> select HANDLE_DOMAIN_IRQ
> select HARDIRQS_SW_RESEND
> select HAVE_ACPI_APEI if (ACPI && EFI)
> + select HAVE_ACPI_APEI_SEA if (ACPI && EFI)
> select HAVE_ALIGNED_STRUCT_PAGE if SLUB
> select HAVE_ARCH_AUDITSYSCALL
> select HAVE_ARCH_BITREVERSE
> diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
> index b0140c8..fb99c1c 100644
> --- a/drivers/acpi/apei/Kconfig
> +++ b/drivers/acpi/apei/Kconfig
> @@ -4,6 +4,21 @@ config HAVE_ACPI_APEI
> config HAVE_ACPI_APEI_NMI
> bool
>
> +config HAVE_ACPI_APEI_SEA
> + bool "APEI Synchronous External Abort logging/recovering support"
> + depends on ARM64
> + help
> + This option should be enabled if the system supports
> + firmware first handling of SEA (Synchronous External Abort).
> + SEA happens with certain faults of data abort or instruction
> + abort synchronous exceptions on ARMv8 systems. If a system
> + supports firmware first handling of SEA, the platform analyzes
> + and handles hardware error notifications with SEA, and it may then
> + form a HW error record for the OS to parse and handle. This
> + option allows the OS to look for such HW error record, and
> + take appropriate action.
OK, I can see that it's firmware first handling, so it's triggered
by firmware to me, correct me if I'm wrong.
[...]
> #ifdef CONFIG_HAVE_ACPI_APEI_NMI
> /*
> * printk is not safe in NMI context. So in NMI handler, we allocate
> @@ -1023,6 +1083,14 @@ static int ghes_probe(struct platform_device *ghes_dev)
> case ACPI_HEST_NOTIFY_EXTERNAL:
> case ACPI_HEST_NOTIFY_SCI:
> break;
> + case ACPI_HEST_NOTIFY_SEA:
> + if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_SEA)) {
> + pr_warn(GHES_PFX "Generic hardware error source: %d notified via SEA is not supported\n",
> + generic->header.source_id);
> + rc = -ENOTSUPP;
> + goto err;
> + }
> + break;
> case ACPI_HEST_NOTIFY_NMI:
> if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_NMI)) {
> pr_warn(GHES_PFX "Generic hardware error source: %d notified via NMI interrupt is not supported!\n",
> @@ -1034,6 +1102,13 @@ static int ghes_probe(struct platform_device *ghes_dev)
> pr_warning(GHES_PFX "Generic hardware error source: %d notified via local interrupt is not supported!\n",
> generic->header.source_id);
> goto err;
> + case ACPI_HEST_NOTIFY_GPIO:
> + case ACPI_HEST_NOTIFY_SEI:
> + case ACPI_HEST_NOTIFY_GSIV:
> + pr_warn(GHES_PFX "Generic hardware error source: %d notified via notification type %u is not supported\n",
> + generic->header.source_id, generic->header.source_id);
Hmm, some platform may trigger a interrupt to OS for firmware handling
and it's in the ACPI 6.1 spec, is it a limitation now, or we need to
add code later to support it?
Thanks
Hanjun
[toc] | [prev] | [next] | [standalone]
| From | "Abdulhamid, Harb" <harba@codeaurora.org> |
|---|---|
| Date | 2016-10-19 19:20 +0200 |
| Subject | Re: [PATCH V3 05/10] acpi: apei: handle SEA notification type for ARMv8 |
| Message-ID | <su2GZ-4ip-13@gated-at.bofh.it> |
| In reply to | #1502977 |
On 10/18/2016 9:04 AM, Hanjun Guo wrote:
> On 2016/10/8 5:31, Tyler Baicar wrote:
>> ARM APEI extension proposal added SEA (Synchrounous External
>> Abort) notification type for ARMv8.
>> Add a new GHES error source handling function for SEA. If an error
>> source's notification type is SEA, then this function can be registered
>> into the SEA exception handler. That way GHES will parse and report
>> SEA exceptions when they occur.
>>
>> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
>> ---
>> arch/arm64/Kconfig | 1 +
>> drivers/acpi/apei/Kconfig | 15 +++++++++
>> drivers/acpi/apei/ghes.c | 83
>> +++++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 99 insertions(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b380c87..ae34349 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -53,6 +53,7 @@ config ARM64
>> select HANDLE_DOMAIN_IRQ
>> select HARDIRQS_SW_RESEND
>> select HAVE_ACPI_APEI if (ACPI && EFI)
>> + select HAVE_ACPI_APEI_SEA if (ACPI && EFI)
>> select HAVE_ALIGNED_STRUCT_PAGE if SLUB
>> select HAVE_ARCH_AUDITSYSCALL
>> select HAVE_ARCH_BITREVERSE
>> diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
>> index b0140c8..fb99c1c 100644
>> --- a/drivers/acpi/apei/Kconfig
>> +++ b/drivers/acpi/apei/Kconfig
>> @@ -4,6 +4,21 @@ config HAVE_ACPI_APEI
>> config HAVE_ACPI_APEI_NMI
>> bool
>>
>> +config HAVE_ACPI_APEI_SEA
>> + bool "APEI Synchronous External Abort logging/recovering support"
>> + depends on ARM64
>> + help
>> + This option should be enabled if the system supports
>> + firmware first handling of SEA (Synchronous External Abort).
>> + SEA happens with certain faults of data abort or instruction
>> + abort synchronous exceptions on ARMv8 systems. If a system
>> + supports firmware first handling of SEA, the platform analyzes
>> + and handles hardware error notifications with SEA, and it may then
>> + form a HW error record for the OS to parse and handle. This
>> + option allows the OS to look for such HW error record, and
>> + take appropriate action.
>
> OK, I can see that it's firmware first handling, so it's triggered
> by firmware to me, correct me if I'm wrong.
Not exactly... the exception itself is *initially* triggered by the
processor itself (e.g. ECC error on a particular load causes a data
abort), but then may be intercepted by firmware (e.g. EL3) to generate
the error record and then be *replayed* back to software (e.g. jump to
appropriate EL and vector that originally caused the exception).
The reason we use the term "platform" here is because platform can be
hardware/firmware, and this can be implemented in different ways
depending on the preference of the platform vendor. This is consistent
with the language in the UEFI/ACPI spec when describing the "thing" that
is not normal software (i.e. OS/Hypervisor).
>
> [...]
>> #ifdef CONFIG_HAVE_ACPI_APEI_NMI
>> /*
>> * printk is not safe in NMI context. So in NMI handler, we allocate
>> @@ -1023,6 +1083,14 @@ static int ghes_probe(struct platform_device
>> *ghes_dev)
>> case ACPI_HEST_NOTIFY_EXTERNAL:
>> case ACPI_HEST_NOTIFY_SCI:
>> break;
>> + case ACPI_HEST_NOTIFY_SEA:
>> + if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_SEA)) {
>> + pr_warn(GHES_PFX "Generic hardware error source: %d
>> notified via SEA is not supported\n",
>> + generic->header.source_id);
>> + rc = -ENOTSUPP;
>> + goto err;
>> + }
>> + break;
>> case ACPI_HEST_NOTIFY_NMI:
>> if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_NMI)) {
>> pr_warn(GHES_PFX "Generic hardware error source: %d
>> notified via NMI interrupt is not supported!\n",
>> @@ -1034,6 +1102,13 @@ static int ghes_probe(struct platform_device
>> *ghes_dev)
>> pr_warning(GHES_PFX "Generic hardware error source: %d
>> notified via local interrupt is not supported!\n",
>> generic->header.source_id);
>> goto err;
>> + case ACPI_HEST_NOTIFY_GPIO:
>> + case ACPI_HEST_NOTIFY_SEI:
>> + case ACPI_HEST_NOTIFY_GSIV:
>> + pr_warn(GHES_PFX "Generic hardware error source: %d notified
>> via notification type %u is not supported\n",
>> + generic->header.source_id, generic->header.source_id);
>
> Hmm, some platform may trigger a interrupt to OS for firmware handling
> and it's in the ACPI 6.1 spec, is it a limitation now, or we need to
> add code later to support it?
On the current platforms we know of, we only leverage "emulated SCI",
which essentially maps to a GPIO interrupt (via ACPI event - mapped to
particular GPIO). We will need to add support for other options
available in the spec (e.g. GSIV and SEI) later as platforms that use
those notification types become available.
Thanks,
--Harb
--
Qualcomm Datacenter Technologies, Inc.
as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Tyler Baicar <tbaicar@codeaurora.org> |
|---|---|
| Date | 2016-10-07 23:40 +0200 |
| Subject | [PATCH V3 04/10] arm64: exception: handle Synchronous External Abort |
| Message-ID | <spL22-6h3-23@gated-at.bofh.it> |
| In reply to | #1497556 |
SEA exceptions are often caused by an uncorrected hardware
error, and are handled when data abort and instruction abort
exception classes have specific values for their Fault Status
Code.
When SEA occurs, before killing the process, go through
the handlers registered in the notification list.
Update fault_info[] with specific SEA faults so that the
new SEA handler is used.
Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
---
arch/arm64/include/asm/system_misc.h | 13 ++++++++
arch/arm64/mm/fault.c | 58 +++++++++++++++++++++++++++++-------
2 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
index 57f110b..90daf4a 100644
--- a/arch/arm64/include/asm/system_misc.h
+++ b/arch/arm64/include/asm/system_misc.h
@@ -64,4 +64,17 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
#endif /* __ASSEMBLY__ */
+/*
+ * The functions below are used to register and unregister callbacks
+ * that are to be invoked when a Synchronous External Abort (SEA)
+ * occurs. An SEA is raised by certain fault status codes that have
+ * either data or instruction abort as the exception class, and
+ * callbacks may be registered to parse or handle such hardware errors.
+ *
+ * Registered callbacks are run in an interrupt/atomic context. They
+ * are not allowed to block or sleep.
+ */
+int sea_register_handler_chain(struct notifier_block *nb);
+void sea_unregister_handler_chain(struct notifier_block *nb);
+
#endif /* __ASM_SYSTEM_MISC_H */
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 05d2bd7..81cb7ad 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -39,6 +39,22 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
+/*
+ * GHES SEA handler code may register a notifier call here to
+ * handle HW error record passed from platform.
+ */
+static ATOMIC_NOTIFIER_HEAD(sea_handler_chain);
+
+int sea_register_handler_chain(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&sea_handler_chain, nb);
+}
+
+void sea_unregister_handler_chain(struct notifier_block *nb)
+{
+ atomic_notifier_chain_unregister(&sea_handler_chain, nb);
+}
+
static const char *fault_name(unsigned int esr);
#ifdef CONFIG_KPROBES
@@ -480,6 +496,28 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
return 1;
}
+/*
+ * This abort handler deals with Synchronous External Abort.
+ * It calls notifiers, and then returns "fault".
+ */
+static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
+{
+ struct siginfo info;
+
+ atomic_notifier_call_chain(&sea_handler_chain, 0, NULL);
+
+ pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
+ fault_name(esr), esr, addr);
+
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = 0;
+ info.si_addr = (void __user *)addr;
+ arm64_notify_die("", regs, &info, esr);
+
+ return 0;
+}
+
static const struct fault_info {
int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
int sig;
@@ -502,22 +540,22 @@ static const struct fault_info {
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
- { do_bad, SIGBUS, 0, "synchronous external abort" },
+ { do_sea, SIGBUS, 0, "synchronous external abort" },
{ do_bad, SIGBUS, 0, "unknown 17" },
{ do_bad, SIGBUS, 0, "unknown 18" },
{ do_bad, SIGBUS, 0, "unknown 19" },
- { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
- { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
- { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
- { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
- { do_bad, SIGBUS, 0, "synchronous parity error" },
+ { do_sea, SIGBUS, 0, "level 0 SEA (trans tbl walk)" },
+ { do_sea, SIGBUS, 0, "level 1 SEA (trans tbl walk)" },
+ { do_sea, SIGBUS, 0, "level 2 SEA (trans tbl walk)" },
+ { do_sea, SIGBUS, 0, "level 3 SEA (trans tbl walk)" },
+ { do_sea, SIGBUS, 0, "synchronous parity or ECC err" },
{ do_bad, SIGBUS, 0, "unknown 25" },
{ do_bad, SIGBUS, 0, "unknown 26" },
{ do_bad, SIGBUS, 0, "unknown 27" },
- { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
- { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
- { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
- { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
+ { do_sea, SIGBUS, 0, "level 0 synch parity error" },
+ { do_sea, SIGBUS, 0, "level 1 synch parity error" },
+ { do_sea, SIGBUS, 0, "level 2 synch parity error" },
+ { do_sea, SIGBUS, 0, "level 3 synch parity error" },
{ do_bad, SIGBUS, 0, "unknown 32" },
{ do_alignment_fault, SIGBUS, BUS_ADRALN, "alignment fault" },
{ do_bad, SIGBUS, 0, "unknown 34" },
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Punit Agrawal <punit.agrawal@arm.com> |
|---|---|
| Date | 2016-10-12 19:50 +0200 |
| Subject | Re: [PATCH V3 04/10] arm64: exception: handle Synchronous External Abort |
| Message-ID | <srvPb-7zM-5@gated-at.bofh.it> |
| In reply to | #1497564 |
Hi Tyler,
A couple of hopefully not bike shedding comments below.
Tyler Baicar <tbaicar@codeaurora.org> writes:
> SEA exceptions are often caused by an uncorrected hardware
> error, and are handled when data abort and instruction abort
> exception classes have specific values for their Fault Status
> Code.
> When SEA occurs, before killing the process, go through
> the handlers registered in the notification list.
> Update fault_info[] with specific SEA faults so that the
> new SEA handler is used.
>
> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
> ---
> arch/arm64/include/asm/system_misc.h | 13 ++++++++
> arch/arm64/mm/fault.c | 58 +++++++++++++++++++++++++++++-------
> 2 files changed, 61 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
> index 57f110b..90daf4a 100644
> --- a/arch/arm64/include/asm/system_misc.h
> +++ b/arch/arm64/include/asm/system_misc.h
> @@ -64,4 +64,17 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
>
> #endif /* __ASSEMBLY__ */
>
> +/*
> + * The functions below are used to register and unregister callbacks
> + * that are to be invoked when a Synchronous External Abort (SEA)
> + * occurs. An SEA is raised by certain fault status codes that have
> + * either data or instruction abort as the exception class, and
> + * callbacks may be registered to parse or handle such hardware errors.
> + *
> + * Registered callbacks are run in an interrupt/atomic context. They
> + * are not allowed to block or sleep.
> + */
> +int sea_register_handler_chain(struct notifier_block *nb);
> +void sea_unregister_handler_chain(struct notifier_block *nb);
> +
> #endif /* __ASM_SYSTEM_MISC_H */
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 05d2bd7..81cb7ad 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -39,6 +39,22 @@
> #include <asm/pgtable.h>
> #include <asm/tlbflush.h>
>
> +/*
> + * GHES SEA handler code may register a notifier call here to
> + * handle HW error record passed from platform.
> + */
> +static ATOMIC_NOTIFIER_HEAD(sea_handler_chain);
> +
> +int sea_register_handler_chain(struct notifier_block *nb)
> +{
> + return atomic_notifier_chain_register(&sea_handler_chain, nb);
> +}
> +
> +void sea_unregister_handler_chain(struct notifier_block *nb)
> +{
> + atomic_notifier_chain_unregister(&sea_handler_chain, nb);
> +}
> +
What do you think of naming the above functions as
[un]register_synchonous_ext_abort_notifier?
For an API, I find "sea" doesn't quite convey the message.
One more comment below.
> static const char *fault_name(unsigned int esr);
>
> #ifdef CONFIG_KPROBES
> @@ -480,6 +496,28 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
> return 1;
> }
>
> +/*
> + * This abort handler deals with Synchronous External Abort.
> + * It calls notifiers, and then returns "fault".
> + */
> +static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
> +{
> + struct siginfo info;
> +
> + atomic_notifier_call_chain(&sea_handler_chain, 0, NULL);
> +
> + pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
> + fault_name(esr), esr, addr);
> +
> + info.si_signo = SIGBUS;
> + info.si_errno = 0;
> + info.si_code = 0;
> + info.si_addr = (void __user *)addr;
> + arm64_notify_die("", regs, &info, esr);
> +
> + return 0;
> +}
> +
> static const struct fault_info {
> int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
> int sig;
> @@ -502,22 +540,22 @@ static const struct fault_info {
> { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
> { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
> { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
> - { do_bad, SIGBUS, 0, "synchronous external abort" },
> + { do_sea, SIGBUS, 0, "synchronous external abort" },
> { do_bad, SIGBUS, 0, "unknown 17" },
> { do_bad, SIGBUS, 0, "unknown 18" },
> { do_bad, SIGBUS, 0, "unknown 19" },
> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous parity error" },
> + { do_sea, SIGBUS, 0, "level 0 SEA (trans tbl walk)" },
> + { do_sea, SIGBUS, 0, "level 1 SEA (trans tbl walk)" },
> + { do_sea, SIGBUS, 0, "level 2 SEA (trans tbl walk)" },
> + { do_sea, SIGBUS, 0, "level 3 SEA (trans tbl walk)" },
^^^
The comment about naming applies here as well.
Thanks,
Punit
[...]
[toc] | [prev] | [next] | [standalone]
| From | "Baicar, Tyler" <tbaicar@codeaurora.org> |
|---|---|
| Date | 2016-10-13 16:00 +0200 |
| Subject | Re: [PATCH V3 04/10] arm64: exception: handle Synchronous External Abort |
| Message-ID | <srOI9-4cr-7@gated-at.bofh.it> |
| In reply to | #1499850 |
Hello Punit,
On 10/12/2016 11:46 AM, Punit Agrawal wrote:
> Hi Tyler,
>
> A couple of hopefully not bike shedding comments below.
>
> Tyler Baicar <tbaicar@codeaurora.org> writes:
>
>> SEA exceptions are often caused by an uncorrected hardware
>> error, and are handled when data abort and instruction abort
>> exception classes have specific values for their Fault Status
>> Code.
>> When SEA occurs, before killing the process, go through
>> the handlers registered in the notification list.
>> Update fault_info[] with specific SEA faults so that the
>> new SEA handler is used.
>>
>> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
>> ---
>> arch/arm64/include/asm/system_misc.h | 13 ++++++++
>> arch/arm64/mm/fault.c | 58 +++++++++++++++++++++++++++++-------
>> 2 files changed, 61 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
>> index 57f110b..90daf4a 100644
>> --- a/arch/arm64/include/asm/system_misc.h
>> +++ b/arch/arm64/include/asm/system_misc.h
>> @@ -64,4 +64,17 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
>>
>> #endif /* __ASSEMBLY__ */
>>
>> +/*
>> + * The functions below are used to register and unregister callbacks
>> + * that are to be invoked when a Synchronous External Abort (SEA)
>> + * occurs. An SEA is raised by certain fault status codes that have
>> + * either data or instruction abort as the exception class, and
>> + * callbacks may be registered to parse or handle such hardware errors.
>> + *
>> + * Registered callbacks are run in an interrupt/atomic context. They
>> + * are not allowed to block or sleep.
>> + */
>> +int sea_register_handler_chain(struct notifier_block *nb);
>> +void sea_unregister_handler_chain(struct notifier_block *nb);
>> +
>> #endif /* __ASM_SYSTEM_MISC_H */
>> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
>> index 05d2bd7..81cb7ad 100644
>> --- a/arch/arm64/mm/fault.c
>> +++ b/arch/arm64/mm/fault.c
>> @@ -39,6 +39,22 @@
>> #include <asm/pgtable.h>
>> #include <asm/tlbflush.h>
>>
>> +/*
>> + * GHES SEA handler code may register a notifier call here to
>> + * handle HW error record passed from platform.
>> + */
>> +static ATOMIC_NOTIFIER_HEAD(sea_handler_chain);
>> +
>> +int sea_register_handler_chain(struct notifier_block *nb)
>> +{
>> + return atomic_notifier_chain_register(&sea_handler_chain, nb);
>> +}
>> +
>> +void sea_unregister_handler_chain(struct notifier_block *nb)
>> +{
>> + atomic_notifier_chain_unregister(&sea_handler_chain, nb);
>> +}
>> +
> What do you think of naming the above functions as
> [un]register_synchonous_ext_abort_notifier?
>
> For an API, I find "sea" doesn't quite convey the message.
>
> One more comment below.
Yes, those names seem easier to understand.
>> static const char *fault_name(unsigned int esr);
>>
>> #ifdef CONFIG_KPROBES
>> @@ -480,6 +496,28 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>> return 1;
>> }
>>
>> +/*
>> + * This abort handler deals with Synchronous External Abort.
>> + * It calls notifiers, and then returns "fault".
>> + */
>> +static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
>> +{
>> + struct siginfo info;
>> +
>> + atomic_notifier_call_chain(&sea_handler_chain, 0, NULL);
>> +
>> + pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n",
>> + fault_name(esr), esr, addr);
>> +
>> + info.si_signo = SIGBUS;
>> + info.si_errno = 0;
>> + info.si_code = 0;
>> + info.si_addr = (void __user *)addr;
>> + arm64_notify_die("", regs, &info, esr);
>> +
>> + return 0;
>> +}
>> +
>> static const struct fault_info {
>> int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
>> int sig;
>> @@ -502,22 +540,22 @@ static const struct fault_info {
>> { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
>> { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
>> { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
>> - { do_bad, SIGBUS, 0, "synchronous external abort" },
>> + { do_sea, SIGBUS, 0, "synchronous external abort" },
>> { do_bad, SIGBUS, 0, "unknown 17" },
>> { do_bad, SIGBUS, 0, "unknown 18" },
>> { do_bad, SIGBUS, 0, "unknown 19" },
>> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
>> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
>> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
>> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
>> - { do_bad, SIGBUS, 0, "synchronous parity error" },
>> + { do_sea, SIGBUS, 0, "level 0 SEA (trans tbl walk)" },
>> + { do_sea, SIGBUS, 0, "level 1 SEA (trans tbl walk)" },
>> + { do_sea, SIGBUS, 0, "level 2 SEA (trans tbl walk)" },
>> + { do_sea, SIGBUS, 0, "level 3 SEA (trans tbl walk)" },
> ^^^
> The comment about naming applies here as well.
>
> Thanks,
> Punit
I'll expand sea here as well. This should make it easier to understand
without knowing the code.
Thanks,
Tyler
>
> [...]
>
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Tyler Baicar <tbaicar@codeaurora.org> |
|---|---|
| Date | 2016-10-07 23:40 +0200 |
| Subject | [PATCH V3 09/10] trace, ras: add ARM processor error trace event |
| Message-ID | <spL22-6h3-29@gated-at.bofh.it> |
| In reply to | #1497556 |
Currently there are trace events for the various RAS
errors with the exception of ARM processor type errors.
Add a new trace event for such errors so that the user
will know when they occur. These trace events are
consistent with the ARM processor error section type
defined in UEFI 2.6 spec section N.2.4.4.
Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
---
drivers/firmware/efi/cper.c | 9 ++++++
drivers/ras/ras.c | 1 +
include/ras/ras_event.h | 67 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 77 insertions(+)
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index f9ffba6..21b8a6f 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -34,6 +34,7 @@
#include <linux/aer.h>
#include <linux/printk.h>
#include <linux/bcd.h>
+#include <ras/ras_event.h>
#define INDENT_SP " "
@@ -256,6 +257,14 @@ static void cper_print_proc_armv8(const char *pfx,
CPER_ARMV8_INFO_VALID_PHYSICAL_ADDR)
printk("%sphysical fault address: 0x%016llx\n",
newpfx, err_info->physical_fault_addr);
+ trace_arm_event(proc->affinity_level, proc->mpidr, proc->midr,
+ proc->running_state, proc->psci_state,
+ err_info->version, err_info->type,
+ err_info->multiple_error,
+ err_info->validation_bits,
+ err_info->error_info,
+ err_info->virt_fault_addr,
+ err_info->physical_fault_addr);
err_info += 1;
}
diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
index fb2500b..8ba5a94 100644
--- a/drivers/ras/ras.c
+++ b/drivers/ras/ras.c
@@ -28,3 +28,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event);
#endif
EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(unknown_sec_event);
+EXPORT_TRACEPOINT_SYMBOL_GPL(arm_event);
diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
index 5861b6f..eb2719a 100644
--- a/include/ras/ras_event.h
+++ b/include/ras/ras_event.h
@@ -162,6 +162,73 @@ TRACE_EVENT(mc_event,
);
/*
+ * ARM Processor Events Report
+ *
+ * This event is generated when hardware detects an ARM processor error
+ * has occurred. UEFI 2.6 spec section N.2.4.4.
+ */
+TRACE_EVENT(arm_event,
+
+ TP_PROTO(const u8 affinity,
+ const u64 mpidr,
+ const u64 midr,
+ const u32 running_state,
+ const u32 psci_state,
+ const u8 version,
+ const u8 type,
+ const u16 err_count,
+ const u8 flags,
+ const u64 info,
+ const u64 virt_fault_addr,
+ const u64 phys_fault_addr),
+
+ TP_ARGS(affinity, mpidr, midr, running_state, psci_state,
+ version, type, err_count, flags, info, virt_fault_addr,
+ phys_fault_addr),
+
+ TP_STRUCT__entry(
+ __field(u8, affinity)
+ __field(u64, mpidr)
+ __field(u64, midr)
+ __field(u32, running_state)
+ __field(u32, psci_state)
+ __field(u8, version)
+ __field(u8, type)
+ __field(u16, err_count)
+ __field(u8, flags)
+ __field(u64, info)
+ __field(u64, virt_fault_addr)
+ __field(u64, phys_fault_addr)
+ ),
+
+ TP_fast_assign(
+ __entry->affinity = affinity;
+ __entry->mpidr = mpidr;
+ __entry->midr = midr;
+ __entry->running_state = running_state;
+ __entry->psci_state = psci_state;
+ __entry->version = version;
+ __entry->type = type;
+ __entry->err_count = err_count;
+ __entry->flags = flags;
+ __entry->info = info;
+ __entry->virt_fault_addr = virt_fault_addr;
+ __entry->phys_fault_addr = phys_fault_addr;
+ ),
+
+ TP_printk("affinity level: %d; MPIDR: %016llx; MIDR: %016llx; "
+ "running state: %d; PSCI state: %d; version: %d; type: %d; "
+ "error count: 0x%04x; flags: 0x%02x; info: %016llx; "
+ "virtual fault address: %016llx; "
+ "physical fault address: %016llx",
+ __entry->affinity, __entry->mpidr, __entry->midr,
+ __entry->running_state, __entry->psci_state, __entry->version,
+ __entry->type, __entry->err_count, __entry->flags,
+ __entry->info, __entry->virt_fault_addr,
+ __entry->phys_fault_addr)
+);
+
+/*
* Unknown Section Report
*
* This event is generated when hardware detected a hardware
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| Date | 2016-10-07 23:50 +0200 |
| Subject | Re: [PATCH V3 09/10] trace, ras: add ARM processor error trace event |
| Message-ID | <spLbH-6kI-1@gated-at.bofh.it> |
| In reply to | #1497566 |
On Fri, 7 Oct 2016 15:31:21 -0600
Tyler Baicar <tbaicar@codeaurora.org> wrote:
> Currently there are trace events for the various RAS
> errors with the exception of ARM processor type errors.
> Add a new trace event for such errors so that the user
> will know when they occur. These trace events are
> consistent with the ARM processor error section type
> defined in UEFI 2.6 spec section N.2.4.4.
>
> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
> ---
> drivers/firmware/efi/cper.c | 9 ++++++
> drivers/ras/ras.c | 1 +
> include/ras/ras_event.h | 67 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 77 insertions(+)
>
> diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
> index f9ffba6..21b8a6f 100644
> --- a/drivers/firmware/efi/cper.c
> +++ b/drivers/firmware/efi/cper.c
> @@ -34,6 +34,7 @@
> #include <linux/aer.h>
> #include <linux/printk.h>
> #include <linux/bcd.h>
> +#include <ras/ras_event.h>
>
> #define INDENT_SP " "
>
> @@ -256,6 +257,14 @@ static void cper_print_proc_armv8(const char *pfx,
> CPER_ARMV8_INFO_VALID_PHYSICAL_ADDR)
> printk("%sphysical fault address: 0x%016llx\n",
> newpfx, err_info->physical_fault_addr);
> + trace_arm_event(proc->affinity_level, proc->mpidr, proc->midr,
> + proc->running_state, proc->psci_state,
> + err_info->version, err_info->type,
> + err_info->multiple_error,
> + err_info->validation_bits,
> + err_info->error_info,
> + err_info->virt_fault_addr,
> + err_info->physical_fault_addr);
Why waste all the effort into passing each individual field. Why not
just pass the structure in and sort it out in the TP_fast_assign()?
> err_info += 1;
> }
>
> diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
> index fb2500b..8ba5a94 100644
> --- a/drivers/ras/ras.c
> +++ b/drivers/ras/ras.c
> @@ -28,3 +28,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event);
> #endif
> EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event);
> EXPORT_TRACEPOINT_SYMBOL_GPL(unknown_sec_event);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(arm_event);
> diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
> index 5861b6f..eb2719a 100644
> --- a/include/ras/ras_event.h
> +++ b/include/ras/ras_event.h
> @@ -162,6 +162,73 @@ TRACE_EVENT(mc_event,
> );
>
> /*
> + * ARM Processor Events Report
> + *
> + * This event is generated when hardware detects an ARM processor error
> + * has occurred. UEFI 2.6 spec section N.2.4.4.
> + */
> +TRACE_EVENT(arm_event,
> +
> + TP_PROTO(const u8 affinity,
> + const u64 mpidr,
> + const u64 midr,
> + const u32 running_state,
> + const u32 psci_state,
> + const u8 version,
> + const u8 type,
> + const u16 err_count,
> + const u8 flags,
> + const u64 info,
> + const u64 virt_fault_addr,
> + const u64 phys_fault_addr),
> +
> + TP_ARGS(affinity, mpidr, midr, running_state, psci_state,
> + version, type, err_count, flags, info, virt_fault_addr,
> + phys_fault_addr),
> +
> + TP_STRUCT__entry(
> + __field(u8, affinity)
> + __field(u64, mpidr)
> + __field(u64, midr)
> + __field(u32, running_state)
> + __field(u32, psci_state)
> + __field(u8, version)
> + __field(u8, type)
> + __field(u16, err_count)
> + __field(u8, flags)
> + __field(u64, info)
> + __field(u64, virt_fault_addr)
> + __field(u64, phys_fault_addr)
The above creates a structure with lots of holes in it. Pack it better.
You want something like:
__field(u64, mpidr)
__field(u64, midr)
__field(u64, info)
__field(u64, virt_fault_addr)
__field(u64, phys_fault_addr)
__field(u32, running_state)
__field(u32, psci_state)
__field(u16, err_count)
__field(u8, affinity)
__field(u8, version)
__field(u8, type)
__field(u8, flags)
The above is a total of 54 bytes. Your original was at a minimum, 64
bytes.
-- Steve
> + ),
> +
> + TP_fast_assign(
> + __entry->affinity = affinity;
> + __entry->mpidr = mpidr;
> + __entry->midr = midr;
> + __entry->running_state = running_state;
> + __entry->psci_state = psci_state;
> + __entry->version = version;
> + __entry->type = type;
> + __entry->err_count = err_count;
> + __entry->flags = flags;
> + __entry->info = info;
> + __entry->virt_fault_addr = virt_fault_addr;
> + __entry->phys_fault_addr = phys_fault_addr;
> + ),
> +
> + TP_printk("affinity level: %d; MPIDR: %016llx; MIDR: %016llx; "
> + "running state: %d; PSCI state: %d; version: %d; type: %d; "
> + "error count: 0x%04x; flags: 0x%02x; info: %016llx; "
> + "virtual fault address: %016llx; "
> + "physical fault address: %016llx",
> + __entry->affinity, __entry->mpidr, __entry->midr,
> + __entry->running_state, __entry->psci_state, __entry->version,
> + __entry->type, __entry->err_count, __entry->flags,
> + __entry->info, __entry->virt_fault_addr,
> + __entry->phys_fault_addr)
> +);
> +
> +/*
> * Unknown Section Report
> *
> * This event is generated when hardware detected a hardware
[toc] | [prev] | [next] | [standalone]
| From | "Baicar, Tyler" <tbaicar@codeaurora.org> |
|---|---|
| Date | 2016-10-12 23:30 +0200 |
| Subject | Re: [PATCH V3 09/10] trace, ras: add ARM processor error trace event |
| Message-ID | <srzg5-1Cz-7@gated-at.bofh.it> |
| In reply to | #1497569 |
Hello Steve,
Thank you for your feedback! Responses below.
On 10/7/2016 3:39 PM, Steven Rostedt wrote:
> On Fri, 7 Oct 2016 15:31:21 -0600
> Tyler Baicar <tbaicar@codeaurora.org> wrote:
>
>> Currently there are trace events for the various RAS
>> errors with the exception of ARM processor type errors.
>> Add a new trace event for such errors so that the user
>> will know when they occur. These trace events are
>> consistent with the ARM processor error section type
>> defined in UEFI 2.6 spec section N.2.4.4.
>>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> ---
>> drivers/firmware/efi/cper.c | 9 ++++++
>> drivers/ras/ras.c | 1 +
>> include/ras/ras_event.h | 67 +++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 77 insertions(+)
>>
>> diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
>> index f9ffba6..21b8a6f 100644
>> --- a/drivers/firmware/efi/cper.c
>> +++ b/drivers/firmware/efi/cper.c
>> @@ -34,6 +34,7 @@
>> #include <linux/aer.h>
>> #include <linux/printk.h>
>> #include <linux/bcd.h>
>> +#include <ras/ras_event.h>
>>
>> #define INDENT_SP " "
>>
>> @@ -256,6 +257,14 @@ static void cper_print_proc_armv8(const char *pfx,
>> CPER_ARMV8_INFO_VALID_PHYSICAL_ADDR)
>> printk("%sphysical fault address: 0x%016llx\n",
>> newpfx, err_info->physical_fault_addr);
>> + trace_arm_event(proc->affinity_level, proc->mpidr, proc->midr,
>> + proc->running_state, proc->psci_state,
>> + err_info->version, err_info->type,
>> + err_info->multiple_error,
>> + err_info->validation_bits,
>> + err_info->error_info,
>> + err_info->virt_fault_addr,
>> + err_info->physical_fault_addr);
> Why waste all the effort into passing each individual field. Why not
> just pass the structure in and sort it out in the TP_fast_assign()?
That should be a lot cleaner, I will make that change in the next patchset.
>> err_info += 1;
>> }
>>
>> diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
>> index fb2500b..8ba5a94 100644
>> --- a/drivers/ras/ras.c
>> +++ b/drivers/ras/ras.c
>> @@ -28,3 +28,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event);
>> #endif
>> EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event);
>> EXPORT_TRACEPOINT_SYMBOL_GPL(unknown_sec_event);
>> +EXPORT_TRACEPOINT_SYMBOL_GPL(arm_event);
>> diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
>> index 5861b6f..eb2719a 100644
>> --- a/include/ras/ras_event.h
>> +++ b/include/ras/ras_event.h
>> @@ -162,6 +162,73 @@ TRACE_EVENT(mc_event,
>> );
>>
>> /*
>> + * ARM Processor Events Report
>> + *
>> + * This event is generated when hardware detects an ARM processor error
>> + * has occurred. UEFI 2.6 spec section N.2.4.4.
>> + */
>> +TRACE_EVENT(arm_event,
>> +
>> + TP_PROTO(const u8 affinity,
>> + const u64 mpidr,
>> + const u64 midr,
>> + const u32 running_state,
>> + const u32 psci_state,
>> + const u8 version,
>> + const u8 type,
>> + const u16 err_count,
>> + const u8 flags,
>> + const u64 info,
>> + const u64 virt_fault_addr,
>> + const u64 phys_fault_addr),
>> +
>> + TP_ARGS(affinity, mpidr, midr, running_state, psci_state,
>> + version, type, err_count, flags, info, virt_fault_addr,
>> + phys_fault_addr),
>> +
>> + TP_STRUCT__entry(
>> + __field(u8, affinity)
>> + __field(u64, mpidr)
>> + __field(u64, midr)
>> + __field(u32, running_state)
>> + __field(u32, psci_state)
>> + __field(u8, version)
>> + __field(u8, type)
>> + __field(u16, err_count)
>> + __field(u8, flags)
>> + __field(u64, info)
>> + __field(u64, virt_fault_addr)
>> + __field(u64, phys_fault_addr)
> The above creates a structure with lots of holes in it. Pack it better.
> You want something like:
>
> __field(u64, mpidr)
> __field(u64, midr)
> __field(u64, info)
> __field(u64, virt_fault_addr)
> __field(u64, phys_fault_addr)
> __field(u32, running_state)
> __field(u32, psci_state)
> __field(u16, err_count)
> __field(u8, affinity)
> __field(u8, version)
> __field(u8, type)
> __field(u8, flags)
>
> The above is a total of 54 bytes. Your original was at a minimum, 64
> bytes.
>
> -- Steve
I will reorder the structure in the next patchset. I originally used
this order because that is the order the entries appear in the spec
(table 260 and 261 of UEFI spec 2.6). It makes more sense to save the
space though.
Thanks,
Tyler
>> + ),
>> +
>> + TP_fast_assign(
>> + __entry->affinity = affinity;
>> + __entry->mpidr = mpidr;
>> + __entry->midr = midr;
>> + __entry->running_state = running_state;
>> + __entry->psci_state = psci_state;
>> + __entry->version = version;
>> + __entry->type = type;
>> + __entry->err_count = err_count;
>> + __entry->flags = flags;
>> + __entry->info = info;
>> + __entry->virt_fault_addr = virt_fault_addr;
>> + __entry->phys_fault_addr = phys_fault_addr;
>> + ),
>> +
>> + TP_printk("affinity level: %d; MPIDR: %016llx; MIDR: %016llx; "
>> + "running state: %d; PSCI state: %d; version: %d; type: %d; "
>> + "error count: 0x%04x; flags: 0x%02x; info: %016llx; "
>> + "virtual fault address: %016llx; "
>> + "physical fault address: %016llx",
>> + __entry->affinity, __entry->mpidr, __entry->midr,
>> + __entry->running_state, __entry->psci_state, __entry->version,
>> + __entry->type, __entry->err_count, __entry->flags,
>> + __entry->info, __entry->virt_fault_addr,
>> + __entry->phys_fault_addr)
>> +);
>> +
>> +/*
>> * Unknown Section Report
>> *
>> * This event is generated when hardware detected a hardware
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Tyler Baicar <tbaicar@codeaurora.org> |
|---|---|
| Date | 2016-10-07 23:40 +0200 |
| Subject | [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 |
| Message-ID | <spL22-6h3-31@gated-at.bofh.it> |
| In reply to | #1497556 |
Currently when a RAS error is reported it is not timestamped.
The ACPI 6.1 spec adds the timestamp field to the generic error
data entry v3 structure. The timestamp of when the firmware
generated the error is now being reported.
Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
Signed-off-by: Richard Ruigrok <rruigrok@codeaurora.org>
Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
---
drivers/acpi/apei/ghes.c | 25 ++++++++++--
drivers/firmware/efi/cper.c | 97 +++++++++++++++++++++++++++++++++++++++------
2 files changed, 105 insertions(+), 17 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 3021f0e..c8488f1 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -80,6 +80,10 @@
((struct acpi_hest_generic_status *) \
((struct ghes_estatus_node *)(estatus_node) + 1))
+#define acpi_hest_generic_data_version(gdata) \
+ (gdata->revision >> 8)
+
+
/*
* This driver isn't really modular, however for the time being,
* continuing to use module_param is the easiest way to remain
@@ -412,6 +416,13 @@ static void ghes_clear_estatus(struct ghes *ghes)
ghes->flags &= ~GHES_TO_CLEAR;
}
+inline void *acpi_hest_generic_data_payload(struct acpi_hest_generic_data *gdata)
+{
+ return acpi_hest_generic_data_version(gdata) >= 3 ?
+ (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1) :
+ gdata + 1;
+}
+
static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev)
{
#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
@@ -419,7 +430,8 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int
int flags = -1;
int sec_sev = ghes_severity(gdata->error_severity);
struct cper_sec_mem_err *mem_err;
- mem_err = (struct cper_sec_mem_err *)(gdata + 1);
+
+ mem_err = acpi_hest_generic_data_payload(gdata);
if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
return;
@@ -449,14 +461,18 @@ static void ghes_do_proc(struct ghes *ghes,
{
int sev, sec_sev;
struct acpi_hest_generic_data *gdata;
+ uuid_le sec_type;
sev = ghes_severity(estatus->error_severity);
apei_estatus_for_each_section(estatus, gdata) {
sec_sev = ghes_severity(gdata->error_severity);
- if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
+ sec_type = *(uuid_le *)gdata->section_type;
+
+ if (!uuid_le_cmp(sec_type,
CPER_SEC_PLATFORM_MEM)) {
struct cper_sec_mem_err *mem_err;
- mem_err = (struct cper_sec_mem_err *)(gdata+1);
+
+ mem_err = acpi_hest_generic_data_payload(gdata);
ghes_edac_report_mem_error(ghes, sev, mem_err);
arch_apei_report_mem_error(sev, mem_err);
@@ -466,7 +482,8 @@ static void ghes_do_proc(struct ghes *ghes,
else if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
CPER_SEC_PCIE)) {
struct cper_sec_pcie *pcie_err;
- pcie_err = (struct cper_sec_pcie *)(gdata+1);
+
+ pcie_err = acpi_hest_generic_data_payload(gdata);
if (sev == GHES_SEV_RECOVERABLE &&
sec_sev == GHES_SEV_RECOVERABLE &&
pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID &&
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index d425374..9fa1317 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -32,9 +32,14 @@
#include <linux/acpi.h>
#include <linux/pci.h>
#include <linux/aer.h>
+#include <linux/printk.h>
+#include <linux/bcd.h>
#define INDENT_SP " "
+#define acpi_hest_generic_data_version(gdata) \
+ (gdata->revision >> 8)
+
static char rcd_decode_str[CPER_REC_LEN];
/*
@@ -386,13 +391,47 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
pfx, pcie->bridge.secondary_status, pcie->bridge.control);
}
+static inline void *acpi_hest_generic_data_payload(struct acpi_hest_generic_data *gdata)
+{
+ return acpi_hest_generic_data_version(gdata) >= 3 ?
+ (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1) :
+ gdata + 1;
+}
+
+static void cper_estatus_print_section_v300(const char *pfx,
+ const 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);
+ memcpy(&sec, timestamp, 1);
+ memcpy(&min, timestamp + 1, 1);
+ memcpy(&hour, timestamp + 2, 1);
+ memcpy(&day, timestamp + 4, 1);
+ memcpy(&mon, timestamp + 5, 1);
+ memcpy(&year, timestamp + 6, 1);
+ memcpy(¢ury, timestamp + 7, 1);
+ printk("%stime: ", pfx);
+ printk("%7s", 0x01 & *(timestamp + 3) ? "precise" : "");
+ printk(" %02d:%02d:%02d %02d%02d-%02d-%02d\n",
+ bcd2bin(hour), bcd2bin(min), bcd2bin(sec),
+ bcd2bin(century), bcd2bin(year), bcd2bin(mon),
+ bcd2bin(day));
+ }
+}
+
static void cper_estatus_print_section(
- const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
+ const char *pfx, struct acpi_hest_generic_data *gdata, int sec_no)
{
uuid_le *sec_type = (uuid_le *)gdata->section_type;
__u16 severity;
char newpfx[64];
+ if ((gdata->revision >> 8) >= 0x03)
+ cper_estatus_print_section_v300(pfx,
+ (const 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));
@@ -403,14 +442,18 @@ static void cper_estatus_print_section(
snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) {
- struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1);
+ struct cper_sec_proc_generic *proc_err;
+
+ proc_err = acpi_hest_generic_data_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 (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) {
- struct cper_sec_mem_err *mem_err = (void *)(gdata + 1);
+ struct cper_sec_mem_err *mem_err;
+
+ mem_err = acpi_hest_generic_data_payload(gdata);
printk("%s""section_type: memory error\n", newpfx);
if (gdata->error_data_length >=
sizeof(struct cper_sec_mem_err_old))
@@ -419,7 +462,9 @@ static void cper_estatus_print_section(
else
goto err_section_too_small;
} else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) {
- struct cper_sec_pcie *pcie = (void *)(gdata + 1);
+ struct cper_sec_pcie *pcie;
+
+ pcie = acpi_hest_generic_data_payload(gdata);
printk("%s""section_type: PCIe error\n", newpfx);
if (gdata->error_data_length >= sizeof(*pcie))
cper_print_pcie(newpfx, pcie, gdata);
@@ -438,6 +483,7 @@ void cper_estatus_print(const char *pfx,
const struct acpi_hest_generic_status *estatus)
{
struct acpi_hest_generic_data *gdata;
+ struct acpi_hest_generic_data_v300 *gdata_v3 = NULL;
unsigned int data_len, gedata_len;
int sec_no = 0;
char newpfx[64];
@@ -451,12 +497,22 @@ void cper_estatus_print(const char *pfx,
printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
data_len = estatus->data_length;
gdata = (struct acpi_hest_generic_data *)(estatus + 1);
+ if ((gdata->revision >> 8) >= 0x03)
+ gdata_v3 = (struct acpi_hest_generic_data_v300 *)gdata;
+
snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
+
while (data_len >= sizeof(*gdata)) {
gedata_len = gdata->error_data_length;
cper_estatus_print_section(newpfx, gdata, sec_no);
- data_len -= gedata_len + sizeof(*gdata);
- gdata = (void *)(gdata + 1) + gedata_len;
+ if(gdata_v3) {
+ data_len -= gedata_len + sizeof(*gdata_v3);
+ gdata_v3 = (void *)(gdata_v3 + 1) + gedata_len;
+ gdata = (struct acpi_hest_generic_data *)gdata_v3;
+ } else {
+ data_len -= gedata_len + sizeof(*gdata);
+ gdata = (void *)(gdata + 1) + gedata_len;
+ }
sec_no++;
}
}
@@ -478,6 +534,7 @@ EXPORT_SYMBOL_GPL(cper_estatus_check_header);
int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
{
struct acpi_hest_generic_data *gdata;
+ struct acpi_hest_generic_data_v300 *gdata_v3 = NULL;
unsigned int data_len, gedata_len;
int rc;
@@ -486,15 +543,29 @@ int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
return rc;
data_len = estatus->data_length;
gdata = (struct acpi_hest_generic_data *)(estatus + 1);
- while (data_len >= sizeof(*gdata)) {
- gedata_len = gdata->error_data_length;
- if (gedata_len > data_len - sizeof(*gdata))
+
+ if ((gdata->revision >> 8) >= 0x03) {
+ gdata_v3 = (struct acpi_hest_generic_data_v300 *)gdata;
+ while (data_len >= sizeof(*gdata_v3)) {
+ gedata_len = gdata_v3->error_data_length;
+ if (gedata_len > data_len - sizeof(*gdata_v3))
+ return -EINVAL;
+ data_len -= gedata_len + sizeof(*gdata_v3);
+ gdata_v3 = (void *)(gdata_v3 + 1) + gedata_len;
+ }
+ if (data_len)
+ return -EINVAL;
+ } else {
+ while (data_len >= sizeof(*gdata)) {
+ gedata_len = gdata->error_data_length;
+ if (gedata_len > data_len - sizeof(*gdata))
+ return -EINVAL;
+ data_len -= gedata_len + sizeof(*gdata);
+ gdata = (void *)(gdata + 1) + gedata_len;
+ }
+ if (data_len)
return -EINVAL;
- data_len -= gedata_len + sizeof(*gdata);
- gdata = (void *)(gdata + 1) + gedata_len;
}
- if (data_len)
- return -EINVAL;
return 0;
}
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Suzuki K Poulose <Suzuki.Poulose@arm.com> |
|---|---|
| Date | 2016-10-11 19:40 +0200 |
| Subject | Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 |
| Message-ID | <sr9c0-195-81@gated-at.bofh.it> |
| In reply to | #1497567 |
On 07/10/16 22:31, Tyler Baicar wrote:
> Currently when a RAS error is reported it is not timestamped.
> The ACPI 6.1 spec adds the timestamp field to the generic error
> data entry v3 structure. The timestamp of when the firmware
> generated the error is now being reported.
>
> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
> Signed-off-by: Richard Ruigrok <rruigrok@codeaurora.org>
> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
Please could you keep the people who reviewed/commented on your series in the past,
whenever you post a new version ?
> ---
> drivers/acpi/apei/ghes.c | 25 ++++++++++--
> drivers/firmware/efi/cper.c | 97 +++++++++++++++++++++++++++++++++++++++------
> 2 files changed, 105 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 3021f0e..c8488f1 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -80,6 +80,10 @@
> ((struct acpi_hest_generic_status *) \
> ((struct ghes_estatus_node *)(estatus_node) + 1))
>
> +#define acpi_hest_generic_data_version(gdata) \
> + (gdata->revision >> 8)
...
> +inline void *acpi_hest_generic_data_payload(struct acpi_hest_generic_data *gdata)
> +{
> + return acpi_hest_generic_data_version(gdata) >= 3 ?
> + (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1) :
> + gdata + 1;
> +}
> +
> diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
> index d425374..9fa1317 100644
> --- a/drivers/firmware/efi/cper.c
> +++ b/drivers/firmware/efi/cper.c
> +#define acpi_hest_generic_data_version(gdata) \
> + (gdata->revision >> 8)
> +
...
> +static inline void *acpi_hest_generic_data_payload(struct acpi_hest_generic_data *gdata)
> +{
> + return acpi_hest_generic_data_version(gdata) >= 3 ?
> + (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1) :
> + gdata + 1;
> +}
Could these go to a header file, so that we don't need duplicate definitions of these helpers in
different files ?
> +
> +static void cper_estatus_print_section_v300(const char *pfx,
> + const 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);
> + memcpy(&sec, timestamp, 1);
> + memcpy(&min, timestamp + 1, 1);
> + memcpy(&hour, timestamp + 2, 1);
> + memcpy(&day, timestamp + 4, 1);
> + memcpy(&mon, timestamp + 5, 1);
> + memcpy(&year, timestamp + 6, 1);
> + memcpy(¢ury, timestamp + 7, 1);
> + printk("%stime: ", pfx);
> + printk("%7s", 0x01 & *(timestamp + 3) ? "precise" : "");
What format is the (timestamp + 3) stored in ? Does it need conversion ?
> + printk(" %02d:%02d:%02d %02d%02d-%02d-%02d\n",
> + bcd2bin(hour), bcd2bin(min), bcd2bin(sec),
> + bcd2bin(century), bcd2bin(year), bcd2bin(mon),
> + bcd2bin(day));
> + }
minor nit: Would it be easier to order/parse the error messages if the date
is printed first followed by time ?
i.e,
17:20:14 2016-09-15 Mon
vs
2016-09-15 Mon 17:20:14
e.g, people looking at a huge log, looking for logs from a specific date might
find the latter more useful to skip the messages.
> +}
> +
> static void cper_estatus_print_section(
> - const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
> + const char *pfx, struct acpi_hest_generic_data *gdata, int sec_no)
> {
> uuid_le *sec_type = (uuid_le *)gdata->section_type;
> __u16 severity;
> char newpfx[64];
>
> + if ((gdata->revision >> 8) >= 0x03)
Could we use the helper defined above ?
> @@ -451,12 +497,22 @@ void cper_estatus_print(const char *pfx,
> printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
> data_len = estatus->data_length;
> gdata = (struct acpi_hest_generic_data *)(estatus + 1);
> + if ((gdata->revision >> 8) >= 0x03)
Same as above, use the macro ?
> + gdata_v3 = (struct acpi_hest_generic_data_v300 *)gdata;
> +
> snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
> +
> while (data_len >= sizeof(*gdata)) {
> gedata_len = gdata->error_data_length;
> cper_estatus_print_section(newpfx, gdata, sec_no);
> - data_len -= gedata_len + sizeof(*gdata);
> - gdata = (void *)(gdata + 1) + gedata_len;
> + if(gdata_v3) {
> + data_len -= gedata_len + sizeof(*gdata_v3);
> + gdata_v3 = (void *)(gdata_v3 + 1) + gedata_len;
> + gdata = (struct acpi_hest_generic_data *)gdata_v3;
> + } else {
> + data_len -= gedata_len + sizeof(*gdata);
> + gdata = (void *)(gdata + 1) + gedata_len;
> + }
> sec_no++;
> }
...
>
> @@ -486,15 +543,29 @@ int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
> return rc;
> data_len = estatus->data_length;
> gdata = (struct acpi_hest_generic_data *)(estatus + 1);
> - while (data_len >= sizeof(*gdata)) {
> - gedata_len = gdata->error_data_length;
> - if (gedata_len > data_len - sizeof(*gdata))
> +
> + if ((gdata->revision >> 8) >= 0x03) {
> + gdata_v3 = (struct acpi_hest_generic_data_v300 *)gdata;
> + while (data_len >= sizeof(*gdata_v3)) {
> + gedata_len = gdata_v3->error_data_length;
> + if (gedata_len > data_len - sizeof(*gdata_v3))
> + return -EINVAL;
> + data_len -= gedata_len + sizeof(*gdata_v3);
> + gdata_v3 = (void *)(gdata_v3 + 1) + gedata_len;
> + }
> + if (data_len)
> + return -EINVAL;
> + } else {
> + while (data_len >= sizeof(*gdata)) {
> + gedata_len = gdata->error_data_length;
> + if (gedata_len > data_len - sizeof(*gdata))
> + return -EINVAL;
> + data_len -= gedata_len + sizeof(*gdata);
> + gdata = (void *)(gdata + 1) + gedata_len;
> + }
> + if (data_len)
As mentioned in the previous version, would it make sense to add some more
helpers to deal with record versions ? We seem to be doing the version switch and
code duplication at different places.
Does the following help ? Thoughts ?
#define acpi_hest_generic_data_error_length(gdata) (((struct acpi_hest_generic_data *)(gdata))->error_data_length)
#define acpi_hest_generic_data_size(gdata) \
((acpi_hest_generic_data_version(gdata) >= 3) ? \
sizeof(struct acpi_hest_generic_data_v300) : \
sizeof(struct acpi_hest_generic_data))
#define acpi_hest_generic_data_record_size(gdata)
(acpi_hest_generic_data_size(gdata) + \
acpi_hest_generic_data_error_length(gdata))
#define acpi_hest_generic_data_next(gdata) \
((void *)(gdata) + acpi_hest_generic_data_record_size(gdata))
Suzuki
[toc] | [prev] | [next] | [standalone]
| From | "Baicar, Tyler" <tbaicar@codeaurora.org> |
|---|---|
| Date | 2016-10-13 00:30 +0200 |
| Subject | Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 |
| Message-ID | <srAc9-2kO-9@gated-at.bofh.it> |
| In reply to | #1499073 |
Hello Suzuki,
Thank you for the feedback! Responses below.
On 10/11/2016 11:28 AM, Suzuki K Poulose wrote:
> On 07/10/16 22:31, Tyler Baicar wrote:
>> Currently when a RAS error is reported it is not timestamped.
>> The ACPI 6.1 spec adds the timestamp field to the generic error
>> data entry v3 structure. The timestamp of when the firmware
>> generated the error is now being reported.
>>
>> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
>> Signed-off-by: Richard Ruigrok <rruigrok@codeaurora.org>
>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
>
> Please could you keep the people who reviewed/commented on your series
> in the past,
> whenever you post a new version ?
Do you mean to just send the new version to their e-mail directly in
addition to the lists? If so, I will do that next time.
I know you provided good feedback on the previous patchset, but I did
not have anyone specifically respond to add "reviewed-by:...". I don't
think I should add reviewed-by for someone unless they specifically add
it in a response :)
>
>> ---
>> drivers/acpi/apei/ghes.c | 25 ++++++++++--
>> drivers/firmware/efi/cper.c | 97
>> +++++++++++++++++++++++++++++++++++++++------
>> 2 files changed, 105 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 3021f0e..c8488f1 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -80,6 +80,10 @@
>> ((struct acpi_hest_generic_status *) \
>> ((struct ghes_estatus_node *)(estatus_node) + 1))
>>
>> +#define acpi_hest_generic_data_version(gdata) \
>> + (gdata->revision >> 8)
>
> ...
>
>> +inline void *acpi_hest_generic_data_payload(struct
>> acpi_hest_generic_data *gdata)
>> +{
>> + return acpi_hest_generic_data_version(gdata) >= 3 ?
>> + (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1) :
>> + gdata + 1;
>> +}
>> +
>
>
>
>> diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
>> index d425374..9fa1317 100644
>> --- a/drivers/firmware/efi/cper.c
>> +++ b/drivers/firmware/efi/cper.c
>
>> +#define acpi_hest_generic_data_version(gdata) \
>> + (gdata->revision >> 8)
>> +
>
> ...
>
>> +static inline void *acpi_hest_generic_data_payload(struct
>> acpi_hest_generic_data *gdata)
>> +{
>> + return acpi_hest_generic_data_version(gdata) >= 3 ?
>> + (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1) :
>> + gdata + 1;
>> +}
>
> Could these go to a header file, so that we don't need duplicate
> definitions of these helpers in
> different files ?
>
I think that should work to avoid duplication. I will move them to a
header file in the next patchset.
>> +
>> +static void cper_estatus_print_section_v300(const char *pfx,
>> + const 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);
>> + memcpy(&sec, timestamp, 1);
>> + memcpy(&min, timestamp + 1, 1);
>> + memcpy(&hour, timestamp + 2, 1);
>> + memcpy(&day, timestamp + 4, 1);
>> + memcpy(&mon, timestamp + 5, 1);
>> + memcpy(&year, timestamp + 6, 1);
>> + memcpy(¢ury, timestamp + 7, 1);
>> + printk("%stime: ", pfx);
>> + printk("%7s", 0x01 & *(timestamp + 3) ? "precise" : "");
>
> What format is the (timestamp + 3) stored in ? Does it need conversion ?
The third byte of the timestamp is currently only used to determine if
the time is precise or not. Bit 0 is used to specify that and the other
bits in this byte are marked as reserved. This is shown in table 247 of
the UEFI spec 2.6:
Byte 3:
Bit 0 – Timestamp is precise if this bit is set and correlates to the
time of the error event.
Bit 7:1 – Reserved
>
>> + printk(" %02d:%02d:%02d %02d%02d-%02d-%02d\n",
>> + bcd2bin(hour), bcd2bin(min), bcd2bin(sec),
>> + bcd2bin(century), bcd2bin(year), bcd2bin(mon),
>> + bcd2bin(day));
>> + }
>
> minor nit: Would it be easier to order/parse the error messages if the
> date
> is printed first followed by time ?
>
> i.e,
> 17:20:14 2016-09-15 Mon
> vs
> 2016-09-15 Mon 17:20:14
>
> e.g, people looking at a huge log, looking for logs from a specific
> date might
> find the latter more useful to skip the messages.
>
The latter does seem like it would be better for parsing large logs. I
can rearrange the order in the next patchset.
>> +}
>> +
>> static void cper_estatus_print_section(
>> - const char *pfx, const struct acpi_hest_generic_data *gdata, int
>> sec_no)
>> + const char *pfx, struct acpi_hest_generic_data *gdata, int sec_no)
>> {
>> uuid_le *sec_type = (uuid_le *)gdata->section_type;
>> __u16 severity;
>> char newpfx[64];
>>
>> + if ((gdata->revision >> 8) >= 0x03)
>
> Could we use the helper defined above ?
Yes, I'll change this to use acpi_hest_generic_data_version(gdata) instead.
>
>> @@ -451,12 +497,22 @@ void cper_estatus_print(const char *pfx,
>> printk("%s""event severity: %s\n", pfx,
>> cper_severity_str(severity));
>> data_len = estatus->data_length;
>> gdata = (struct acpi_hest_generic_data *)(estatus + 1);
>> + if ((gdata->revision >> 8) >= 0x03)
>
> Same as above, use the macro ?
Yes, I'll change this to use acpi_hest_generic_data_version(gdata) instead.
>
>> + gdata_v3 = (struct acpi_hest_generic_data_v300 *)gdata;
>> +
>> snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
>> +
>> while (data_len >= sizeof(*gdata)) {
>> gedata_len = gdata->error_data_length;
>> cper_estatus_print_section(newpfx, gdata, sec_no);
>> - data_len -= gedata_len + sizeof(*gdata);
>> - gdata = (void *)(gdata + 1) + gedata_len;
>> + if(gdata_v3) {
>> + data_len -= gedata_len + sizeof(*gdata_v3);
>> + gdata_v3 = (void *)(gdata_v3 + 1) + gedata_len;
>> + gdata = (struct acpi_hest_generic_data *)gdata_v3;
>> + } else {
>> + data_len -= gedata_len + sizeof(*gdata);
>> + gdata = (void *)(gdata + 1) + gedata_len;
>> + }
>> sec_no++;
>> }
>
> ...
>
>>
>> @@ -486,15 +543,29 @@ int cper_estatus_check(const struct
>> acpi_hest_generic_status *estatus)
>> return rc;
>> data_len = estatus->data_length;
>> gdata = (struct acpi_hest_generic_data *)(estatus + 1);
>> - while (data_len >= sizeof(*gdata)) {
>> - gedata_len = gdata->error_data_length;
>> - if (gedata_len > data_len - sizeof(*gdata))
>> +
>> + if ((gdata->revision >> 8) >= 0x03) {
>> + gdata_v3 = (struct acpi_hest_generic_data_v300 *)gdata;
>> + while (data_len >= sizeof(*gdata_v3)) {
>> + gedata_len = gdata_v3->error_data_length;
>> + if (gedata_len > data_len - sizeof(*gdata_v3))
>> + return -EINVAL;
>> + data_len -= gedata_len + sizeof(*gdata_v3);
>> + gdata_v3 = (void *)(gdata_v3 + 1) + gedata_len;
>> + }
>> + if (data_len)
>> + return -EINVAL;
>> + } else {
>> + while (data_len >= sizeof(*gdata)) {
>> + gedata_len = gdata->error_data_length;
>> + if (gedata_len > data_len - sizeof(*gdata))
>> + return -EINVAL;
>> + data_len -= gedata_len + sizeof(*gdata);
>> + gdata = (void *)(gdata + 1) + gedata_len;
>> + }
>> + if (data_len)
>
> As mentioned in the previous version, would it make sense to add some
> more
> helpers to deal with record versions ? We seem to be doing the version
> switch and
> code duplication at different places.
>
> Does the following help ? Thoughts ?
>
> #define acpi_hest_generic_data_error_length(gdata) (((struct
> acpi_hest_generic_data *)(gdata))->error_data_length)
> #define acpi_hest_generic_data_size(gdata) \
> ((acpi_hest_generic_data_version(gdata) >= 3) ? \
> sizeof(struct acpi_hest_generic_data_v300) : \
> sizeof(struct acpi_hest_generic_data))
> #define acpi_hest_generic_data_record_size(gdata)
> (acpi_hest_generic_data_size(gdata) + \
> acpi_hest_generic_data_error_length(gdata))
> #define acpi_hest_generic_data_next(gdata) \
> ((void *)(gdata) + acpi_hest_generic_data_record_size(gdata))
>
>
> Suzuki
These helpers will definitely help consolidate this code. I will use
these in the next version to remove the code duplication here.
Thanks,
Tyler
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Suzuki K Poulose <Suzuki.Poulose@arm.com> |
|---|---|
| Date | 2016-10-13 11:00 +0200 |
| Subject | Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 |
| Message-ID | <srK1Q-1cz-7@gated-at.bofh.it> |
| In reply to | #1499941 |
On 12/10/16 23:10, Baicar, Tyler wrote:
> Hello Suzuki,
>
> Thank you for the feedback! Responses below.
>
>
> On 10/11/2016 11:28 AM, Suzuki K Poulose wrote:
>> On 07/10/16 22:31, Tyler Baicar wrote:
>>> Currently when a RAS error is reported it is not timestamped.
>>> The ACPI 6.1 spec adds the timestamp field to the generic error
>>> data entry v3 structure. The timestamp of when the firmware
>>> generated the error is now being reported.
>>>
>>> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
>>> Signed-off-by: Richard Ruigrok <rruigrok@codeaurora.org>
>>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>>> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
>>
>> Please could you keep the people who reviewed/commented on your series in the past,
>> whenever you post a new version ?
> Do you mean to just send the new version to their e-mail directly in addition to the lists? If so, I will do that next time.
If you send a new version of a series to the list, it is a good idea to keep
the people who commented (significantly) on your previous version in Cc, especially
when you have addressed their feedback. That will help them to keep track of the
series. People can always see the new version in the list, but then it is so easy
to miss something in the 100s of emails you get each day. I am sure people have
special filters for the emails based on if they are in Cc/To etc.
>
> I know you provided good feedback on the previous patchset, but I did not have anyone specifically respond to add "reviewed-by:...". I don't think I should add reviewed-by for someone unless they specifically add it in a response :)
No, I haven't yet "Reviewed-by" your patches. I had some comments on it, which means
I expected it to be addressed as you committed in your response.
>>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>>> index 3021f0e..c8488f1 100644
>>> --- a/drivers/acpi/apei/ghes.c
>>> +++ b/drivers/acpi/apei/ghes.c
>>> @@ -80,6 +80,10 @@
> I think that should work to avoid duplication. I will move them to a header file in the next patchset.
>>> +
>>> +static void cper_estatus_print_section_v300(const char *pfx,
>>> + const 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);
>>> + memcpy(&sec, timestamp, 1);
>>> + memcpy(&min, timestamp + 1, 1);
>>> + memcpy(&hour, timestamp + 2, 1);
>>> + memcpy(&day, timestamp + 4, 1);
>>> + memcpy(&mon, timestamp + 5, 1);
>>> + memcpy(&year, timestamp + 6, 1);
>>> + memcpy(¢ury, timestamp + 7, 1);
>>> + printk("%stime: ", pfx);
>>> + printk("%7s", 0x01 & *(timestamp + 3) ? "precise" : "");
>>
>> What format is the (timestamp + 3) stored in ? Does it need conversion ?
> The third byte of the timestamp is currently only used to determine if the time is precise or not. Bit 0 is used to specify that and the other bits in this byte are marked as reserved. This is shown in table 247 of the UEFI spec 2.6:
>
> Byte 3:
> Bit 0 – Timestamp is precise if this bit is set and correlates to the time of the error event.
> Bit 7:1 – Reserved
Is it always the same endianness as that of the CPU ?
Cheers
Suzuki
[toc] | [prev] | [next] | [standalone]
| From | "Baicar, Tyler" <tbaicar@codeaurora.org> |
|---|---|
| Date | 2016-10-13 21:50 +0200 |
| Subject | Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 |
| Message-ID | <srUaR-7SK-13@gated-at.bofh.it> |
| In reply to | #1500102 |
Hello Suzuki,
On 10/13/2016 2:50 AM, Suzuki K Poulose wrote:
> On 12/10/16 23:10, Baicar, Tyler wrote:
>> Hello Suzuki,
>>
>> Thank you for the feedback! Responses below.
>>
>> On 10/11/2016 11:28 AM, Suzuki K Poulose wrote:
>>> On 07/10/16 22:31, Tyler Baicar wrote:
>>>> Currently when a RAS error is reported it is not timestamped.
>>>> The ACPI 6.1 spec adds the timestamp field to the generic error
>>>> data entry v3 structure. The timestamp of when the firmware
>>>> generated the error is now being reported.
>>>>
>>>> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
>>>> Signed-off-by: Richard Ruigrok <rruigrok@codeaurora.org>
>>>> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
>>>> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
>>>
>>> Please could you keep the people who reviewed/commented on your
>>> series in the past,
>>> whenever you post a new version ?
>> Do you mean to just send the new version to their e-mail directly in
>> addition to the lists? If so, I will do that next time.
>
> If you send a new version of a series to the list, it is a good idea
> to keep
> the people who commented (significantly) on your previous version in
> Cc, especially
> when you have addressed their feedback. That will help them to keep
> track of the
> series. People can always see the new version in the list, but then it
> is so easy
> to miss something in the 100s of emails you get each day. I am sure
> people have
> special filters for the emails based on if they are in Cc/To etc.
>
Okay, understood. I'll make sure to add those who have commented in the
cc/to list to avoid the e-mail filters.
>>
>> I know you provided good feedback on the previous patchset, but I did
>> not have anyone specifically respond to add "reviewed-by:...". I
>> don't think I should add reviewed-by for someone unless they
>> specifically add it in a response :)
>
> No, I haven't yet "Reviewed-by" your patches. I had some comments on
> it, which means
> I expected it to be addressed as you committed in your response.
>
>>>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>>>> index 3021f0e..c8488f1 100644
>>>> --- a/drivers/acpi/apei/ghes.c
>>>> +++ b/drivers/acpi/apei/ghes.c
>>>> @@ -80,6 +80,10 @@
>
>> I think that should work to avoid duplication. I will move them to a
>> header file in the next patchset.
>>>> +
>>>> +static void cper_estatus_print_section_v300(const char *pfx,
>>>> + const 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);
>>>> + memcpy(&sec, timestamp, 1);
>>>> + memcpy(&min, timestamp + 1, 1);
>>>> + memcpy(&hour, timestamp + 2, 1);
>>>> + memcpy(&day, timestamp + 4, 1);
>>>> + memcpy(&mon, timestamp + 5, 1);
>>>> + memcpy(&year, timestamp + 6, 1);
>>>> + memcpy(¢ury, timestamp + 7, 1);
>>>> + printk("%stime: ", pfx);
>>>> + printk("%7s", 0x01 & *(timestamp + 3) ? "precise" : "");
>>>
>>> What format is the (timestamp + 3) stored in ? Does it need
>>> conversion ?
>> The third byte of the timestamp is currently only used to determine
>> if the time is precise or not. Bit 0 is used to specify that and the
>> other bits in this byte are marked as reserved. This is shown in
>> table 247 of the UEFI spec 2.6:
>>
>> Byte 3:
>> Bit 0 – Timestamp is precise if this bit is set and correlates to
>> the time of the error event.
>> Bit 7:1 – Reserved
>
> Is it always the same endianness as that of the CPU ?
It is a fair assumption that the firmware populating this record will
use a CPU of the same endianness. There is no mechanism in the spec to
indicate otherwise.
Thanks,
Tyler
>
> Cheers
> Suzuki
>
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Suzuki K Poulose <Suzuki.Poulose@arm.com> |
|---|---|
| Date | 2016-10-14 18:30 +0200 |
| Subject | Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 |
| Message-ID | <ssdwS-3Da-21@gated-at.bofh.it> |
| In reply to | #1500521 |
On 13/10/16 20:37, Baicar, Tyler wrote: > Hello Suzuki, > > On 10/13/2016 2:50 AM, Suzuki K Poulose wrote: >> On 12/10/16 23:10, Baicar, Tyler wrote: >>>> Please could you keep the people who reviewed/commented on your series in the past, >>>> whenever you post a new version ? >>> Do you mean to just send the new version to their e-mail directly in addition to the lists? If so, I will do that next time. >> >> If you send a new version of a series to the list, it is a good idea to keep >> the people who commented (significantly) on your previous version in Cc, especially >> when you have addressed their feedback. That will help them to keep track of the >> series. People can always see the new version in the list, but then it is so easy >> to miss something in the 100s of emails you get each day. I am sure people have >> special filters for the emails based on if they are in Cc/To etc. >> > Okay, understood. I'll make sure to add those who have commented in the cc/to list to avoid the e-mail filters. Thanks ! >> Is it always the same endianness as that of the CPU ? > It is a fair assumption that the firmware populating this record will use a CPU of the same endianness. There is no mechanism in the spec to indicate otherwise. Yep, you are right. The EFI expects the EL2/EL1 to be of the same endianness Cheers Suzuki
[toc] | [prev] | [next] | [standalone]
| From | Mark Rutland <mark.rutland@arm.com> |
|---|---|
| Date | 2016-10-14 18:50 +0200 |
| Subject | Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 |
| Message-ID | <ssdQd-3JZ-1@gated-at.bofh.it> |
| In reply to | #1501087 |
On Fri, Oct 14, 2016 at 05:28:58PM +0100, Suzuki K Poulose wrote: > On 13/10/16 20:37, Baicar, Tyler wrote: > >On 10/13/2016 2:50 AM, Suzuki K Poulose wrote: > >>Is it always the same endianness as that of the CPU ? > > > >It is a fair assumption that the firmware populating this record will > >use a CPU of the same endianness. There is no mechanism in the spec > >to indicate otherwise. > > Yep, you are right. The EFI expects the EL2/EL1 to be of the same endianness To be clear, it is specifically required in the ACPI spec that elements are in little-endian. Per the ACPI 6.1 spec, page 109: All numeric values in ACPI-defined tables, blocks, and structures are always encoded in little endian format. Given that CPER, HEST, etc are defined within the ACPI specification, they are covered by this requirement. Elements outside of the ACPI spec are not necessarily covered by this requirement, but their specifications should state their endianness. Thanks, Mark.
[toc] | [prev] | [next] | [standalone]
| From | Russell King - ARM Linux <linux@armlinux.org.uk> |
|---|---|
| Date | 2016-10-11 21:10 +0200 |
| Subject | Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 |
| Message-ID | <sraB3-2b0-5@gated-at.bofh.it> |
| In reply to | #1497567 |
On Fri, Oct 07, 2016 at 03:31:14PM -0600, Tyler Baicar wrote:
> +static void cper_estatus_print_section_v300(const char *pfx,
> + const 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);
> + memcpy(&sec, timestamp, 1);
> + memcpy(&min, timestamp + 1, 1);
> + memcpy(&hour, timestamp + 2, 1);
> + memcpy(&day, timestamp + 4, 1);
> + memcpy(&mon, timestamp + 5, 1);
> + memcpy(&year, timestamp + 6, 1);
> + memcpy(¢ury, timestamp + 7, 1);
This is utterly silly. Why are you using memcpy() to access individual
bytes of a u8 pointer? What's wrong with:
sec = timestamp[0];
min = timestamp[1];
hour = timestamp[2];
day = timestamp[4];
mon = timestamp[5];
year = timestamp[6];
century = timestamp[7];
or even do the conversion here:
sec = bcd2bin(timestamp[0]);
... etc ...
> + printk("%stime: ", pfx);
> + printk("%7s", 0x01 & *(timestamp + 3) ? "precise" : "");
> + printk(" %02d:%02d:%02d %02d%02d-%02d-%02d\n",
> + bcd2bin(hour), bcd2bin(min), bcd2bin(sec),
> + bcd2bin(century), bcd2bin(year), bcd2bin(mon),
> + bcd2bin(day));
> + }
It's also a good idea to (as much as possible) keep to single printk()
statements - which makes the emission of the string more atomic wrt
other CPUs and contexts. So, this should probably become (with the
conversion being done at the assignment of sec etc):
printk("%stime: %7s %02d:%02d:%02d %02d%02d-%02d-%02d\n",
pfx, 0x01 & timestamp[3] ? "precise" : "",
hour, min, sec, century, year, mon, day);
which, IMHO, looks a lot nicer and doesn't risk some other printk()
getting between each individual part of the line.
> +}
> +
> static void cper_estatus_print_section(
> - const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
> + const char *pfx, struct acpi_hest_generic_data *gdata, int sec_no)
> {
> uuid_le *sec_type = (uuid_le *)gdata->section_type;
> __u16 severity;
> char newpfx[64];
>
> + if ((gdata->revision >> 8) >= 0x03)
> + cper_estatus_print_section_v300(pfx,
> + (const 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));
Not sure why you have the "" here - %sError works just as well and the
"" is just obfuscation - the compiler will eliminate the double-double
quote and merge the strings anyway.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
[toc] | [prev] | [next] | [standalone]
| From | "Baicar, Tyler" <tbaicar@codeaurora.org> |
|---|---|
| Date | 2016-10-13 00:20 +0200 |
| Subject | Re: [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1 |
| Message-ID | <srA2t-2h0-19@gated-at.bofh.it> |
| In reply to | #1499158 |
Hello Russell,
Thank you for the feedback! Responses below
On 10/11/2016 12:52 PM, Russell King - ARM Linux wrote:
> On Fri, Oct 07, 2016 at 03:31:14PM -0600, Tyler Baicar wrote:
>> +static void cper_estatus_print_section_v300(const char *pfx,
>> + const 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);
>> + memcpy(&sec, timestamp, 1);
>> + memcpy(&min, timestamp + 1, 1);
>> + memcpy(&hour, timestamp + 2, 1);
>> + memcpy(&day, timestamp + 4, 1);
>> + memcpy(&mon, timestamp + 5, 1);
>> + memcpy(&year, timestamp + 6, 1);
>> + memcpy(¢ury, timestamp + 7, 1);
> This is utterly silly. Why are you using memcpy() to access individual
> bytes of a u8 pointer? What's wrong with:
>
> sec = timestamp[0];
> min = timestamp[1];
> hour = timestamp[2];
> day = timestamp[4];
> mon = timestamp[5];
> year = timestamp[6];
> century = timestamp[7];
>
> or even do the conversion here:
>
> sec = bcd2bin(timestamp[0]);
> ... etc ...
Yes, that will be a lot cleaner especially with moving the conversion here.
>
>> + printk("%stime: ", pfx);
>> + printk("%7s", 0x01 & *(timestamp + 3) ? "precise" : "");
>> + printk(" %02d:%02d:%02d %02d%02d-%02d-%02d\n",
>> + bcd2bin(hour), bcd2bin(min), bcd2bin(sec),
>> + bcd2bin(century), bcd2bin(year), bcd2bin(mon),
>> + bcd2bin(day));
>> + }
> It's also a good idea to (as much as possible) keep to single printk()
> statements - which makes the emission of the string more atomic wrt
> other CPUs and contexts. So, this should probably become (with the
> conversion being done at the assignment of sec etc):
>
> printk("%stime: %7s %02d:%02d:%02d %02d%02d-%02d-%02d\n",
> pfx, 0x01 & timestamp[3] ? "precise" : "",
> hour, min, sec, century, year, mon, day);
>
> which, IMHO, looks a lot nicer and doesn't risk some other printk()
> getting between each individual part of the line.
I will make this change in the next version. This printk does look a lot
nicer and avoids other prints from getting in the middle (I actually
just saw that happen in testing a couple days ago)
>> +}
>> +
>> static void cper_estatus_print_section(
>> - const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
>> + const char *pfx, struct acpi_hest_generic_data *gdata, int sec_no)
>> {
>> uuid_le *sec_type = (uuid_le *)gdata->section_type;
>> __u16 severity;
>> char newpfx[64];
>>
>> + if ((gdata->revision >> 8) >= 0x03)
>> + cper_estatus_print_section_v300(pfx,
>> + (const 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));
> Not sure why you have the "" here - %sError works just as well and the
> "" is just obfuscation - the compiler will eliminate the double-double
> quote and merge the strings anyway.
>
I will remove the "" in the next version.
Thanks,
Tyler
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Tyler Baicar <tbaicar@codeaurora.org> |
|---|---|
| Date | 2016-10-07 23:40 +0200 |
| Subject | [PATCH V3 06/10] acpi: apei: panic OS with fatal error status block |
| Message-ID | <spL22-6h3-33@gated-at.bofh.it> |
| In reply to | #1497556 |
From: "Jonathan (Zhixiong) Zhang" <zjzhang@codeaurora.org>
Even if an error status block's severity is fatal, the kernel does not
honor the severity level and panic.
With the firmware first model, the platform could inform the OS about a
fatal hardware error through the non-NMI GHES notification type. The OS
should panic when a hardware error record is received with this
severity.
Call panic() after CPER data in error status block is printed if
severity is fatal, before each error section is handled.
Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
---
drivers/acpi/apei/ghes.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 28d5a09..36894c8 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -141,6 +141,8 @@ static unsigned long ghes_estatus_pool_size_request;
static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
static atomic_t ghes_estatus_cache_alloced;
+static int ghes_panic_timeout __read_mostly = 30;
+
static int ghes_ioremap_init(void)
{
ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES,
@@ -715,6 +717,12 @@ static int ghes_proc(struct ghes *ghes)
if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus))
ghes_estatus_cache_add(ghes->generic, ghes->estatus);
}
+ if (ghes_severity(ghes->estatus->error_severity) >= GHES_SEV_PANIC) {
+ if (panic_timeout == 0)
+ panic_timeout = ghes_panic_timeout;
+ panic("Fatal hardware error!");
+ }
+
ghes_do_proc(ghes, ghes->estatus);
if (ghes->generic_v2) {
@@ -859,8 +867,6 @@ static atomic_t ghes_in_nmi = ATOMIC_INIT(0);
static LIST_HEAD(ghes_nmi);
-static int ghes_panic_timeout __read_mostly = 30;
-
static void ghes_proc_in_irq(struct irq_work *irq_work)
{
struct llist_node *llnode, *next;
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.
[toc] | [prev] | [next] | [standalone]
| From | Suzuki K Poulose <Suzuki.Poulose@arm.com> |
|---|---|
| Date | 2016-10-13 15:10 +0200 |
| Subject | Re: [PATCH V3 06/10] acpi: apei: panic OS with fatal error status block |
| Message-ID | <srNVM-3VP-3@gated-at.bofh.it> |
| In reply to | #1497568 |
On 07/10/16 22:31, Tyler Baicar wrote:
> From: "Jonathan (Zhixiong) Zhang" <zjzhang@codeaurora.org>
>
> Even if an error status block's severity is fatal, the kernel does not
> honor the severity level and panic.
>
> With the firmware first model, the platform could inform the OS about a
> fatal hardware error through the non-NMI GHES notification type. The OS
> should panic when a hardware error record is received with this
> severity.
>
> Call panic() after CPER data in error status block is printed if
> severity is fatal, before each error section is handled.
>
> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
> ---
> drivers/acpi/apei/ghes.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 28d5a09..36894c8 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -141,6 +141,8 @@ static unsigned long ghes_estatus_pool_size_request;
> static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
> static atomic_t ghes_estatus_cache_alloced;
>
> +static int ghes_panic_timeout __read_mostly = 30;
> +
> static int ghes_ioremap_init(void)
> {
> ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES,
> @@ -715,6 +717,12 @@ static int ghes_proc(struct ghes *ghes)
> if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus))
> ghes_estatus_cache_add(ghes->generic, ghes->estatus);
> }
> + if (ghes_severity(ghes->estatus->error_severity) >= GHES_SEV_PANIC) {
> + if (panic_timeout == 0)
> + panic_timeout = ghes_panic_timeout;
> + panic("Fatal hardware error!");
I think there is a chance that we might miss the o/p of ghes_print_estatus() as we use
no pfx, and it could default to the normal loglevel and would never get printed
if panic() is encountered before it. On the other hand, there is already a
__ghes_panic() which does similar stuff. Is there a way we could reuse
(may be even parts of) it ? Or at least use KERN_EMERG for the ghes_print_estatus(),
if the severity could result in panic() ?
Cheers
Suzuki
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | linux.kernel
csiph-web