RE: [PATCH v2 1/2] EDAC/ghes: Add EDAC device for reporting the CPU cache errors

2021-03-17 Thread Shiju Jose
Hi James,

Can you review and help to merge this patch?

Thanks,
Shiju

>-Original Message-
>From: Rafael J. Wysocki [mailto:raf...@kernel.org]
>Sent: 05 February 2021 12:54
>To: Shiju Jose ; Borislav Petkov ;
>James Morse 
>Cc: open list:EDAC-CORE ; ACPI Devel Maling
>List ; Linux Kernel Mailing List ker...@vger.kernel.org>; Tony Luck ; Rafael J. Wysocki
>; Len Brown ; Robert Richter
>; Mauro Carvalho Chehab
>; linux...@openeuler.org; xuwei (O)
>; Jonathan Cameron
>; John Garry ;
>tanxiaofei ; Shameerali Kolothum Thodi
>; Salil Mehta
>
>Subject: Re: [PATCH v2 1/2] EDAC/ghes: Add EDAC device for reporting the
>CPU cache errors
>
>On Fri, Jan 29, 2021 at 1:03 PM Shiju Jose  wrote:
>>
>> CPU L2 cache corrected errors are detected occasionally on few of our
>> ARM64 hardware boards. Though it is rare, the probability of the CPU
>> cache errors frequently occurring can't be avoided. The earlier
>> failure detection by monitoring the cache corrected errors for the
>> frequent occurrences and taking preventive action could prevent more
>> serious hardware faults.
>>
>> On Intel architectures, cache corrected errors are reported and the
>> affected cores are offlined in the architecture specific method.
>> http://www.mcelog.org/cache.html
>>
>> However for the firmware-first error reporting, specifically on
>> ARM64 architectures, there is no provision present for reporting the
>> cache corrected error count to the user-space and taking preventive
>> action such as offline the affected cores.
>>
>> For this purpose, it was suggested to create the CPU EDAC device for
>> the CPU caches for reporting the cache error count for the
>> firmware-first error reporting.
>> The EDAC device blocks for the CPU caches would be created based on
>> the cache information obtained from the cpu_cacheinfo.
>>
>> User-space application could monitor the recorded corrected error
>> count for the earlier hardware failure detection and could take
>> preventive action, such as offline the corresponding CPU core/s.
>>
>> Add an EDAC device and device blocks for the CPU caches based on the
>> cache information from the cpu_cacheinfo.
>> The cache's corrected error count would be stored in the
>> /sys/devices/system/edac/cpu/cpu*/cache*/ce_count.
>>
>> Issues and possible solutions,
>> 1.Cache info is not available for the CPUs offline.
>>  EDAC device interface requires creating EDAC device  and device
>> blocks together. It requires the number  of caches per CPU as device
>> blocks for the creation.
>>  However, this info is not available for the  offlined CPUs.
>> Tested Solution: Find the max number of caches among
>>   online CPUs, create the EDAC device for CPUs caches
>>   and get and populate the cache info for an offline
>>   CPU later, when the error is reported on that CPU for
>>   the first time.
>>
>> 2. Reporting error count for the Shared caches.
>>There are few possible solutions,
>> Tested Solution:
>> Kernel would report a new error count for a shared cache
>> through the EDAC device block for that CPU on which the error
>>     is reported. Then user-space application would sum the total
>> error count from EDAC device block of all the CPUs in the
>> shared CPU list of that shared cache.
>>
>> For the firmware-first error reporting, add an interface in the
>> ghes_edac allow to report a CPU corrected error count.
>>
>> Suggested-by: James Morse 
>> Signed-off-by: Shiju Jose 
>
>Boris, James, I need your input here.
>
>> ---
>>  Documentation/ABI/testing/sysfs-devices-edac |  15 ++
>>  drivers/acpi/apei/ghes.c |   8 +-
>>  drivers/edac/Kconfig |  12 ++
>>  drivers/edac/ghes_edac.c | 186 +++
>>  include/acpi/ghes.h  |  27 +++
>>  5 files changed, 247 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-devices-edac
>> b/Documentation/ABI/testing/sysfs-devices-edac
>> index 256a9e990c0b..56a18b0af419 100644
>> --- a/Documentation/ABI/testing/sysfs-devices-edac
>> +++ b/Documentation/ABI/testing/sysfs-devices-edac
>> @@ -155,3 +155,18 @@ Description:   This attribute file displays the
>total count of uncorrectable
>> errors that have occurred on this DIMM. If panic_on_ue is 
>> set, this
>> counter will not have a chance to increment, since EDAC will 
>> panic
>the
>>

RE: [PATCH v2] arm64/ras: Update code to trace out more data for ARM processor

2021-02-24 Thread Shiju Jose
>-Original Message-
>From: linux-arm-kernel [mailto:linux-arm-kernel-boun...@lists.infradead.org]
>On Behalf Of Jason Tian
>Sent: 05 February 2021 02:22
>To: linux-kernel@vger.kernel.org; linux-e...@vger.kernel.org; linux-arm-
>ker...@lists.infradead.org; james.mo...@arm.com;
>bai...@os.amperecomputing.com
>Cc: zw...@amperecomputing.com; ja...@os.amperecomputing.com
>Subject: [PATCH v2] arm64/ras: Update code to trace out more data for ARM
>processor
>
>The original arm_event trace code only traces out ARM processor error
>information data. According to UEFI_2_8_A_Feb14 specification chapter
>N2.4.4, the ARM processor error section includes several ARM processor
>error information, several ARM processor context information and several
>vendor specific error information structures.
>
>Add code to trace out all ARM processor context information and vendor
>specific error information with raw hex format.
>
>Signed-off-by: Jason Tian 
>---
> drivers/ras/ras.c   | 22 +-
> include/ras/ras_event.h | 41 +++---
>---
> 2 files changed, 56 insertions(+), 7 deletions(-)
>

Tested-by: Shiju Jose 

>diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c index
>95540ea8dd9d..6f3269da9476 100644
>--- a/drivers/ras/ras.c
>+++ b/drivers/ras/ras.c
>@@ -23,7 +23,27 @@ void log_non_standard_event(const guid_t
>*sec_type, const guid_t *fru_id,
>
> void log_arm_hw_error(struct cper_sec_proc_arm *err)  {
>-  trace_arm_event(err);
>+  u32 pei_len;
>+  u32 ctx_len;
>+  u32 vsei_len;
>+  u8 *pei_err;
>+  u8 *ctx_err;
>+  u8 *ven_err_data;
>+
>+  pei_len = sizeof(struct cper_arm_err_info) * err->err_info_num;
>+  pei_err = (u8 *) err + sizeof(struct cper_sec_proc_arm);
>+
>+  ctx_len = sizeof(struct cper_arm_ctx_info) * err->context_info_num;
>+  ctx_err = pei_err + sizeof(struct cper_arm_err_info) *
>+  err->err_info_num;
>+
>+  vsei_len = err->section_length - (sizeof(struct cper_sec_proc_arm) +
>+pei_len + ctx_len);
>+  ven_err_data = ctx_err + sizeof(struct cper_arm_ctx_info) *
>+err->context_info_num;
>+
>+  trace_arm_event(err, pei_err, pei_len, ctx_err, ctx_len,
>+  ven_err_data, vsei_len);
> }
>
> static int __init ras_init(void)
>diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h index
>0bdbc0d17d2f..fd9201214be8 100644
>--- a/include/ras/ras_event.h
>+++ b/include/ras/ras_event.h
>@@ -168,11 +168,22 @@ TRACE_EVENT(mc_event,
>  * This event is generated when hardware detects an ARM processor error
>  * has occurred. UEFI 2.6 spec section N.2.4.4.
>  */
>+ #define APEIL "ARM Processor Err Info data len"
>+ #define APEID "ARM Processor Err Info raw data"
>+ #define APECIL "ARM Processor Err Context Info data len"
>+ #define APECID "ARM Processor Err Context Info raw data"
>+ #define VSEIL "Vendor Specific Err Info data len"
>+ #define VSEID "Vendor Specific Err Info raw data"
> TRACE_EVENT(arm_event,
>
>-  TP_PROTO(const struct cper_sec_proc_arm *proc),
>+  TP_PROTO(const struct cper_sec_proc_arm *proc, const u8 *pei_err,
>+  const u32 pei_len,
>+  const u8 *ctx_err,
>+  const u32 ctx_len,
>+  const u8 *oem,
>+  const u32 oem_len),
>
>-  TP_ARGS(proc),
>+  TP_ARGS(proc, pei_err, pei_len, ctx_err, ctx_len, oem, oem_len),
>
>   TP_STRUCT__entry(
>   __field(u64, mpidr)
>@@ -180,6 +191,12 @@ TRACE_EVENT(arm_event,
>   __field(u32, running_state)
>   __field(u32, psci_state)
>   __field(u8, affinity)
>+  __field(u32, pei_len)
>+  __dynamic_array(u8, buf, pei_len)
>+  __field(u32, ctx_len)
>+  __dynamic_array(u8, buf1, ctx_len)
>+  __field(u32, oem_len)
>+  __dynamic_array(u8, buf2, oem_len)
>   ),
>
>   TP_fast_assign(
>@@ -199,12 +216,24 @@ TRACE_EVENT(arm_event,
>   __entry->running_state = ~0;
>   __entry->psci_state = ~0;
>   }
>+  __entry->pei_len = pei_len;
>+  memcpy(__get_dynamic_array(buf), pei_err, pei_len);
>+  __entry->ctx_len = ctx_len;
>+  memcpy(__get_dynamic_array(buf1), ctx_err, ctx_len);
>+  __entry->oem_len = oem_len;
>+  memcpy(__get_dynamic_array(buf2), oem, oem_len);
>   ),
>
>-  TP_printk("affinity level: 

[PATCH v2 1/2] EDAC/ghes: Add EDAC device for reporting the CPU cache errors

2021-01-29 Thread Shiju Jose
CPU L2 cache corrected errors are detected occasionally on
few of our ARM64 hardware boards. Though it is rare, the
probability of the CPU cache errors frequently occurring
can't be avoided. The earlier failure detection by monitoring
the cache corrected errors for the frequent occurrences and
taking preventive action could prevent more serious hardware
faults.

On Intel architectures, cache corrected errors are reported and
the affected cores are offlined in the architecture specific method.
http://www.mcelog.org/cache.html

However for the firmware-first error reporting, specifically on
ARM64 architectures, there is no provision present for reporting
the cache corrected error count to the user-space and taking
preventive action such as offline the affected cores.

For this purpose, it was suggested to create the CPU EDAC
device for the CPU caches for reporting the cache error count
for the firmware-first error reporting.
The EDAC device blocks for the CPU caches would be created
based on the cache information obtained from the cpu_cacheinfo.

User-space application could monitor the recorded corrected error
count for the earlier hardware failure detection and could take
preventive action, such as offline the corresponding CPU core/s.

Add an EDAC device and device blocks for the CPU caches
based on the cache information from the cpu_cacheinfo.
The cache's corrected error count would be stored in the
/sys/devices/system/edac/cpu/cpu*/cache*/ce_count.

Issues and possible solutions,
1.Cache info is not available for the CPUs offline.
 EDAC device interface requires creating EDAC device
 and device blocks together. It requires the number
 of caches per CPU as device blocks for the creation.
 However, this info is not available for the
 offlined CPUs.
Tested Solution: Find the max number of caches among
  online CPUs, create the EDAC device for CPUs caches
  and get and populate the cache info for an offline
  CPU later, when the error is reported on that CPU for
  the first time.

2. Reporting error count for the Shared caches.
   There are few possible solutions,
Tested Solution:
Kernel would report a new error count for a shared cache
through the EDAC device block for that CPU on which the error
is reported. Then user-space application would sum the total
error count from EDAC device block of all the CPUs in the
shared CPU list of that shared cache.

For the firmware-first error reporting, add an interface in the
ghes_edac allow to report a CPU corrected error count.

Suggested-by: James Morse 
Signed-off-by: Shiju Jose 
---
 Documentation/ABI/testing/sysfs-devices-edac |  15 ++
 drivers/acpi/apei/ghes.c |   8 +-
 drivers/edac/Kconfig |  12 ++
 drivers/edac/ghes_edac.c | 186 +++
 include/acpi/ghes.h  |  27 +++
 5 files changed, 247 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-devices-edac 
b/Documentation/ABI/testing/sysfs-devices-edac
index 256a9e990c0b..56a18b0af419 100644
--- a/Documentation/ABI/testing/sysfs-devices-edac
+++ b/Documentation/ABI/testing/sysfs-devices-edac
@@ -155,3 +155,18 @@ Description:   This attribute file displays the total 
count of uncorrectable
errors that have occurred on this DIMM. If panic_on_ue is set, 
this
counter will not have a chance to increment, since EDAC will 
panic the
system
+
+What:   /sys/devices/system/edac/cpu/cpu*/cache*/ce_count
+Date:   December 2020
+Contact:linux-e...@vger.kernel.org
+Description:This attribute file displays the total count of correctable
+errors that have occurred on this CPU cache. This count is 
very important
+to examine. CEs provide early indications that a cache is 
beginning
+to fail. This count field should be monitored for non-zero 
values
+and report such information to the system administrator.
+
+What:   /sys/devices/system/edac/cpu/cpu*/cache*/ue_count
+Date:   December 2020
+Contact:linux-e...@vger.kernel.org
+Description:This attribute file displays the total count of uncorrectable
+errors that have occurred on this CPU cache.
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index fce7ade2aba9..139540f2c8f4 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -1452,4 +1452,10 @@ static int __init ghes_init(void)
 err:
return rc;
 }
-device_initcall(ghes_init);
+
+/*
+ * device_initcall_sync() is added instead of the device_initcall()
+ * because the CPU cacheinfo should be populated and is required for
+ * adding the CPU cache edac device in the ghes_edac_register().
+ */
+device_initcall_sync(ghes_init);
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 81c42664f21b..39fb53aa9cd9 100644
--- a/drivers/edac/Kconfig
+++ b

RE: [RFC PATCH 1/2] EDAC/ghes: Add EDAC device for the CPU caches

2021-01-19 Thread Shiju Jose
Hi Boris,

>-Original Message-
>From: Borislav Petkov [mailto:b...@alien8.de]
>Sent: 18 January 2021 18:37
>To: Shiju Jose 
>Cc: linux-e...@vger.kernel.org; linux-a...@vger.kernel.org; linux-
>ker...@vger.kernel.org; james.mo...@arm.com;
>mchehab+hua...@kernel.org; tony.l...@intel.com; r...@rjwysocki.net;
>l...@kernel.org; rrich...@marvell.com; Jonathan Cameron
>; tanxiaofei ;
>linux...@openeuler.org
>Subject: Re: [RFC PATCH 1/2] EDAC/ghes: Add EDAC device for the CPU
>caches
>
>On Fri, Jan 15, 2021 at 11:06:30AM +, Shiju Jose wrote:
>> L2 cache corrected errors are detected occasionally on few of our
>> ARM64 hardware boards. Though it is rare, the probability of the CPU
>> cache errors frequently occurring can't be avoided.
>> The earlier failure detection by monitoring the cache corrected errors
>> for the frequent occurrences and taking preventive action could
>> prevent more serious hardware faults.
>>
>> On Intel architectures, cache corrected errors are reported and the
>> affected cores are offline in the architecture specific method.
>> http://www.mcelog.org/cache.html
>>
>> However for the firmware-first error reporting, specifically on
>> ARM64 architectures, there is no provision present for reporting the
>> cache corrected error count to the user-space and taking preventive
>> action such as offline the affected cores.
>
>How hard was it to write that in your first submission? What do you think
>would be the best way to persuade a patch reviewer/maintainer to take a
>look at your submission?
>
>> >Why a separate Kconfig item?
>> CONFIG_EDAC_GHES_CPU_CACHE_ERROR is added to make this feature
>> optional only for the platforms which need this and supported.
>>
>> >
>> >> + depends on EDAC_GHES
>
>depends on EDAC_GHES hardly expresses which platforms need it/support it.
>
>If anything, depends on ARM64.
Sure. I will add dependency on ARM64.
This EDAC code for the cache errors is  architecture independent for the
firmware-first error reporting and  could be used for other architectures,
though now we need it for the ARM64. 

>
>> >Init stuff belongs into ghes_scan_system().
>> >
>> Did you mean calling  ghes_edac_create_cpu_device() in the
>ghes_scan_system()?
>
>I mean, all hardware discovery needs to happen in ghes_scan_system
>- you don't need to call those from outside the driver, in
>ghes_edac_register().

sure. Will modify.
>
>--
>Regards/Gruss,
>Boris.

Thanks,
Shiju


RE: [RFC PATCH 1/2] EDAC/ghes: Add EDAC device for the CPU caches

2021-01-15 Thread Shiju Jose
Hi Boris,

Thanks for the feedback.
Apologies for the delay.

>-Original Message-
>From: Borislav Petkov [mailto:b...@alien8.de]
>Sent: 31 December 2020 16:44
>To: Shiju Jose 
>Cc: linux-e...@vger.kernel.org; linux-a...@vger.kernel.org; linux-
>ker...@vger.kernel.org; james.mo...@arm.com;
>mchehab+hua...@kernel.org; tony.l...@intel.com; r...@rjwysocki.net;
>l...@kernel.org; rrich...@marvell.com; Linuxarm ;
>xuwei (O) ; Jonathan Cameron
>; John Garry ;
>tanxiaofei ; Shameerali Kolothum Thodi
>; Salil Mehta
>
>Subject: Re: [RFC PATCH 1/2] EDAC/ghes: Add EDAC device for the CPU
>caches
>
>On Tue, Dec 08, 2020 at 05:29:58PM +, Shiju Jose wrote:
>> The corrected error count on the CPU caches required reporting to the
>> user-space for the predictive failure analysis. For this purpose, add
>> an EDAC device and device blocks for the CPU caches found.
>> The cache's corrected error count would be stored in the
>> /sys/devices/system/edac/cpu/cpu*/cache*/ce_count.
>
>This still doesn't begin to explain why the kernel needs this. I had already
>asked whether errors in CPU caches are something which happen often
>enough so that software should count them but nothing came. So pls justify
>first why this wants to be added to the kernel.

L2 cache corrected errors are detected occasionally on few of
our ARM64 hardware boards. Though it is rare, the probability of
the CPU cache errors frequently occurring can't be avoided.
The earlier failure detection by monitoring the cache corrected
errors for the frequent occurrences and taking preventive
action could prevent more serious hardware faults.

On Intel architectures, cache corrected errors are reported and
the affected cores are offline in the architecture specific method.
http://www.mcelog.org/cache.html

However for the firmware-first error reporting, specifically on
ARM64 architectures, there is no provision present for reporting
the cache corrected error count to the user-space and taking
preventive action such as offline the affected cores.
>
>> diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index
>> 7a47680d6f07..c73eeab27ac9 100644
>> --- a/drivers/edac/Kconfig
>> +++ b/drivers/edac/Kconfig
>> @@ -74,6 +74,16 @@ config EDAC_GHES
>>
>>In doubt, say 'Y'.
>>
>> +config EDAC_GHES_CPU_ERROR
>> +bool "EDAC device for reporting firmware-first BIOS detected CPU
>error count"
>
>Why a separate Kconfig item?
CONFIG_EDAC_GHES_CPU_CACHE_ERROR is added to make this
feature optional only for the platforms which need this and supported.

>
>> +depends on EDAC_GHES
>> +help
>> +  EDAC device for the firmware-first BIOS detected CPU error count
>> +reported
>
>Well this is not what it is doing - you're talking about cache errors.
>"CPU errors" can be a lot more than just cache errors.
Sure. I will change.

>
>> +static void ghes_edac_create_cpu_device(struct device *dev) {
>> +int cpu;
>> +struct cpu_cacheinfo *this_cpu_ci;
>> +
>> +/*
>> + * Find the maximum number of caches present in the CPU heirarchy
>> + * among the online CPUs.
>> + */
>> +for_each_online_cpu(cpu) {
>> +this_cpu_ci = get_cpu_cacheinfo(cpu);
>> +if (!this_cpu_ci)
>> +continue;
>> +if (max_number_of_caches < this_cpu_ci->num_leaves)
>> +max_number_of_caches = this_cpu_ci->num_leaves;
>
>So this is counting the number of cache levels on the system? So you want to
>count the errors per cache levels?
Yes. This was the suggestion from James and to offline the affected cores for 
the shared cache.

>
>> +}
>> +if (!max_number_of_caches)
>> +return;
>> +
>> +/*
>> + * EDAC device interface only supports creating the CPU cache
>hierarchy for alls
>> + * the CPUs together. Thus need to allocate cpu_edac_block_list for
>the
>> + * max_number_of_caches among all the CPUs irrespective of the
>number of caches
>> + * per CPU might vary.
>> + */
>
>So this is lumping all the caches together into a single list? What for?
>To untangle to the proper ones when the error gets reported?
>
>Have you heard of percpu variables?
Yes. Changed the list to the percpu variable.

>
>> @@ -624,6 +787,10 @@ int ghes_edac_register(struct ghes *ghes, struct
>device *dev)
>>  ghes_pvt = pvt;
>>  spin_unlock_irqrestore(_lock, flags);
>>
>> +#if defined(CONFIG_EDAC_GHES_CPU_ERROR)
>> +ghes_edac_create_cpu_device(dev);
>> +#endif
>> +
>
>Init stuff belongs into ghes_scan

[RFC PATCH 2/2] ACPI / APEI: Add reporting ARM64 CPU cache corrected error count

2020-12-08 Thread Shiju Jose
Add reporting ARM64 CPU cache corrected error count to the ghes_edac.
The error count would be updated in the EDAC CPU cache sysfs
interface.

Note: This patch would be recreated after the patch
"ACPI / APEI: do memory failure on the physical address reported by ARM 
processor error section"
would be merged on the mainline.

Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 68 ++--
 include/linux/cper.h |  4 +++
 2 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index e7b0edbda0f8..37f8b09d810d 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -523,6 +524,69 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static u8 arm_err_transaction_type_to_cache_type(u8 trans_type)
+{
+   switch (trans_type) {
+   case CPER_ARM_CACHE_TRANS_TYPE_INSTRUCTION:
+   return CACHE_TYPE_INST;
+   case CPER_ARM_CACHE_TRANS_TYPE_DATA:
+   return CACHE_TYPE_DATA;
+   case CPER_ARM_CACHE_TRANS_TYPE_GENERIC:
+   default:
+   return CACHE_TYPE_UNIFIED;
+   }
+}
+
+static void ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata)
+{
+   struct cper_sec_proc_arm *error = acpi_hest_get_payload(gdata);
+   struct cper_arm_err_info *err_info;
+   struct ghes_einfo_cpu einfo;
+   u8 transaction_type;
+   u64 error_info;
+   int sec_sev;
+   int i;
+
+   log_arm_hw_error(error);
+
+   sec_sev = ghes_severity(gdata->error_severity);
+
+#if defined(CONFIG_ARM64)
+   if (sec_sev == GHES_SEV_CORRECTED) {
+   memset(, 0, sizeof(einfo));
+   einfo.cpu = get_logical_index(error->mpidr);
+   if (einfo.cpu == -EINVAL)
+   return;
+
+   /*
+* ARM processor error types are cache/TLB/bus errors.
+* Presently corrected error count for caches only
+* is reported.
+*/
+   err_info = (struct cper_arm_err_info *)(error + 1);
+
+   for (i = 0; i < error->err_info_num; i++) {
+   if (err_info->type != CPER_ARM_CACHE_ERROR)
+   continue;
+   einfo.ce_count = err_info->multiple_error + 1;
+
+   error_info = err_info->error_info;
+   if (!(error_info & CPER_ARM_ERR_VALID_TRANSACTION_TYPE) 
||
+   !(error_info & CPER_ARM_ERR_VALID_LEVEL))
+   continue;
+
+   transaction_type = ((error_info >> 
CPER_ARM_ERR_TRANSACTION_SHIFT)
+   & CPER_ARM_ERR_TRANSACTION_MASK);
+   einfo.cache_type = 
arm_err_transaction_type_to_cache_type(transaction_type);
+   einfo.cache_level = ((error_info >> 
CPER_ARM_ERR_LEVEL_SHIFT)
+   & CPER_ARM_ERR_LEVEL_MASK);
+   ghes_edac_report_cpu_error();
+   err_info += 1;
+   }
+   }
+#endif
+}
+
 static BLOCKING_NOTIFIER_HEAD(vendor_record_notify_list);
 
 int ghes_register_vendor_record_notifier(struct notifier_block *nb)
@@ -605,9 +669,7 @@ static bool ghes_do_proc(struct ghes *ghes,
ghes_handle_aer(gdata);
}
else if (guid_equal(sec_type, _SEC_PROC_ARM)) {
-   struct cper_sec_proc_arm *err = 
acpi_hest_get_payload(gdata);
-
-   log_arm_hw_error(err);
+   ghes_handle_arm_hw_error(gdata);
} else {
void *err = acpi_hest_get_payload(gdata);
 
diff --git a/include/linux/cper.h b/include/linux/cper.h
index 6a511a1078ca..0ea966af6ad9 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -314,6 +314,10 @@ enum {
 #define CPER_ARM_ERR_ACCESS_MODE_SHIFT 43
 #define CPER_ARM_ERR_ACCESS_MODE_MASK  GENMASK(0,0)
 
+#define CPER_ARM_CACHE_TRANS_TYPE_INSTRUCTION  0
+#define CPER_ARM_CACHE_TRANS_TYPE_DATA 1
+#define CPER_ARM_CACHE_TRANS_TYPE_GENERIC  2
+
 /*
  * All tables and structs must be byte-packed to match CPER
  * specification, since the tables are provided by the system BIOS
-- 
2.17.1



[RFC PATCH 1/2] EDAC/ghes: Add EDAC device for the CPU caches

2020-12-08 Thread Shiju Jose
The corrected error count on the CPU caches required
reporting to the user-space for the predictive failure
analysis. For this purpose, add an EDAC device and device
blocks for the CPU caches found.
The cache's corrected error count would be stored in the
/sys/devices/system/edac/cpu/cpu*/cache*/ce_count.

Issues and possible solutions,
1.Cache info is not available for the CPUs offline.
 EDAC device interface supports only creating EDAC device
 and device blocks for the all the CPU caches together.
 It requires the number of caches as device blocks for
 the creation. However, this info is not available for
 the CPUs which offline and may become online later.

Tested Solution: Find the max number of caches among
  online CPUs, create the EDAC device for CPUs caches
  and get and populate the cache info for an offline
  CPU later, when the error is reported on that CPU for
  the first time.

2. Reporting error count for the Shared caches.
   There are few possible solutions,
2.1 Kernel would report a new error count for a shared cache
per CPU through the EDAC device block for that CPU.
Then user-space application sums the total error count
for a shared cache from EDAC device blocks of all the
CPUs in the shared CPU list of that shared cache.
2.2 Kernel would report a new error count for a shared cache
through the EDAC device blocks for all the CPUs in the
shared CPU list of that shared cache.

Tested Solution: The current implementation used the solution 2.1

For the firmware-first error handling, add an interface in the
ghes_edac for reporting the CPU corrected error count for
a CPU core to the user-space through the CPU EDAC device.

Suggested-by: James Morse 
Signed-off-by: Shiju Jose 
---
 Documentation/ABI/testing/sysfs-devices-edac |  15 ++
 drivers/acpi/apei/ghes.c |   8 +-
 drivers/edac/Kconfig |  10 ++
 drivers/edac/ghes_edac.c | 171 +++
 include/acpi/ghes.h  |  27 +++
 5 files changed, 230 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-devices-edac 
b/Documentation/ABI/testing/sysfs-devices-edac
index 256a9e990c0b..56a18b0af419 100644
--- a/Documentation/ABI/testing/sysfs-devices-edac
+++ b/Documentation/ABI/testing/sysfs-devices-edac
@@ -155,3 +155,18 @@ Description:   This attribute file displays the total 
count of uncorrectable
errors that have occurred on this DIMM. If panic_on_ue is set, 
this
counter will not have a chance to increment, since EDAC will 
panic the
system
+
+What:   /sys/devices/system/edac/cpu/cpu*/cache*/ce_count
+Date:   December 2020
+Contact:linux-e...@vger.kernel.org
+Description:This attribute file displays the total count of correctable
+errors that have occurred on this CPU cache. This count is 
very important
+to examine. CEs provide early indications that a cache is 
beginning
+to fail. This count field should be monitored for non-zero 
values
+and report such information to the system administrator.
+
+What:   /sys/devices/system/edac/cpu/cpu*/cache*/ue_count
+Date:   December 2020
+Contact:linux-e...@vger.kernel.org
+Description:This attribute file displays the total count of uncorrectable
+errors that have occurred on this CPU cache.
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index fce7ade2aba9..e7b0edbda0f8 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -1452,4 +1452,10 @@ static int __init ghes_init(void)
 err:
return rc;
 }
-device_initcall(ghes_init);
+
+/*
+ * device_initcall_sync() is added instead of the device_initcall()
+ * because the CPU cacheinfo should be populated and needed for
+ * adding the CPU cache edac device blocks in the ghes_edac_register().
+ */
+device_initcall_sync(ghes_init);
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 7a47680d6f07..c73eeab27ac9 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -74,6 +74,16 @@ config EDAC_GHES
 
  In doubt, say 'Y'.
 
+config EDAC_GHES_CPU_ERROR
+   bool "EDAC device for reporting firmware-first BIOS detected CPU error 
count"
+   depends on EDAC_GHES
+   help
+ EDAC device for the firmware-first BIOS detected CPU error count 
reported
+ via ACPI APEI/GHES. By enabling this option, EDAC device for the CPU
+ hierarchy and edac device blocks for caches would be created.
+ The cpu error count is shared with the userspace via the CPU EDAC
+ device's sysfs interface.
+
 config EDAC_AMD64
tristate "AMD64 (Opteron, Athlon64)"
depends on AMD_NB && EDAC_DECODE_MCE
diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
index a918ca93e4f7..e6a73a413b33 100644
--- a/drivers/ed

[RFC PATCH 0/2] EDAC/ghes: Add EDAC device for recording the CPU error count

2020-12-08 Thread Shiju Jose
For the firmware-first error handling on ARM64 hardware platforms,
CPU cache corrected error count is not recorded.
Create an CPU EDAC device and device blocks for the CPU caches
for this purpose. The EDAC device blocks are created based on the
cache information from the cpu_cacheinfo.

User-space application could monitor the recorded corrected error
count for the predictive failure analysis.

More information in the patch headers.

Shiju Jose (2):
  EDAC/ghes: Add EDAC device for the CPU caches
  ACPI / APEI: Add reporting ARM64 CPU cache corrected error count

 Documentation/ABI/testing/sysfs-devices-edac |  15 ++
 drivers/acpi/apei/ghes.c |  76 -
 drivers/edac/Kconfig |  10 ++
 drivers/edac/ghes_edac.c | 171 +++
 include/acpi/ghes.h  |  27 +++
 include/linux/cper.h |   4 +
 6 files changed, 299 insertions(+), 4 deletions(-)

-- 
2.17.1



RE: [RFC PATCH 1/4] ACPI: PPTT: Fix for a high level cache node detected in the low level

2020-11-09 Thread Shiju Jose
Hi James,

Thanks for the feedback.

>-Original Message-
>From: James Morse [mailto:james.mo...@arm.com]
>Sent: 06 November 2020 19:34
>To: Shiju Jose ; linux-kernel@vger.kernel.org;
>b...@alien8.de; tony.l...@intel.com; r...@rjwysocki.net; l...@kernel.org;
>rrich...@marvell.com
>Cc: linux-e...@vger.kernel.org; linux-a...@vger.kernel.org; Linuxarm
>; Jonathan Cameron
>
>Subject: Re: [RFC PATCH 1/4] ACPI: PPTT: Fix for a high level cache node
>detected in the low level
>
>Hi Shiju, Jonathan,
>
>On 05/11/2020 17:42, Shiju Jose wrote:
>> From: Jonathan Cameron 
>>
>> According to the following sections of the PPTT definition in the ACPI
>> specification(V6.3), a high level cache node( For example L2 cache)
>> could be represented simultaneously both in the private resource of a
>> CPU node and via the next_level_of_cache pointer of a low level cache
>> node.
>> 1. Section 5.2.29.1 Processor hierarchy node structure (Type 0) "Each
>> processor node includes a list of resources that are private to that
>> node. Resources are described in other PPTT structures such as Type 1
>> cache structures. The processor node’s private resource list includes
>> a reference to each of the structures that represent private resources
>> to a given processor node. For example, an SoC level processor node
>> might contain two references, one pointing to a Level 3 cache resource
>> and another pointing to an ID structure."
>>
>> 2. Section 5.2.29.2 Cache Type Structure - Type 1
>>Figure 5-26 Cache Type Structure - Type 1 Example
>
>'fix' in the subject makes me twitch ... is there a user-space visible bug
>because of this?
>
>
>> For the use case of creating EDAC device blocks for the CPU caches, we
>> need to search for cache node types in all levels using
>> acpi_find_cache_node(), as a platform independent solution to
>
>I'm nervous to base the edac user-space view of caches on something other
>than what is described in /sys/devices/system/cpu/cpu0/cache. These things
>have to match, otherwise user-space can't work out which cpu's L2's it should
>add to get the value for the physical cache.
With this fix the /sys/devices/system/edac/cpu/cpu0/cacheN match with  
/sys/devices/system/cpu/cpu0/cache/indexN.
and thus user-space could extract cpu list for the shared caches.

>
>Getting the data from somewhere else risks making this more complicated.
>
>Using the PPTT means this won't work on "HPE Server"s that use ghes_edac
>too. I don't think we should have any arm64 specific behaviour here.
>
>
>> retrieve the cache info from the ACPI PPTT. The reason is that
>> cacheinfo in the drivers/base/cacheinfo.c would not be populated in
>> this stage.
>
>Because both ghes_init() and cacheinfo_sysfs_init() are device_initcall()?
>
>Couldn't we fix this by making ghes_init(), device_initcall_sync() (with a
>comment saying what it depends on)

I checked by making ghes_init(), device_initcall_sync(). Then the
ghes_probe() and ghes_edac_register() are getting
called after detect_cache_attributes() of base/cacheinfo.c function is called, 
where per_cpu_cacheinfo is allocated and populated for the cpu online. 
Thus cacheinfo data is available for the online CPUs.

>
>
>I agree this means dealing with cpuhp as the cacheinfo data is only available
>for online CPUs.

Does this require the EDAC device instance for a cpu become online/offline to 
be added/deleted
on cpuhp notify functions in the ghes_edac because the cache structure among 
CPU cores would vary?
If so, I think edac device does not support dynamic addition/deletion of a 
device instance because
edac_device_alloc_ctl_info() pre-allocates memory for the internal edac dev 
structures for the number of 
instances(number of CPUs) and number of blocks(number of Caches) passed?

>
>
>> In this case, we found acpi_find_cache_node() mistakenly detecting
>> high level cache as low level cache, when the cache node is in the
>> processor node’s private resource list.
>>
>> To fix this issue add duplication check in the
>> acpi_find_cache_level(), for a cache node found in the private
>> resource of a CPU node with all the next level of caches present in the other
>cache nodes.
>
>I'm not overly familiar with the PPTT, is it possible this issue is visible in
>/sys/devices/system/cpu/cpu0/cache?
>
>
>Thanks,
>
>James
>
>
>> diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index
>> 4ae93350b70d..de1dd605d3ad 100644
>> --- a/drivers/acpi/pptt.c
>> +++ b/drivers/acpi/pptt.c
>> @@ -132,21 +132,80 @@ static unsigned int acpi_pptt_walk_cache(struct
>acpi_table_header *table_hdr,
>>

[RFC PATCH 3/4] EDAC/ghes: Add EDAC device for the CPU caches

2020-11-05 Thread Shiju Jose
Find CPU caches in the ACPI PPTT and add CPU EDAC device
and EDAC device blocks for the caches found.

For the firmware-first error handling, add an interface in the
ghes_edac, enable to report the CPU corrected error count for
a CPU core to the user-space through the CPU EDAC device.

Suggested-by: James Morse 
Signed-off-by: Jonathan Cameron 
Signed-off-by: Shiju Jose 
---
 drivers/edac/Kconfig |  10 +++
 drivers/edac/ghes_edac.c | 135 +++
 include/acpi/ghes.h  |  27 
 3 files changed, 172 insertions(+)

diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 7a47680d6f07..3a0d8d134dcc 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -74,6 +74,16 @@ config EDAC_GHES
 
  In doubt, say 'Y'.
 
+config EDAC_GHES_CPU_ERROR
+   bool "EDAC device for reporting firmware-first BIOS detected CPU error 
count"
+   depends on EDAC_GHES && ACPI_PPTT
+   help
+ EDAC device for the firmware-first BIOS detected CPU error count 
reported
+ via ACPI APEI/GHES. By enabling this option, EDAC device for the CPU
+ hierarchy and EDAC device blocks for caches hierarchy would be 
created.
+ The cpu error count is shared with the userspace via the CPU EDAC
+ device's sysfs interface.
+
 config EDAC_AMD64
tristate "AMD64 (Opteron, Athlon64)"
depends on AMD_NB && EDAC_DECODE_MCE
diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
index a918ca93e4f7..96619483e5f3 100644
--- a/drivers/edac/ghes_edac.c
+++ b/drivers/edac/ghes_edac.c
@@ -12,6 +12,9 @@
 #include 
 #include 
 #include 
+#if defined(CONFIG_EDAC_GHES_CPU_ERROR)
+#include 
+#endif
 #include "edac_module.h"
 #include 
 
@@ -497,6 +500,130 @@ void ghes_edac_report_mem_error(int sev, struct 
cper_sec_mem_err *mem_err)
spin_unlock_irqrestore(_lock, flags);
 }
 
+#if defined(CONFIG_EDAC_GHES_CPU_ERROR)
+#define MAX_NUM_CACHES 20
+static struct ghes_edac_cpu_block {
+   int cpu;
+   u8 level;
+   u8 type;
+   int block_nr;
+} *cpu_edac_block_list;
+
+static struct edac_device_ctl_info *cpu_edac_dev;
+static int max_number_of_caches;
+
+void ghes_edac_report_cpu_error(struct ghes_einfo_cpu *einfo)
+{
+   struct ghes_edac_cpu_block *block;
+   int i;
+
+   if (!einfo || !(einfo->ce_count) || !max_number_of_caches)
+   return;
+
+   for (i = 0; i < max_number_of_caches; i++) {
+   block = cpu_edac_block_list + (einfo->cpu * 
max_number_of_caches) + i;
+   if ((block->level == einfo->cache_level) && (block->type == 
einfo->cache_type)) {
+   edac_device_handle_ce_count(cpu_edac_dev, 
einfo->ce_count,
+   einfo->cpu, 
block->block_nr, "");
+   break;
+   }
+   }
+}
+
+static  int ghes_edac_add_cpu_device(struct device *dev)
+{
+   int rc;
+
+   cpu_edac_dev = edac_device_alloc_ctl_info(0, "cpu",  
num_possible_cpus(),
+ "cache", 
max_number_of_caches, 0, NULL,
+ 0, edac_device_alloc_index());
+   if (!cpu_edac_dev) {
+   pr_warn("edac_device_alloc_ctl_info for cpu_edac_dev failed\n");
+   return -ENOMEM;
+   }
+
+   cpu_edac_dev->dev = dev;
+   cpu_edac_dev->ctl_name = "cpu_edac_dev";
+   cpu_edac_dev->dev_name = "ghes";
+   cpu_edac_dev->mod_name = "ghes_edac.c";
+   rc = edac_device_add_device(cpu_edac_dev);
+   if (rc) {
+   pr_warn("edac_device_add_device failed\n");
+   edac_device_free_ctl_info(cpu_edac_dev);
+   return rc;
+   }
+
+   return 0;
+}
+
+static  void ghes_edac_delete_cpu_device(void)
+{
+   max_number_of_caches = 0;
+   if (cpu_edac_dev) {
+   edac_device_del_device(cpu_edac_dev->dev);
+   edac_device_free_ctl_info(cpu_edac_dev);
+   }
+   vfree(cpu_edac_block_list);
+}
+
+static void ghes_edac_create_cpu_device(struct device *dev)
+{
+   int cpu, i;
+   struct ghes_edac_cpu_block *block;
+   int number_of_caches;
+   struct acpi_cacheinfo cacheinfo[MAX_NUM_CACHES];
+
+   /* Find the maximum number of caches present in the cpu heirarchy among 
the CPUs */
+   for_each_possible_cpu(cpu) {
+   number_of_caches = acpi_find_cache_info(cpu, [0], 
MAX_NUM_CACHES);
+   if (number_of_caches <= 0)
+   return;
+
+   if (max_number_of_caches < number_of_caches)
+   max_number_of_caches = number_of_caches;
+   }
+   if (!max_number_of_caches)
+   return;
+
+   /*
+* EDAC device interface 

[RFC PATCH 1/4] ACPI: PPTT: Fix for a high level cache node detected in the low level

2020-11-05 Thread Shiju Jose
From: Jonathan Cameron 

According to the following sections of the PPTT definition in the
ACPI specification(V6.3), a high level cache node( For example L2 cache)
could be represented simultaneously both in the private resource
of a CPU node and via the next_level_of_cache pointer of a low level
cache node.
1. Section 5.2.29.1 Processor hierarchy node structure (Type 0)
"Each processor node includes a list of resources that are private
to that node. Resources are described in other PPTT structures such as
Type 1 cache structures. The processor node’s private resource list
includes a reference to each of the structures that represent private
resources to a given processor node. For example, an SoC level processor
node might contain two references, one pointing to a Level 3 cache
resource and another pointing to an ID structure."

2. Section 5.2.29.2 Cache Type Structure - Type 1
   Figure 5-26 Cache Type Structure - Type 1 Example

For the use case of creating EDAC device blocks for the CPU caches,
we need to search for cache node types in all levels using
acpi_find_cache_node(), as a platform independent solution to
retrieve the cache info from the ACPI PPTT. The reason is that
cacheinfo in the drivers/base/cacheinfo.c would not be populated
in this stage. In this case, we found acpi_find_cache_node()
mistakenly detecting high level cache as low level cache, when
the cache node is in the processor node’s private resource list.

To fix this issue add duplication check in the acpi_find_cache_level(),
for a cache node found in the private resource of a CPU node
with all the next level of caches present in the other cache nodes.

Signed-off-by: Jonathan Cameron 
Co-developed-by: Shiju Jose 
Signed-off-by: Shiju Jose 
---
 drivers/acpi/pptt.c | 61 -
 1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index 4ae93350b70d..de1dd605d3ad 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -132,21 +132,80 @@ static unsigned int acpi_pptt_walk_cache(struct 
acpi_table_header *table_hdr,
return local_level;
 }
 
+/**
+ * acpi_pptt_walk_check_duplicate() - Find the cache resource to check,
+ * is a duplication in the next_level_of_cache pointer of other cache.
+ * @table_hdr: Pointer to the head of the PPTT table
+ * @res: cache resource in the PPTT we want to walk
+ * @res_check: cache resource in the PPTT we want to check for duplication.
+ *
+ * Given both PPTT resource, verify that they are cache nodes, then walk
+ * down each level of cache @res, and check for the duplication.
+ *
+ * Return: true if duplication found, false otherwise.
+ */
+static bool acpi_pptt_walk_check_duplicate(struct acpi_table_header *table_hdr,
+  struct acpi_subtable_header *res,
+  struct acpi_subtable_header 
*res_check)
+{
+   struct acpi_pptt_cache *cache;
+   struct acpi_pptt_cache *check;
+
+   if (res->type != ACPI_PPTT_TYPE_CACHE ||
+   res_check->type != ACPI_PPTT_TYPE_CACHE)
+   return false;
+
+   cache = (struct acpi_pptt_cache *)res;
+   check = (struct acpi_pptt_cache *)res_check;
+   while (cache) {
+   if (cache == check)
+   return true;
+   cache = fetch_pptt_cache(table_hdr, cache->next_level_of_cache);
+   }
+
+   return false;
+}
+
 static struct acpi_pptt_cache *
 acpi_find_cache_level(struct acpi_table_header *table_hdr,
  struct acpi_pptt_processor *cpu_node,
  unsigned int *starting_level, unsigned int level,
  int type)
 {
-   struct acpi_subtable_header *res;
+   struct acpi_subtable_header *res, *res2;
unsigned int number_of_levels = *starting_level;
int resource = 0;
+   int resource2 = 0;
+   bool duplicate = false;
struct acpi_pptt_cache *ret = NULL;
unsigned int local_level;
 
/* walk down from processor node */
while ((res = acpi_get_pptt_resource(table_hdr, cpu_node, resource))) {
resource++;
+   /*
+* PPTT definition in the ACPI specification allows a high 
level cache
+* node would be represented simultaneously both in the private 
resource
+* of a CPU node and via the next_level_of_cache pointer of 
another cache node,
+* within the same CPU hierarchy. This resulting 
acpi_find_cache_level()
+* mistakenly detects a higher level cache node in the low 
level as well.
+*
+* Check a cache node in the private resource of the CPU node 
for any
+* duplication.
+*/
+   resource2 = 0;
+   duplicate = false;
+   while ((res2 = acpi_get_pptt_resource(table_hdr, c

[RFC PATCH 2/4] ACPI: PPTT: Add function acpi_find_cache_info

2020-11-05 Thread Shiju Jose
Add function acpi_find_cache_info() to find the
information of the caches found in a CPU hierarchy
represented in the PPTT.

Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
Signed-off-by: Shiju Jose 
---
 drivers/acpi/pptt.c   | 62 +++
 include/linux/cacheinfo.h | 12 
 2 files changed, 74 insertions(+)

diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index de1dd605d3ad..5f46e6257e6b 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -670,6 +670,68 @@ int acpi_find_last_cache_level(unsigned int cpu)
return number_of_levels;
 }
 
+/**
+ * acpi_find_cache_info() - Find the information of CPU caches
+ * represented in the PPTT.
+ * @cpu: Kernel logical CPU number.
+ * @cacheinfo: array of struct acpi_cacheinfo.
+ * @size: dimension of the array.
+ *
+ * Given a logical CPU number, returns the info of caches
+ * represented in the PPTT.
+ * Errors caused by lack of a PPTT table, or otherwise, return 0
+ * indicating we didn't find any cache levels.
+ *
+ * Return: total number of caches found in the CPU hierarchy or error.
+ */
+int acpi_find_cache_info(unsigned int cpu, struct acpi_cacheinfo *cacheinfo,
+size_t size)
+{
+   u32 acpi_cpu_id;
+   acpi_status status;
+   struct acpi_table_header *table_hdr;
+   struct acpi_pptt_processor *cpu_node = NULL;
+   struct acpi_pptt_cache *found_cache;
+   int i, number_of_caches = 0;
+   int max_level, level = 1;
+   enum cache_type type[] = {
+   CACHE_TYPE_DATA,
+   CACHE_TYPE_INST,
+   CACHE_TYPE_UNIFIED,
+   };
+
+   if (!cacheinfo || !size)
+   return -ENOMEM;
+
+   status = acpi_get_table(ACPI_SIG_PPTT, 0, _hdr);
+   if (ACPI_FAILURE(status)) {
+   acpi_pptt_warn_missing();
+   return -ENOENT;
+   }
+
+   acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+   max_level = acpi_find_cache_levels(table_hdr, acpi_cpu_id);
+   while (level <= max_level) {
+   for (i = 0; i < ARRAY_SIZE(type); i++) {
+   found_cache = acpi_find_cache_node(table_hdr, 
acpi_cpu_id,
+  type[i], level, 
_node);
+   if (found_cache) {
+   cacheinfo[number_of_caches].level = level;
+   cacheinfo[number_of_caches].type = 
acpi_cache_type(type[i]);
+   number_of_caches++;
+   if (number_of_caches >= size) {
+   acpi_put_table(table_hdr);
+   return -ENOMEM;
+   }
+   }
+   }
+   level++;
+   }
+   acpi_put_table(table_hdr);
+
+   return number_of_caches;
+}
+
 /**
  * cache_setup_acpi() - Override CPU cache topology with data from the PPTT
  * @cpu: Kernel logical CPU number
diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h
index 4f72b47973c3..7d37945d2650 100644
--- a/include/linux/cacheinfo.h
+++ b/include/linux/cacheinfo.h
@@ -79,6 +79,11 @@ struct cpu_cacheinfo {
bool cpu_map_populated;
 };
 
+struct acpi_cacheinfo {
+   u8 level;
+   u8 type;
+};
+
 /*
  * Helpers to make sure "func" is executed on the cpu whose cache
  * attributes are being detected
@@ -114,8 +119,15 @@ static inline int acpi_find_last_cache_level(unsigned int 
cpu)
 {
return 0;
 }
+static inline int acpi_find_cache_info(unsigned int cpu, struct acpi_cacheinfo 
*cacheinfo,
+  size_t size)
+{
+   return 0;
+}
 #else
 int acpi_find_last_cache_level(unsigned int cpu);
+int acpi_find_cache_info(unsigned int cpu, struct acpi_cacheinfo *cacheinfo,
+size_t size);
 #endif
 
 const struct attribute_group *cache_get_priv_group(struct cacheinfo 
*this_leaf);
-- 
2.17.1



[RFC PATCH 0/4] EDAC/ghes: Add EDAC device for recording the CPU error count

2020-11-05 Thread Shiju Jose
For the firmware-first error handling on ARM64 hardware platforms,
CPU cache corrected error count is not recorded.
Create an CPU EDAC device and device blocks for the CPU caches
for this purpose. The EDAC device blocks  are created based on the
CPU caches information represented in the ACPI PPTT.

User-space application could monitor the recorded corrected error
count for the early fault detection.

Jonathan Cameron (1):
  ACPI: PPTT: Fix for a high level cache node detected in the low level

Shiju Jose (3):
  ACPI: PPTT: Add function acpi_find_cache_info
  EDAC/ghes: Add EDAC device for the CPU caches
  ACPI / APEI: Add reporting ARM64 CPU cache corrected error count

 drivers/acpi/apei/ghes.c  |  79 +-
 drivers/acpi/pptt.c   | 123 +-
 drivers/edac/Kconfig  |  10 +++
 drivers/edac/ghes_edac.c  | 135 ++
 include/acpi/ghes.h   |  27 
 include/linux/cacheinfo.h |  12 
 include/linux/cper.h  |   4 ++
 7 files changed, 386 insertions(+), 4 deletions(-)

-- 
2.17.1



[RFC PATCH 4/4] ACPI / APEI: Add reporting ARM64 CPU cache corrected error count

2020-11-05 Thread Shiju Jose
Add reporting ARM64 CPU cache corrected error count to the ghes_edac.
The error count would be updated in the EDAC CPU cache sysfs
interface.

Signed-off-by: Jonathan Cameron 
Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 79 ++--
 include/linux/cper.h |  4 ++
 2 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index fce7ade2aba9..b17173312087 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -523,6 +523,81 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+/*
+ * arm_err_trans_type_to_acpi_cache_type: Function to convert transaction type
+ * in the CPER's ARM cache error structure to the ACPI PPTT cache type.
+ *
+ * @type - transaction type. Type of cache error instruction/data/generic.
+ *
+ * Return: Success: ACPI PPTT cache type. Failure: Negative value.
+ */
+static u8 arm_err_trans_type_to_acpi_cache_type(u8 type)
+{
+   switch (type) {
+   case CPER_ARM_CACHE_TRANS_TYPE_INSTRUCTION:
+   return ACPI_PPTT_CACHE_TYPE_INSTR;
+   case CPER_ARM_CACHE_TRANS_TYPE_DATA:
+   return ACPI_PPTT_CACHE_TYPE_DATA;
+   case CPER_ARM_CACHE_TRANS_TYPE_GENERIC:
+   return ACPI_PPTT_CACHE_TYPE_UNIFIED;
+   default:
+   pr_warn_ratelimited("FW_WARN GHES_PFX ARM CPER: Invalid cache 
transaction type\n");
+   return -EINVAL;
+   }
+}
+
+static void ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata)
+{
+   struct cper_sec_proc_arm *error = acpi_hest_get_payload(gdata);
+   struct cper_arm_err_info *err_info;
+   struct ghes_einfo_cpu einfo;
+   u8 trans_type;
+   u64 error_info;
+   int sec_sev;
+   int i, cache_type;
+
+   log_arm_hw_error(error);
+
+   sec_sev = ghes_severity(gdata->error_severity);
+
+#if defined(CONFIG_ARM64)
+   if (sec_sev == GHES_SEV_CORRECTED) {
+   memset(, 0, sizeof(einfo));
+   einfo.cpu = get_logical_index(error->mpidr);
+   if (einfo.cpu == -EINVAL)
+   return;
+
+   /* ARM processor error types are cache/TLB/bus errors.
+* Presently corrected error count for caches only
+* is reported.
+*/
+   err_info = (struct cper_arm_err_info *)(error + 1);
+
+   for (i = 0; i < error->err_info_num; i++) {
+   if (err_info->type != CPER_ARM_CACHE_ERROR)
+   continue;
+   einfo.ce_count = err_info->multiple_error + 1;
+
+   error_info = err_info->error_info;
+   if (!(error_info & CPER_ARM_ERR_VALID_TRANSACTION_TYPE) 
||
+   !(error_info & CPER_ARM_ERR_VALID_LEVEL))
+   continue;
+
+   trans_type = ((error_info >> 
CPER_ARM_ERR_TRANSACTION_SHIFT)
+   & CPER_ARM_ERR_TRANSACTION_MASK);
+   cache_type = 
arm_err_trans_type_to_acpi_cache_type(trans_type);
+   if (cache_type < 0)
+   continue;
+   einfo.cache_type = cache_type;
+   einfo.cache_level = ((error_info >> 
CPER_ARM_ERR_LEVEL_SHIFT)
+   & CPER_ARM_ERR_LEVEL_MASK);
+   ghes_edac_report_cpu_error();
+   err_info += 1;
+   }
+   }
+#endif
+}
+
 static BLOCKING_NOTIFIER_HEAD(vendor_record_notify_list);
 
 int ghes_register_vendor_record_notifier(struct notifier_block *nb)
@@ -605,9 +680,7 @@ static bool ghes_do_proc(struct ghes *ghes,
ghes_handle_aer(gdata);
}
else if (guid_equal(sec_type, _SEC_PROC_ARM)) {
-   struct cper_sec_proc_arm *err = 
acpi_hest_get_payload(gdata);
-
-   log_arm_hw_error(err);
+   ghes_handle_arm_hw_error(gdata);
} else {
void *err = acpi_hest_get_payload(gdata);
 
diff --git a/include/linux/cper.h b/include/linux/cper.h
index 6a511a1078ca..0ea966af6ad9 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -314,6 +314,10 @@ enum {
 #define CPER_ARM_ERR_ACCESS_MODE_SHIFT 43
 #define CPER_ARM_ERR_ACCESS_MODE_MASK  GENMASK(0,0)
 
+#define CPER_ARM_CACHE_TRANS_TYPE_INSTRUCTION  0
+#define CPER_ARM_CACHE_TRANS_TYPE_DATA 1
+#define CPER_ARM_CACHE_TRANS_TYPE_GENERIC  2
+
 /*
  * All tables and structs must be byte-packed to match CPER
  * specification, since the tables are provided by the system BIOS
-- 
2.17.1



[PATCH 1/1] ACPI/IORT: Fix doc warnings in iort.c

2020-10-14 Thread Shiju Jose
Fix following warnings caused by mismatch between
function parameters and function comments.

drivers/acpi/arm64/iort.c:55: warning: Function parameter or member 'iort_node' 
not described in 'iort_set_fwnode'
drivers/acpi/arm64/iort.c:55: warning: Excess function parameter 'node' 
description in 'iort_set_fwnode'
drivers/acpi/arm64/iort.c:682: warning: Function parameter or member 'id' not 
described in 'iort_get_device_domain'
drivers/acpi/arm64/iort.c:682: warning: Function parameter or member 
'bus_token' not described in 'iort_get_device_domain'
drivers/acpi/arm64/iort.c:682: warning: Excess function parameter 'req_id' 
description in 'iort_get_device_domain'
drivers/acpi/arm64/iort.c:1142: warning: Function parameter or member 
'dma_size' not described in 'iort_dma_setup'
drivers/acpi/arm64/iort.c:1142: warning: Excess function parameter 'size' 
description in 'iort_dma_setup'
drivers/acpi/arm64/iort.c:1534: warning: Function parameter or member 'ops' not 
described in 'iort_add_platform_device'

Signed-off-by: Shiju Jose 
---
 drivers/acpi/arm64/iort.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 9929ff50c0c0..770d84071a32 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -44,7 +44,7 @@ static DEFINE_SPINLOCK(iort_fwnode_lock);
  * iort_set_fwnode() - Create iort_fwnode and use it to register
  *iommu data in the iort_fwnode_list
  *
- * @node: IORT table node associated with the IOMMU
+ * @iort_node: IORT table node associated with the IOMMU
  * @fwnode: fwnode associated with the IORT node
  *
  * Returns: 0 on success
@@ -673,7 +673,8 @@ static int iort_dev_find_its_id(struct device *dev, u32 id,
 /**
  * iort_get_device_domain() - Find MSI domain related to a device
  * @dev: The device.
- * @req_id: Requester ID for the device.
+ * @id: Requester ID for the device.
+ * @bus_token: irq domain bus token.
  *
  * Returns: the MSI domain for this device, NULL otherwise
  */
@@ -1136,7 +1137,7 @@ static int rc_dma_get_range(struct device *dev, u64 *size)
  *
  * @dev: device to configure
  * @dma_addr: device DMA address result pointer
- * @size: DMA range size result pointer
+ * @dma_size: DMA range size result pointer
  */
 void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
 {
@@ -1526,6 +1527,7 @@ static __init const struct iort_dev_config 
*iort_get_dev_cfg(
 /**
  * iort_add_platform_device() - Allocate a platform device for IORT node
  * @node: Pointer to device ACPI IORT node
+ * @ops: Pointer to IORT device config struct
  *
  * Returns: 0 on success, <0 failure
  */
-- 
2.17.1




[PATCH 1/1] crypto: hisilicon: Fix doc warnings in sgl.c and qm.c

2020-10-09 Thread Shiju Jose
Fix following warnings caused by mismatch between
function parameters and function comments.

drivers/crypto/hisilicon/sgl.c:256: warning: Excess function parameter 
'hw_sgl_dma' description in 'hisi_acc_sg_buf_unmap'
drivers/crypto/hisilicon/sgl.c:256: warning: Excess function parameter 'pool' 
description in 'hisi_acc_sg_buf_unmap'
drivers/crypto/hisilicon/qm.c:1849: warning: Function parameter or member 'qp' 
not described in 'qm_drain_qp'
drivers/crypto/hisilicon/qm.c:2420: warning: Function parameter or member 'qm' 
not described in 'hisi_qm_set_vft'
drivers/crypto/hisilicon/qm.c:2420: warning: Function parameter or member 
'fun_num' not described in 'hisi_qm_set_vft'
drivers/crypto/hisilicon/qm.c:2420: warning: Function parameter or member 
'base' not described in 'hisi_qm_set_vft'
drivers/crypto/hisilicon/qm.c:2420: warning: Function parameter or member 
'number' not described in 'hisi_qm_set_vft'
drivers/crypto/hisilicon/qm.c:2620: warning: Function parameter or member 'qm' 
not described in 'qm_clear_queues'

Signed-off-by: Shiju Jose 
Reviewed-by: Zhou Wang 
---
 drivers/crypto/hisilicon/qm.c  | 13 +
 drivers/crypto/hisilicon/sgl.c |  2 --
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 530f23116d7c..050fe4e74523 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -1843,6 +1843,9 @@ int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long 
arg)
 EXPORT_SYMBOL_GPL(hisi_qm_start_qp);
 
 /**
+ * qm_drain_qp() - Drain a qp.
+ * @qp: The qp we want to drain.
+ *
  * Determine whether the queue is cleared by judging the tail pointers of
  * sq and cq.
  */
@@ -2486,6 +2489,12 @@ int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 
*number)
 EXPORT_SYMBOL_GPL(hisi_qm_get_vft);
 
 /**
+ * hisi_qm_set_vft() - Set vft to a qm.
+ * @qm: The qm we want to set its vft.
+ * @fun_num: The function number.
+ * @base: The base number of queue in vft.
+ * @number: The number of queues in vft.
+ *
  * This function is alway called in PF driver, it is used to assign queues
  * among PF and VFs.
  *
@@ -2690,7 +2699,11 @@ static int qm_stop_started_qp(struct hisi_qm *qm)
return 0;
 }
 
+
 /**
+ * qm_clear_queues() - Clear all queues memory in a qm.
+ * @qm: The qm in which the queues will be cleared.
+ *
  * This function clears all queues memory in a qm. Reset of accelerator can
  * use this to clear queues.
  */
diff --git a/drivers/crypto/hisilicon/sgl.c b/drivers/crypto/hisilicon/sgl.c
index 725a739800b0..3bff6394acaf 100644
--- a/drivers/crypto/hisilicon/sgl.c
+++ b/drivers/crypto/hisilicon/sgl.c
@@ -246,8 +246,6 @@ EXPORT_SYMBOL_GPL(hisi_acc_sg_buf_map_to_hw_sgl);
  * @dev: The device which hw sgl belongs to.
  * @sgl: Related scatterlist.
  * @hw_sgl: Virtual address of hw sgl.
- * @hw_sgl_dma: DMA address of hw sgl.
- * @pool: Pool which hw sgl is allocated in.
  *
  * This function unmaps allocated hw sgl.
  */
-- 
2.17.1




RE: [RFC PATCH 0/7] RAS/CEC: Extend CEC for errors count check on short time period

2020-10-06 Thread Shiju Jose
Hi James,

Thanks for the reply and the information shared.

>-Original Message-
>From: James Morse [mailto:james.mo...@arm.com]
>Sent: 02 October 2020 18:33
>To: Shiju Jose 
>Cc: Borislav Petkov ; linux-e...@vger.kernel.org; linux-
>a...@vger.kernel.org; linux-kernel@vger.kernel.org; tony.l...@intel.com;
>r...@rjwysocki.net; l...@kernel.org; Linuxarm 
>Subject: Re: [RFC PATCH 0/7] RAS/CEC: Extend CEC for errors count check on
>short time period
>
>Hi Shiju,
>
>On 02/10/2020 16:38, Shiju Jose wrote:
>>> -Original Message-
>>> From: Borislav Petkov [mailto:b...@alien8.de]
>>> Sent: 02 October 2020 13:44
>>> To: Shiju Jose 
>>> Cc: linux-e...@vger.kernel.org; linux-a...@vger.kernel.org; linux-
>>> ker...@vger.kernel.org; tony.l...@intel.com; r...@rjwysocki.net;
>>> james.mo...@arm.com; l...@kernel.org; Linuxarm
>
>>> Subject: Re: [RFC PATCH 0/7] RAS/CEC: Extend CEC for errors count
>>> check on short time period
>>>
>>> On Fri, Oct 02, 2020 at 01:22:28PM +0100, Shiju Jose wrote:
>>>> Open Questions based on the feedback from Boris, 1. ARM processor
>>>> error types are cache/TLB/bus errors.
>>>>[Reference N2.4.4.1 ARM Processor Error Information UEFI Spec
>>>> v2.8] Any of the above error types should not be consider for the
>>>> error collection and CPU core isolation?
>
>Boris' earlier example was that Bus errors have very little to do with the CPU.
>It may just be that this CPU is handling the IRQs for a fault device, and thus
>receiving the errors. irqbalance could change that anytime.
>
>I'd prefer we just stick with the caches for now.
>
[...]

>
>>> Open question from James with my reply to it:
>>>
>>> On Thu, Oct 01, 2020 at 06:16:03PM +0100, James Morse wrote:
>>>> If the corrected-count is available somewhere, can't this policy be
>>>> made in user-space?
>
>> The error count is present in the struct cper_arm_err_info, the fields
>> of this structure  are not reported to the user-space through trace events?
>
>> Presently the fields of table struct cper_sec_proc_arm only are
>> reported to the user-space through trace-arm-event.
>> Also there can be multiple cper_arm_err_info per cper_sec_proc_arm.
>> Thus I think this need reporting through a new trace event?
>
>I think it would be more useful to feed this into edac like ghes.c already does
>for memory errors. These would end up as corrected errors counts on devices
>for L3 or whatever.
>
>This saves fixing your user-space component to the arm specific CPER record
>format, or even firmware-first, meaning its useful to the widest number of
>people.
>
>
>> Also the logical index of a CPU which I think need to extract from the
>'mpidr' field of
>> struct cper_sec_proc_arm using platform dependent kernel function
>get_logical_index().
>> Thus cpu index also need to report to the user space.
>
>I thought you were talking about caches. These structures have a 'level' for
>cache errors.
>
>Certainly you need a way of knowing which cache it is, and from that number
>you should also be able to work out which the CPUs it is attached to.
>
>x86 already has a way of doing this:
>https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Docu
>mentation/x86/resctrl_ui.rst#n327
>
>arm64 doesn't have anything equivalent, but my current proposal for MPAM
>is here:
>https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/commit/?h=
>mpam/snapshot/feb=ce3148bd39509ac8b12f5917f0f92ce014a5b22f
>
>I was hoping the PPTT table would grow something we could use as an ID, but
>I've not seen anything yet.

Please find following pseudo code we added for the kernel side to make sure
we correctly understand your suggestions.

1. Create edac device and edac device sysfs entries for the online CPU caches.
/drivers/edac/edac_device.c
struct edac_device_ctl_info  *edac_device_add_cache(unsigned int id, u8 level, 
u8 type) {
...
/* Check edac entry for cache already present */   
edev_cache = find_edac_device_cache(id, level, type);
if (edev_cache)
return edev_cache;
 
edev_cache = edac_device_alloc_ctrl_info(...);
if (!edev_cache)
return NULL;

rc = edac_device_add_device(edev_cache);
if (rc)
goto exit;

/* store edev_cache for future use */
...
return edev_cache;

 exit:
...
return NULL; 
 }

/drivers/base/cacheinfo.c
int cache_create_edac_entries(u64 mpidr, u8 cache_level, u8 cache_type)
{ 
...
/* Get cacheinfo for each online cpus */

RE: [RFC PATCH 0/7] RAS/CEC: Extend CEC for errors count check on short time period

2020-10-02 Thread Shiju Jose
Hi Boris, Hi James,

>-Original Message-
>From: Borislav Petkov [mailto:b...@alien8.de]
>Sent: 02 October 2020 13:44
>To: Shiju Jose 
>Cc: linux-e...@vger.kernel.org; linux-a...@vger.kernel.org; linux-
>ker...@vger.kernel.org; tony.l...@intel.com; r...@rjwysocki.net;
>james.mo...@arm.com; l...@kernel.org; Linuxarm
>
>Subject: Re: [RFC PATCH 0/7] RAS/CEC: Extend CEC for errors count check on
>short time period
>
>On Fri, Oct 02, 2020 at 01:22:28PM +0100, Shiju Jose wrote:
>> Open Questions based on the feedback from Boris, 1. ARM processor
>> error types are cache/TLB/bus errors.
>>[Reference N2.4.4.1 ARM Processor Error Information UEFI Spec v2.8]
>> Any of the above error types should not be consider for the error
>> collection and CPU core isolation?
>>
>> 2.If disabling entire CPU core is not acceptable, please suggest
>> method to disable L1 and L2 cache on ARM64 core?
>
>More open questions:
>
>> This requirement is the part of the early fault prediction by taking
>> action when large number of corrected errors reported on a CPU core
>> before it causing serious faults.
>
>And do you know of actual real-life examples where this is really the case? Do
>you have any users who report a large error count on ARM CPUs, originating
>from the caches and that something like that would really help?
>
>Because from my x86 CPUs limited experience, the cache arrays are mostly
>fine and errors reported there are not something that happens very
>frequently so we don't even need to collect and count those.
>
>So is this something which you need to have in order to check a box
>somewhere that there is some functionality or is there an actual real-life use
>case behind it which a customer has requested?
We have not got a real-life example for this case. However rare errors
like this can occur frequently sometimes at scale, which would cause
more serious issues if not handled.
>
>Open question from James with my reply to it:
>
>On Thu, Oct 01, 2020 at 06:16:03PM +0100, James Morse wrote:
>> If the corrected-count is available somewhere, can't this policy be
>> made in user-space?
The error count is present in the struct cper_arm_err_info, the fields of
this structure  are not reported to the user-space through trace events?
Presently the fields of table struct cper_sec_proc_arm only are reported 
to the user-space through trace-arm-event.
Also there can be multiple cper_arm_err_info per cper_sec_proc_arm.
Thus I think this need reporting through a new trace event?

Also the logical index of a CPU which I think need to extract from the 'mpidr' 
field of
struct cper_sec_proc_arm using platform dependent kernel function 
get_logical_index().
Thus cpu index also need to report to the user space.
>
>You mean rasdaemon goes and offlines CPUs when certain thresholds are
>reached? Sure. It would be much more flexible too.
I think adding the CPU error collection to the kernel
has the following advantages,
1. The CPU error collection and isolation would not be active if the
 rasdaemon stopped running or not running on a machine.
2. Receiving errors and isolating a CPU core from the user-space would
probably delayed more,  when large number of errors are reported.
   3. Supporting the interface for configuration parameters and  error 
statistics etc
probably easy to implement in the kernel.
   4. The interface given for disabling a CPU is easy to use from the kernel 
level.

>
>First we answer questions and discuss, then we code.
>
>--
>Regards/Gruss,
>Boris.
>

Thanks,
Shiju

>https://people.kernel.org/tglx/notes-about-netiquette


[RFC PATCH 7/7] ACPI / APEI: Add reporting ARM64 CPU correctable errors to the CEC

2020-10-02 Thread Shiju Jose
Add reporting ARM64 CPU correctable errors to the RAS correctable
errors collector(CEC).

ARM processor error types are cache/TLB/bus errors.
Any of the above error types should not be consider for the
error collection and CPU core isolation?

Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 36 +---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 81bf71b10d44..3cecb457d352 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -511,6 +511,38 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static void ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata)
+{
+   struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
+   struct cper_arm_err_info *err_info;
+   int sec_sev;
+   int cpu, i, ret;
+
+   log_arm_hw_error(err);
+
+   sec_sev = ghes_severity(gdata->error_severity);
+   if (sec_sev != GHES_SEV_CORRECTED)
+   return;
+
+#if defined(CONFIG_ARM64)
+   cpu = get_logical_index(err->mpidr);
+   if (cpu == -EINVAL)
+   return;
+
+   /* ARM processor error types are cache/tlb/bus errors.
+* Any of the above error types should not be consider for the
+* error collection and CPU core isolation?
+*/
+   err_info = (struct cper_arm_err_info *)(err + 1);
+   for (i = 0; i < err->err_info_num; i++) {
+   ret = cec_cpu_add_elem(cpu, err_info->multiple_error + 1);
+   if (ret)
+   break;
+   err_info += 1;
+   }
+#endif
+}
+
 static bool ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -543,9 +575,7 @@ static bool ghes_do_proc(struct ghes *ghes,
ghes_handle_aer(gdata);
}
else if (guid_equal(sec_type, _SEC_PROC_ARM)) {
-   struct cper_sec_proc_arm *err = 
acpi_hest_get_payload(gdata);
-
-   log_arm_hw_error(err);
+   ghes_handle_arm_hw_error(gdata);
} else {
void *err = acpi_hest_get_payload(gdata);
 
-- 
2.17.1




[RFC PATCH 6/7] RAS/CEC: Add CPU Correctable Error Collector to isolate an erroneous CPU core

2020-10-02 Thread Shiju Jose
When the CPU correctable errors, for example L1/L2 cache errors,
reported on an ARM64 CPU core too often, it should be isolated.
Add the CPU correctable error collector to store the CPU correctable
error count.

When the correctable error count for a CPU exceed the threshold
value in a short time period, it will try to isolate the CPU core.

If disabling entire CPU core is not acceptable, Please suggest
method to disable L1 and L2 cache on ARM64 core?

Signed-off-by: Shiju Jose 
---
 arch/arm64/ras/Kconfig |  17 +++
 drivers/ras/Kconfig|   1 +
 drivers/ras/cec.c  | 231 +++--
 include/linux/ras.h|   9 ++
 4 files changed, 247 insertions(+), 11 deletions(-)
 create mode 100644 arch/arm64/ras/Kconfig

diff --git a/arch/arm64/ras/Kconfig b/arch/arm64/ras/Kconfig
new file mode 100644
index ..bfa14157cd2e
--- /dev/null
+++ b/arch/arm64/ras/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
+config RAS_CEC
+bool "Correctable Errors Collector"
+depends on ARM64 && HOTPLUG_CPU && DEBUG_FS
+help
+  This is a small cache which collects correctable CPU errors and
+  counts their repeated occurrence. Once the counter for a CPU
+  overflows in a short time period, we try to offline that CPU
+  as we take it to mean that it has reached a relatively high error
+  count and would probably be best if we don't use it anymore.
+
+  Presently CPU error correction enabld for ARM64 platform only.
+
+config RAS_CEC_DEBUG
+bool "CEC debugging machinery"
+default n
+depends on RAS_CEC
diff --git a/drivers/ras/Kconfig b/drivers/ras/Kconfig
index c2a236f2e846..d2f877e5f7ad 100644
--- a/drivers/ras/Kconfig
+++ b/drivers/ras/Kconfig
@@ -32,5 +32,6 @@ menuconfig RAS
 if RAS
 
 source "arch/x86/ras/Kconfig"
+source "arch/arm64/ras/Kconfig"
 
 endif
diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index ca52917d514c..408bf2ac2461 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -7,6 +7,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #if defined(CONFIG_X86_MCE)
 #include 
@@ -143,7 +145,7 @@ static struct ce_array {
};
__u32 flags;
};
-} ce_arr;
+} ce_arr, cpu_ce_arr;
 
 static u64 dfs_pfn;
 
@@ -156,6 +158,8 @@ static u64 action_threshold = COUNT_MASK;
 #define CEC_DECAY_MAX_INTERVAL30 * 24 * 60 * 60/* one month */
 static u64 decay_interval = CEC_DECAY_DEFAULT_INTERVAL;
 
+static const char * const bins[] = { "00", "01", "10", "11" };
+
 /* Definitions for elements (for example CPU) for which
  * error count on shrot time period is checked with threshold.
  *
@@ -484,6 +488,172 @@ static int cec_add_elem(u64 pfn)
return ret;
 }
 
+struct cec_elem_offline {
+   struct work_struct work;
+   struct ce_array *ca;
+   int array_index;
+   int elem_id;
+};
+
+/*
+ * Work function to offline a cpu because the offlining to be done
+ * in the process context.
+ */
+static void cec_cpu_offline_work_fn(struct work_struct *work)
+{
+   int rc, cpu;
+   struct cec_elem_offline *elem;
+   struct ce_array *ca;
+
+   elem = container_of(work, struct cec_elem_offline, work);
+
+   cpu = elem->elem_id;
+   if (!cpu_online(cpu))
+   return;
+
+   rc = remove_cpu(cpu);
+   if (rc) {
+   pr_warn("Failed to offline CPU%d, error %d\n", cpu, rc);
+   } else {
+   ca = elem->ca;
+   ca->array[elem->array_index] |= ELEM_STATUS_BIT;
+   }
+
+   kfree(elem);
+}
+
+int cec_cpu_add_elem(int cpu, u64 ce_count)
+{
+   struct ce_array *ca = _ce_arr;
+   unsigned int to = 0;
+   int count, ret = 0;
+   unsigned long flags;
+   struct cec_elem_offline *elem;
+
+   /*
+* We can be called very early on the identify_cpu() path where we are
+* not initialized yet. We ignore the error for simplicity.
+*/
+   if (!ca->array || ca->disabled || !cpu_online(cpu))
+   return -ENODEV;
+
+   spin_lock_irqsave(>spin_lock, flags);
+
+   ca->ces_entered++;
+
+   ret = find_elem(ca, cpu, );
+   if (ret < 0) {
+   /*
+* Shift range [to-end] to make room for one more element.
+*/
+   memmove((void *)>array[to + 1],
+   (void *)>array[to],
+   (ca->n - to) * sizeof(u64));
+
+   ca->array[to] = cpu << ca->id_shift;
+   ca->n++;
+   }
+
+   /* Error received for a previously CEC offlined CPU, which later online 
elsewhere.
+* reset array.
+*/
+   if (ca->array[to] & ELEM_STATUS_BIT) {
+   ca->array[to] &= ~(ELEM_STATUS_BIT);
+  

[RFC PATCH 5/7] RAS/CEC: Add support for errors count check on short time period

2020-10-02 Thread Shiju Jose
Some types of elements, for example CPU core, should be isolated
when the corrected errors reported too often. This is used for the
early fault prediction and would help to prevent serious faults
by taking corrective actions.
Modify CEC to support for the errors count check on short
time period. Implementation details is added in the file.

Signed-off-by: Shiju Jose 
---
 drivers/ras/cec.c | 125 --
 1 file changed, 109 insertions(+), 16 deletions(-)

diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index f869e7a270b8..ca52917d514c 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -119,6 +119,23 @@ static struct ce_array {
 * shift for element id.
 */
 
+   struct delayed_work work;   /*
+* delayed work.
+*/
+
+   bool short_period;  /* Indicates threshold check for the 
error count
+* over short time period.
+*/
+
+   u8 time_slot;   /*
+* time slot's number within the decay 
interval.
+*/
+
+   union {
+   struct mutexmutex;
+   spinlock_t  spin_lock;
+   };
+
union {
struct {
__u32   disabled : 1,   /* cmdline disabled */
@@ -128,7 +145,6 @@ static struct ce_array {
};
 } ce_arr;
 
-static DEFINE_MUTEX(ce_mutex);
 static u64 dfs_pfn;
 
 /* Amount of errors after which we offline */
@@ -138,9 +154,35 @@ static u64 action_threshold = COUNT_MASK;
 #define CEC_DECAY_DEFAULT_INTERVAL 24 * 60 * 60/* 24 hrs */
 #define CEC_DECAY_MIN_INTERVAL  1 * 60 * 60/* 1h */
 #define CEC_DECAY_MAX_INTERVAL30 * 24 * 60 * 60/* one month */
-static struct delayed_work cec_work;
 static u64 decay_interval = CEC_DECAY_DEFAULT_INTERVAL;
 
+/* Definitions for elements (for example CPU) for which
+ * error count on shrot time period is checked with threshold.
+ *
+ * An element such as a CPU core may need to isolate when large number of
+ * correctable errors are reported on that element too often. When the
+ * CEs count is exceeded the threshold value in a short time period.
+ *
+ * The decay interval is divided into a number of time slots. The CE collector
+ * calculates the average error count at the end of each decay interval. Then
+ * the average count would be subtracted from the total count in each following
+ * time slots. The work function for the decay interval would be set  for the
+ * reduced time period = decay interval/ number of time slots. When the new
+ * CE count for a cpu is added, the element would be offlined when the sum of
+ * the most recent CEs counts exceeded the CE threshold value.
+ */
+
+/*
+ * u64: [ 63 ELEM ID 23 | ELEM_STATUS_BIT 22 | 21 AVG_COUNT_BITS 12 | 11 
DECAY_BITS 10 | 9 COUNT_BITS 0]
+ */
+
+/* Number of time slots in the decay interval */
+#define RAS_CEC_NUM_TIME_SLOTS 10
+
+#define AVG_COUNT_SHIFT(DECAY_BITS + COUNT_BITS)
+#define ELEM_STATUS_BITBIT(22) /* Indicates an element offlined by CEC 
*/
+#define ELEM_ID_SHIFT  (1 + AVG_COUNT_SHIFT + COUNT_BITS)
+
 /*
  * Decrement decay value. We're using DECAY_BITS bits to denote decay of an
  * element in the array. On insertion and any access, it gets reset to max.
@@ -177,11 +219,62 @@ static void cec_mod_work(struct delayed_work *dwork, 
unsigned long interval)
 
 static void cec_work_fn(struct work_struct *work)
 {
-   mutex_lock(_mutex);
-   do_spring_cleaning(_arr);
-   mutex_unlock(_mutex);
+   struct ce_array *ca;
+   unsigned long flags;
+   u64 avg_count;
+   int i, time_slots = 1;
+   struct delayed_work *d_work = container_of(work, struct delayed_work, 
work);
+
+   if (!d_work)
+   return;
+
+   ca = container_of(d_work, struct ce_array, work);
+   if (!ca->array || ca->disabled)
+   return;
 
-   cec_mod_work(_work, decay_interval);
+   if (!ca->short_period) {
+   mutex_lock(>mutex);
+   do_spring_cleaning(ca);
+   mutex_unlock(>mutex);
+   } else {
+   time_slots = RAS_CEC_NUM_TIME_SLOTS;
+   spin_lock_irqsave(>spin_lock, flags);
+   ca->time_slot = (ca->time_slot + 1) % RAS_CEC_NUM_TIME_SLOTS;
+
+   for (i = 0; i < ca->n; i++) {
+   if (ca->array[i] & ELEM_STATUS_BIT)
+   continue;
+
+   /* clear old errors count approximately by subtracting 
the avg count
+* from the total errors count.
+*/
+   avg_count = (ca->array[i] >> AVG_COUNT_SH

[RFC PATCH 4/7] RAS/CEC: Modify cec_mod_work() for common use

2020-10-02 Thread Shiju Jose
Modify the function cec_mod_work() for the common use
with the other error sources.

Signed-off-by: Shiju Jose 
---
 drivers/ras/cec.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index 803e641d8e5c..f869e7a270b8 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -167,12 +167,12 @@ static void do_spring_cleaning(struct ce_array *ca)
 /*
  * @interval in seconds
  */
-static void cec_mod_work(unsigned long interval)
+static void cec_mod_work(struct delayed_work *dwork, unsigned long interval)
 {
unsigned long iv;
 
iv = interval * HZ;
-   mod_delayed_work(system_wq, _work, round_jiffies(iv));
+   mod_delayed_work(system_wq, dwork, round_jiffies(iv));
 }
 
 static void cec_work_fn(struct work_struct *work)
@@ -181,7 +181,7 @@ static void cec_work_fn(struct work_struct *work)
do_spring_cleaning(_arr);
mutex_unlock(_mutex);
 
-   cec_mod_work(decay_interval);
+   cec_mod_work(_work, decay_interval);
 }
 
 /*
@@ -420,7 +420,7 @@ static int decay_interval_set(void *data, u64 val)
*(u64 *)data   = val;
decay_interval = val;
 
-   cec_mod_work(decay_interval);
+   cec_mod_work(_work, decay_interval);
 
return 0;
 }
-- 
2.17.1




[RFC PATCH 3/7] RAS/CEC: Move X86 MCE specific code under CONFIG_X86_MCE

2020-10-02 Thread Shiju Jose
CEC may need to support other architectures such as ARM64.
Move X86 MCE specific code under CONFIG_X86_MCE to support
building for other architectures.

Signed-off-by: Shiju Jose 
---
 drivers/ras/cec.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index f20da1103f27..803e641d8e5c 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -8,7 +8,9 @@
 #include 
 #include 
 
+#if defined(CONFIG_X86_MCE)
 #include 
+#endif
 
 #include "debugfs.h"
 
@@ -511,6 +513,7 @@ static int __init create_debugfs_nodes(void)
if (!IS_ENABLED(CONFIG_RAS_CEC_DEBUG))
return 0;
 
+#if defined(CONFIG_X86_MCE)
pfn = debugfs_create_file("pfn", S_IRUSR | S_IWUSR, d, _pfn, 
_ops);
if (!pfn) {
pr_warn("Error creating pfn debugfs node!\n");
@@ -522,6 +525,7 @@ static int __init create_debugfs_nodes(void)
pr_warn("Error creating array debugfs node!\n");
goto err;
}
+#endif
 
return 0;
 
@@ -531,6 +535,7 @@ static int __init create_debugfs_nodes(void)
return 1;
 }
 
+#if defined(CONFIG_X86_MCE)
 static int cec_notifier(struct notifier_block *nb, unsigned long val,
void *data)
 {
@@ -556,28 +561,33 @@ static struct notifier_block cec_nb = {
.notifier_call  = cec_notifier,
.priority   = MCE_PRIO_CEC,
 };
+#endif
 
 static void __init cec_init(void)
 {
if (ce_arr.disabled)
return;
 
+#if defined(CONFIG_X86_MCE)
ce_arr.array = (void *)get_zeroed_page(GFP_KERNEL);
if (!ce_arr.array) {
pr_err("Error allocating CE array page!\n");
return;
}
+#endif
 
if (create_debugfs_nodes()) {
free_page((unsigned long)ce_arr.array);
return;
}
 
+#if defined(CONFIG_X86_MCE)
ce_arr.id_shift = PAGE_SHIFT;
INIT_DELAYED_WORK(_work, cec_work_fn);
schedule_delayed_work(_work, CEC_DECAY_DEFAULT_INTERVAL);
 
mce_register_decode_chain(_nb);
+#endif
 
pr_info("Correctable Errors collector initialized.\n");
 }
-- 
2.17.1




[RFC PATCH 2/7] RAS/CEC: Replace pfns_poisoned with elems_poisoned

2020-10-02 Thread Shiju Jose
Replace the variable pfns_poisoned with elems_poisoned
for the common use.

Signed-off-by: Shiju Jose 
---
 drivers/ras/cec.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index 22d11c66c266..f20da1103f27 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -100,8 +100,8 @@ static struct ce_array {
 * since the last spring cleaning.
 */
 
-   u64 pfns_poisoned;  /*
-* number of PFNs which got poisoned.
+   u64 elems_poisoned; /*
+* number of elements which got 
poisoned.
 */
 
u64 ces_entered;/*
@@ -362,7 +362,7 @@ static int cec_add_elem(u64 pfn)
/* We have reached max count for this page, 
soft-offline it. */
pr_err("Soft-offlining pfn: 0x%llx\n", pfn);
memory_failure_queue(pfn, MF_SOFT_OFFLINE);
-   ca->pfns_poisoned++;
+   ca->elems_poisoned++;
}
 
del_elem(ca, to);
@@ -457,7 +457,7 @@ static int array_dump(struct seq_file *m, void *v)
seq_printf(m, "}\n");
 
seq_printf(m, "Stats:\nCEs: %llu\nofflined pages: %llu\n",
-  ca->ces_entered, ca->pfns_poisoned);
+  ca->ces_entered, ca->elems_poisoned);
 
seq_printf(m, "Flags: 0x%x\n", ca->flags);
 
-- 
2.17.1




[RFC PATCH 1/7] RAS/CEC: Replace the macro PFN with ELEM_NO

2020-10-02 Thread Shiju Jose
Replace the macro PFN with ELEM_NO for common use.

Signed-off-by: Shiju Jose 
---
 drivers/ras/cec.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index 569d9ad2c594..22d11c66c266 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -86,7 +86,7 @@
  * u64: [ 63 ... 12 | DECAY_BITS | COUNT_BITS ]
  */
 
-#define PFN(e) ((e) >> PAGE_SHIFT)
+#define ELEM_NO(e, shift)  ((e) >> (shift))
 #define DECAY(e)   (((e) >> COUNT_BITS) & DECAY_MASK)
 #define COUNT(e)   ((unsigned int)(e) & COUNT_MASK)
 #define FULL_COUNT(e)  ((e) & (PAGE_SIZE - 1))
@@ -113,6 +113,10 @@ static struct ce_array {
 * Times we did spring cleaning.
 */
 
+   u8 id_shift;/*
+* shift for element id.
+*/
+
union {
struct {
__u32   disabled : 1,   /* cmdline disabled */
@@ -191,7 +195,7 @@ static int __find_elem(struct ce_array *ca, u64 pfn, 
unsigned int *to)
while (min <= max) {
int i = (min + max) >> 1;
 
-   this_pfn = PFN(ca->array[i]);
+   this_pfn = ELEM_NO(ca->array[i], ca->id_shift);
 
if (this_pfn < pfn)
min = i + 1;
@@ -258,7 +262,7 @@ static u64 del_lru_elem_unlocked(struct ce_array *ca)
 
del_elem(ca, min_idx);
 
-   return PFN(ca->array[min_idx]);
+   return ELEM_NO(ca->array[min_idx], ca->id_shift);
 }
 
 /*
@@ -287,7 +291,7 @@ static bool sanity_check(struct ce_array *ca)
int i;
 
for (i = 0; i < ca->n; i++) {
-   u64 this = PFN(ca->array[i]);
+   u64 this = ELEM_NO(ca->array[i], ca->id_shift);
 
if (WARN(prev > this, "prev: 0x%016llx <-> this: 0x%016llx\n", 
prev, this))
ret = true;
@@ -300,7 +304,7 @@ static bool sanity_check(struct ce_array *ca)
 
pr_info("Sanity check dump:\n{ n: %d\n", ca->n);
for (i = 0; i < ca->n; i++) {
-   u64 this = PFN(ca->array[i]);
+   u64 this = ELEM_NO(ca->array[i], ca->id_shift);
 
pr_info(" %03d: [%016llx|%03llx]\n", i, this, 
FULL_COUNT(ca->array[i]));
}
@@ -444,7 +448,7 @@ static int array_dump(struct seq_file *m, void *v)
 
seq_printf(m, "{ n: %d\n", ca->n);
for (i = 0; i < ca->n; i++) {
-   u64 this = PFN(ca->array[i]);
+   u64 this = ELEM_NO(ca->array[i], ca->id_shift);
 
seq_printf(m, " %3d: [%016llx|%s|%03llx]\n",
   i, this, bins[DECAY(ca->array[i])], 
COUNT(ca->array[i]));
@@ -569,6 +573,7 @@ static void __init cec_init(void)
return;
}
 
+   ce_arr.id_shift = PAGE_SHIFT;
INIT_DELAYED_WORK(_work, cec_work_fn);
schedule_delayed_work(_work, CEC_DECAY_DEFAULT_INTERVAL);
 
-- 
2.17.1




[RFC PATCH 0/7] RAS/CEC: Extend CEC for errors count check on short time period

2020-10-02 Thread Shiju Jose
In ARM64 hardware platforms, for example our Kunpeng platforms, CPU L1/L2
cache corrected errors are reported in the ARM processor error section.
The situations the CPU CE errors are reported too often is not unlikely
and may need to isolate that CPU core to prevent leading to more 
serious faults. This is important for the early fault prediction.

Extend the existing RAS CEC to support the errors count check on short
time period with the threshold. The decay interval is divided into a
number of time slots for these elements. The CEC calculates the average
error count for each element at the end of each decay interval. Then the
average count would be subtracted from the total count in each of the
following time slots within the decay interval. The work function for
the decay interval would be set for a reduced time period = decay
interval/ number of time slots. When the new CE count for a CPU is added,
the element would try to offline when the sum of the most recent CEs
counts exceeded the CEs threshold value. More implementation details is
added in the file.

Add collection of CPU correctable errors, for example ARM64 L1/L2 cache
errors and isolation of the CPU core when the errors count in the short
time interval exceed the threshold value.

Open Questions based on the feedback from Boris,
1. ARM processor error types are cache/TLB/bus errors.
   [Reference N2.4.4.1 ARM Processor Error Information UEFI Spec v2.8]
Any of the above error types should not be consider for the
error collection and CPU core isolation?

2.If disabling entire CPU core is not acceptable,
please suggest method to disable L1 and L2 cache on ARM64 core?

Shiju Jose (7):
  RAS/CEC: Replace the macro PFN with ELEM_NO
  RAS/CEC: Replace pfns_poisoned with elems_poisoned
  RAS/CEC: Move X86 MCE specific code under CONFIG_X86_MCE
  RAS/CEC: Modify cec_mod_work() for common use
  RAS/CEC: Add support for errors count check on short time period
  RAS/CEC: Add CPU Correctable Error Collector to isolate an erroneous
CPU core
  ACPI / APEI: Add reporting ARM64 CPU correctable errors to the CEC

 arch/arm64/ras/Kconfig   |  17 ++
 drivers/acpi/apei/ghes.c |  36 +++-
 drivers/ras/Kconfig  |   1 +
 drivers/ras/cec.c| 399 +++
 include/linux/ras.h  |   9 +
 5 files changed, 418 insertions(+), 44 deletions(-)
 create mode 100644 arch/arm64/ras/Kconfig

-- 
2.17.1




RE: [PATCH 1/1] RAS: Add CPU Correctable Error Collector to isolate an erroneous CPU core

2020-10-02 Thread Shiju Jose
Hi Boris, Hi James,

>-Original Message-
>From: Borislav Petkov [mailto:b...@alien8.de]
>Sent: 01 October 2020 18:31
>To: James Morse 
>Cc: Shiju Jose ; linux-e...@vger.kernel.org; linux-
>a...@vger.kernel.org; linux-kernel@vger.kernel.org; tony.l...@intel.com;
>r...@rjwysocki.net; l...@kernel.org; Linuxarm 
>Subject: Re: [PATCH 1/1] RAS: Add CPU Correctable Error Collector to isolate
>an erroneous CPU core
>
>On Thu, Oct 01, 2020 at 06:16:03PM +0100, James Morse wrote:
>> If the corrected-count is available somewhere, can't this policy be
>> made in user-space?
>
>You mean rasdaemon goes and offlines CPUs when certain thresholds are
>reached? Sure. It would be much more flexible too.

I will send the kernel changes for existing CEC to support the CPU CE errors. 
Can you please have a look?

Thanks,
Shiju

>
>--
>Regards/Gruss,
>Boris.
>
>https://people.kernel.org/tglx/notes-about-netiquette


RE: [PATCH 1/1] EDAC/ghes: Fix for NULL pointer dereference in ghes_edac_register()

2020-09-15 Thread Shiju Jose
Hi Boris,

Sorry for the delay.

>-Original Message-
>From: Borislav Petkov [mailto:b...@alien8.de]
>Sent: 11 September 2020 17:48
>To: Shiju Jose 
>Cc: linux-e...@vger.kernel.org; linux-kernel@vger.kernel.org;
>mche...@kernel.org; tony.l...@intel.com; james.mo...@arm.com;
>Linuxarm ; Robert Richter 
>Subject: Re: [PATCH 1/1] EDAC/ghes: Fix for NULL pointer dereference in
>ghes_edac_register()
>
>On Thu, Aug 27, 2020 at 02:02:27PM +, Shiju Jose wrote:
>> I tested with your changes and it fixes the issue.  I will send v2.
>
>Btw, I don't know how it managed to work on your machine because even
>with this patch, it isn't all fixed because num_dimms needs to be cleared too,
>see here:

I debug with adding more logs. 
I found that in our platform hw->num_dimms was 32 when called 
ghes_edac_register() second time
when probe a new ghes instance,  the check !(hw->num_dimms % 16) in the 
enumerate_dimms() passed and 
it allocated memory for  hw->dimms. Thus it did not fail with NULL pointer 
dereference in ghes_edac_register().
With the your new fix hw->num_dimms reset to 0.

>
>---
>From: Borislav Petkov 
>Date: Fri, 11 Sep 2020 12:55:55 +0200
>Subject: [PATCH] EDAC/ghes: Clear scanned data on unload
>
>Commit
>
>  b972fdba8665 ("EDAC/ghes: Fix NULL pointer dereference in
>ghes_edac_register()")
>
>didn't clear all the information from the scanned system and, more
>specifically, left ghes_hw.num_dimms to its previous value. On a second load
>(CONFIG_DEBUG_TEST_DRIVER_REMOVE=y), the driver would use the
>leftover num_dimms value which is not 0 and thus the 0 check in
>enumerate_dimms() will get bypassed and it would go directly to the pointer
>deref:
>
>  d = >dimms[hw->num_dimms];
>
>which is, of course, NULL:
>
>  #PF: supervisor write access in kernel mode
>  #PF: error_code(0x0002) - not-present page
>  PGD 0 P4D 0
>  Oops: 0002 [#1] PREEMPT SMP
>  CPU: 7 PID: 1 Comm: swapper/0 Not tainted 5.9.0-rc4+ #7
>  Hardware name: GIGABYTE MZ01-CE1-00/MZ01-CE1-00, BIOS F02
>08/29/2018
>  RIP: 0010:enumerate_dimms.cold+0x7b/0x375
>
>Reset the whole ghes_hw on driver unregister so that no stale values are
>used on a second system scan.
>
>Fixes: b972fdba8665 ("EDAC/ghes: Fix NULL pointer dereference in
>ghes_edac_register()")
>Cc: Shiju Jose 
>Signed-off-by: Borislav Petkov 
>---
> drivers/edac/ghes_edac.c | 1 +
> 1 file changed, 1 insertion(+)
>
>diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index
>a6b9c0b2a15c..eb6034a6fbbb 100644
>--- a/drivers/edac/ghes_edac.c
>+++ b/drivers/edac/ghes_edac.c
>@@ -632,6 +632,7 @@ void ghes_edac_unregister(struct ghes *ghes)
>   mutex_lock(_reg_mutex);
>
>   system_scanned = false;
>+  memset(_hw, 0, sizeof(struct ghes_hw_desc));
>
>   if (!refcount_dec_and_test(_refcount))
>   goto unlock;
>--
>2.21.0
>
>--
>Regards/Gruss,
>Boris.
>
>https://people.kernel.org/tglx/notes-about-netiquette

Thanks,
Shiju


RE: [PATCH v15 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-09-14 Thread Shiju Jose
Hello,

Can you help to merge this series?

Thanks,
Shiju

>-Original Message-
>From: Linuxarm [mailto:linuxarm-boun...@huawei.com] On Behalf Of Shiju
>Jose
>Sent: 03 September 2020 13:35
>To: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>b...@alien8.de; james.mo...@arm.com; lorenzo.pieral...@arm.com;
>r...@kernel.org; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; andriy.shevche...@linux.intel.com
>Cc: Linuxarm 
>Subject: [PATCH v15 0/2] ACPI / APEI: Add support to notify the vendor
>specific HW errors
>
>CPER records describing a firmware-first error are identified by GUID.
>The ghes driver currently logs, but ignores any unknown CPER records.
>This prevents describing errors that can't be represented by a standard entry,
>that would otherwise allow a driver to recover from an error.
>The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of version 2.8).
>
>patch set
>1. add the notifier chain for these non-standard/vendor-records
>   in the ghes driver.
>
>2. add the driver to handle HiSilicon HIP PCIe controller's errors.
>
>Changes:
>
>V15:
>1. Change in the HIP PCIe error handling driver
>   for a comment by Andy Shevchenko.
>   Removed "depends on ACPI" as it already depends on
>   it through ACPI_APEI_GHES.
>
>V14:
>1. Add patch[1] posted by James to the series.
>
>2. Following changes made for Bjorn's comments,
>2.1 Deleted stub code from ghes.h
>2.2 Made CONFIG_PCIE_HISI_ERR depend on CONFIG_ACPI_APEI_GHES.
>
>V13:
>1. Following changes in the HIP PCIe error handling driver.
>1.1 Add Bjorn's acked-by.
>1.2. Address the comments and macros order Bjorn mentioned.
> Fix the words in the commit.
>
>V12:
>1. Changed the Signed-off-by tag to Co-developed-by tag in the patch
>   "ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records"
>
>V11:
>1. Following modifications made by James Morse in the APEI patch
>   for the vendor error record.
>   - Removed kfifo and ghes_gdata_pool. Expanded commit message.
>
>2. Changes in the HIP PCIe error handling driver
>   for the comments by Andy Shevchenko.
>
>V10:
>1. Changes for Bjorn's comments on HIP PCIe error handler driver
>   and APEI patch.
>
>2. Changes in the HIP PCIe error handler driver
>   for the feedbacks by Andy Shevchenko.
>
>V9:
>1. Fixed 2 improvements suggested by the kbuild test robot.
>1.1 Change ghes_gdata_pool_init() as static function.
>1.2. Removed using buffer to store the error data for
> logging in the hisi_pcie_handle_error()
>
>V8:
>1. Removed reporting the standard errors through the interface
>   because of the conflict with the recent patches in the
>   memory error handling path.
>2. Fix comments by Dan Carpenter.
>
>V7:
>1. Add changes in the APEI driver suggested by Borislav Petkov, for
>   queuing up all the non-fatal HW errors to the work queue and
>   notify the registered kernel drivers from the bottom half using
>   blocking notifier, common interface for both standard and
>   vendor-spcific errors.
>2. Fix for further feedbacks in v5 HIP PCIe error handler driver
>   by Bjorn Helgaas.
>
>V6:
>1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.
>
>V5:
>1. Fix comments from James Morse.
>1.1 Changed the notification method to use the atomic_notifier_chain.
>1.2 Add the error handled status for the user space.
>
>V4:
>1. Fix for the following smatch warning in the PCIe error driver,
>   reported by kbuild test robot:
>   warn: should '1))) << (9 + i))' be a 64 bit type?
>   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
>   ^^^ This should be BIT_ULL() because it goes up to 9 + 32.
>
>V3:
>1. Fix the comments from Bjorn Helgaas.
>
>V2:
>1. Changes in the HiSilicon PCIe controller's error handling driver
>   for the comments from Bjorn Helgaas.
>
>2. Changes in the APEI interface to support reporting the vendor error
>   for module with multiple devices, but use the same section type.
>   In the error handler will use socket id/sub module id etc to distinguish
>   the device.
>
>V1:
>1. Fix comments from James Morse.
>
>2. add driver to handle HiSilicon hip08 PCIe controller's errors,
>   which is an application of the above interface.
>
>Shiju Jose (1):
>  ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records
>
>Yicong Yang (1):
>  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors
>
> drivers/acpi/apei/ghes.c |  63 +
> drivers/pci/controller/Kconfig   |   7 +
> drivers/pci/controller/Makefile  |   1 +
> drivers/pci/controller/pcie-hisi-error.c | 327 +++
> include/acpi/ghes.h  |  18 ++
> 5 files changed, 416 insertions(+)
> create mode 100644 drivers/pci/controller/pcie-hisi-error.c
>
>--
>2.17.1
>
>
>___
>Linuxarm mailing list
>linux...@huawei.com
>http://hulk.huawei.com/mailman/listinfo/linuxarm


RE: [PATCH 1/1] RAS: Add CPU Correctable Error Collector to isolate an erroneous CPU core

2020-09-10 Thread Shiju Jose
Hello Boris,

>-Original Message-
>From: Borislav Petkov [mailto:b...@alien8.de]
>Sent: 09 September 2020 13:02
>To: Shiju Jose 
>Cc: linux-e...@vger.kernel.org; linux-a...@vger.kernel.org; linux-
>ker...@vger.kernel.org; tony.l...@intel.com; r...@rjwysocki.net;
>james.mo...@arm.com; l...@kernel.org; Linuxarm
>
>Subject: Re: [PATCH 1/1] RAS: Add CPU Correctable Error Collector to isolate
>an erroneous CPU core
>
>On Tue, Sep 01, 2020 at 04:20:54PM +, Shiju Jose wrote:
>> CPU CEC derived the infrastructure of the CEC only and the logic used
>> in the CEC for CE count storage, CE count calculation and page
>> isolation is very unique for the memory pages, which seems cannot be
>> reusable for the CPU CEs.
>
>Oh, because it saves the reported error's PFN and you want to save
>
>[CPU num | error count]
>
>?
Yes. 

>
>Well, you can easily change that by extending the existing CEC to have a
>different storage format for CPU errors, i.e., use a different ce_array which
>gets passed to the functions anyway.
Ok. However the functions such as __find_elem() use
memory specific PFN() and PAGE_SHIFT.

>
>> Also the values set for the parameters such as threshold, time period
>> for the memory errors and CPU errors would be different.
>
>And your implementation with sliding windows is so totally different that it
>warrants the duplication of the code? I don't think so.
>
>You can use the current CEC to do exactly what you wanna do, with the
>decaying and so on.
I will check this.
For CPU, the corrected errors count for a short time period to be checked.
Thus old errors outside this period would not be considered and would be 
cleared. 
It is not clear to me whether in the current CEC, the count for the old errors 
outside
a time period would be excluded for the threshold check or removed?

>
>Because all you wanna do is count the errors a CPU triggered.
>
>However, a CPU can trigger a *lot* of different types of errors.
>You're putting them all in the same basket by doing:
>
>else if (guid_equal(sec_type, _SEC_PROC_ARM))
>   /* add to CEC */
>
>and only for correctable.
>
>What type of errors get reported in CPER_SEC_PROC_ARM?
According to the ARM Processor CPER definition the error types reported are
Cache Error, TLB Error, Bus Error and micro-architectural Error.

>
>If they're all lumped together and if some functional unit generates a lot of
>errors, instead of disabling that unit only, you'll go and remove the whole
>CPU?
>
Few thoughts on this,
1. Not sure will a CPU core would work/perform as normal after disabling
a functional unit?
2. Support in the HW to disable a function unit alone may not available.
3. If it is require to store and retrieve the error count based on functional 
unit,
then CEC will become more complex?

>Doesn't make a whole lot of sense to me.
>
>How about you define what exactly you're trying to solve, maybe give an
>example of a real issue someone is encountering and you're trying to
>address? Because there was never a necessity so far to disable CPUs on
>x86 due to correctable errors. Why is that needed on ARM?
>
This requirement is the part of the early fault prediction by taking action
when large number of corrected errors reported on a CPU core
before it causing serious faults. 
We are mainly looking for disable CPU core on large number of L1/L2 cache
corrected errors  reported on a CPU core. Can we add atleast removing CPU core
for the CPU cache corrected errors filtering out other error types?
 
[...]

Thanks,
Shiju



[PATCH v15 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-09-03 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

Add a notifier chain for these non-standard/vendor-records. Callers
must identify their type of records by GUID.

Record data is copied to memory from the ghes_estatus_pool to allow
us to keep it until after the notifier has run.

Co-developed-by: James Morse 
Signed-off-by: James Morse 
Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 63 
 include/acpi/ghes.h  | 18 
 2 files changed, 81 insertions(+)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 81bf71b10d44..99df00f64306 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -79,6 +79,12 @@
((struct acpi_hest_generic_status *)\
 ((struct ghes_estatus_node *)(estatus_node) + 1))
 
+#define GHES_VENDOR_ENTRY_LEN(gdata_len)   \
+   (sizeof(struct ghes_vendor_record_entry) + (gdata_len))
+#define GHES_GDATA_FROM_VENDOR_ENTRY(vendor_entry) \
+   ((struct acpi_hest_generic_data *)  \
+   ((struct ghes_vendor_record_entry *)(vendor_entry) + 1))
+
 /*
  *  NMI-like notifications vary by architecture, before the compiler can prune
  *  unused static functions it needs a value for these enums.
@@ -123,6 +129,12 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_vendor_record_entry {
+   struct work_struct work;
+   int error_severity;
+   char vendor_record[];
+};
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -511,6 +523,56 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(vendor_record_notify_list);
+
+int ghes_register_vendor_record_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_vendor_record_notifier);
+
+void ghes_unregister_vendor_record_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_vendor_record_notifier);
+
+static void ghes_vendor_record_work_func(struct work_struct *work)
+{
+   struct ghes_vendor_record_entry *entry;
+   struct acpi_hest_generic_data *gdata;
+   u32 len;
+
+   entry = container_of(work, struct ghes_vendor_record_entry, work);
+   gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+
+   blocking_notifier_call_chain(_record_notify_list,
+entry->error_severity, gdata);
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   gen_pool_free(ghes_estatus_pool, (unsigned long)entry, len);
+}
+
+static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
+ int sev)
+{
+   struct acpi_hest_generic_data *copied_gdata;
+   struct ghes_vendor_record_entry *entry;
+   u32 len;
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   entry = (void *)gen_pool_alloc(ghes_estatus_pool, len);
+   if (!entry)
+   return;
+
+   copied_gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+   memcpy(copied_gdata, gdata, acpi_hest_get_record_size(gdata));
+   entry->error_severity = sev;
+
+   INIT_WORK(>work, ghes_vendor_record_work_func);
+   schedule_work(>work);
+}
+
 static bool ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -549,6 +611,7 @@ static bool ghes_do_proc(struct ghes *ghes,
} else {
void *err = acpi_hest_get_payload(gdata);
 
+   ghes_defer_non_standard_event(gdata, sev);
log_non_standard_event(sec_type, fru_id, fru_text,
   sec_sev, err,
   gdata->error_data_length);
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 517a5231cc1b..34fb3431a8f3 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -53,6 +53,24 @@ enum {
GHES_SEV_PANIC = 0x3,
 };
 
+#ifdef CONFIG_ACPI_APEI_GHES
+/**
+ * ghes_register_vendor_record_notifier - register a notifier for vendor
+ * records that the kernel would otherwise ignore.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_vendor_record_notifier(struct not

[PATCH v15 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-09-03 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

patch set
1. add the notifier chain for these non-standard/vendor-records
   in the ghes driver.

2. add the driver to handle HiSilicon HIP PCIe controller's errors.
   
Changes:

V15:
1. Change in the HIP PCIe error handling driver
   for a comment by Andy Shevchenko.
   Removed "depends on ACPI" as it already depends on
   it through ACPI_APEI_GHES.

V14:
1. Add patch[1] posted by James to the series.
   
2. Following changes made for Bjorn's comments,
2.1 Deleted stub code from ghes.h
2.2 Made CONFIG_PCIE_HISI_ERR depend on CONFIG_ACPI_APEI_GHES.

V13:
1. Following changes in the HIP PCIe error handling driver.
1.1 Add Bjorn's acked-by.
1.2. Address the comments and macros order Bjorn mentioned.
 Fix the words in the commit.

V12:
1. Changed the Signed-off-by tag to Co-developed-by tag in the patch
   "ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records"

V11:
1. Following modifications made by James Morse in the APEI patch
   for the vendor error record.
   - Removed kfifo and ghes_gdata_pool. Expanded commit message.
   
2. Changes in the HIP PCIe error handling driver
   for the comments by Andy Shevchenko.

V10:
1. Changes for Bjorn's comments on HIP PCIe error handler driver
   and APEI patch.
   
2. Changes in the HIP PCIe error handler driver
   for the feedbacks by Andy Shevchenko.
   
V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c |  63 +
 drivers/pci/controller/Kconfig   |   7 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 include/acpi/ghes.h  |  18 ++
 5 files changed, 416 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




[PATCH v15 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-09-03 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and performing port reset separately at each root port.

Add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC IP.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
Acked-by: Bjorn Helgaas 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   7 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 3 files changed, 335 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index f18c3725ef80..42dbc167765c 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -294,6 +294,13 @@ config PCI_LOONGSON
  Say Y here if you want to enable PCI controller support on
  Loongson systems.
 
+config PCIE_HISI_ERR
+   depends on ACPI_APEI_GHES && (ARM64 || COMPILE_TEST)
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index bcdbf49ab1e4..04c6edc285c5 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
 obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..7959c9c8d2bc
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2020 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+static guid_t hisi_pcie_sec_guid =
+   GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+ 0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+/*
+ * Firmware reports the socket port ID where the error occurred.  These
+ * macros convert that to the core ID and core port ID required by the
+ * ACPI reset method.
+ */
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) & 7) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+struct hisi_pcie_error_private {
+   struct notifier_block   nb;
+   struct device *dev;
+};
+
+enum hisi_pcie_submodule_id {
+   HISI_PCIE_SUB_MODULE_ID_AP,
+   HISI_PCIE_SUB_MODULE_ID_TL,
+   HISI_PCIE_SUB_MODULE_ID_MAC,
+   HISI_PCIE_SUB_MODULE_

RE: [RESEND PATCH v14 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-09-03 Thread Shiju Jose
Hi Andy,

>-Original Message-
>From: Andy Shevchenko [mailto:andriy.shevche...@linux.intel.com]
>Sent: 01 September 2020 09:26
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>b...@alien8.de; james.mo...@arm.com; lorenzo.pieral...@arm.com;
>r...@kernel.org; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; yangyicong ;
>Jonathan Cameron ; tanxiaofei
>; Linuxarm ; Bjorn
>Helgaas 
>Subject: Re: [RESEND PATCH v14 2/2] PCI: hip: Add handling of HiSilicon HIP
>PCIe controller errors
>
>On Mon, Aug 31, 2020 at 10:26:06PM +0100, Shiju Jose wrote:
>> From: Yicong Yang 
>>
>> The HiSilicon HIP PCIe controller is capable of handling errors on
>> root port and performing port reset separately at each root port.
>>
>> Add error handling driver for HIP PCIe controller to log and report
>> recoverable errors. Perform root port reset and restore link status
>> after the recovery.
>>
>> Following are some of the PCIe controller's recoverable errors 1.
>> completion transmission timeout error.
>> 2. CRS retry counter over the threshold error.
>> 3. ECC 2 bit errors
>> 4. AXI bresponse/rresponse errors etc.
>>
>> The driver placed in the drivers/pci/controller/ because the HIP PCIe
>> controller does not use DWC IP.
>>
>> Signed-off-by: Yicong Yang 
>> Signed-off-by: Shiju Jose 
>> Acked-by: Bjorn Helgaas 
>> --
>> drivers/pci/controller/Kconfig   |   8 +
>> drivers/pci/controller/Makefile  |   1 +
>> drivers/pci/controller/pcie-hisi-error.c | 336
>> +++
>> 3 files changed, 345 insertions(+)
>> create mode 100644 drivers/pci/controller/pcie-hisi-error.c
>> ---
>>  drivers/pci/controller/Kconfig   |   8 +
>>  drivers/pci/controller/Makefile  |   1 +
>>  drivers/pci/controller/pcie-hisi-error.c | 327
>> +++
>>  3 files changed, 336 insertions(+)
>>  create mode 100644 drivers/pci/controller/pcie-hisi-error.c
>>
>> diff --git a/drivers/pci/controller/Kconfig
>> b/drivers/pci/controller/Kconfig index f18c3725ef80..b1b8a8805dd8
>> 100644
>> --- a/drivers/pci/controller/Kconfig
>> +++ b/drivers/pci/controller/Kconfig
>> @@ -294,6 +294,14 @@ config PCI_LOONGSON
>>Say Y here if you want to enable PCI controller support on
>>Loongson systems.
>>
>> +config PCIE_HISI_ERR
>> +depends on ACPI_APEI_GHES && (ARM64 || COMPILE_TEST)
>
>> +depends on ACPI
>
>Isn't this implied by
>   drivers/acpi/Kconfig:45:if ACPI
>?

This can be removed as  ACPI_APEI_GHES depends on ACPI.

Do you have any other comments on this patch?

>
>> +bool "HiSilicon HIP PCIe controller error handling driver"
>> +help
>> +  Say Y here if you want error handling support
>> +  for the PCIe controller's errors on HiSilicon HIP SoCs
>> +
>>  source "drivers/pci/controller/dwc/Kconfig"
>>  source "drivers/pci/controller/mobiveil/Kconfig"
>>  source "drivers/pci/controller/cadence/Kconfig"
>> diff --git a/drivers/pci/controller/Makefile
>> b/drivers/pci/controller/Makefile index bcdbf49ab1e4..04c6edc285c5
>> 100644
>> --- a/drivers/pci/controller/Makefile
>> +++ b/drivers/pci/controller/Makefile
>> @@ -31,6 +31,7 @@ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-
>tango.o
>>  obj-$(CONFIG_VMD) += vmd.o
>>  obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
>>  obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
>> +obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
>>  # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
>>  obj-y   += dwc/
>>  obj-y   += mobiveil/
>> diff --git a/drivers/pci/controller/pcie-hisi-error.c
>> b/drivers/pci/controller/pcie-hisi-error.c
>> new file mode 100644
>> index ..7959c9c8d2bc
>> --- /dev/null
>> +++ b/drivers/pci/controller/pcie-hisi-error.c
>> @@ -0,0 +1,327 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Driver for handling the PCIe controller errors on
>> + * HiSilicon HIP SoCs.
>> + *
>> + * Copyright (c) 2020 HiSilicon Limited.
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +/* HISI PCIe controller error definitions */
>> +#define HISI_PCIE_ERR_MISC_REGS 33

RE: [PATCH 1/1] RAS: Add CPU Correctable Error Collector to isolate an erroneous CPU core

2020-09-01 Thread Shiju Jose
Hi Boris,

>-Original Message-
>From: Borislav Petkov [mailto:b...@alien8.de]
>Sent: 01 September 2020 15:36
>To: Shiju Jose 
>Cc: linux-e...@vger.kernel.org; linux-a...@vger.kernel.org; linux-
>ker...@vger.kernel.org; tony.l...@intel.com; r...@rjwysocki.net;
>james.mo...@arm.com; l...@kernel.org; Linuxarm
>
>Subject: Re: [PATCH 1/1] RAS: Add CPU Correctable Error Collector to isolate
>an erroneous CPU core
>
>On Tue, Sep 01, 2020 at 03:01:40PM +0100, Shiju Jose wrote:
>> When the CPU correctable errors reported on an ARM64 CPU core too
>> often, it should be isolated. Add the CPU correctable error collector
>> to store the CPU correctable error count.
>>
>> When the correctable error count for a CPU exceed the threshold value
>> in a short time period, it will try to isolate the CPU core.
>> The threshold value, time period etc are configurable.
>>
>> Implementation details is added in the file.
>>
>> Signed-off-by: Shiju Jose 
>> ---
>>  Documentation/ABI/testing/debugfs-cpu-cec |  22 ++
>>  arch/arm64/ras/Kconfig|   8 +
>>  drivers/acpi/apei/ghes.c  |  30 +-
>>  drivers/ras/Kconfig   |   1 +
>>  drivers/ras/Makefile  |   1 +
>>  drivers/ras/cpu_cec.c | 393 ++
>
>So instead of adding the ability to collect other error types to the CEC, 
>you're
>duplicating the CEC itself?!
>
>Why?
CPU CEC derived the infrastructure of the CEC only and the logic used in the 
CEC for
CE count storage, CE count calculation and page isolation is very unique for the
memory pages,  which seems cannot be reusable for the CPU CEs. 
Also the values set for the parameters such as threshold, time period for the 
memory errors
and  CPU errors would be different.
Thus extending cec.c to support CPU CEs would include adding CPU CEC specific 
code
for storing error count, isolation etc which I thought would result the code 
less tidy and
less readable unless find more reusable logic.

>
>--
>Regards/Gruss,
>Boris.
>
>https://people.kernel.org/tglx/notes-about-netiquette

Thanks,
Shiju


[PATCH 1/1] RAS: Add CPU Correctable Error Collector to isolate an erroneous CPU core

2020-09-01 Thread Shiju Jose
When the CPU correctable errors reported on an ARM64 CPU core too often,
it should be isolated. Add the CPU correctable error collector to
store the CPU correctable error count.

When the correctable error count for a CPU exceed the threshold
value in a short time period, it will try to isolate the CPU core.
The threshold value, time period etc are configurable.

Implementation details is added in the file.

Signed-off-by: Shiju Jose 
---
 Documentation/ABI/testing/debugfs-cpu-cec |  22 ++
 arch/arm64/ras/Kconfig|   8 +
 drivers/acpi/apei/ghes.c  |  30 +-
 drivers/ras/Kconfig   |   1 +
 drivers/ras/Makefile  |   1 +
 drivers/ras/cpu_cec.c | 393 ++
 drivers/ras/ras.c |   3 +
 include/linux/ras.h   |  16 +
 8 files changed, 471 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/ABI/testing/debugfs-cpu-cec
 create mode 100644 arch/arm64/ras/Kconfig
 create mode 100644 drivers/ras/cpu_cec.c

diff --git a/Documentation/ABI/testing/debugfs-cpu-cec 
b/Documentation/ABI/testing/debugfs-cpu-cec
new file mode 100644
index ..31f4e8c902e4
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-cpu-cec
@@ -0,0 +1,22 @@
+What:   /sys/kernel/debug/ras/cpu_cec/threshold
+Date:   Aug 2020
+Contact:linux-e...@vger.kernel.org
+Description:Threshold value for the CPU corrected errors to
+   offline a CPU core. Default value is 5000.
+
+What:   /sys/kernel/debug/ras/cpu_cec/disable
+Date:   Aug 2020
+Contact:linux-e...@vger.kernel.org
+Description:Disable the RAS CPU corrected errors collector.
+   1:disable, 0:enable. Enabled by default.
+
+What:   /sys/kernel/debug/ras/cpu_cec/stats
+Date:   Aug 2020
+Contact:linux-e...@vger.kernel.org
+Description:Dump the stats of the CPU correctable errors.
+
+What:   /sys/kernel/debug/ras/cpu_cec/time_period
+Date:   Aug 2020
+Contact:linux-e...@vger.kernel.org
+Description:Time period, in seconds, for the CPU CEs count
+   threshold check. Default value is 24hrs.
diff --git a/arch/arm64/ras/Kconfig b/arch/arm64/ras/Kconfig
new file mode 100644
index ..a892245193f0
--- /dev/null
+++ b/arch/arm64/ras/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+config RAS_CPU_CEC
+   bool "RAS CPU Correctable Error Collector"
+   depends on ARM64 && HOTPLUG_CPU && DEBUG_FS
+   help
+ Collects the CPU correctable errors. When the CEs count for
+ a CPU exceeds the threshold, try to isolate the CPU core.
+
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 81bf71b10d44..b6ff4866ca32 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -511,6 +511,32 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static void ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata)
+{
+   struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
+   struct cper_arm_err_info *err_info;
+   int sec_sev;
+   int cpu, i, ret;
+
+   log_arm_hw_error(err);
+
+   sec_sev = ghes_severity(gdata->error_severity);
+   if (sec_sev != GHES_SEV_CORRECTED)
+   return;
+
+   cpu = get_logical_index(err->mpidr);
+   if (cpu == -EINVAL)
+   return;
+
+   err_info = (struct cper_arm_err_info *)(err + 1);
+   for (i = 0; i < err->err_info_num; i++) {
+   ret = cpu_cec_add_ce(cpu, err_info->multiple_error + 1);
+   if (ret)
+   break;
+   err_info += 1;
+   }
+}
+
 static bool ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -543,9 +569,7 @@ static bool ghes_do_proc(struct ghes *ghes,
ghes_handle_aer(gdata);
}
else if (guid_equal(sec_type, _SEC_PROC_ARM)) {
-   struct cper_sec_proc_arm *err = 
acpi_hest_get_payload(gdata);
-
-   log_arm_hw_error(err);
+   ghes_handle_arm_hw_error(gdata);
} else {
void *err = acpi_hest_get_payload(gdata);
 
diff --git a/drivers/ras/Kconfig b/drivers/ras/Kconfig
index c2a236f2e846..d2f877e5f7ad 100644
--- a/drivers/ras/Kconfig
+++ b/drivers/ras/Kconfig
@@ -32,5 +32,6 @@ menuconfig RAS
 if RAS
 
 source "arch/x86/ras/Kconfig"
+source "arch/arm64/ras/Kconfig"
 
 endif
diff --git a/drivers/ras/Makefile b/drivers/ras/Makefile
index 6f0404f50107..d6e8c38be3cb 100644
--- a/drivers/ras/Makefile
+++ b/drivers/ras/Makefile
@@ -2,3 +2,4 @@
 obj-$(CONFIG_RAS)  += ras.o
 obj-$(CONFIG_DEBUG_FS) += debugfs.o
 obj-$(CONFIG_RAS_CEC)  += cec.o
+obj-$(CONFIG_RAS_CP

[RESEND PATCH v14 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-08-31 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

Add a notifier chain for these non-standard/vendor-records. Callers
must identify their type of records by GUID.

Record data is copied to memory from the ghes_estatus_pool to allow
us to keep it until after the notifier has run.

Co-developed-by: James Morse 
Signed-off-by: James Morse 
Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 63 
 include/acpi/ghes.h  | 18 
 2 files changed, 81 insertions(+)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 81bf71b10d44..99df00f64306 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -79,6 +79,12 @@
((struct acpi_hest_generic_status *)\
 ((struct ghes_estatus_node *)(estatus_node) + 1))
 
+#define GHES_VENDOR_ENTRY_LEN(gdata_len)   \
+   (sizeof(struct ghes_vendor_record_entry) + (gdata_len))
+#define GHES_GDATA_FROM_VENDOR_ENTRY(vendor_entry) \
+   ((struct acpi_hest_generic_data *)  \
+   ((struct ghes_vendor_record_entry *)(vendor_entry) + 1))
+
 /*
  *  NMI-like notifications vary by architecture, before the compiler can prune
  *  unused static functions it needs a value for these enums.
@@ -123,6 +129,12 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_vendor_record_entry {
+   struct work_struct work;
+   int error_severity;
+   char vendor_record[];
+};
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -511,6 +523,56 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(vendor_record_notify_list);
+
+int ghes_register_vendor_record_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_vendor_record_notifier);
+
+void ghes_unregister_vendor_record_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_vendor_record_notifier);
+
+static void ghes_vendor_record_work_func(struct work_struct *work)
+{
+   struct ghes_vendor_record_entry *entry;
+   struct acpi_hest_generic_data *gdata;
+   u32 len;
+
+   entry = container_of(work, struct ghes_vendor_record_entry, work);
+   gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+
+   blocking_notifier_call_chain(_record_notify_list,
+entry->error_severity, gdata);
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   gen_pool_free(ghes_estatus_pool, (unsigned long)entry, len);
+}
+
+static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
+ int sev)
+{
+   struct acpi_hest_generic_data *copied_gdata;
+   struct ghes_vendor_record_entry *entry;
+   u32 len;
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   entry = (void *)gen_pool_alloc(ghes_estatus_pool, len);
+   if (!entry)
+   return;
+
+   copied_gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+   memcpy(copied_gdata, gdata, acpi_hest_get_record_size(gdata));
+   entry->error_severity = sev;
+
+   INIT_WORK(>work, ghes_vendor_record_work_func);
+   schedule_work(>work);
+}
+
 static bool ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -549,6 +611,7 @@ static bool ghes_do_proc(struct ghes *ghes,
} else {
void *err = acpi_hest_get_payload(gdata);
 
+   ghes_defer_non_standard_event(gdata, sev);
log_non_standard_event(sec_type, fru_id, fru_text,
   sec_sev, err,
   gdata->error_data_length);
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 517a5231cc1b..34fb3431a8f3 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -53,6 +53,24 @@ enum {
GHES_SEV_PANIC = 0x3,
 };
 
+#ifdef CONFIG_ACPI_APEI_GHES
+/**
+ * ghes_register_vendor_record_notifier - register a notifier for vendor
+ * records that the kernel would otherwise ignore.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_vendor_record_notifier(struct not

[RESEND PATCH v14 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-08-31 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and performing port reset separately at each root port.

Add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC IP.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
Acked-by: Bjorn Helgaas 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 3 files changed, 336 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index f18c3725ef80..b1b8a8805dd8 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -294,6 +294,14 @@ config PCI_LOONGSON
  Say Y here if you want to enable PCI controller support on
  Loongson systems.
 
+config PCIE_HISI_ERR
+   depends on ACPI_APEI_GHES && (ARM64 || COMPILE_TEST)
+   depends on ACPI
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index bcdbf49ab1e4..04c6edc285c5 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
 obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..7959c9c8d2bc
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2020 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+static guid_t hisi_pcie_sec_guid =
+   GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+ 0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+/*
+ * Firmware reports the socket port ID where the error occurred.  These
+ * macros convert that to the core ID and core port ID required by the
+ * ACPI reset method.
+ */
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) & 7) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+struct hisi_pcie_error_private {
+   struct notifier_block   nb;
+   struct device *dev;
+};
+
+enum hisi_pcie_submodule_id {
+   HISI_PCIE_SUB_MODULE_ID_AP,
+   HISI_PCIE_SUB_MODULE_ID_TL,
+   HISI_PCIE_SUB_MODULE_ID_MAC,
+   HISI_PCI

[RESEND PATCH v14 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-08-31 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

patch set
1. add the notifier chain for these non-standard/vendor-records
   in the ghes driver.

2. add the driver to handle HiSilicon HIP PCIe controller's errors.
   
Changes:

V14:
1. Rebase to v5.9-rc3
2. Add patch[1] posted by James to the series.
   
3. Following changes made for Bjorn's comments,
3.1 Deleted stub code from ghes.h
3.2 Made CONFIG_PCIE_HISI_ERR depend on CONFIG_ACPI_APEI_GHES.

V13:
1. Following changes in the HIP PCIe error handling driver.
1.1 Add Bjorn's acked-by.
1.2. Address the comments and macros order Bjorn mentioned.
 Fix the words in the commit.

V12:
1. Changed the Signed-off-by tag to Co-developed-by tag in the patch
   "ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records"

V11:
1. Following modifications made by James Morse in the APEI patch
   for the vendor error record.
   - Removed kfifo and ghes_gdata_pool. Expanded commit message.
   
2. Changes in the HIP PCIe error handling driver
   for the comments by Andy Shevchenko.

V10:
1. Changes for Bjorn's comments on HIP PCIe error handler driver
   and APEI patch.
   
2. Changes in the HIP PCIe error handler driver
   for the feedbacks by Andy Shevchenko.
   
V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c |  63 +
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 include/acpi/ghes.h  |  18 ++
 5 files changed, 417 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




RE: [PATCH 1/1] EDAC/ghes: Fix for NULL pointer dereference in ghes_edac_register()

2020-08-27 Thread Shiju Jose
Hello Boris,

Thanks for reviewing.

>-Original Message-
>From: linux-edac-ow...@vger.kernel.org [mailto:linux-edac-
>ow...@vger.kernel.org] On Behalf Of Borislav Petkov
>Sent: 26 August 2020 09:52
>To: Shiju Jose 
>Cc: linux-e...@vger.kernel.org; linux-kernel@vger.kernel.org;
>mche...@kernel.org; tony.l...@intel.com; james.mo...@arm.com;
>rrich...@marvell.com; Linuxarm 
>Subject: Re: [PATCH 1/1] EDAC/ghes: Fix for NULL pointer dereference in
>ghes_edac_register()
>
>On Tue, Aug 25, 2020 at 02:01:08PM +0100, Shiju Jose wrote:
>> After the 'commit b9cae27728d1 ("EDAC/ghes: Scan the system once on
>driver init")'
>> applied, following error has occurred in ghes_edac_register() when
>> CONFIG_DEBUG_TEST_DRIVER_REMOVE is enabled. The null
>ghes_hw.dimms
>> pointer in the mci_for_each_dimm() of ghes_edac_register() caused the
>error.
>>
>> The error occurs when all the previously initialized ghes instances
>> are removed and then probe a new ghes instance. In this case, the
>> ghes_refcount would be 0, ghes_hw.dimms and mci already freed. The
>> ghes_hw.dimms would be null because ghes_scan_system() would not call
>enumerate_dimms() again.
>
>Try the below instead and see if it fixes the issue for you too.
>
>If it does, pls send it as v2 but do not add the splat to the commit message -
>that's a lot of noise for something which is clear why it happens and you
>explain it properly in text anyway.

I tested with your changes and it fixes the issue.  I will send v2.
 
>
>Thx.
>
>---
>diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index
>da60c29468a7..54ebc8afc6b1 100644
>--- a/drivers/edac/ghes_edac.c
>+++ b/drivers/edac/ghes_edac.c
>@@ -55,6 +55,8 @@ static DEFINE_SPINLOCK(ghes_lock);  static bool
>__read_mostly force_load;  module_param(force_load, bool, 0);
>
>+static bool system_scanned;
>+
> /* Memory Device - Type 17 of SMBIOS spec */  struct memdev_dmi_entry {
>   u8 type;
>@@ -225,14 +227,12 @@ static void enumerate_dimms(const struct
>dmi_header *dh, void *arg)
>
> static void ghes_scan_system(void)
> {
>-  static bool scanned;
>-
>-  if (scanned)
>+  if (system_scanned)
>   return;
>
>   dmi_walk(enumerate_dimms, _hw);
>
>-  scanned = true;
>+  system_scanned = true;
> }
>
> void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err
>*mem_err) @@ -631,6 +631,8 @@ void ghes_edac_unregister(struct ghes
>*ghes)
>
>   mutex_lock(_reg_mutex);
>
>+  system_scanned = false;
>+
>   if (!refcount_dec_and_test(_refcount))
>   goto unlock;
>
>
>--
>Regards/Gruss,
>Boris.
>
>https://people.kernel.org/tglx/notes-about-netiquette

Thanks,
Shiju


RE: [PATCH V2 topic-edac-5.1 0/2] EDAC: Add support for reporting the non-standard errors to vendor drivers

2020-08-27 Thread Shiju Jose
Sorry. Please ignore this.

>-Original Message-
>From: linux-edac-ow...@vger.kernel.org [mailto:linux-edac-
>ow...@vger.kernel.org] On Behalf Of Shiju Jose
>Sent: 27 August 2020 15:01
>To: linux-e...@vger.kernel.org; linux-kernel@vger.kernel.org; b...@alien8.de;
>mche...@kernel.org; tony.l...@intel.com; james.mo...@arm.com;
>rrich...@marvell.com
>Cc: Linuxarm 
>Subject: [PATCH V2 topic-edac-5.1 0/2] EDAC: Add support for reporting the
>non-standard errors to vendor drivers
>
>Presently non-standard HW errors are not reported to the vendor drivers for
>the recovery.
>This patch set adds support for reporting the non-standard errors to the
>registered vendor drivers.
>Also adds HIP08 EDAC driver, for the  recovery of the PCIe OEM errors on
>HiSilicon HIP08.
>
>RFC -> V2
>1.Add error recovery for the PCIe local errors 2.Removed code for the other
>OEM errors from HIP08 edac driver
>  because there is no current requirement for the recovery.
>
>Shiju Jose (2):
>  EDAC: Add support for reporting the non-standard errors to the vendor
>drivers
>  EDAC: Add handling for the PCIe OEM errors on HiSilicon HIP08
>
> drivers/acpi/apei/ghes.c|   5 +
> drivers/edac/Makefile   |   3 +-
> drivers/edac/edac_non_standard.c| 124 ++
> drivers/edac/hisi_hip08_edac_non_standard.c | 255
>
> include/linux/edac_non_standard.h   |  74 
> 5 files changed, 460 insertions(+), 1 deletion(-)  create mode 100644
>drivers/edac/edac_non_standard.c  create mode 100644
>drivers/edac/hisi_hip08_edac_non_standard.c
> create mode 100644 include/linux/edac_non_standard.h
>
>--
>1.9.1
>



[PATCH v2 1/1] EDAC/ghes: Fix for NULL pointer dereference in ghes_edac_register()

2020-08-27 Thread Shiju Jose
After the 'commit b9cae27728d1 ("EDAC/ghes: Scan the system once on driver 
init")'
applied, following error has occurred in the ghes_edac_register() when
CONFIG_DEBUG_TEST_DRIVER_REMOVE is enabled. The null ghes_hw.dimms pointer
in the mci_for_each_dimm() of ghes_edac_register() caused the error.

The error occurs when all the previously initialized ghes instances are
removed and then probe a new ghes instance. In this case, the ghes_refcount
would be 0, ghes_hw.dimms and mci already freed. The ghes_hw.dimms would
be null because ghes_scan_system() would not call enumerate_dimms() again.

Suggested-by: Borislav Petkov 
Signed-off-by: Shiju Jose 
---
 drivers/edac/ghes_edac.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
index da60c29468a7..54ebc8afc6b1 100644
--- a/drivers/edac/ghes_edac.c
+++ b/drivers/edac/ghes_edac.c
@@ -55,6 +55,8 @@ static DEFINE_SPINLOCK(ghes_lock);
 static bool __read_mostly force_load;
 module_param(force_load, bool, 0);
 
+static bool system_scanned;
+
 /* Memory Device - Type 17 of SMBIOS spec */
 struct memdev_dmi_entry {
u8 type;
@@ -225,14 +227,12 @@ static void enumerate_dimms(const struct dmi_header *dh, 
void *arg)
 
 static void ghes_scan_system(void)
 {
-   static bool scanned;
-
-   if (scanned)
+   if (system_scanned)
return;
 
dmi_walk(enumerate_dimms, _hw);
 
-   scanned = true;
+   system_scanned = true;
 }
 
 void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
@@ -631,6 +631,8 @@ void ghes_edac_unregister(struct ghes *ghes)
 
mutex_lock(_reg_mutex);
 
+   system_scanned = false;
+
if (!refcount_dec_and_test(_refcount))
goto unlock;
 
-- 
2.17.1




[PATCH V2 topic-edac-5.1 0/2] EDAC: Add support for reporting the non-standard errors to vendor drivers

2020-08-27 Thread Shiju Jose
Presently non-standard HW errors are not reported to the vendor drivers
for the recovery.
This patch set adds support for reporting the non-standard errors to the
registered vendor drivers.
Also adds HIP08 EDAC driver, for the  recovery of the PCIe OEM errors on
HiSilicon HIP08.

RFC -> V2
1.Add error recovery for the PCIe local errors
2.Removed code for the other OEM errors from HIP08 edac driver
  because there is no current requirement for the recovery.
    
Shiju Jose (2):
  EDAC: Add support for reporting the non-standard errors to the vendor
drivers
  EDAC: Add handling for the PCIe OEM errors on HiSilicon HIP08

 drivers/acpi/apei/ghes.c|   5 +
 drivers/edac/Makefile   |   3 +-
 drivers/edac/edac_non_standard.c| 124 ++
 drivers/edac/hisi_hip08_edac_non_standard.c | 255 
 include/linux/edac_non_standard.h   |  74 
 5 files changed, 460 insertions(+), 1 deletion(-)
 create mode 100644 drivers/edac/edac_non_standard.c
 create mode 100644 drivers/edac/hisi_hip08_edac_non_standard.c
 create mode 100644 include/linux/edac_non_standard.h

-- 
1.9.1




[PATCH 1/1] EDAC/ghes: Fix for NULL pointer dereference in ghes_edac_register()

2020-08-25 Thread Shiju Jose
After the 'commit b9cae27728d1 ("EDAC/ghes: Scan the system once on driver 
init")'
applied, following error has occurred in ghes_edac_register() when
CONFIG_DEBUG_TEST_DRIVER_REMOVE is enabled. The null ghes_hw.dimms pointer
in the mci_for_each_dimm() of ghes_edac_register() caused the error.

The error occurs when all the previously initialized ghes instances are
removed and then probe a new ghes instance. In this case, the ghes_refcount
would be 0, ghes_hw.dimms and mci already freed. The ghes_hw.dimms would
be null because ghes_scan_system() would not call enumerate_dimms() again.

Following is the error log:

EDAC MC0: Giving out device to module ghes_edac.c controller ghes_edac: DEV 
ghes (INTERRUPT)
EDAC MC: Removed device 0 for ghes_edac.c ghes_edac: DEV ghes
Unable to handle kernel NULL pointer dereference at virtual address 
0330
Mem abort info:
  ESR = 0x9604
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
Data abort info:
  ISV = 0, ISS = 0x0004
  CM = 0, WnR = 0
[0330] user address but active_mm is swapper
Internal error: Oops: 9604 [#1] PREEMPT SMP
Modules linked in:
CPU: 34 PID: 1 Comm: swapper/0 Not tainted 5.9.0-rc1-00085-g06a4ec1d9dc6-dirty 
#29
Hardware name: Huawei TaiShan 2280 V2/BC82AMDC, BIOS 2280-V2 CS V3.B270.01 
05/08/2020
pstate: 60c9 (nZCv daif +PAN +UAO BTYPE=--)
pc : ghes_edac_register+0x19c/0x340
lr : ghes_edac_register+0x12c/0x340
sp : 80001041bad0
x29: 80001041bad0 x28: c56e16f210a0
x27:  x26: c56e175d
x25:  x24: 007ef7e2a010
x23: 007ef5c3a6ec x22: c56e17606000
x21: c56e17409000 x20: 007ef5c3a000
x19: c56e176a7000 x18: 000e
x17: 80001007dfff x16: 0080
x15: 80001007dfff x14: 44011000
x13: 4000 x12: 80001007e000
x11:  x10: 
x9 : 0002 x8 : 207ef6c502fc
x7 : 0360 x6 : 
x5 : fffc x4 : 007ef5c3a6e0
x3 : 0020 x2 : 207ef6c27c00
x1 :  x0 : 
Call trace:
 ghes_edac_register+0x19c/0x340
 ghes_probe+0x1f0/0x3dc
 platform_drv_probe+0x4c/0xb0
 really_probe+0x1c4/0x444
 driver_probe_device+0x54/0xb0
 device_driver_attach+0x68/0x70
 __driver_attach+0x94/0xdc
 bus_for_each_dev+0x64/0xc0
 driver_attach+0x20/0x28
 bus_add_driver+0x138/0x1f8
 driver_register+0x60/0x10c
 __platform_driver_register+0x4c/0x54
 ghes_init+0x94/0x110
 do_one_initcall+0x58/0x1ac
 kernel_init_freeable+0x204/0x274
 kernel_init+0x10/0x10c
 ret_from_fork+0x10/0x18
Code: 5280 52806c07 f9401026 9b271801 (b9433023)
---[ end trace f7c77f8c8dfe4b4a ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x000b
SMP: stopping secondary CPUs
Kernel Offset: 0x456e05a6 from 0x80001000
PHYS_OFFSET: 0xc584
CPU features: 0x0040002,22808a18
Memory Limit: none
---[ end Kernel panic - not syncing: Attempted to kill init! 
exitcode=0x000b ]---

Signed-off-by: Shiju Jose 
---
 drivers/edac/ghes_edac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
index da60c29468a7..7930643c6811 100644
--- a/drivers/edac/ghes_edac.c
+++ b/drivers/edac/ghes_edac.c
@@ -227,7 +227,7 @@ static void ghes_scan_system(void)
 {
static bool scanned;
 
-   if (scanned)
+   if (scanned && refcount_read(_refcount))
return;
 
dmi_walk(enumerate_dimms, _hw);
-- 
2.17.1




[PATCH v14 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-08-03 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

Add a notifier chain for these non-standard/vendor-records. Callers
must identify their type of records by GUID.

Record data is copied to memory from the ghes_estatus_pool to allow
us to keep it until after the notifier has run.

Co-developed-by: James Morse 
Signed-off-by: James Morse 
Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 63 
 include/acpi/ghes.h  | 18 
 2 files changed, 81 insertions(+)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 81bf71b10d44..99df00f64306 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -79,6 +79,12 @@
((struct acpi_hest_generic_status *)\
 ((struct ghes_estatus_node *)(estatus_node) + 1))
 
+#define GHES_VENDOR_ENTRY_LEN(gdata_len)   \
+   (sizeof(struct ghes_vendor_record_entry) + (gdata_len))
+#define GHES_GDATA_FROM_VENDOR_ENTRY(vendor_entry) \
+   ((struct acpi_hest_generic_data *)  \
+   ((struct ghes_vendor_record_entry *)(vendor_entry) + 1))
+
 /*
  *  NMI-like notifications vary by architecture, before the compiler can prune
  *  unused static functions it needs a value for these enums.
@@ -123,6 +129,12 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_vendor_record_entry {
+   struct work_struct work;
+   int error_severity;
+   char vendor_record[];
+};
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -511,6 +523,56 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(vendor_record_notify_list);
+
+int ghes_register_vendor_record_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_vendor_record_notifier);
+
+void ghes_unregister_vendor_record_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_vendor_record_notifier);
+
+static void ghes_vendor_record_work_func(struct work_struct *work)
+{
+   struct ghes_vendor_record_entry *entry;
+   struct acpi_hest_generic_data *gdata;
+   u32 len;
+
+   entry = container_of(work, struct ghes_vendor_record_entry, work);
+   gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+
+   blocking_notifier_call_chain(_record_notify_list,
+entry->error_severity, gdata);
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   gen_pool_free(ghes_estatus_pool, (unsigned long)entry, len);
+}
+
+static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
+ int sev)
+{
+   struct acpi_hest_generic_data *copied_gdata;
+   struct ghes_vendor_record_entry *entry;
+   u32 len;
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   entry = (void *)gen_pool_alloc(ghes_estatus_pool, len);
+   if (!entry)
+   return;
+
+   copied_gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+   memcpy(copied_gdata, gdata, acpi_hest_get_record_size(gdata));
+   entry->error_severity = sev;
+
+   INIT_WORK(>work, ghes_vendor_record_work_func);
+   schedule_work(>work);
+}
+
 static bool ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -549,6 +611,7 @@ static bool ghes_do_proc(struct ghes *ghes,
} else {
void *err = acpi_hest_get_payload(gdata);
 
+   ghes_defer_non_standard_event(gdata, sev);
log_non_standard_event(sec_type, fru_id, fru_text,
   sec_sev, err,
   gdata->error_data_length);
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 517a5231cc1b..34fb3431a8f3 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -53,6 +53,24 @@ enum {
GHES_SEV_PANIC = 0x3,
 };
 
+#ifdef CONFIG_ACPI_APEI_GHES
+/**
+ * ghes_register_vendor_record_notifier - register a notifier for vendor
+ * records that the kernel would otherwise ignore.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_vendor_record_notifier(struct not

[PATCH v14 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-08-03 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and performing port reset separately at each root port.

Add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC IP.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
Acked-by: Bjorn Helgaas 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 3 files changed, 336 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index adddf21fa381..52f0b99cfd20 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -286,6 +286,14 @@ config PCI_LOONGSON
  Say Y here if you want to enable PCI controller support on
  Loongson systems.
 
+config PCIE_HISI_ERR
+   depends on ACPI_APEI_GHES && (ARM64 || COMPILE_TEST)
+   depends on ACPI
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index efd9733ead26..90afd865bf6b 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
 obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..e734ea6009c5
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2020 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+static guid_t hisi_pcie_sec_guid =
+   GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+ 0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+/*
+ * Firmware reports the socket port ID where the error occurred.  These
+ * macros convert that to the core ID and core port ID required by the
+ * ACPI reset method.
+ */
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) & 7) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+struct hisi_pcie_error_private {
+   struct notifier_block   nb;
+   struct device *dev;
+};
+
+enum hisi_pcie_submodule_id {
+   HISI_PCIE_SUB_MODULE_ID_AP,
+   HISI_PCIE_SUB_MODULE_ID_TL,
+   HISI_PCIE_SUB_MODULE_ID_MAC,
+   HISI_PCI

[PATCH v14 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-08-03 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

patch set
1. add the notifier chain for these non-standard/vendor-records
   in the ghes driver.

2. add the driver to handle HiSilicon HIP PCIe controller's errors.
   
Changes:

V14:
1. Add patch[1] posted by James to the series.
   
2. Following changes made for Bjorn's comments,
2.1 Deleted stub code from ghes.h
2.2 Made CONFIG_PCIE_HISI_ERR depend on CONFIG_ACPI_APEI_GHES.

V13:
1. Following changes in the HIP PCIe error handling driver.
1.1 Add Bjorn's acked-by.
1.2. Address the comments and macros order Bjorn mentioned.
 Fix the words in the commit.

V12:
1. Changed the Signed-off-by tag to Co-developed-by tag in the patch
   "ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records"

V11:
1. Following modifications made by James Morse in the APEI patch
   for the vendor error record.
   - Removed kfifo and ghes_gdata_pool. Expanded commit message.
   
2. Changes in the HIP PCIe error handling driver
   for the comments by Andy Shevchenko.

V10:
1. Changes for Bjorn's comments on HIP PCIe error handler driver
   and APEI patch.
   
2. Changes in the HIP PCIe error handler driver
   for the feedbacks by Andy Shevchenko.
   
V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c |  63 +
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 include/acpi/ghes.h  |  18 ++
 5 files changed, 417 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




RE: [PATCH v13 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-07-31 Thread Shiju Jose
Hi James, 

>-Original Message-
>From: linux-acpi-ow...@vger.kernel.org [mailto:linux-acpi-
>ow...@vger.kernel.org] On Behalf Of James Morse
>Sent: 31 July 2020 14:48
>To: Shiju Jose 
>Cc: Andy Shevchenko ; linux-
>a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>b...@alien8.de; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com; Wangkefeng
>(OS Kernel Lab) ; jroe...@suse.de;
>Linuxarm ; yangyicong ;
>Jonathan Cameron ; tanxiaofei
>
>Subject: Re: [PATCH v13 1/2] ACPI / APEI: Add a notifier chain for unknown
>(vendor) CPER records
>
>Hi Shiju,
>
>On 22/07/2020 13:50, Andy Shevchenko wrote:
>> On Wed, Jul 22, 2020 at 12:34:23PM +, Shiju Jose wrote:
>
>>>>> Co-developed-by: James Morse 
>>>>
>>>> Co-developed-by: is going _in conjunction with_ SoB tag which is
>>>> missing here.
>>> This tag was added as per instruction from Rafael.
>>> I was told that I cannot add SoB tag for others unless specifically given.
>>> Probably I will leave it with Rafael/James to help on this SoB tag as
>>> Rafael was ok to merge this patch.
>>
>> I think it's a misunderstanding somewhere. According to [1]:
>> "Since Co-developed-by: denotes authorship, every Co-developed-by:
>> must be immediately followed by a Signed-off-by: of the associated co-
>author."
>>
>> It means either both or none.
>>
>> [1]:
>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html
>
>Sorry for this mess! My intention was to summarise my suggestion in the
>form of a patch, I wasn't expecting you to pick it up. (and I didn't post it
>because there was ongoing discussion on the second part)
>
>I'll repost this with the Co-Developed-by stuff. You'll need to re-post it with
>the series, you'll need to move your Signed-Off-By to be last when you do
>that.

Sure. Thanks.
Also please consider make you as the author of this patch 
because it has more changes from you.

>
>
>Thanks,
>
>James

Thanks,
Shiju


RE: [PATCH v13 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-07-24 Thread Shiju Jose
>-Original Message-
>From: Bjorn Helgaas [mailto:helg...@kernel.org]
>Sent: 24 July 2020 13:54
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>james.mo...@arm.com; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com;
>andriy.shevche...@linux.intel.com; Wangkefeng (OS Kernel Lab)
>; jroe...@suse.de; Linuxarm
>; yangyicong ; Jonathan
>Cameron ; tanxiaofei
>
>Subject: Re: [PATCH v13 1/2] ACPI / APEI: Add a notifier chain for unknown
>(vendor) CPER records
>
>On Fri, Jul 24, 2020 at 09:00:41AM +, Shiju Jose wrote:
>> >-Original Message-
>> >From: Bjorn Helgaas [mailto:helg...@kernel.org]
>> >Sent: 24 July 2020 00:21
>> >To: Shiju Jose 
>> >Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>> >ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>> >james.mo...@arm.com; l...@kernel.org; tony.l...@intel.com;
>> >dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com;
>> >andriy.shevche...@linux.intel.com; Wangkefeng (OS Kernel Lab)
>> >; jroe...@suse.de; Linuxarm
>> >; yangyicong ;
>Jonathan
>> >Cameron ; tanxiaofei
>> >
>> >Subject: Re: [PATCH v13 1/2] ACPI / APEI: Add a notifier chain for
>> >unknown
>> >(vendor) CPER records
>> >
>> >On Wed, Jul 22, 2020 at 11:39:51AM +0100, Shiju Jose wrote:
>> >> CPER records describing a firmware-first error are identified by GUID.
>> >> The ghes driver currently logs, but ignores any unknown CPER records.
>> >> This prevents describing errors that can't be represented by a
>> >> standard entry, that would otherwise allow a driver to recover from
>> >> an
>> >error.
>> >> The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
>> >> version 2.8).
>> >
>> >> +#ifdef CONFIG_ACPI_APEI_GHES
>> >> +/**
>> >> + * ghes_register_vendor_record_notifier - register a notifier for
>> >> +vendor
>> >> + * records that the kernel would otherwise ignore.
>> >> + * @nb: pointer to the notifier_block structure of the event handler.
>> >> + *
>> >> + * return 0 : SUCCESS, non-zero : FAIL  */ int
>> >> +ghes_register_vendor_record_notifier(struct notifier_block *nb);
>> >> +
>> >> +/**
>> >> + * ghes_unregister_vendor_record_notifier - unregister the
>> >> +previously
>> >> + * registered vendor record notifier.
>> >> + * @nb: pointer to the notifier_block structure of the vendor
>> >> +record
>> >handler.
>> >> + */
>> >> +void ghes_unregister_vendor_record_notifier(struct notifier_block
>> >> +*nb); #else static inline int
>> >> +ghes_register_vendor_record_notifier(struct notifier_block *nb) {
>> >> + return -ENODEV;
>> >> +}
>> >> +
>> >> +static inline void ghes_unregister_vendor_record_notifier(struct
>> >> +notifier_block *nb) { }
>> >
>> >If you made CONFIG_PCIE_HISI_ERR depend on CONFIG_ACPI_APEI_GHES,
>> >you'd be able to get rid of these stubs, wouldn't you?  It doesn't
>> >look like there's any point in building pcie-hisi-error.c at all
>> >unless CONFIG_ACPI_APEI_GHES is enabled.
>>
>> The stub is added because this interface is expected to use by the
>> other drivers as well.  Some drivers may not want add the build depend
>> on the CONFIG_ACPI_APEI_GHES if the error reporting has less priority
>> in the driver.  However we can add dependency on
>CONFIG_ACPI_APEI_GHES
>> for building pcie-hisi-error.c.
>
>The usual route is to add stubs when they're needed, not just in anticipation
>of some need that may never materialize.
ok. I will change in the next version.

Thanks,
Shiju


RE: [PATCH v13 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-07-24 Thread Shiju Jose
Hi Bjorn,

>-Original Message-
>From: Bjorn Helgaas [mailto:helg...@kernel.org]
>Sent: 24 July 2020 00:23
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>james.mo...@arm.com; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com;
>andriy.shevche...@linux.intel.com; Wangkefeng (OS Kernel Lab)
>; jroe...@suse.de; Linuxarm
>; yangyicong ; Jonathan
>Cameron ; tanxiaofei
>
>Subject: Re: [PATCH v13 0/2] ACPI / APEI: Add support to notify the vendor
>specific HW errors
>
>On Wed, Jul 22, 2020 at 11:42:43AM +0100, Shiju Jose wrote:
>> CPER records describing a firmware-first error are identified by GUID.
>> The ghes driver currently logs, but ignores any unknown CPER records.
>> This prevents describing errors that can't be represented by a
>> standard entry, that would otherwise allow a driver to recover from an
>error.
>> The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
>> version 2.8).
>>
>> patch set
>> 1. add a notifier chain for these non-standard/vendor-records
>>in the ghes driver.
>>
>> 2. add a driver to handle HiSilicon HIP PCIe controller's errors.
>>
>> Changes:
>>
>> V13:
>> 1. Following changes in the HIP PCIe error handling driver.
>> 1.1 Add Bjorn's acked-by.
>> 1.2. Address the comments and macros order Bjorn mentioned.
>>  Fix the words in the commit.
>
>This series is ill-formed:
>
>  - Jul 22  5:39 Shiju Jose  [PATCH v13 0/2] ACPI / APEI: Add support to 
> not
>  - Jul 22  5:39 Shiju Jose  └─>[PATCH v13 1/2] ACPI / APEI: Add a notifier
>  - Jul 22  5:42 Shiju Jose  [PATCH v13 0/2] ACPI / APEI: Add support to 
> not
>  - Jul 22  5:42 Shiju Jose  └─>[PATCH v13 2/2] PCI: hip: Add handling of 
> Hi
git send-email failed to send out one patch each time in the patch series
due to some internal error. 
>
>Patches 1/2 and 2/2 never appear in the same thread.  Both should be replies
>to 0/2.  And should be only *one* v13 0/2, not two :)
>
>Bjorn

Thanks,
Shiju



RE: [PATCH v13 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-07-24 Thread Shiju Jose
Hi Bjorn,

Thanks for reviewing.

>-Original Message-
>From: Bjorn Helgaas [mailto:helg...@kernel.org]
>Sent: 24 July 2020 00:21
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>james.mo...@arm.com; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com;
>andriy.shevche...@linux.intel.com; Wangkefeng (OS Kernel Lab)
>; jroe...@suse.de; Linuxarm
>; yangyicong ; Jonathan
>Cameron ; tanxiaofei
>
>Subject: Re: [PATCH v13 1/2] ACPI / APEI: Add a notifier chain for unknown
>(vendor) CPER records
>
>On Wed, Jul 22, 2020 at 11:39:51AM +0100, Shiju Jose wrote:
>> CPER records describing a firmware-first error are identified by GUID.
>> The ghes driver currently logs, but ignores any unknown CPER records.
>> This prevents describing errors that can't be represented by a
>> standard entry, that would otherwise allow a driver to recover from an
>error.
>> The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
>> version 2.8).
>
>> +#ifdef CONFIG_ACPI_APEI_GHES
>> +/**
>> + * ghes_register_vendor_record_notifier - register a notifier for
>> +vendor
>> + * records that the kernel would otherwise ignore.
>> + * @nb: pointer to the notifier_block structure of the event handler.
>> + *
>> + * return 0 : SUCCESS, non-zero : FAIL  */ int
>> +ghes_register_vendor_record_notifier(struct notifier_block *nb);
>> +
>> +/**
>> + * ghes_unregister_vendor_record_notifier - unregister the previously
>> + * registered vendor record notifier.
>> + * @nb: pointer to the notifier_block structure of the vendor record
>handler.
>> + */
>> +void ghes_unregister_vendor_record_notifier(struct notifier_block
>> +*nb); #else static inline int
>> +ghes_register_vendor_record_notifier(struct notifier_block *nb) {
>> +return -ENODEV;
>> +}
>> +
>> +static inline void ghes_unregister_vendor_record_notifier(struct
>> +notifier_block *nb) { }
>
>If you made CONFIG_PCIE_HISI_ERR depend on CONFIG_ACPI_APEI_GHES,
>you'd be able to get rid of these stubs, wouldn't you?  It doesn't look like
>there's any point in building pcie-hisi-error.c at all unless
>CONFIG_ACPI_APEI_GHES is enabled.
The stub is added because this interface is expected to use by the other 
drivers as well.
Some drivers may not want add the build depend on the CONFIG_ACPI_APEI_GHES
if the error reporting has less priority in the driver.
However we can add dependency on CONFIG_ACPI_APEI_GHES for building 
pcie-hisi-error.c.  
>
>> +#endif
>> +
>>  int ghes_estatus_pool_init(int num_ghes);
>>
>>  /* From drivers/edac/ghes_edac.c */
>> --
>> 2.17.1
>>
>>

Thanks,
Shiju


RE: [PATCH v13 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-07-23 Thread Shiju Jose
Adding Lorenzo.

Thanks,
Shiju

>-Original Message-
>From: linux-acpi-ow...@vger.kernel.org [mailto:linux-acpi-
>ow...@vger.kernel.org] On Behalf Of Shiju Jose
>Sent: 22 July 2020 11:43
>To: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>b...@alien8.de; james.mo...@arm.com; l...@kernel.org;
>tony.l...@intel.com; dan.carpen...@oracle.com;
>zhangligu...@linux.alibaba.com; andriy.shevche...@linux.intel.com;
>Wangkefeng (OS Kernel Lab) ;
>jroe...@suse.de
>Cc: Linuxarm ; yangyicong
>; Jonathan Cameron
>; tanxiaofei ;
>Bjorn Helgaas 
>Subject: [PATCH v13 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe
>controller errors
>
>From: Yicong Yang 
>
>The HiSilicon HIP PCIe controller is capable of handling errors on root port
>and performing port reset separately at each root port.
>
>Add error handling driver for HIP PCIe controller to log and report recoverable
>errors. Perform root port reset and restore link status after the recovery.
>
>Following are some of the PCIe controller's recoverable errors 1. completion
>transmission timeout error.
>2. CRS retry counter over the threshold error.
>3. ECC 2 bit errors
>4. AXI bresponse/rresponse errors etc.
>
>The driver placed in the drivers/pci/controller/ because the HIP PCIe
>controller does not use DWC IP.
>
>Signed-off-by: Yicong Yang 
>Signed-off-by: Shiju Jose 
>Acked-by: Bjorn Helgaas 
>--
>drivers/pci/controller/Kconfig   |   8 +
>drivers/pci/controller/Makefile  |   1 +
>drivers/pci/controller/pcie-hisi-error.c | 336
>+++
>3 files changed, 345 insertions(+)
>create mode 100644 drivers/pci/controller/pcie-hisi-error.c
>---
> drivers/pci/controller/Kconfig   |   8 +
> drivers/pci/controller/Makefile  |   1 +
> drivers/pci/controller/pcie-hisi-error.c | 327 +++
> 3 files changed, 336 insertions(+)
> create mode 100644 drivers/pci/controller/pcie-hisi-error.c
>
>diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
>index adddf21fa381..b7949b37c029 100644
>--- a/drivers/pci/controller/Kconfig
>+++ b/drivers/pci/controller/Kconfig
>@@ -286,6 +286,14 @@ config PCI_LOONGSON
> Say Y here if you want to enable PCI controller support on
> Loongson systems.
>
>+config PCIE_HISI_ERR
>+  depends on ARM64 || COMPILE_TEST
>+  depends on ACPI
>+  bool "HiSilicon HIP PCIe controller error handling driver"
>+  help
>+Say Y here if you want error handling support
>+for the PCIe controller's errors on HiSilicon HIP SoCs
>+
> source "drivers/pci/controller/dwc/Kconfig"
> source "drivers/pci/controller/mobiveil/Kconfig"
> source "drivers/pci/controller/cadence/Kconfig"
>diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
>index efd9733ead26..90afd865bf6b 100644
>--- a/drivers/pci/controller/Makefile
>+++ b/drivers/pci/controller/Makefile
>@@ -30,6 +30,7 @@ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
> obj-$(CONFIG_VMD) += vmd.o
> obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
> obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
>+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
> # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
> obj-y += dwc/
> obj-y += mobiveil/
>diff --git a/drivers/pci/controller/pcie-hisi-error.c
>b/drivers/pci/controller/pcie-hisi-error.c
>new file mode 100644
>index ..e734ea6009c5
>--- /dev/null
>+++ b/drivers/pci/controller/pcie-hisi-error.c
>@@ -0,0 +1,327 @@
>+// SPDX-License-Identifier: GPL-2.0
>+/*
>+ * Driver for handling the PCIe controller errors on
>+ * HiSilicon HIP SoCs.
>+ *
>+ * Copyright (c) 2020 HiSilicon Limited.
>+ */
>+
>+#include 
>+#include 
>+#include 
>+#include 
>+#include 
>+#include 
>+#include 
>+#include 
>+
>+/* HISI PCIe controller error definitions */
>+#define HISI_PCIE_ERR_MISC_REGS   33
>+
>+#define HISI_PCIE_LOCAL_VALID_VERSION BIT(0)
>+#define HISI_PCIE_LOCAL_VALID_SOC_ID  BIT(1)
>+#define HISI_PCIE_LOCAL_VALID_SOCKET_ID   BIT(2)
>+#define HISI_PCIE_LOCAL_VALID_NIMBUS_ID   BIT(3)
>+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_ID   BIT(4)
>+#define HISI_PCIE_LOCAL_VALID_CORE_ID BIT(5)
>+#define HISI_PCIE_LOCAL_VALID_PORT_ID BIT(6)
>+#define HISI_PCIE_LOCAL_VALID_ERR_TYPEBIT(7)
>+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITYBIT(8)
>+#define HISI_PCIE_LOCAL_VALID_ERR_MISC9
>+
>+static guid_t hisi_pcie_sec_

RE: [PATCH v13 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-07-22 Thread Shiju Jose
Hi Andy,

>-Original Message-
>From: Andy Shevchenko [mailto:andriy.shevche...@linux.intel.com]
>Sent: 22 July 2020 12:02
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>b...@alien8.de; james.mo...@arm.com; l...@kernel.org;
>tony.l...@intel.com; dan.carpen...@oracle.com;
>zhangligu...@linux.alibaba.com; Wangkefeng (OS Kernel Lab)
>; jroe...@suse.de; Linuxarm
>; yangyicong ; Jonathan
>Cameron ; tanxiaofei
>
>Subject: Re: [PATCH v13 1/2] ACPI / APEI: Add a notifier chain for unknown
>(vendor) CPER records
>
>On Wed, Jul 22, 2020 at 11:39:51AM +0100, Shiju Jose wrote:
>> CPER records describing a firmware-first error are identified by GUID.
>> The ghes driver currently logs, but ignores any unknown CPER records.
>> This prevents describing errors that can't be represented by a
>> standard entry, that would otherwise allow a driver to recover from an
>error.
>> The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
>> version 2.8).
>>
>> Add a notifier chain for these non-standard/vendor-records. Callers
>> must identify their type of records by GUID.
>>
>> Record data is copied to memory from the ghes_estatus_pool to allow us
>> to keep it until after the notifier has run.
>>
>> Co-developed-by: James Morse 
>
>Co-developed-by: is going _in conjunction with_ SoB tag which is missing
>here.
This tag was added as per instruction from Rafael.
I was told that I cannot add SoB tag for others unless specifically given.
Probably I will leave it with Rafael/James to help on this SoB tag
as Rafael was ok to merge this patch.
>
>> Signed-off-by: Shiju Jose 
>
>--
>With Best Regards,
>Andy Shevchenko
>
Thanks,
Shiju




[PATCH v13 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-07-22 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and performing port reset separately at each root port.

Add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC IP.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
Acked-by: Bjorn Helgaas 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 3 files changed, 336 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index adddf21fa381..b7949b37c029 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -286,6 +286,14 @@ config PCI_LOONGSON
  Say Y here if you want to enable PCI controller support on
  Loongson systems.
 
+config PCIE_HISI_ERR
+   depends on ARM64 || COMPILE_TEST
+   depends on ACPI
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index efd9733ead26..90afd865bf6b 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
 obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..e734ea6009c5
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2020 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+static guid_t hisi_pcie_sec_guid =
+   GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+ 0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+/*
+ * Firmware reports the socket port ID where the error occurred.  These
+ * macros convert that to the core ID and core port ID required by the
+ * ACPI reset method.
+ */
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) & 7) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+struct hisi_pcie_error_private {
+   struct notifier_block   nb;
+   struct device *dev;
+};
+
+enum hisi_pcie_submodule_id {
+   HISI_PCIE_SUB_MODULE_ID_AP,
+   HISI_PCIE_SUB_MODULE_ID_TL,
+   HISI_PCIE_SUB_MODULE_ID_MAC,
+   HISI_PCIE_SUB_MODULE_ID_DL,
+

[PATCH v13 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-07-22 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

patch set
1. add a notifier chain for these non-standard/vendor-records
   in the ghes driver.

2. add a driver to handle HiSilicon HIP PCIe controller's errors.
   
Changes:

V13:
1. Following changes in the HIP PCIe error handling driver.
1.1 Add Bjorn's acked-by.
1.2. Address the comments and macros order Bjorn mentioned.
 Fix the words in the commit.

V12:
1. Changed the Signed-off-by tag to Co-developed-by tag in the patch
   "ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records"

V11:
1. Following modifications made by James Morse in the APEI patch
   for the vendor error record.
   - Removed kfifo and ghes_gdata_pool. Expanded commit message.
   
2. Changes in the HIP PCIe error handling driver
   for the comments by Andy Shevchenko.

V10:
1. Changes for Bjorn's comments on HIP PCIe error handler driver
   and APEI patch.
   
2. Changes in the HIP PCIe error handler driver
   for the feedbacks by Andy Shevchenko.
   
V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c |  63 +
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 include/acpi/ghes.h  |  27 ++
 5 files changed, 426 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




[PATCH v13 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-07-22 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

Add a notifier chain for these non-standard/vendor-records. Callers
must identify their type of records by GUID.

Record data is copied to memory from the ghes_estatus_pool to allow
us to keep it until after the notifier has run.

Co-developed-by: James Morse 
Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 63 
 include/acpi/ghes.h  | 27 +
 2 files changed, 90 insertions(+)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 81bf71b10d44..99df00f64306 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -79,6 +79,12 @@
((struct acpi_hest_generic_status *)\
 ((struct ghes_estatus_node *)(estatus_node) + 1))
 
+#define GHES_VENDOR_ENTRY_LEN(gdata_len)   \
+   (sizeof(struct ghes_vendor_record_entry) + (gdata_len))
+#define GHES_GDATA_FROM_VENDOR_ENTRY(vendor_entry) \
+   ((struct acpi_hest_generic_data *)  \
+   ((struct ghes_vendor_record_entry *)(vendor_entry) + 1))
+
 /*
  *  NMI-like notifications vary by architecture, before the compiler can prune
  *  unused static functions it needs a value for these enums.
@@ -123,6 +129,12 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_vendor_record_entry {
+   struct work_struct work;
+   int error_severity;
+   char vendor_record[];
+};
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -511,6 +523,56 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(vendor_record_notify_list);
+
+int ghes_register_vendor_record_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_vendor_record_notifier);
+
+void ghes_unregister_vendor_record_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_vendor_record_notifier);
+
+static void ghes_vendor_record_work_func(struct work_struct *work)
+{
+   struct ghes_vendor_record_entry *entry;
+   struct acpi_hest_generic_data *gdata;
+   u32 len;
+
+   entry = container_of(work, struct ghes_vendor_record_entry, work);
+   gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+
+   blocking_notifier_call_chain(_record_notify_list,
+entry->error_severity, gdata);
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   gen_pool_free(ghes_estatus_pool, (unsigned long)entry, len);
+}
+
+static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
+ int sev)
+{
+   struct acpi_hest_generic_data *copied_gdata;
+   struct ghes_vendor_record_entry *entry;
+   u32 len;
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   entry = (void *)gen_pool_alloc(ghes_estatus_pool, len);
+   if (!entry)
+   return;
+
+   copied_gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+   memcpy(copied_gdata, gdata, acpi_hest_get_record_size(gdata));
+   entry->error_severity = sev;
+
+   INIT_WORK(>work, ghes_vendor_record_work_func);
+   schedule_work(>work);
+}
+
 static bool ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -549,6 +611,7 @@ static bool ghes_do_proc(struct ghes *ghes,
} else {
void *err = acpi_hest_get_payload(gdata);
 
+   ghes_defer_non_standard_event(gdata, sev);
log_non_standard_event(sec_type, fru_id, fru_text,
   sec_sev, err,
   gdata->error_data_length);
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 517a5231cc1b..491bd8c6d600 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -53,6 +53,33 @@ enum {
GHES_SEV_PANIC = 0x3,
 };
 
+#ifdef CONFIG_ACPI_APEI_GHES
+/**
+ * ghes_register_vendor_record_notifier - register a notifier for vendor
+ * records that the kernel would otherwise ignore.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_vendor_record_notifier(struct not

[PATCH v13 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-07-22 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

patch set
1. add a notifier chain for these non-standard/vendor-records
   in the ghes driver.

2. add a driver to handle HiSilicon HIP PCIe controller's errors.
   
Changes:

V13:
1. Following changes in the HIP PCIe error handling driver.
1.1 Add Bjorn's acked-by.
1.2. Address the comments and macros order Bjorn mentioned.
 Fix the words in the commit.

V12:
1. Changed the Signed-off-by tag to Co-developed-by tag in the patch
   "ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records"

V11:
1. Following modifications made by James Morse in the APEI patch
   for the vendor error record.
   - Removed kfifo and ghes_gdata_pool. Expanded commit message.
   
2. Changes in the HIP PCIe error handling driver
   for the comments by Andy Shevchenko.

V10:
1. Changes for Bjorn's comments on HIP PCIe error handler driver
   and APEI patch.
   
2. Changes in the HIP PCIe error handler driver
   for the feedbacks by Andy Shevchenko.
   
V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c |  63 +
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 include/acpi/ghes.h  |  27 ++
 5 files changed, 426 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




[PATCH v12 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-07-13 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and perform port reset separately at each root port.

Add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC ip.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 3 files changed, 336 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index adddf21fa381..b7949b37c029 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -286,6 +286,14 @@ config PCI_LOONGSON
  Say Y here if you want to enable PCI controller support on
  Loongson systems.
 
+config PCIE_HISI_ERR
+   depends on ARM64 || COMPILE_TEST
+   depends on ACPI
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index efd9733ead26..90afd865bf6b 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
 obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..9bd050cadb31
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2020 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+static guid_t hisi_pcie_sec_guid =
+   GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+ 0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+/*
+ * We pass core id and core port id to the ACPI reset method to identify
+ * certain root port to reset, while the firmware reports sockets port
+ * id which occurs an error. Use the macros here to do the conversion
+ */
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) & 7) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+struct hisi_pcie_error_private {
+   struct notifier_block   nb;
+   struct device *dev;
+};
+
+enum hisi_pcie_submodule_id {
+   HISI_PCIE_SUB_MODULE_ID_AP,
+   HISI_PCIE_SUB_MODULE_ID_TL,
+   HISI_PCIE_SUB_MODULE_ID_MAC,
+   HISI_PCIE_SUB_MO

[PATCH v12 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-07-13 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

patch set
1. add a notifier chain for these non-standard/vendor-records
   in the ghes driver.

2. add a driver to handle HiSilicon hip PCIe controller's errors.
   
Changes:
V12:
1. Changed the Signed-off-by tag to Co-developed-by tag in the patch
   "ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records"

V11:
1. Following modifications made by James Morse in the APEI patch
   for the vendor error record.
   - Removed kfifo and ghes_gdata_pool. Expanded commit message.
   
   Note: Kept the Signed-off-by: James Morse as he is given
   because I am not sure the right format.
   
2. Changes in the HIP PCIe error handler driver
   for the comments by Andy Shevchenko.

V10:
1. Changes for Bjorn's comments on HIP PCIe error handler driver
   and APEI patch.
   
2. Changes in the HIP PCIe error handler driver
   for the feedbacks by Andy Shevchenko.
   
V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c |  63 +
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 include/acpi/ghes.h  |  27 ++
 5 files changed, 426 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




[PATCH v12 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-07-13 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

Add a notifier chain for these non-standard/vendor-records. Callers
must identify their type of records by GUID.

Record data is copied to memory from the ghes_estatus_pool to allow
us to keep it until after the notifier has run.

Co-developed-by: James Morse 
Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 63 
 include/acpi/ghes.h  | 27 +
 2 files changed, 90 insertions(+)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 81bf71b10d44..99df00f64306 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -79,6 +79,12 @@
((struct acpi_hest_generic_status *)\
 ((struct ghes_estatus_node *)(estatus_node) + 1))
 
+#define GHES_VENDOR_ENTRY_LEN(gdata_len)   \
+   (sizeof(struct ghes_vendor_record_entry) + (gdata_len))
+#define GHES_GDATA_FROM_VENDOR_ENTRY(vendor_entry) \
+   ((struct acpi_hest_generic_data *)  \
+   ((struct ghes_vendor_record_entry *)(vendor_entry) + 1))
+
 /*
  *  NMI-like notifications vary by architecture, before the compiler can prune
  *  unused static functions it needs a value for these enums.
@@ -123,6 +129,12 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_vendor_record_entry {
+   struct work_struct work;
+   int error_severity;
+   char vendor_record[];
+};
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -511,6 +523,56 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(vendor_record_notify_list);
+
+int ghes_register_vendor_record_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_vendor_record_notifier);
+
+void ghes_unregister_vendor_record_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_vendor_record_notifier);
+
+static void ghes_vendor_record_work_func(struct work_struct *work)
+{
+   struct ghes_vendor_record_entry *entry;
+   struct acpi_hest_generic_data *gdata;
+   u32 len;
+
+   entry = container_of(work, struct ghes_vendor_record_entry, work);
+   gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+
+   blocking_notifier_call_chain(_record_notify_list,
+entry->error_severity, gdata);
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   gen_pool_free(ghes_estatus_pool, (unsigned long)entry, len);
+}
+
+static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
+ int sev)
+{
+   struct acpi_hest_generic_data *copied_gdata;
+   struct ghes_vendor_record_entry *entry;
+   u32 len;
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   entry = (void *)gen_pool_alloc(ghes_estatus_pool, len);
+   if (!entry)
+   return;
+
+   copied_gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+   memcpy(copied_gdata, gdata, acpi_hest_get_record_size(gdata));
+   entry->error_severity = sev;
+
+   INIT_WORK(>work, ghes_vendor_record_work_func);
+   schedule_work(>work);
+}
+
 static bool ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -549,6 +611,7 @@ static bool ghes_do_proc(struct ghes *ghes,
} else {
void *err = acpi_hest_get_payload(gdata);
 
+   ghes_defer_non_standard_event(gdata, sev);
log_non_standard_event(sec_type, fru_id, fru_text,
   sec_sev, err,
   gdata->error_data_length);
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 517a5231cc1b..ae0e8847fdd5 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -53,6 +53,33 @@ enum {
GHES_SEV_PANIC = 0x3,
 };
 
+#ifdef CONFIG_ACPI_APEI_GHES
+/**
+ * ghes_register_vendor_record_notifier - register a notifier for vendor
+ * records that the kernel would otherwise ignore.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_vendor_record_notifier(struct not

RE: [PATCH v11 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-07-13 Thread Shiju Jose
Hi Rafael,

>-Original Message-
>From: linux-pci-ow...@vger.kernel.org [mailto:linux-pci-
>ow...@vger.kernel.org] On Behalf Of Rafael J. Wysocki
>Sent: 13 July 2020 14:38
>To: Shiju Jose 
>Cc: Rafael J. Wysocki ; linux-a...@vger.kernel.org; linux-
>p...@vger.kernel.org; linux-kernel@vger.kernel.org; r...@rjwysocki.net;
>helg...@kernel.org; b...@alien8.de; james.mo...@arm.com;
>l...@kernel.org; tony.l...@intel.com; dan.carpen...@oracle.com;
>zhangligu...@linux.alibaba.com; andriy.shevche...@linux.intel.com;
>Wangkefeng (OS Kernel Lab) ;
>jroe...@suse.de; Linuxarm ; yangyicong
>; Jonathan Cameron
>; tanxiaofei 
>Subject: Re: [PATCH v11 1/2] ACPI / APEI: Add a notifier chain for unknown
>(vendor) CPER records
>
>On Mon, Jul 13, 2020 at 3:33 PM Shiju Jose  wrote:
>>
>> Hi Rafael,
>>
>> >-Original Message-
>> >From: Rafael J. Wysocki [mailto:raf...@kernel.org]
>> >Sent: 13 July 2020 12:18
>> >To: Shiju Jose 
>> >Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>> >ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>> >b...@alien8.de; james.mo...@arm.com; l...@kernel.org;
>> >tony.l...@intel.com; dan.carpen...@oracle.com;
>> >zhangligu...@linux.alibaba.com; andriy.shevche...@linux.intel.com;
>> >Wangkefeng (OS Kernel Lab) ;
>> >jroe...@suse.de; Linuxarm ; yangyicong
>> >; Jonathan Cameron
>> >; tanxiaofei 
>> >Subject: Re: [PATCH v11 1/2] ACPI / APEI: Add a notifier chain for
>> >unknown
>> >(vendor) CPER records
>> >
>> >On Mon, Jul 13, 2020 at 10:35 AM Shiju Jose 
>> >wrote:
>> >>
>> >> Hi Rafael, Hi James,
>> >>
>> >> Can you help to merge this patch because I added and tested all the
>> >suggestions from James.
>> >
>> >I could apply the [1/2] in principle, but I need an ACK for the [2/2]
>> >from the PCI side.
>> >
>> >That said, it looks like the [1/2] is a James' patch that you are
>> >sending with some changes made by you.
>> James added following changes on top of the original patch(V10) by me,
>> [ Removed kfifo and ghes_gdata_pool. Expanded commit message ] I had
>> confusion how the S-o-b tag to be added for James's changes in the V11
>patch posted.
>
>So James should have sent the patch with his S-o-b under it.
>
>You cannot add S-o-b for somebody else to any patches.  You can only add
>your S-o-b to somebody else's patch if you have made any changes on top of
>the original.
>
>In case you want to make a record of somebody else's contribution to your
>patch, you can use the Co-developed-by tag.

Ok. I will resend the patch with Co-developed-by tag.

>
>Thanks!

Thanks,
Shiju


RE: [PATCH v11 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-07-13 Thread Shiju Jose
Hi Rafael,

>-Original Message-
>From: Rafael J. Wysocki [mailto:raf...@kernel.org]
>Sent: 13 July 2020 12:18
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>b...@alien8.de; james.mo...@arm.com; l...@kernel.org;
>tony.l...@intel.com; dan.carpen...@oracle.com;
>zhangligu...@linux.alibaba.com; andriy.shevche...@linux.intel.com;
>Wangkefeng (OS Kernel Lab) ;
>jroe...@suse.de; Linuxarm ; yangyicong
>; Jonathan Cameron
>; tanxiaofei 
>Subject: Re: [PATCH v11 1/2] ACPI / APEI: Add a notifier chain for unknown
>(vendor) CPER records
>
>On Mon, Jul 13, 2020 at 10:35 AM Shiju Jose 
>wrote:
>>
>> Hi Rafael, Hi James,
>>
>> Can you help to merge this patch because I added and tested all the
>suggestions from James.
>
>I could apply the [1/2] in principle, but I need an ACK for the [2/2] from the
>PCI side.
>
>That said, it looks like the [1/2] is a James' patch that you are sending with
>some changes made by you.
James added following changes on top of the original patch(V10) by me, 
[ Removed kfifo and ghes_gdata_pool. Expanded commit message ]
I had confusion how the S-o-b tag to be added for James's changes in the V11 
patch posted.

>
>In that case the ordering of the S-o-b tags under it should be different (the 
>S-
>o-b from James, the what-you-have-change line and the S-o-b from you) and
>also the From: tag should point to James.
>
>Thanks!

Thanks,
Shiju


RE: [PATCH v11 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-07-13 Thread Shiju Jose
Hi Rafael, Hi James,

Can you help to merge this patch because I added and tested all the suggestions 
from James.

Thanks,
Shiju

>-Original Message-
>From: linux-pci-ow...@vger.kernel.org [mailto:linux-pci-
>ow...@vger.kernel.org] On Behalf Of Shiju Jose
>Sent: 22 June 2020 13:05
>To: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>b...@alien8.de; james.mo...@arm.com; l...@kernel.org;
>tony.l...@intel.com; dan.carpen...@oracle.com;
>zhangligu...@linux.alibaba.com; andriy.shevche...@linux.intel.com;
>Wangkefeng (OS Kernel Lab) ;
>jroe...@suse.de
>Cc: Linuxarm ; yangyicong
>; Jonathan Cameron
>; tanxiaofei 
>Subject: [PATCH v11 1/2] ACPI / APEI: Add a notifier chain for unknown
>(vendor) CPER records
>
>CPER records describing a firmware-first error are identified by GUID.
>The ghes driver currently logs, but ignores any unknown CPER records.
>This prevents describing errors that can't be represented by a standard entry,
>that would otherwise allow a driver to recover from an error.
>The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of version 2.8).
>
>Add a notifier chain for these non-standard/vendor-records. Callers must
>identify their type of records by GUID.
>
>Record data is copied to memory from the ghes_estatus_pool to allow us to
>keep it until after the notifier has run.
>
>Signed-off-by: Shiju Jose  [ Removed kfifo and
>ghes_gdata_pool. Expanded commit message ]
>Signed-off-by: James Morse 
>---
> drivers/acpi/apei/ghes.c | 63
>
> include/acpi/ghes.h  | 27 +
> 2 files changed, 90 insertions(+)
>
>diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index
>81bf71b10d44..99df00f64306 100644
>--- a/drivers/acpi/apei/ghes.c
>+++ b/drivers/acpi/apei/ghes.c
>@@ -79,6 +79,12 @@
>   ((struct acpi_hest_generic_status *)\
>((struct ghes_estatus_node *)(estatus_node) + 1))
>
>+#define GHES_VENDOR_ENTRY_LEN(gdata_len)   \
>+  (sizeof(struct ghes_vendor_record_entry) + (gdata_len))
>+#define GHES_GDATA_FROM_VENDOR_ENTRY(vendor_entry) \
>+  ((struct acpi_hest_generic_data *)  \
>+  ((struct ghes_vendor_record_entry *)(vendor_entry) + 1))
>+
> /*
>  *  NMI-like notifications vary by architecture, before the compiler can prune
>  *  unused static functions it needs a value for these enums.
>@@ -123,6 +129,12 @@ static DEFINE_MUTEX(ghes_list_mutex);
>  */
> static DEFINE_SPINLOCK(ghes_notify_lock_irq);
>
>+struct ghes_vendor_record_entry {
>+  struct work_struct work;
>+  int error_severity;
>+  char vendor_record[];
>+};
>+
> static struct gen_pool *ghes_estatus_pool;  static unsigned long
>ghes_estatus_pool_size_request;
>
>@@ -511,6 +523,56 @@ static void ghes_handle_aer(struct
>acpi_hest_generic_data *gdata)  #endif  }
>
>+static BLOCKING_NOTIFIER_HEAD(vendor_record_notify_list);
>+
>+int ghes_register_vendor_record_notifier(struct notifier_block *nb) {
>+  return blocking_notifier_chain_register(_record_notify_list,
>+nb); } EXPORT_SYMBOL_GPL(ghes_register_vendor_record_notifier);
>+
>+void ghes_unregister_vendor_record_notifier(struct notifier_block *nb)
>+{
>+  blocking_notifier_chain_unregister(_record_notify_list, nb);
>}
>+EXPORT_SYMBOL_GPL(ghes_unregister_vendor_record_notifier);
>+
>+static void ghes_vendor_record_work_func(struct work_struct *work) {
>+  struct ghes_vendor_record_entry *entry;
>+  struct acpi_hest_generic_data *gdata;
>+  u32 len;
>+
>+  entry = container_of(work, struct ghes_vendor_record_entry, work);
>+  gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
>+
>+  blocking_notifier_call_chain(_record_notify_list,
>+   entry->error_severity, gdata);
>+
>+  len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
>+  gen_pool_free(ghes_estatus_pool, (unsigned long)entry, len); }
>+
>+static void ghes_defer_non_standard_event(struct acpi_hest_generic_data
>*gdata,
>+int sev)
>+{
>+  struct acpi_hest_generic_data *copied_gdata;
>+  struct ghes_vendor_record_entry *entry;
>+  u32 len;
>+
>+  len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
>+  entry = (void *)gen_pool_alloc(ghes_estatus_pool, len);
>+  if (!entry)
>+  return;
>+
>+  copied_gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
>+  memcpy(copied_gdata, gdata, acpi_hest_get_record_size(gdata));
>

[PATCH v11 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-06-22 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and perform port reset separately at each root port.

Add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC ip.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 3 files changed, 336 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index adddf21fa381..b7949b37c029 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -286,6 +286,14 @@ config PCI_LOONGSON
  Say Y here if you want to enable PCI controller support on
  Loongson systems.
 
+config PCIE_HISI_ERR
+   depends on ARM64 || COMPILE_TEST
+   depends on ACPI
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index efd9733ead26..90afd865bf6b 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
 obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..9bd050cadb31
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2020 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+static guid_t hisi_pcie_sec_guid =
+   GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+ 0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+/*
+ * We pass core id and core port id to the ACPI reset method to identify
+ * certain root port to reset, while the firmware reports sockets port
+ * id which occurs an error. Use the macros here to do the conversion
+ */
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) & 7) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+struct hisi_pcie_error_private {
+   struct notifier_block   nb;
+   struct device *dev;
+};
+
+enum hisi_pcie_submodule_id {
+   HISI_PCIE_SUB_MODULE_ID_AP,
+   HISI_PCIE_SUB_MODULE_ID_TL,
+   HISI_PCIE_SUB_MODULE_ID_MAC,
+   HISI_PCIE_SUB_MO

[PATCH v11 1/2] ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

2020-06-22 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

Add a notifier chain for these non-standard/vendor-records. Callers
must identify their type of records by GUID.

Record data is copied to memory from the ghes_estatus_pool to allow
us to keep it until after the notifier has run.

Signed-off-by: Shiju Jose 
[ Removed kfifo and ghes_gdata_pool. Expanded commit message ]
Signed-off-by: James Morse 
---
 drivers/acpi/apei/ghes.c | 63 
 include/acpi/ghes.h  | 27 +
 2 files changed, 90 insertions(+)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 81bf71b10d44..99df00f64306 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -79,6 +79,12 @@
((struct acpi_hest_generic_status *)\
 ((struct ghes_estatus_node *)(estatus_node) + 1))
 
+#define GHES_VENDOR_ENTRY_LEN(gdata_len)   \
+   (sizeof(struct ghes_vendor_record_entry) + (gdata_len))
+#define GHES_GDATA_FROM_VENDOR_ENTRY(vendor_entry) \
+   ((struct acpi_hest_generic_data *)  \
+   ((struct ghes_vendor_record_entry *)(vendor_entry) + 1))
+
 /*
  *  NMI-like notifications vary by architecture, before the compiler can prune
  *  unused static functions it needs a value for these enums.
@@ -123,6 +129,12 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_vendor_record_entry {
+   struct work_struct work;
+   int error_severity;
+   char vendor_record[];
+};
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -511,6 +523,56 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(vendor_record_notify_list);
+
+int ghes_register_vendor_record_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_vendor_record_notifier);
+
+void ghes_unregister_vendor_record_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_record_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_vendor_record_notifier);
+
+static void ghes_vendor_record_work_func(struct work_struct *work)
+{
+   struct ghes_vendor_record_entry *entry;
+   struct acpi_hest_generic_data *gdata;
+   u32 len;
+
+   entry = container_of(work, struct ghes_vendor_record_entry, work);
+   gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+
+   blocking_notifier_call_chain(_record_notify_list,
+entry->error_severity, gdata);
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   gen_pool_free(ghes_estatus_pool, (unsigned long)entry, len);
+}
+
+static void ghes_defer_non_standard_event(struct acpi_hest_generic_data *gdata,
+ int sev)
+{
+   struct acpi_hest_generic_data *copied_gdata;
+   struct ghes_vendor_record_entry *entry;
+   u32 len;
+
+   len = GHES_VENDOR_ENTRY_LEN(acpi_hest_get_record_size(gdata));
+   entry = (void *)gen_pool_alloc(ghes_estatus_pool, len);
+   if (!entry)
+   return;
+
+   copied_gdata = GHES_GDATA_FROM_VENDOR_ENTRY(entry);
+   memcpy(copied_gdata, gdata, acpi_hest_get_record_size(gdata));
+   entry->error_severity = sev;
+
+   INIT_WORK(>work, ghes_vendor_record_work_func);
+   schedule_work(>work);
+}
+
 static bool ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -549,6 +611,7 @@ static bool ghes_do_proc(struct ghes *ghes,
} else {
void *err = acpi_hest_get_payload(gdata);
 
+   ghes_defer_non_standard_event(gdata, sev);
log_non_standard_event(sec_type, fru_id, fru_text,
   sec_sev, err,
   gdata->error_data_length);
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 517a5231cc1b..ae0e8847fdd5 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -53,6 +53,33 @@ enum {
GHES_SEV_PANIC = 0x3,
 };
 
+#ifdef CONFIG_ACPI_APEI_GHES
+/**
+ * ghes_register_vendor_record_notifier - register a notifier for vendor
+ * records that the kernel would otherwise ignore.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_vendor_record_

[PATCH v11 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-06-22 Thread Shiju Jose
CPER records describing a firmware-first error are identified by GUID.
The ghes driver currently logs, but ignores any unknown CPER records.
This prevents describing errors that can't be represented by a standard
entry, that would otherwise allow a driver to recover from an error.
The UEFI spec calls these 'Non-standard Section Body' (N.2.3 of
version 2.8).

patch set
1. add a notifier chain for these non-standard/vendor-records
   in the ghes driver.

2. add a driver to handle HiSilicon hip PCIe controller's errors.
   
Changes:

V11:
1. Following modifications made by James Morse in the APEI patch
   for the vendor error record.
   - Removed kfifo and ghes_gdata_pool. Expanded commit message.
   
   Note: Kept the Signed-off-by: James Morse as he is given
   because I am not sure the right format.
   
2. Changes in the HIP PCIe error handler driver
   for the comments by Andy Shevchenko.

V10:
1. Changes for Bjorn's comments on HIP PCIe error handler driver
   and APEI patch.
   
2. Changes in the HIP PCIe error handler driver
   for the feedbacks by Andy Shevchenko.
   
V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add a notifier chain for unknown (vendor) CPER records

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c |  63 +
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 include/acpi/ghes.h  |  27 ++
 5 files changed, 426 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




RE: [PATCH v9 1/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-06-19 Thread Shiju Jose
Hi James,

Thanks for reviewing the patch and the modifications.
 
>-Original Message-
>From: James Morse [mailto:james.mo...@arm.com]
>Sent: 18 June 2020 19:20
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de; l...@kernel.org;
>tony.l...@intel.com; dan.carpen...@oracle.com;
>zhangligu...@linux.alibaba.com; andriy.shevche...@linux.intel.com;
>Wangkefeng (OS Kernel Lab) ;
>jroe...@suse.de; yangyicong ; Jonathan Cameron
>; tanxiaofei 
>Subject: Re: [PATCH v9 1/2] ACPI / APEI: Add support to notify the vendor
>specific HW errors
>
>Hi Shiju,
>
>On 15/06/2020 10:53, Shiju Jose wrote:
>> Add support to notify the vendor specific non-fatal HW errors to the
>> drivers for the error recovery.
>
>This doesn't apply cleanly to v5.8-rc1... thanks for waiting for the merge
>window to finish, but please rebase onto the latest and greatest kernel!

V10 was posted based on v5.8-rc1.
>
>I'm glad the notifier chains for stuff that should be built-in has gone.
>(In my opinion, the RAS code should be moving in the direction of having less
>code run between being told of an error, and the handler running. Notifier
>chains for things like memory-errors was moving in the wrong direction!)
>
>
>The Kfifo and pool are adding complexity I don't think you need.
>Please make it clear from the naming this is for vendor records. (what is an
>event?)
>
>The memcpy() for the records is annoying, but eliminating it takes some
>really invasive changes. Lets live with it for now.
Ok.

>
>
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index
>> 24c9642e8fc7..854d8115cdfc 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -63,6 +64,11 @@
>>  #define GHES_ESTATUS_CACHES_SIZE4
>>
>>  #define GHES_ESTATUS_IN_CACHE_MAX_NSEC  100ULL
>> +
>> +#define GHES_EVENT_RING_SIZE256
>> +#define GHES_GDATA_POOL_MIN_ALLOC_ORDER 3
>> +#define GHES_GDATA_POOL_MIN_SIZE65536
>
>Huh. Another pool of memory, and we don't know if this will ever be used.
>Can we allocate from ghes_estatus_pool instead?
>
>ghes_estatus_pool is already scaled with the number of error sources
>firmware describes in ghes_estatus_pool_init(), so it should be big enough.
>
>ghes_estatus_pool already has multiple users, estatus_nodes for work
>deferred from NMI come from here, as do ghes_estatus_caches for the low-
>pass filter thing.

Ok.
>
>
>> @@ -122,6 +128,19 @@ static DEFINE_MUTEX(ghes_list_mutex);
>>   */
>>  static DEFINE_SPINLOCK(ghes_notify_lock_irq);
>>
>> +struct ghes_event_entry {
>
>ghes_vendor_record_entry ?
>
>> +struct acpi_hest_generic_data *gdata;
>> +int error_severity;
>> +};
>
>> +static DEFINE_KFIFO(ghes_event_ring, struct ghes_event_entry,
>> +GHES_EVENT_RING_SIZE);
>> +
>> +static DEFINE_SPINLOCK(ghes_event_ring_lock);
>
>Do you need the FIFO behaviour?
>If you put a work_struct in the struct and schedule_work() that, these would
>run in any order, and it would be less code.
>
>
>> +static struct gen_pool *ghes_gdata_pool; static unsigned long
>> +ghes_gdata_pool_size_request;
>> +
>>  static struct gen_pool *ghes_estatus_pool;  static unsigned long
>> ghes_estatus_pool_size_request;
>
>Please use the existing ghes_estatus_pool.
>
>
>> @@ -188,6 +207,40 @@ int ghes_estatus_pool_init(int num_ghes)
>
>[...]
>
>> +static int ghes_gdata_pool_init(void) {
>> +unsigned long addr, len;
>> +int rc;
>> +
>> +ghes_gdata_pool =
>gen_pool_create(GHES_GDATA_POOL_MIN_ALLOC_ORDER, -1);
>> +if (!ghes_gdata_pool)
>> +return -ENOMEM;
>> +
>> +if (ghes_gdata_pool_size_request < GHES_GDATA_POOL_MIN_SIZE)
>> +ghes_gdata_pool_size_request =
>GHES_GDATA_POOL_MIN_SIZE;
>> +
>> +len = ghes_gdata_pool_size_request;
>> +addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
>> +if (!addr)
>> +goto err_pool_alloc;
>
>> +vmalloc_sync_mappings();
>(This isn't needed anymore. See commit 73f693c3a705 ("mm: remove
>vmalloc_sync_(un)mappings()"))
>
>
>> +rc = gen_pool_add(ghes_gdata_pool, addr, PAGE_ALIGN(len), -1);
>> +if (rc)
>> +goto err_pool_add;
>> +
>> +return 0;
>> +
>> +err_pool_add:
>> +vfree((void *)addr);
>> +
>> +err_pool_alloc:
>> +gen_pool_destroy(ghes_gdata_pool);
>> +
>> +return -ENOM

RE: [PATCH v10 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-06-18 Thread Shiju Jose
Hi Andy,

>-Original Message-
>From: Andy Shevchenko [mailto:andriy.shevche...@linux.intel.com]
>Sent: 18 June 2020 16:56
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>b...@alien8.de; james.mo...@arm.com; l...@kernel.org;
>tony.l...@intel.com; dan.carpen...@oracle.com;
>zhangligu...@linux.alibaba.com; Wangkefeng (OS Kernel Lab)
>; jroe...@suse.de; Linuxarm
>; yangyicong ; Jonathan
>Cameron ; tanxiaofei
>
>Subject: Re: [PATCH v10 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe
>controller errors
>
>On Thu, Jun 18, 2020 at 04:40:51PM +0100, Shiju Jose wrote:
>> From: Yicong Yang 
>>
>> The HiSilicon HIP PCIe controller is capable of handling errors on
>> root port and perform port reset separately at each root port.
>>
>> Add error handling driver for HIP PCIe controller to log and report
>> recoverable errors. Perform root port reset and restore link status
>> after the recovery.
>>
>> Following are some of the PCIe controller's recoverable errors 1.
>> completion transmission timeout error.
>> 2. CRS retry counter over the threshold error.
>> 3. ECC 2 bit errors
>> 4. AXI bresponse/rresponse errors etc.
>>
>> The driver placed in the drivers/pci/controller/ because the HIP PCIe
>> controller does not use DWC ip.
>
>> Reviewed-by: Andy Shevchenko 
>
>Hmm... Did I give a tag?
>
>...
>
>> +static guid_t hisi_pcie_sec_guid =
>> +GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
>> +0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
>
>Drop one TAB in each line and add two spaces before 0xA8 on the last.

Sure.

>
>
>...
>
>> +idx = HISI_PCIE_LOCAL_VALID_ERR_MISC;
>
>> +for_each_set_bit_from(idx, (const unsigned long *)>val_bits,
>
>Can't you make val_bits unsigned long? Because this casting is incorrect.
>Otherwise, make a local copy into unsigned long variable.

The data val_bits in the error record is 64 bits, thus used u64.
Casting is added because of a compilation warning on _find_nex_bit_ function as 
it 
expects the type of the address as const unsigned long*.
Probably I will make local copy of val_bits into unsigned long variable.

>
>> +  HISI_PCIE_LOCAL_VALID_ERR_MISC +
>HISI_PCIE_ERR_MISC_REGS)
>> +dev_info(dev, "ERR_MISC_%d = 0x%x\n", idx -
>HISI_PCIE_LOCAL_VALID_ERR_MISC,
>> + edata->err_misc[idx]);
>
>...
>
>> +static int hisi_pcie_error_handler_probe(struct platform_device
>> +*pdev) {
>> +struct hisi_pcie_error_private *priv;
>> +int ret;
>> +
>
>> +priv = devm_kzalloc(>dev, sizeof(*priv), GFP_KERNEL);
>
>(1)
>
>> +if (!priv)
>> +return -ENOMEM;
>> +
>> +priv->nb.notifier_call = hisi_pcie_notify_error;
>> +priv->dev = >dev;
>> +ret = ghes_register_event_notifier(>nb);
>> +if (ret) {
>> +dev_err(>dev,
>> +"Failed to register hisi_pcie_notify_error
>function\n");
>> +return ret;
>> +}
>> +
>> +platform_set_drvdata(pdev, priv);
>> +
>> +return 0;
>> +}
>> +
>> +static int hisi_pcie_error_handler_remove(struct platform_device
>> +*pdev) {
>> +struct hisi_pcie_error_private *priv = platform_get_drvdata(pdev);
>> +
>> +ghes_unregister_event_notifier(>nb);
>
>> +kfree(priv);
>
>See (1), as I told you, this is double free.
>Have you tested this?
>
>> +return 0;
>> +}
>
>--
>With Best Regards,
>Andy Shevchenko
>

Thanks,
Shiju


[PATCH v10 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-06-18 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and perform port reset separately at each root port.

Add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC ip.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
Reviewed-by: Bjorn Helgaas 
Reviewed-by: Andy Shevchenko 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 3 files changed, 336 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index adddf21fa381..b7949b37c029 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -286,6 +286,14 @@ config PCI_LOONGSON
  Say Y here if you want to enable PCI controller support on
  Loongson systems.
 
+config PCIE_HISI_ERR
+   depends on ARM64 || COMPILE_TEST
+   depends on ACPI
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index efd9733ead26..90afd865bf6b 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
 obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..3cfcc31568f0
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2020 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+static guid_t hisi_pcie_sec_guid =
+   GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+   0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+/*
+ * We pass core id and core port id to the ACPI reset method to identify
+ * certain root port to reset, while the firmware reports sockets port
+ * id which occurs an error. Use the macros here to do the conversion
+ */
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) & 7) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+struct hisi_pcie_error_private {
+   struct notifier_block   nb;
+   struct device *dev;
+};
+
+enum hisi_pcie_submodule_id {
+   HISI_PCIE_SUB_MODULE_ID_AP,
+  

[PATCH v10 1/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-06-18 Thread Shiju Jose
Add support to report the vendor specific non-fatal HW errors
to the drivers for the error recovery.

The interface functions ghes_register_event_notifier() and
ghes_unregister_event_notifier() enables the drivers to register and
unregister the vendor specific error handlers. The interface uses
work queue for queuing each vendor-specific error record and uses
blocking notifier chain, in the work function, to report the error to
the registered drivers.
The drivers should match the section type of the error record before
processing the error data.

Signed-off-by: Shiju Jose 
Reviewed-by: Bjorn Helgaas 
---
 drivers/acpi/apei/ghes.c | 123 +++
 include/acpi/ghes.h  |  29 +
 2 files changed, 152 insertions(+)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 81bf71b10d44..b6dc4eaa6345 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -64,6 +65,7 @@
 #define GHES_ESTATUS_CACHES_SIZE   4
 
 #define GHES_ESTATUS_IN_CACHE_MAX_NSEC 100ULL
+
 /* Prevent too many caches are allocated because of RCU */
 #define GHES_ESTATUS_CACHE_ALLOCED_MAX (GHES_ESTATUS_CACHES_SIZE * 3 / 2)
 
@@ -88,6 +90,10 @@
 #define FIX_APEI_GHES_SDEI_CRITICAL__end_of_fixed_addresses
 #endif
 
+#define GHES_EVENT_RING_SIZE   256
+#define GHES_EVENT_GDATA_POOL_MIN_ALLOC_ORDER  3
+#define GHES_EVENT_GDATA_POOL_MIN_SIZE 65536
+
 static inline bool is_hest_type_generic_v2(struct ghes *ghes)
 {
return ghes->generic->header.type == ACPI_HEST_TYPE_GENERIC_ERROR_V2;
@@ -123,6 +129,19 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_event_entry {
+   struct acpi_hest_generic_data *gdata;
+   int error_severity;
+};
+
+static DEFINE_KFIFO(ghes_event_ring, struct ghes_event_entry,
+   GHES_EVENT_RING_SIZE);
+
+static DEFINE_SPINLOCK(ghes_event_ring_lock);
+
+static struct gen_pool *ghes_event_gdata_pool;
+static unsigned long ghes_event_gdata_pool_size_request;
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -183,6 +202,38 @@ int ghes_estatus_pool_init(int num_ghes)
return -ENOMEM;
 }
 
+static int ghes_event_gdata_pool_init(void)
+{
+   unsigned long addr, len;
+   int rc;
+
+   ghes_event_gdata_pool = 
gen_pool_create(GHES_EVENT_GDATA_POOL_MIN_ALLOC_ORDER, -1);
+   if (!ghes_event_gdata_pool)
+   return -ENOMEM;
+
+   if (ghes_event_gdata_pool_size_request < GHES_EVENT_GDATA_POOL_MIN_SIZE)
+   ghes_event_gdata_pool_size_request = 
GHES_EVENT_GDATA_POOL_MIN_SIZE;
+
+   len = ghes_event_gdata_pool_size_request;
+   addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
+   if (!addr)
+   goto err_pool_alloc;
+
+   rc = gen_pool_add(ghes_event_gdata_pool, addr, PAGE_ALIGN(len), -1);
+   if (rc)
+   goto err_pool_add;
+
+   return 0;
+
+err_pool_add:
+   vfree((void *)addr);
+
+err_pool_alloc:
+   gen_pool_destroy(ghes_event_gdata_pool);
+
+   return -ENOMEM;
+}
+
 static int map_gen_v2(struct ghes *ghes)
 {
return apei_map_generic_address(>generic_v2->read_ack_register);
@@ -242,6 +293,10 @@ static struct ghes *ghes_new(struct acpi_hest_generic 
*generic)
goto err_unmap_status_addr;
}
 
+   ghes_event_gdata_pool_size_request += generic->records_to_preallocate *
+ generic->max_sections_per_record *
+ generic->max_raw_data_length;
+
return ghes;
 
 err_unmap_status_addr:
@@ -511,6 +566,69 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(ghes_event_notify_list);
+
+/**
+ * ghes_register_event_notifier - register an event notifier
+ * for the non-fatal HW errors.Presently supported to notify
+ * the vendor-specific HW errors only, though it can be used to
+ * notify the standard errors also.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_event_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_event_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_event_notifier);
+
+/**
+ * ghes_unregister_event_notifier - unregister the previously
+ * registered event notifier.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ */
+void ghes_unregister_event_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_event_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_event_notifier);
+
+static void ghes_event_work_func(struct work_struct *work)
+{
+   struct ghes_event_entry entry;
+   u32 len;
+
+   whil

[PATCH v10 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-06-18 Thread Shiju Jose
Presently the vendor drivers are unable to do the recovery for the
vendor specific recoverable HW errors because APEI driver does not
support reporting the error to the vendor drivers.

patch set
1. add new interface to the APEI driver for reporting the 
   vendor specific non-fatal HW errors to the drivers.

2. add driver to handle HiSilicon hip PCIe controller's errors.

V10:
1. Changes for Bjorn's comments on HIP PCIe error handler driver
   and APEI patch.
   
2. Changes in the HIP PCIe error handler driver
   for the feedbacks by Andy Shevchenko.
   
V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add support to notify the vendor specific HW errors

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c | 123 +
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 327 +++
 include/acpi/ghes.h  |  29 ++
 5 files changed, 488 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




RE: [PATCH v9 1/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-06-17 Thread Shiju Jose
Hi Bjorn,

Thanks for reviewing.

I will make changes for your suggestions in both patches.

Regards,
Shiju  

>-Original Message-
>From: Bjorn Helgaas [mailto:helg...@kernel.org]
>Sent: 16 June 2020 23:57
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>james.mo...@arm.com; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com;
>andriy.shevche...@linux.intel.com; Wangkefeng (OS Kernel Lab)
>; jroe...@suse.de; yangyicong
>; Jonathan Cameron
>; tanxiaofei 
>Subject: Re: [PATCH v9 1/2] ACPI / APEI: Add support to notify the vendor
>specific HW errors
>
>On Mon, Jun 15, 2020 at 10:53:11AM +0100, Shiju Jose wrote:
>> Add support to notify the vendor specific non-fatal HW errors to the
>> drivers for the error recovery.
>
>This doesn't actually say anything about what this patch does.  Sure, it "adds
>support," but it doesn't say anything about how that support works or how
>to use it.
>
>This should say something about a FIFO and it should mention that an event
>handler registered with ghes_register_event_notifier() will be called with
>each vendor-specific error record.
>
>> Signed-off-by: Shiju Jose 
>> ---
>>  drivers/acpi/apei/ghes.c | 130
>++-
>>  include/acpi/ghes.h  |  28 +
>>  2 files changed, 157 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index
>> 24c9642e8fc7..854d8115cdfc 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -33,6 +33,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -63,6 +64,11 @@
>>  #define GHES_ESTATUS_CACHES_SIZE4
>>
>>  #define GHES_ESTATUS_IN_CACHE_MAX_NSEC  100ULL
>> +
>> +#define GHES_EVENT_RING_SIZE256
>> +#define GHES_GDATA_POOL_MIN_ALLOC_ORDER 3
>> +#define GHES_GDATA_POOL_MIN_SIZE65536
>
>Don't drop these new #defines right in the middle of the GHES_ESTATUS
>block.  The ESTATUS ones are all related, and these new ones are something
>separate.
>
>These new names should be related somehow.  The names don't make it clear
>that GHES_EVENT and GHES_GDATA are related.  IIUC GHES_GDATA is space
>for storing GHES structures, and GHES_EVENT is a FIFO of struct
>ghes_event_entry, each of which points to one of those GHES structures.
>
>>  /* Prevent too many caches are allocated because of RCU */
>>  #define GHES_ESTATUS_CACHE_ALLOCED_MAX
>   (GHES_ESTATUS_CACHES_SIZE * 3 / 2)
>>
>> @@ -122,6 +128,19 @@ static DEFINE_MUTEX(ghes_list_mutex);
>>   */
>>  static DEFINE_SPINLOCK(ghes_notify_lock_irq);
>>
>> +struct ghes_event_entry {
>> +struct acpi_hest_generic_data *gdata;
>> +int error_severity;
>> +};
>> +
>> +static DEFINE_KFIFO(ghes_event_ring, struct ghes_event_entry,
>> +GHES_EVENT_RING_SIZE);
>> +
>> +static DEFINE_SPINLOCK(ghes_event_ring_lock);
>> +
>> +static struct gen_pool *ghes_gdata_pool; static unsigned long
>> +ghes_gdata_pool_size_request;
>> +
>>  static struct gen_pool *ghes_estatus_pool;  static unsigned long
>> ghes_estatus_pool_size_request;
>>
>> @@ -188,6 +207,40 @@ int ghes_estatus_pool_init(int num_ghes)
>>  return -ENOMEM;
>>  }
>>
>> +static int ghes_gdata_pool_init(void) {
>> +unsigned long addr, len;
>> +int rc;
>> +
>> +ghes_gdata_pool =
>gen_pool_create(GHES_GDATA_POOL_MIN_ALLOC_ORDER, -1);
>> +if (!ghes_gdata_pool)
>> +return -ENOMEM;
>> +
>> +if (ghes_gdata_pool_size_request < GHES_GDATA_POOL_MIN_SIZE)
>> +ghes_gdata_pool_size_request =
>GHES_GDATA_POOL_MIN_SIZE;
>> +
>> +len = ghes_gdata_pool_size_request;
>> +addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
>> +if (!addr)
>> +goto err_pool_alloc;
>> +
>> +vmalloc_sync_mappings();
>> +
>> +rc = gen_pool_add(ghes_gdata_pool, addr, PAGE_ALIGN(len), -1);
>> +if (rc)
>> +goto err_pool_add;
>> +
>> +return 0;
>> +
>> +err_pool_add:
>> +vfree((void *)addr);
>> +
>> +err_pool_alloc:
>> +gen_pool_destroy(ghes_gdata_pool);
>> +
>> +return -ENOMEM;
>> +}
>> +
>>  static int map_gen_v2(struct ghes *ghes)  {
>>  return
>> apei_map_generic_

RE: [PATCH v9 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-06-16 Thread Shiju Jose
Hi Andy,

>-Original Message-
>From: Andy Shevchenko [mailto:andriy.shevche...@linux.intel.com]
>Sent: 16 June 2020 13:41
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>james.mo...@arm.com; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com; Wangkefeng
>(OS Kernel Lab) ; jroe...@suse.de;
>yangyicong ; Jonathan Cameron
>; tanxiaofei ;
>Linuxarm 
>Subject: Re: [PATCH v9 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe
>controller errors
>
>On Tue, Jun 16, 2020 at 11:55:46AM +, Shiju Jose wrote:
>> >From: linux-acpi-ow...@vger.kernel.org [mailto:linux-acpi-
>> >ow...@vger.kernel.org] On Behalf Of Andy Shevchenko On Tue, Jun 16,
>> >2020 at 09:12:56AM +, Shiju Jose wrote:
>> >> >From: Andy Shevchenko [mailto:andriy.shevche...@linux.intel.com]
>> >> >On Mon, Jun 15, 2020 at 11:15:52AM +0100, Shiju Jose wrote:
>
>...
>
>> >> >> +#define HISI_PCIE_CORE_PORT_ID(v)(((v) % 8) << 1)
>> >> >
>> >> >% -> & ?
>> >> (((v) % 8) << 1) is correct. We can make bit operation instead.
>> >
>> >y % x is usually being used when we consume y / x or in cases when y
>> >is advanced and we need to keep it under some threshold.
>> >
>> >Here it's not obvious to me, and usual pattern is to use bitwise
>operations.
>> >
>> >In any case some clarification is needed.
>> We want (v % 8) * 2 here to get the core port id, a numerical value but not
>a bit mask.
>> Maybe you want us to use ((v) & 7) << 1?
>> please point it out if I understand wrong.
>
>I understand the result, I do not understand the properties of v.
>So, looks like
>a) (v & 7) << 1 // take 3 LSBs from v and shift right to get port id pair 
>(looks
>like)
>b) (v % 8) * 2 // get next free port or circle over 0 if no free pair found
>
>Add some comment explaining what's going on.
Sure.

>
>...
>
>> >> >> +  switch (id) {
>> >> >> +  case HISI_PCIE_SUB_MODULE_ID_AP: return "AP Layer";
>> >> >> +  case HISI_PCIE_SUB_MODULE_ID_TL: return "TL Layer";
>> >> >> +  case HISI_PCIE_SUB_MODULE_ID_MAC: return "MAC Layer";
>> >> >> +  case HISI_PCIE_SUB_MODULE_ID_DL: return "DL Layer";
>> >> >> +  case HISI_PCIE_SUB_MODULE_ID_SDI: return "SDI Layer";
>> >> >> +  }
>> >> >
>> >> >match_string() ?
>> >>
>> >> match_string() does not work here because we need sub module id ->
>> >> string conversion.
>> >
>> >Why? Are you using non-sequential (a.k.a. sparse) values?
>> These are the sequential values.
>> I mean in this case we do not have the third parameter to the
>> match_string(), string to match with the strings in the array, we just
>> have the value for the sub module id.
>> Can you suggest some example of match_string() for the similar case?
>
>Ah, I realize, this is the opposite, but still perhaps better to have like 
>this:
>
>static const char * const foo[] = {
>   "AB",
>   "CD",
>};
>
>const char *bar(int id)
>{
>   if (id >= ARRAY_SIZE(foo))
>   return "unknown"; // whatever
>   return foo[id];
>}
Sure.
  
>
>--
>With Best Regards,
>Andy Shevchenko
>
Thanks,
Shiju



RE: [PATCH v9 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-06-16 Thread Shiju Jose
Hi Andy,

>-Original Message-
>From: linux-acpi-ow...@vger.kernel.org [mailto:linux-acpi-
>ow...@vger.kernel.org] On Behalf Of Andy Shevchenko
>Sent: 16 June 2020 10:31
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>james.mo...@arm.com; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com; Wangkefeng
>(OS Kernel Lab) ; jroe...@suse.de;
>yangyicong ; Jonathan Cameron
>; tanxiaofei ;
>Linuxarm 
>Subject: Re: [PATCH v9 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe
>controller errors
>
>On Tue, Jun 16, 2020 at 09:12:56AM +, Shiju Jose wrote:
>> >-Original Message-
>> >From: Andy Shevchenko [mailto:andriy.shevche...@linux.intel.com]
>> >Sent: 15 June 2020 13:01
>> >To: Shiju Jose 
>> >Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>> >ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>> >james.mo...@arm.com; l...@kernel.org; tony.l...@intel.com;
>> >dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com; Wangkefeng
>> >(OS Kernel Lab) ; jroe...@suse.de;
>> >yangyicong ; Jonathan Cameron
>> >; tanxiaofei 
>> >Subject: Re: [PATCH v9 2/2] PCI: hip: Add handling of HiSilicon HIP
>> >PCIe controller errors
>> >
>> >On Mon, Jun 15, 2020 at 11:15:52AM +0100, Shiju Jose wrote:
>
>...
>
>> >bits.h ?
>>
>> Ok. I think bits.h was already included through some other .h files.
>
>You have direct users of the header here.
>The rule of thumb is to include all headers of which you have direct users.
>Some exceptions of course can be applied, but for generic headers like bits.h
>there are only bitops.h or bitmap.h that guarantee inclusion of the
>mentioned macros / definitions.
>
>I don't see any header of the same domain in the list.

Ok.
>
>...
>
>> >> +#define HISI_PCIE_CORE_PORT_ID(v)(((v) % 8) << 1)
>> >
>> >% -> & ?
>> (((v) % 8) << 1) is correct. We can make bit operation instead.
>
>y % x is usually being used when we consume y / x or in cases when y is
>advanced and we need to keep it under some threshold.
>
>Here it's not obvious to me, and usual pattern is to use bitwise operations.
>
>In any case some clarification is needed.
We want (v % 8) * 2 here to get the core port id, a numerical value but not a 
bit mask.
Maybe you want us to use ((v) & 7) << 1? 
please point it out if I understand wrong.

>
>...
>
>> >> +struct hisi_pcie_error_private {
>> >> + struct notifier_block   nb;
>> >> + struct platform_device  *pdev;
>> >
>> >Do you really need platform device? Isn't struct device * enough?
>> We need platform device as the error recovery device is a platform
>> device, which provides us the "RST" reset method.
>
>Can't you derive platform device from struct device pointer?
>I really didn't see an evidence you need to keep it like this.
>
>And in probably single case you may derive it, no?

We will check by making this change.

>
>> >> +};
>
>...
>
>> >> +static char *hisi_pcie_sub_module_name(u8 id) {
>> >> + switch (id) {
>> >> + case HISI_PCIE_SUB_MODULE_ID_AP: return "AP Layer";
>> >> + case HISI_PCIE_SUB_MODULE_ID_TL: return "TL Layer";
>> >> + case HISI_PCIE_SUB_MODULE_ID_MAC: return "MAC Layer";
>> >> + case HISI_PCIE_SUB_MODULE_ID_DL: return "DL Layer";
>> >> + case HISI_PCIE_SUB_MODULE_ID_SDI: return "SDI Layer";
>> >> + }
>> >
>> >match_string() ?
>>
>> match_string() does not work here because we need sub module id ->
>> string conversion.
>
>Why? Are you using non-sequential (a.k.a. sparse) values?
These are the sequential values.
I mean in this case we do not have the third parameter to the match_string(),
string to match with the strings in the array,
we just have the value for the sub module id.
Can you suggest some example of match_string()
for the similar case?

>
>
...
>...
>
>> >> + for (i = 0; i < HISI_PCIE_ERR_MISC_REGS; i++) {
>> >> + if (edata->val_bits &
>> >> + BIT_ULL(HISI_PCIE_LOCAL_VALID_ERR_MISC
>> >+ i))
>> >
>> >for_each_set_bit() ?
>>
>> Can't use for_each_set_bit() here because edata->val_bits contains
>> valid bits for other fields of the error data as well, those need to printed
>separately.
>
>So, I don't get why.
>
>You have at least two possibilities:
>1/ use bitwise & to drop non-related bits (maybe in temporary variable) 2/
>use for_each_set_bit_from()

Ok. I think  for_each_set_bit_from() may be better.
>
>

Thanks,
Shiju



RE: [PATCH v9 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-06-16 Thread Shiju Jose
Hi Andy,

Thanks for the reviewing the patch.

>-Original Message-
>From: Andy Shevchenko [mailto:andriy.shevche...@linux.intel.com]
>Sent: 15 June 2020 13:01
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>james.mo...@arm.com; l...@kernel.org; tony.l...@intel.com;
>dan.carpen...@oracle.com; zhangligu...@linux.alibaba.com; Wangkefeng
>(OS Kernel Lab) ; jroe...@suse.de;
>yangyicong ; Jonathan Cameron
>; tanxiaofei 
>Subject: Re: [PATCH v9 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe
>controller errors
>
>On Mon, Jun 15, 2020 at 11:15:52AM +0100, Shiju Jose wrote:
>> From: Yicong Yang 
>>
>> The HiSilicon HIP PCIe controller is capable of handling errors on
>> root port and perform port reset separately at each root port.
>>
>> Add error handling driver for HIP PCIe controller to log and report
>> recoverable errors. Perform root port reset and restore link status
>> after the recovery.
>>
>> Following are some of the PCIe controller's recoverable errors 1.
>> completion transmission timeout error.
>> 2. CRS retry counter over the threshold error.
>> 3. ECC 2 bit errors
>> 4. AXI bresponse/rresponse errors etc.
>>
>> The driver placed in the drivers/pci/controller/ because the HIP PCIe
>> controller does not use DWC ip.
>
>...
>
>> +#include 
>> +#include 
>
>bits.h ?

Ok. I think bits.h was already included through some other .h files.

>
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>
>...
>
>> +static guid_t hisi_pcie_sec_type = GUID_INIT(0xB2889FC9, 0xE7D7,
>0x4F9D,
>> +0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
>
>Can we have it in more common pattern, i.e.
>
>static guid_t hisi_pcie_sec_type =
>   GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
> 0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72); ?

Ok. Will change it.
>
>...
>
>> +#define HISI_PCIE_CORE_PORT_ID(v)(((v) % 8) << 1)
>
>% -> & ?
(((v) % 8) << 1) is correct. We can make bit operation instead. 

>
>...
>
>> +struct hisi_pcie_error_private {
>> +struct notifier_block   nb;
>> +struct platform_device  *pdev;
>
>Do you really need platform device? Isn't struct device * enough?
We need platform device as the error recovery device is a platform device,
which provides us the "RST" reset method.
>
>> +};
>
>...
>
>> +static char *hisi_pcie_sub_module_name(u8 id) {
>> +switch (id) {
>> +case HISI_PCIE_SUB_MODULE_ID_AP: return "AP Layer";
>> +case HISI_PCIE_SUB_MODULE_ID_TL: return "TL Layer";
>> +case HISI_PCIE_SUB_MODULE_ID_MAC: return "MAC Layer";
>> +case HISI_PCIE_SUB_MODULE_ID_DL: return "DL Layer";
>> +case HISI_PCIE_SUB_MODULE_ID_SDI: return "SDI Layer";
>> +}
>
>match_string() ?

match_string() does not work here because we need sub module id -> string
conversion. 

>
>> +return "unknown";
>
>> +}
>> +
>> +static char *hisi_pcie_error_severity(u8 err_sev) {
>> +switch (err_sev) {
>> +case HISI_ERR_SEV_RECOVERABLE: return "recoverable";
>> +case HISI_ERR_SEV_FATAL: return "fatal";
>> +case HISI_ERR_SEV_CORRECTED: return "corrected";
>> +case HISI_ERR_SEV_NONE: return "none";
>> +}
>
>Ditto?

Same as above.

>
>> +return "unknown";
>> +}
>
>...
>
>> +pdev = pci_get_domain_bus_and_slot(domain, busnr, devfn);
>> +if (!pdev) {
>
>> +dev_info(device, "Fail to get root port %04x:%02x:%02x.%d
>device\n",
>> + domain, busnr, PCI_SLOT(devfn), PCI_FUNC(devfn));
>
>pci_info() ?

It's wrong to use pci_info() here, as in the branch we haven't get a pci device 
and also 
we're printing info's of the error handler device driver, not a pci device 
driver.

>
>> +return -ENODEV;
>> +}
>
>...
>
>> +/*
>> + * The initialization time of subordinate devices after
>> + * hot reset is no more than 1s, which is required by
>> + * the PCI spec v5.0 sec 6.6.1. The time will shorten
>> + * if Readiness Notifications mechanisms are used. But
>> + * wait 1s here to adapt any conditions.
>> + */
>> +ssleep(1UL);
>
>It's a huge time out... Can we reduce it somehow?

Less time may leads downstream traffic not recove

[PATCH v9 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-06-15 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and perform port reset separately at each root port.

Add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC ip.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 305 +++
 3 files changed, 314 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 91bfdb784829..7ba4b94f8604 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -258,6 +258,14 @@ config PCI_HYPERV_INTERFACE
  The Hyper-V PCI Interface is a helper driver allows other drivers to
  have a common interface with the Hyper-V PCI frontend driver.
 
+config PCIE_HISI_ERR
+   depends on ARM64 || COMPILE_TEST
+   depends on ACPI
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 158c59771824..ab3a528bf988 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
 obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..cfcec3b1e173
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2018-2019 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_SUB_MODULE_ID_AP 0
+#define HISI_PCIE_SUB_MODULE_ID_TL 1
+#define HISI_PCIE_SUB_MODULE_ID_MAC2
+#define HISI_PCIE_SUB_MODULE_ID_DL 3
+#define HISI_PCIE_SUB_MODULE_ID_SDI4
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+#define HISI_ERR_SEV_RECOVERABLE   0
+#define HISI_ERR_SEV_FATAL 1
+#define HISI_ERR_SEV_CORRECTED 2
+#define HISI_ERR_SEV_NONE  3
+
+static guid_t hisi_pcie_sec_type = GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+   0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) % 8) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+struct hisi_pcie_error_private {
+   struct notifier_

[PATCH v9 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-06-15 Thread Shiju Jose
Presently the vendor drivers are unable to do the recovery for the
vendor specific recoverable HW errors because APEI driver does not
support reporting the error to the vendor drivers.

patch set
1. add new interface to the APEI driver for reporting the 
   vendor specific non-fatal HW errors to the drivers.

2. add driver to handle HiSilicon hip PCIe controller's errors.

V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add support to notify the vendor specific HW errors

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c | 130 +-
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 305 +++
 include/acpi/ghes.h  |  28 +++
 5 files changed, 471 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




[PATCH v9 1/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-06-15 Thread Shiju Jose
Add support to notify the vendor specific non-fatal HW errors
to the drivers for the error recovery.

Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 130 ++-
 include/acpi/ghes.h  |  28 +
 2 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 24c9642e8fc7..854d8115cdfc 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -63,6 +64,11 @@
 #define GHES_ESTATUS_CACHES_SIZE   4
 
 #define GHES_ESTATUS_IN_CACHE_MAX_NSEC 100ULL
+
+#define GHES_EVENT_RING_SIZE   256
+#define GHES_GDATA_POOL_MIN_ALLOC_ORDER3
+#define GHES_GDATA_POOL_MIN_SIZE   65536
+
 /* Prevent too many caches are allocated because of RCU */
 #define GHES_ESTATUS_CACHE_ALLOCED_MAX (GHES_ESTATUS_CACHES_SIZE * 3 / 2)
 
@@ -122,6 +128,19 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_event_entry {
+   struct acpi_hest_generic_data *gdata;
+   int error_severity;
+};
+
+static DEFINE_KFIFO(ghes_event_ring, struct ghes_event_entry,
+   GHES_EVENT_RING_SIZE);
+
+static DEFINE_SPINLOCK(ghes_event_ring_lock);
+
+static struct gen_pool *ghes_gdata_pool;
+static unsigned long ghes_gdata_pool_size_request;
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -188,6 +207,40 @@ int ghes_estatus_pool_init(int num_ghes)
return -ENOMEM;
 }
 
+static int ghes_gdata_pool_init(void)
+{
+   unsigned long addr, len;
+   int rc;
+
+   ghes_gdata_pool = gen_pool_create(GHES_GDATA_POOL_MIN_ALLOC_ORDER, -1);
+   if (!ghes_gdata_pool)
+   return -ENOMEM;
+
+   if (ghes_gdata_pool_size_request < GHES_GDATA_POOL_MIN_SIZE)
+   ghes_gdata_pool_size_request = GHES_GDATA_POOL_MIN_SIZE;
+
+   len = ghes_gdata_pool_size_request;
+   addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
+   if (!addr)
+   goto err_pool_alloc;
+
+   vmalloc_sync_mappings();
+
+   rc = gen_pool_add(ghes_gdata_pool, addr, PAGE_ALIGN(len), -1);
+   if (rc)
+   goto err_pool_add;
+
+   return 0;
+
+err_pool_add:
+   vfree((void *)addr);
+
+err_pool_alloc:
+   gen_pool_destroy(ghes_gdata_pool);
+
+   return -ENOMEM;
+}
+
 static int map_gen_v2(struct ghes *ghes)
 {
return apei_map_generic_address(>generic_v2->read_ack_register);
@@ -247,6 +300,10 @@ static struct ghes *ghes_new(struct acpi_hest_generic 
*generic)
goto err_unmap_status_addr;
}
 
+   ghes_gdata_pool_size_request += generic->records_to_preallocate *
+   generic->max_sections_per_record *
+   generic->max_raw_data_length;
+
return ghes;
 
 err_unmap_status_addr:
@@ -490,6 +547,68 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(ghes_event_notify_list);
+
+/**
+ * ghes_register_event_notifier - register an event notifier
+ * for the non-fatal HW errors.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_event_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_event_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_event_notifier);
+
+/**
+ * ghes_unregister_event_notifier - unregister the previously
+ * registered event notifier.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ */
+void ghes_unregister_event_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_event_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_event_notifier);
+
+static void ghes_event_work_func(struct work_struct *work)
+{
+   struct ghes_event_entry entry;
+   u32 len;
+
+   while (kfifo_get(_event_ring, )) {
+   blocking_notifier_call_chain(_event_notify_list,
+entry.error_severity,
+entry.gdata);
+   len = acpi_hest_get_record_size(entry.gdata);
+   gen_pool_free(ghes_gdata_pool, (unsigned long)entry.gdata, len);
+   }
+}
+
+static DECLARE_WORK(ghes_event_work, ghes_event_work_func);
+
+static void ghes_handle_non_standard_event(struct acpi_hest_generic_data 
*gdata,
+  int sev)
+{
+   u32 len;
+   struct ghes_event_entry event_entry;
+
+   len = acpi_hest_get_record_size(gdata);
+   event_entry.gdata = (void *)gen_pool_alloc(ghes_gdata_pool, len);
+   if (event_entry.gdata) {
+   memcpy(event_entry.gdata, gdata, len);
+   event_entry.er

[PATCH v9 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-06-15 Thread Shiju Jose
Presently the vendor drivers are unable to do the recovery for the
vendor specific recoverable HW errors because APEI driver does not
support reporting the error to the vendor drivers.

patch set
1. add new interface to the APEI driver for reporting the 
   vendor specific non-fatal HW errors to the drivers.

2. add driver to handle HiSilicon hip PCIe controller's errors.

V9:
1. Fixed 2 improvements suggested by the kbuild test robot. 
1.1 Change ghes_gdata_pool_init() as static function.
1.2. Removed using buffer to store the error data for
 logging in the hisi_pcie_handle_error()

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.

Shiju Jose (1):
  ACPI / APEI: Add support to notify the vendor specific HW errors

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c | 130 +-
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 305 +++
 include/acpi/ghes.h  |  28 +++
 5 files changed, 471 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




[PATCH RESEND v8 1/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-05-29 Thread Shiju Jose
Add support to report the vendor specific non-fatal HW errors
to the drivers for the error recovery.

Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 130 ++-
 include/acpi/ghes.h  |  28 +
 2 files changed, 157 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 24c9642e8fc7..2d10709b2eb5 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -63,6 +64,11 @@
 #define GHES_ESTATUS_CACHES_SIZE   4
 
 #define GHES_ESTATUS_IN_CACHE_MAX_NSEC 100ULL
+
+#define GHES_EVENT_RING_SIZE   256
+#define GHES_GDATA_POOL_MIN_ALLOC_ORDER3
+#define GHES_GDATA_POOL_MIN_SIZE   65536
+
 /* Prevent too many caches are allocated because of RCU */
 #define GHES_ESTATUS_CACHE_ALLOCED_MAX (GHES_ESTATUS_CACHES_SIZE * 3 / 2)
 
@@ -122,6 +128,19 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_event_entry {
+   struct acpi_hest_generic_data *gdata;
+   int error_severity;
+};
+
+static DEFINE_KFIFO(ghes_event_ring, struct ghes_event_entry,
+   GHES_EVENT_RING_SIZE);
+
+static DEFINE_SPINLOCK(ghes_event_ring_lock);
+
+static struct gen_pool *ghes_gdata_pool;
+static unsigned long ghes_gdata_pool_size_request;
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -188,6 +207,40 @@ int ghes_estatus_pool_init(int num_ghes)
return -ENOMEM;
 }
 
+int ghes_gdata_pool_init(void)
+{
+   unsigned long addr, len;
+   int rc;
+
+   ghes_gdata_pool = gen_pool_create(GHES_GDATA_POOL_MIN_ALLOC_ORDER, -1);
+   if (!ghes_gdata_pool)
+   return -ENOMEM;
+
+   if (ghes_gdata_pool_size_request < GHES_GDATA_POOL_MIN_SIZE)
+   ghes_gdata_pool_size_request = GHES_GDATA_POOL_MIN_SIZE;
+
+   len = ghes_gdata_pool_size_request;
+   addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
+   if (!addr)
+   goto err_pool_alloc;
+
+   vmalloc_sync_mappings();
+
+   rc = gen_pool_add(ghes_gdata_pool, addr, PAGE_ALIGN(len), -1);
+   if (rc)
+   goto err_pool_add;
+
+   return 0;
+
+err_pool_add:
+   vfree((void *)addr);
+
+err_pool_alloc:
+   gen_pool_destroy(ghes_gdata_pool);
+
+   return -ENOMEM;
+}
+
 static int map_gen_v2(struct ghes *ghes)
 {
return apei_map_generic_address(>generic_v2->read_ack_register);
@@ -247,6 +300,10 @@ static struct ghes *ghes_new(struct acpi_hest_generic 
*generic)
goto err_unmap_status_addr;
}
 
+   ghes_gdata_pool_size_request += generic->records_to_preallocate *
+   generic->max_sections_per_record *
+   generic->max_raw_data_length;
+
return ghes;
 
 err_unmap_status_addr:
@@ -490,6 +547,68 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(ghes_event_notify_list);
+
+/**
+ * ghes_register_event_notifier - register an event notifier
+ * for the non-fatal HW errors.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_event_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_event_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_event_notifier);
+
+/**
+ * ghes_unregister_event_notifier - unregister the previously
+ * registered event notifier.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ */
+void ghes_unregister_event_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_event_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_event_notifier);
+
+static void ghes_event_work_func(struct work_struct *work)
+{
+   struct ghes_event_entry entry;
+   u32 len;
+
+   while (kfifo_get(_event_ring, )) {
+   blocking_notifier_call_chain(_event_notify_list,
+entry.error_severity,
+entry.gdata);
+   len = acpi_hest_get_record_size(entry.gdata);
+   gen_pool_free(ghes_gdata_pool, (unsigned long)entry.gdata, len);
+   }
+}
+
+static DECLARE_WORK(ghes_event_work, ghes_event_work_func);
+
+static void ghes_handle_non_standard_event(struct acpi_hest_generic_data 
*gdata,
+  int sev)
+{
+   u32 len;
+   struct ghes_event_entry event_entry;
+
+   len = acpi_hest_get_record_size(gdata);
+   event_entry.gdata = (void *)gen_pool_alloc(ghes_gdata_pool, len);
+   if (event_entry.gdata) {
+   memcpy(event_entry.gdata, gdata, len);
+   event_entry.er

[PATCH RESEND v8 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-05-29 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and perform port reset separately at each root port.

This patch add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC ip.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 321 +++
 3 files changed, 330 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 91bfdb784829..7ba4b94f8604 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -258,6 +258,14 @@ config PCI_HYPERV_INTERFACE
  The Hyper-V PCI Interface is a helper driver allows other drivers to
  have a common interface with the Hyper-V PCI frontend driver.
 
+config PCIE_HISI_ERR
+   depends on ARM64 || COMPILE_TEST
+   depends on ACPI
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 158c59771824..ab3a528bf988 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
 obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..7886df01fd8a
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,321 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2018-2019 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#defineHISI_PCIE_ERR_INFO_SIZE 1024
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_SUB_MODULE_ID_AP 0
+#define HISI_PCIE_SUB_MODULE_ID_TL 1
+#define HISI_PCIE_SUB_MODULE_ID_MAC2
+#define HISI_PCIE_SUB_MODULE_ID_DL 3
+#define HISI_PCIE_SUB_MODULE_ID_SDI4
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+#define HISI_ERR_SEV_RECOVERABLE   0
+#define HISI_ERR_SEV_FATAL 1
+#define HISI_ERR_SEV_CORRECTED 2
+#define HISI_ERR_SEV_NONE  3
+
+static guid_t hisi_pcie_sec_type = GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+   0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) % 8) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+str

[PATCH RESEND v8 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-05-29 Thread Shiju Jose
Presently the vendor drivers are unable to do the recovery for the
vendor specific recoverable HW errors because APEI driver does not
support reporting the error to the vendor drivers.

patch set
1. add new interface to the APEI driver for reporting the 
   vendor specific non-fatal HW errors to the drivers.

2. add driver to handle HiSilicon hip PCIe controller's errors.

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the recent patches in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.   

Shiju Jose (1):
  ACPI / APEI: Add support to notify the vendor specific HW errors To:

linux-a...@vger.kernel.org,linux-...@vger.kernel.org,linux-kernel@vger.kernel.org,r...@rjwysocki.net,b...@alien8.de,james.mo...@arm.com,helg...@kernel.org,l...@kernel.org,tony.l...@intel.com,dan.carpen...@oracle.com,gre...@linuxfoundation.org,zhangligu...@linux.alibaba.com,t...@linutronix.de
Cc: linux...@huawei.com,yangyic...@hisilicon.com

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c | 130 -
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 321 +++
 include/acpi/ghes.h  |  28 ++
 5 files changed, 487 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




RE: [PATCH v8 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-05-29 Thread Shiju Jose
Please ignore this patch set. Resending soon.

Thanks,
Shiju

>-Original Message-
>From: Shiju Jose
>Sent: 29 May 2020 18:39
>To: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; b...@alien8.de;
>james.mo...@arm.com; helg...@kernel.org; l...@kernel.org;
>tony.l...@intel.com; dan.carpen...@oracle.com;
>gre...@linuxfoundation.org; zhangligu...@linux.alibaba.com;
>t...@linutronix.de
>Cc: Shiju Jose ; Linuxarm ;
>yangyicong 
>Subject: [PATCH v8 0/2] ACPI / APEI: Add support to notify the vendor
>specific HW errors
>
>Presently the vendor drivers are unable to do the recovery for the vendor
>specific recoverable HW errors because APEI driver does not support
>reporting the error to the vendor drivers.
>
>patch set
>1. add new interface to the APEI driver for reporting the
>   vendor specific non-fatal HW errors to the drivers.
>
>2. add driver to handle HiSilicon hip PCIe controller's errors.
>
>V8:
>1. Removed reporting the standard errors through the interface
>   because of the conflict with the changes in the
>   memory error handling path.
>2. Fix comments by Dan Carpenter.
>
>V7:
>1. Add changes in the APEI driver suggested by Borislav Petkov, for
>   queuing up all the non-fatal HW errors to the work queue and
>   notify the registered kernel drivers from the bottom half using
>   blocking notifier, common interface for both standard and
>   vendor-spcific errors.
>2. Fix for further feedbacks in v5 HIP PCIe error handler driver
>   by Bjorn Helgaas.
>
>V6:
>1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.
>
>V5:
>1. Fix comments from James Morse.
>1.1 Changed the notification method to use the atomic_notifier_chain.
>1.2 Add the error handled status for the user space.
>
>V4:
>1. Fix for the following smatch warning in the PCIe error driver,
>   reported by kbuild test robot:
>   warn: should '1))) << (9 + i))' be a 64 bit type?
>   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
>   ^^^ This should be BIT_ULL() because it goes up to 9 + 32.
>
>V3:
>1. Fix the comments from Bjorn Helgaas.
>
>V2:
>1. Changes in the HiSilicon PCIe controller's error handling driver
>   for the comments from Bjorn Helgaas.
>
>2. Changes in the APEI interface to support reporting the vendor error
>   for module with multiple devices, but use the same section type.
>   In the error handler will use socket id/sub module id etc to distinguish
>   the device.
>
>V1:
>1. Fix comments from James Morse.
>
>2. add driver to handle HiSilicon hip08 PCIe controller's errors,
>   which is an application of the above interface.
>
>Shiju Jose (1):
>  ACPI / APEI: Add support to notify the vendor specific HW errors
>
>Yicong Yang (1):
>  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors
>
> drivers/acpi/apei/ghes.c | 126 -
> drivers/pci/controller/Kconfig   |   8 +
> drivers/pci/controller/Makefile  |   1 +
> drivers/pci/controller/pcie-hisi-error.c | 321 +++
> include/acpi/ghes.h  |  28 ++
> 5 files changed, 483 insertions(+), 1 deletion(-)  create mode 100644
>drivers/pci/controller/pcie-hisi-error.c
>
>--
>2.17.1
>



[PATCH v8 2/2] PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

2020-05-29 Thread Shiju Jose
From: Yicong Yang 

The HiSilicon HIP PCIe controller is capable of handling errors
on root port and perform port reset separately at each root port.

This patch add error handling driver for HIP PCIe controller to log
and report recoverable errors. Perform root port reset and restore
link status after the recovery.

Following are some of the PCIe controller's recoverable errors
1. completion transmission timeout error.
2. CRS retry counter over the threshold error.
3. ECC 2 bit errors
4. AXI bresponse/rresponse errors etc.

The driver placed in the drivers/pci/controller/ because the
HIP PCIe controller does not use DWC ip.

Signed-off-by: Yicong Yang 
Signed-off-by: Shiju Jose 
--
drivers/pci/controller/Kconfig   |   8 +
drivers/pci/controller/Makefile  |   1 +
drivers/pci/controller/pcie-hisi-error.c | 336 +++
3 files changed, 345 insertions(+)
create mode 100644 drivers/pci/controller/pcie-hisi-error.c
---
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 321 +++
 3 files changed, 330 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 91bfdb784829..7ba4b94f8604 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -258,6 +258,14 @@ config PCI_HYPERV_INTERFACE
  The Hyper-V PCI Interface is a helper driver allows other drivers to
  have a common interface with the Hyper-V PCI frontend driver.
 
+config PCIE_HISI_ERR
+   depends on ARM64 || COMPILE_TEST
+   depends on ACPI
+   bool "HiSilicon HIP PCIe controller error handling driver"
+   help
+ Say Y here if you want error handling support
+ for the PCIe controller's errors on HiSilicon HIP SoCs
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 158c59771824..ab3a528bf988 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
 obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
 obj-$(CONFIG_VMD) += vmd.o
 obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
+obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
 # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
 obj-y  += dwc/
 obj-y  += mobiveil/
diff --git a/drivers/pci/controller/pcie-hisi-error.c 
b/drivers/pci/controller/pcie-hisi-error.c
new file mode 100644
index ..7886df01fd8a
--- /dev/null
+++ b/drivers/pci/controller/pcie-hisi-error.c
@@ -0,0 +1,321 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for handling the PCIe controller errors on
+ * HiSilicon HIP SoCs.
+ *
+ * Copyright (c) 2018-2019 HiSilicon Limited.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#defineHISI_PCIE_ERR_INFO_SIZE 1024
+
+/* HISI PCIe controller error definitions */
+#define HISI_PCIE_ERR_MISC_REGS33
+
+#define HISI_PCIE_SUB_MODULE_ID_AP 0
+#define HISI_PCIE_SUB_MODULE_ID_TL 1
+#define HISI_PCIE_SUB_MODULE_ID_MAC2
+#define HISI_PCIE_SUB_MODULE_ID_DL 3
+#define HISI_PCIE_SUB_MODULE_ID_SDI4
+
+#define HISI_PCIE_LOCAL_VALID_VERSION  BIT(0)
+#define HISI_PCIE_LOCAL_VALID_SOC_ID   BIT(1)
+#define HISI_PCIE_LOCAL_VALID_SOCKET_IDBIT(2)
+#define HISI_PCIE_LOCAL_VALID_NIMBUS_IDBIT(3)
+#define HISI_PCIE_LOCAL_VALID_SUB_MODULE_IDBIT(4)
+#define HISI_PCIE_LOCAL_VALID_CORE_ID  BIT(5)
+#define HISI_PCIE_LOCAL_VALID_PORT_ID  BIT(6)
+#define HISI_PCIE_LOCAL_VALID_ERR_TYPE BIT(7)
+#define HISI_PCIE_LOCAL_VALID_ERR_SEVERITY BIT(8)
+#define HISI_PCIE_LOCAL_VALID_ERR_MISC 9
+
+#define HISI_ERR_SEV_RECOVERABLE   0
+#define HISI_ERR_SEV_FATAL 1
+#define HISI_ERR_SEV_CORRECTED 2
+#define HISI_ERR_SEV_NONE  3
+
+static guid_t hisi_pcie_sec_type = GUID_INIT(0xB2889FC9, 0xE7D7, 0x4F9D,
+   0xA8, 0x67, 0xAF, 0x42, 0xE9, 0x8B, 0xE7, 0x72);
+
+#define HISI_PCIE_CORE_ID(v) ((v) >> 3)
+#define HISI_PCIE_PORT_ID(core, v)   (((v) >> 1) + ((core) << 3))
+#define HISI_PCIE_CORE_PORT_ID(v)(((v) % 8) << 1)
+
+struct hisi_pcie_error_data {
+   u64 val_bits;
+   u8  version;
+   u8  soc_id;
+   u8  socket_id;
+   u8  nimbus_id;
+   u8  sub_module_id;
+   u8  core_id;
+   u8  port_id;
+   u8  err_severity;
+   u16 err_type;
+   u8  reserv[2];
+   u32 err_misc[HISI_PCIE_ERR_MISC_REGS];
+};
+
+str

[PATCH v8 0/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-05-29 Thread Shiju Jose
Presently the vendor drivers are unable to do the recovery for the
vendor specific recoverable HW errors because APEI driver does not
support reporting the error to the vendor drivers.

patch set
1. add new interface to the APEI driver for reporting the 
   vendor specific non-fatal HW errors to the drivers.

2. add driver to handle HiSilicon hip PCIe controller's errors.

V8:
1. Removed reporting the standard errors through the interface
   because of the conflict with the changes in the
   memory error handling path.
2. Fix comments by Dan Carpenter.
   
V7:
1. Add changes in the APEI driver suggested by Borislav Petkov, for
   queuing up all the non-fatal HW errors to the work queue and
   notify the registered kernel drivers from the bottom half using
   blocking notifier, common interface for both standard and
   vendor-spcific errors.
2. Fix for further feedbacks in v5 HIP PCIe error handler driver
   by Bjorn Helgaas.

V6:
1. Fix few changes in the patch subject line suggested by Bjorn Helgaas.

V5:
1. Fix comments from James Morse.
1.1 Changed the notification method to use the atomic_notifier_chain.
1.2 Add the error handled status for the user space.  

V4:
1. Fix for the following smatch warning in the PCIe error driver,
   reported by kbuild test robot:
   warn: should '1))) << (9 + i))' be a 64 bit type?
   if (err->val_bits & BIT(HISI_PCIE_LOCAL_VALID_ERR_MISC + i))
^^^ This should be BIT_ULL() because it goes up to 9 + 32.

V3:
1. Fix the comments from Bjorn Helgaas.

V2:
1. Changes in the HiSilicon PCIe controller's error handling driver
   for the comments from Bjorn Helgaas.
   
2. Changes in the APEI interface to support reporting the vendor error
   for module with multiple devices, but use the same section type.
   In the error handler will use socket id/sub module id etc to distinguish
   the device.

V1:  
1. Fix comments from James Morse.

2. add driver to handle HiSilicon hip08 PCIe controller's errors,
   which is an application of the above interface.   
   
Shiju Jose (1):
  ACPI / APEI: Add support to notify the vendor specific HW errors

Yicong Yang (1):
  PCI: hip: Add handling of HiSilicon HIP PCIe controller errors

 drivers/acpi/apei/ghes.c | 126 -
 drivers/pci/controller/Kconfig   |   8 +
 drivers/pci/controller/Makefile  |   1 +
 drivers/pci/controller/pcie-hisi-error.c | 321 +++
 include/acpi/ghes.h  |  28 ++
 5 files changed, 483 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pci/controller/pcie-hisi-error.c

-- 
2.17.1




[PATCH v8 1/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-05-29 Thread Shiju Jose
Add support to report the vendor specific non-fatal HW errors
to the drivers for the error recovery.

Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 126 ++-
 include/acpi/ghes.h  |  28 +
 2 files changed, 153 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 24c9642e8fc7..d89a74dfae6a 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -63,6 +64,11 @@
 #define GHES_ESTATUS_CACHES_SIZE   4
 
 #define GHES_ESTATUS_IN_CACHE_MAX_NSEC 100ULL
+
+#define GHES_EVENT_RING_SIZE   256
+#define GHES_GDATA_POOL_MIN_ALLOC_ORDER3
+#define GHES_GDATA_POOL_MIN_SIZE   65536
+
 /* Prevent too many caches are allocated because of RCU */
 #define GHES_ESTATUS_CACHE_ALLOCED_MAX (GHES_ESTATUS_CACHES_SIZE * 3 / 2)
 
@@ -122,6 +128,19 @@ static DEFINE_MUTEX(ghes_list_mutex);
  */
 static DEFINE_SPINLOCK(ghes_notify_lock_irq);
 
+struct ghes_event_entry {
+   struct acpi_hest_generic_data *gdata;
+   int error_severity;
+};
+
+static DEFINE_KFIFO(ghes_event_ring, struct ghes_event_entry,
+   GHES_EVENT_RING_SIZE);
+
+static DEFINE_SPINLOCK(ghes_event_ring_lock);
+
+static struct gen_pool *ghes_gdata_pool;
+static unsigned long ghes_gdata_pool_size_request;
+
 static struct gen_pool *ghes_estatus_pool;
 static unsigned long ghes_estatus_pool_size_request;
 
@@ -188,6 +207,40 @@ int ghes_estatus_pool_init(int num_ghes)
return -ENOMEM;
 }
 
+int ghes_gdata_pool_init(void)
+{
+   unsigned long addr, len;
+   int rc;
+
+   ghes_gdata_pool = gen_pool_create(GHES_GDATA_POOL_MIN_ALLOC_ORDER, -1);
+   if (!ghes_gdata_pool)
+   return -ENOMEM;
+
+   if (ghes_gdata_pool_size_request < GHES_GDATA_POOL_MIN_SIZE)
+   ghes_gdata_pool_size_request = GHES_GDATA_POOL_MIN_SIZE;
+
+   len = ghes_gdata_pool_size_request;
+   addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
+   if (!addr)
+   goto err_pool_alloc;
+
+   vmalloc_sync_mappings();
+
+   rc = gen_pool_add(ghes_gdata_pool, addr, PAGE_ALIGN(len), -1);
+   if (rc)
+   goto err_pool_add;
+
+   return 0;
+
+err_pool_add:
+   vfree((void *)addr);
+
+err_pool_alloc:
+   gen_pool_destroy(ghes_gdata_pool);
+
+   return -ENOMEM;
+}
+
 static int map_gen_v2(struct ghes *ghes)
 {
return apei_map_generic_address(>generic_v2->read_ack_register);
@@ -247,6 +300,10 @@ static struct ghes *ghes_new(struct acpi_hest_generic 
*generic)
goto err_unmap_status_addr;
}
 
+   ghes_gdata_pool_size_request += generic->records_to_preallocate *
+   generic->max_sections_per_record *
+   generic->max_raw_data_length;
+
return ghes;
 
 err_unmap_status_addr:
@@ -490,6 +547,48 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+static BLOCKING_NOTIFIER_HEAD(ghes_event_notify_list);
+
+/**
+ * ghes_register_event_notifier - register an event notifier
+ * for the non-fatal HW errors.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_register_event_notifier(struct notifier_block *nb)
+{
+   return blocking_notifier_chain_register(_event_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_register_event_notifier);
+
+/**
+ * ghes_unregister_event_notifier - unregister the previously
+ * registered event notifier.
+ * @nb: pointer to the notifier_block structure of the event handler.
+ */
+void ghes_unregister_event_notifier(struct notifier_block *nb)
+{
+   blocking_notifier_chain_unregister(_event_notify_list, nb);
+}
+EXPORT_SYMBOL_GPL(ghes_unregister_event_notifier);
+
+static void ghes_event_work_func(struct work_struct *work)
+{
+   struct ghes_event_entry entry;
+   u32 len;
+
+   while (kfifo_get(_event_ring, )) {
+   blocking_notifier_call_chain(_event_notify_list,
+entry.error_severity,
+entry.gdata);
+   len = acpi_hest_get_record_size(entry.gdata);
+   gen_pool_free(ghes_gdata_pool, (unsigned long)entry.gdata, len);
+   }
+}
+
+static DECLARE_WORK(ghes_event_work, ghes_event_work_func);
+
 static void ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -498,6 +597,8 @@ static void ghes_do_proc(struct ghes *ghes,
guid_t *sec_type;
const guid_t *fru_id = _null;
char *fru_text = "";
+   struct ghes_event_entry event_entry;
+   u32 len;
 
sev = ghes_severity(estatus->error_severity);
apei_estatus_for_each_section(estatus, gdata) {
@

RE: [PATCH v6 1/2] ACPI / APEI: Add support to notify the vendor specific HW errors

2020-05-11 Thread Shiju Jose
Hi Boris, Hi James,

>-Original Message-
>From: linux-pci-ow...@vger.kernel.org [mailto:linux-pci-
>ow...@vger.kernel.org] On Behalf Of James Morse
>Sent: 08 April 2020 11:03
>To: Borislav Petkov ; Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; helg...@kernel.org;
>l...@kernel.org; tony.l...@intel.com; gre...@linuxfoundation.org;
>zhangligu...@linux.alibaba.com; t...@linutronix.de; Linuxarm
>; Jonathan Cameron
>; tanxiaofei ;
>yangyicong 
>Subject: Re: [PATCH v6 1/2] ACPI / APEI: Add support to notify the vendor
>specific HW errors
>
>Hi Boris, Shiju,
>
>Sorry for not spotting this reply earlier: Its in-reply to v1, so gets buried.
>
>On 27/03/2020 18:22, Borislav Petkov wrote:
>> On Wed, Mar 25, 2020 at 04:42:22PM +, Shiju Jose wrote:
>>> Presently APEI does not support reporting the vendor specific HW
>>> errors, received in the vendor defined table entries, to the vendor
>>> drivers for any recovery.
>>>
>>> This patch adds the support to register and unregister the
>>
>> Avoid having "This patch" or "This commit" in the commit message. It
>> is tautologically useless.
>>
>> Also, do
>>
>> $ git grep 'This patch' Documentation/process
>>
>> for more details.
>>
>>> error handling function for the vendor specific HW errors and notify
>>> the registered kernel driver.
>
>>> @@ -526,10 +552,17 @@ static void ghes_do_proc(struct ghes *ghes,
>>> log_arm_hw_error(err);
>>> } else {
>>> void *err = acpi_hest_get_payload(gdata);
>>> +   u8 error_handled = false;
>>> +   int ret;
>>> +
>>> +   ret =
>atomic_notifier_call_chain(_event_notify_list, 0,
>>> +gdata);
>>
>> Well, this is a notifier with standard name for a non-standard event.
>> Not optimal.
>>
>> Why does only this event need a notifier? Because your driver is
>> interested in only those events?
>
>Its the 'else' catch-all for stuff drivers/acpi/apei  doesn't know to handle.
>
>In this case its because its a vendor specific GUID that only the vendor driver
>knows how to parse.
>
>
>>> +   if (ret & NOTIFY_OK)
>>> +   error_handled = true;
>>>
>>> log_non_standard_event(sec_type, fru_id, fru_text,
>>>sec_sev, err,
>>> -  gdata->error_data_length);
>>> +  gdata->error_data_length,
>>> +  error_handled);
>>
>> What's that error_handled thing for? That's just silly.
>>
>> Your notifier returns NOTIFY_STOP when it has queued the error. If you
>> don't want to log it, just test == NOTIFY_STOP and do not log it then.
>
>My thinking for this being needed was so user-space consumers of those
>tracepoints keep working. Otherwise you upgrade, get this feature, and your
>user-space counters stop working.
>
>You'd need to know this error source was now managed by an in-kernel
>driver, which may report the errors somewhere else...
>
>
>> Then your notifier callback is queuing the error into a kfifo for
>> whatever reason and then scheduling a workqueue to handle it in user
>> context...
>>
>> So I'm thinking that it would be better if you:
>>
>> * make that kfifo generic and part of ghes.c and queue all types of
>> error records into it in ghes_do_proc() - not just the non-standard
>> ones.
>
>Move the drop to process context into ghes.c? This should result in less code.
>
>I asked for this hooking to only be for the 'catch all' don't-know case so that
>we don't get drivers trying to hook and handle memory errors. (if we ever
>wanted that, it should be from part of memory_failure() so it catches all the
>ways of reporting memory-failure) 32bit arm has prior in this area.
>
>
>> * then, when you're done queuing, you kick a workqueue.
>>
>> * that workqueue runs a normal, blocking notifier to which drivers
>> register.
>>
>> Your driver can register to that notifier too and do the normal
>> handling then and not have this ad-hoc, semi-generic, semi-vendor-specific
>thing.
>
>As long as we don't walk a list of things that might handle a memory-error,
>and have some random driver try and NOTIFY_STOP it
>
>aer_recover_queue() would be replaced by this. memory_failure_queue() has
>one additional caller in drivers/ras/cec.c.

Can you suggest whether the standard errors can report through the 
notifier (kfifo + blocking notifier), [which implemented  in V7 patch], or not 
so that we can proceed with the changes to notify the vendor specific errors?

>
>
>Thanks,
>
>James

Thanks,
Shiju


RE: [PATCH RFC 2/4] ACPI: APEI: Add ghes_handle_memory_failure to the new notification method

2019-08-22 Thread Shiju Jose
Hi James,

>-Original Message-
>From: James Morse [mailto:james.mo...@arm.com]
>Sent: 21 August 2019 18:23
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-e...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; l...@kernel.org;
>tony.l...@intel.com; b...@alien8.de; bai...@os.amperecomputing.com;
>Linuxarm ; Jonathan Cameron
>; tanxiaofei 
>Subject: Re: [PATCH RFC 2/4] ACPI: APEI: Add ghes_handle_memory_failure to
>the new notification method
>
>Hi,
>
>On 12/08/2019 11:11, Shiju Jose wrote:
>> This patch adds ghes_handle_memory_failure to the new error
>> notification method.
>
>The commit message doesn't answer the question: why?
>
>The existing code works. This just looks like additional churn.
>Given a user, I think the vendor specific example is useful. I don't think 
>making
>this thing more pluggable is a good idea.
This was intended to replace the  number of if(guid_equal(...)) else 
if(guid_equal(...)) checks in the ghes_do_proc() , which would grow when new 
UEFI defined error sections would be added in the future.
>
>
>Thanks,
>
>James

Thanks,
Shiju


RE: [PATCH RFC 1/4] ACPI: APEI: Add support to notify the vendor specific HW errors

2019-08-22 Thread Shiju Jose
Hi James,

>-Original Message-
>From: James Morse [mailto:james.mo...@arm.com]
>Sent: 21 August 2019 18:24
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-e...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; l...@kernel.org;
>tony.l...@intel.com; b...@alien8.de; bai...@os.amperecomputing.com;
>Linuxarm ; Jonathan Cameron
>; tanxiaofei 
>Subject: Re: [PATCH RFC 1/4] ACPI: APEI: Add support to notify the vendor
>specific HW errors
>
>Hi,
>
>On 12/08/2019 11:11, Shiju Jose wrote:
>> Presently the vendor specific HW errors, in the non-standard format,
>> are not reported to the vendor drivers for the recovery.
>>
>> This patch adds support to notify the vendor specific HW errors to the
>> registered kernel drivers.
>
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index
>> a66e00f..374d197 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -477,6 +477,77 @@ static void ghes_handle_aer(struct
>> acpi_hest_generic_data *gdata)  #endif  }
>>
>> +struct ghes_error_notify {
>> +struct list_head list;> +   struct rcu_head rcu_head;
>> +guid_t sec_type; /* guid of the error record */
>
>> +error_handle handle; /* error handler function */
>
>ghes_error_handler_t error_handler; ?
Sure.

>
>
>> +void *data; /* handler driver's private data if any */ };
>> +
>> +/* List to store the registered error handling functions */ static
>> +DEFINE_MUTEX(ghes_error_notify_mutex);
>> +static LIST_HEAD(ghes_error_notify_list);
>
>> +static refcount_t ghes_ref_count;
>
>I don't think this refcount is needed.
refcount was added to register standard error handlers with this notification 
method one time when
multiple ghes platform devices are probed.
 
>
>
>> +/**
>> + * ghes_error_notify_register - register an error handling function
>> + * for the hw errors.
>> + * @sec_type: sec_type of the corresponding CPER to be notified.
>> + * @handle: pointer to the error handling function.
>> + * @data: handler driver's private data.
>> + *
>> + * return 0 : SUCCESS, non-zero : FAIL  */ int
>> +ghes_error_notify_register(guid_t sec_type, error_handle handle, void
>> +*data) {
>> +struct ghes_error_notify *err_notify;
>> +
>> +mutex_lock(_error_notify_mutex);
>> +err_notify = kzalloc(sizeof(*err_notify), GFP_KERNEL);
>> +if (!err_notify)
>> +return -ENOMEM;
>
>Leaving the mutex locked.
>You may as well allocate the memory before taking the lock.
Good spot. I will fix.

>
>
>> +
>> +err_notify->handle = handle;
>> +guid_copy(_notify->sec_type, _type);
>> +err_notify->data = data;
>> +list_add_rcu(_notify->list, _error_notify_list);
>> +mutex_unlock(_error_notify_mutex);
>> +
>> +return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(ghes_error_notify_register);
>
>Could we leave exporting this to modules until there is a user?
>
>
>> +/**
>> + * ghes_error_notify_unregister - unregister an error handling function.
>> + * @sec_type: sec_type of the corresponding CPER.
>> + * @handle: pointer to the error handling function.
>> + *
>> + * return none.
>> + */
>> +void ghes_error_notify_unregister(guid_t sec_type, error_handle
>> +handle)
>
>Why do we need the handle(r) a second time? Surely there can only be one
>callback for a given guid.
There is a possibility of sharing the guid between drivers if the non-standard 
error section format is common
for more than one devices if the error data to be reported is in the same 
format.
 
>
>
>> +{
>> +struct ghes_error_notify *err_notify;
>> +bool found = 0;
>> +
>> +mutex_lock(_error_notify_mutex);
>> +rcu_read_lock();
>> +list_for_each_entry_rcu(err_notify, _error_notify_list, list) {
>> +if (guid_equal(_notify->sec_type, _type) &&
>> +err_notify->handle == handle) {
>> +list_del_rcu(_notify->list);
>> +found = 1;
>> +break;
>> +}
>> +}
>> +rcu_read_unlock();
>
>> +synchronize_rcu();
>
>Is this for the kfree()? Please keep them together so its obvious what its for.
>Putting it outside the mutex will also save any contended waiter some time.
Yes. I will move synchronize_rcu () just before kfree. 
 
>
>
>> +mutex_unlock(_error_notify_mutex);
>> +if (found)
>> +kfree(e

RE: [PATCH RFC 0/4] ACPI: APEI: Add support to notify the vendor specific HW errors

2019-08-22 Thread Shiju Jose
Hi James, 

Thanks for the feedback.

>-Original Message-
>From: linux-acpi-ow...@vger.kernel.org [mailto:linux-acpi-
>ow...@vger.kernel.org] On Behalf Of James Morse
>Sent: 21 August 2019 18:23
>To: Shiju Jose 
>Cc: linux-a...@vger.kernel.org; linux-e...@vger.kernel.org; linux-
>ker...@vger.kernel.org; r...@rjwysocki.net; l...@kernel.org;
>tony.l...@intel.com; b...@alien8.de; bai...@os.amperecomputing.com;
>Linuxarm ; Jonathan Cameron
>; tanxiaofei 
>Subject: Re: [PATCH RFC 0/4] ACPI: APEI: Add support to notify the vendor
>specific HW errors
>
>Hi,
>
>On 12/08/2019 11:11, Shiju Jose wrote:
>> Presently kernel does not support reporting the vendor specific HW
>> errors, in the non-standard format, to the vendor drivers for the recovery.
>
>'non standard' here is probably a little jarring to the casual reader. You're
>referring to the UEFI spec's "N.2.3 Non-standard Section Body", which refers to
>any section type published somewhere other than the UEFI spec.
OK. I will change it.  
>
>These still have to have a GUID to identify them, so they still have the same
>section header format.
Yes. 
 
>
>
>> This patch set add this support and also move the existing handler
>> functions for the standard errors to the new callback method.
>
>Could you give an example of where this would be useful? You're adding an API
>with no caller to justify its existence.
One such example is handling the local errors occurred in a device controller, 
such as PCIe.

>
>
>GUIDs should only belong to one driver.
UEFI spec's N.2.3 Non-standard Section Body mentioned,  "The type (e.g. format) 
of a non-standard section is identified by the GUID populated in the Section 
Descriptor's Section Type field." 
There is a possibility to define common non-standard error section format which 
will be used for more than one driver if the error data to be reported is in 
the same format. Then can the same GUID belong to multiple drivers?

>
>I don't think we should call drivers for something described as a fatal error.
>(which is the case with what you have here)
The notification is intended only for the recoverable errors as the ghes_proc() 
call panic for the fatal errors in the early stage.

>
>
>> Also the CCIX RAS patches could be move to the proposed callback method.
>
>Presumably for any vendor-specific stuff?
This information was related to the proposal to replace the  number of 
if(guid_equal(...)) else if(guid_equal(...)) checks in the ghes_do_proc() for 
the existing UEFI spec defined error sections(such as PCIe,  Memory, ARM HW 
error) by registering the corresponding handler functions to the proposed 
notification method. The same apply to the CCIX error sections and any other 
error sections defined by the UEFI spec in the future.  

>
>
>Thanks,
>
>James

Thanks,
Shiju


[PATCH RFC 2/4] ACPI: APEI: Add ghes_handle_memory_failure to the new notification method

2019-08-12 Thread Shiju Jose
This patch adds ghes_handle_memory_failure to the new error
notification method.

Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 51 ++--
 1 file changed, 36 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 374d197..4400d56 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -401,14 +401,18 @@ static void ghes_clear_estatus(struct ghes *ghes,
ghes_ack_error(ghes->generic_v2);
 }
 
-static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, 
int sev)
+static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
+  int sev, void *data)
 {
-#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
+   struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
+   int sec_sev = ghes_severity(gdata->error_severity);
unsigned long pfn;
int flags = -1;
-   int sec_sev = ghes_severity(gdata->error_severity);
-   struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
 
+   ghes_edac_report_mem_error(sev, mem_err);
+   arch_apei_report_mem_error(sev, mem_err);
+
+#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
return;
 
@@ -569,15 +573,7 @@ static void ghes_do_proc(struct ghes *ghes,
if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
fru_text = gdata->fru_text;
 
-   if (guid_equal(sec_type, _SEC_PLATFORM_MEM)) {
-   struct cper_sec_mem_err *mem_err = 
acpi_hest_get_payload(gdata);
-
-   ghes_edac_report_mem_error(sev, mem_err);
-
-   arch_apei_report_mem_error(sev, mem_err);
-   ghes_handle_memory_failure(gdata, sev);
-   }
-   else if (guid_equal(sec_type, _SEC_PCIE)) {
+   if (guid_equal(sec_type, _SEC_PCIE)) {
ghes_handle_aer(gdata);
}
else if (guid_equal(sec_type, _SEC_PROC_ARM)) {
@@ -1190,11 +1186,25 @@ static int apei_sdei_unregister_ghes(struct ghes *ghes)
return sdei_unregister_ghes(ghes);
 }
 
+struct ghes_err_handler_tab {
+   guid_t sec_type;
+   error_handle handle;
+};
+
+static struct ghes_err_handler_tab handler_tab[] = {
+   {
+   .sec_type = CPER_SEC_PLATFORM_MEM,
+   .handle = ghes_handle_memory_failure,
+   },
+   { /* sentinel */ }
+};
+
 static int ghes_probe(struct platform_device *ghes_dev)
 {
struct acpi_hest_generic *generic;
struct ghes *ghes = NULL;
unsigned long flags;
+   int i;
 
int rc = -EINVAL;
 
@@ -1308,9 +1318,20 @@ static int ghes_probe(struct platform_device *ghes_dev)
 
ghes_edac_register(ghes, _dev->dev);
 
-   if (!refcount_read(_ref_count))
+   if (!refcount_read(_ref_count)) {
refcount_set(_ref_count, 1);
-   else
+   /* register handler functions for the standard errors.
+* This may be done from the corresponding drivers.
+*/
+   for (i = 0; handler_tab[i].handle; i++) {
+   if (ghes_error_notify_register(handler_tab[i].sec_type,
+   handler_tab[i].handle, NULL)) {
+   ghes_edac_unregister(ghes);
+   platform_set_drvdata(ghes_dev, NULL);
+   goto err;
+   }
+   }
+   } else
refcount_inc(_ref_count);
 
/* Handle any pending errors right away */
-- 
1.9.1




[PATCH RFC 3/4] ACPI: APEI: Add ghes_handle_aer to the new notification method

2019-08-12 Thread Shiju Jose
This patch adds ghes_handle_aer to the new error notification method.

Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 4400d56..ffc309c 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -450,7 +450,8 @@ static void ghes_handle_memory_failure(struct 
acpi_hest_generic_data *gdata,
  * GHES_SEV_PANIC does not make it to this handling since the kernel must
  * panic.
  */
-static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
+static void ghes_handle_aer(struct acpi_hest_generic_data *gdata,
+   int sev, void *data)
 {
 #ifdef CONFIG_ACPI_APEI_PCIEAER
struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
@@ -573,10 +574,7 @@ static void ghes_do_proc(struct ghes *ghes,
if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
fru_text = gdata->fru_text;
 
-   if (guid_equal(sec_type, _SEC_PCIE)) {
-   ghes_handle_aer(gdata);
-   }
-   else if (guid_equal(sec_type, _SEC_PROC_ARM)) {
+   if (guid_equal(sec_type, _SEC_PROC_ARM)) {
struct cper_sec_proc_arm *err = 
acpi_hest_get_payload(gdata);
 
log_arm_hw_error(err);
@@ -1196,6 +1194,10 @@ struct ghes_err_handler_tab {
.sec_type = CPER_SEC_PLATFORM_MEM,
.handle = ghes_handle_memory_failure,
},
+   {
+   .sec_type = CPER_SEC_PCIE,
+   .handle = ghes_handle_aer,
+   },
{ /* sentinel */ }
 };
 
-- 
1.9.1




[PATCH RFC 1/4] ACPI: APEI: Add support to notify the vendor specific HW errors

2019-08-12 Thread Shiju Jose
Presently the vendor specific HW errors, in the non-standard format,
are not reported to the vendor drivers for the recovery.

This patch adds support to notify the vendor specific HW errors to the
registered kernel drivers.

Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 118 +--
 include/acpi/ghes.h  |  47 +++
 2 files changed, 160 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index a66e00f..374d197 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -477,6 +477,77 @@ static void ghes_handle_aer(struct acpi_hest_generic_data 
*gdata)
 #endif
 }
 
+struct ghes_error_notify {
+   struct list_head list;
+   struct rcu_head rcu_head;
+   guid_t sec_type; /* guid of the error record */
+   error_handle handle; /* error handler function */
+   void *data; /* handler driver's private data if any */
+};
+
+/* List to store the registered error handling functions */
+static DEFINE_MUTEX(ghes_error_notify_mutex);
+static LIST_HEAD(ghes_error_notify_list);
+static refcount_t ghes_ref_count;
+
+/**
+ * ghes_error_notify_register - register an error handling function
+ * for the hw errors.
+ * @sec_type: sec_type of the corresponding CPER to be notified.
+ * @handle: pointer to the error handling function.
+ * @data: handler driver's private data.
+ *
+ * return 0 : SUCCESS, non-zero : FAIL
+ */
+int ghes_error_notify_register(guid_t sec_type, error_handle handle, void 
*data)
+{
+   struct ghes_error_notify *err_notify;
+
+   mutex_lock(_error_notify_mutex);
+   err_notify = kzalloc(sizeof(*err_notify), GFP_KERNEL);
+   if (!err_notify)
+   return -ENOMEM;
+
+   err_notify->handle = handle;
+   guid_copy(_notify->sec_type, _type);
+   err_notify->data = data;
+   list_add_rcu(_notify->list, _error_notify_list);
+   mutex_unlock(_error_notify_mutex);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(ghes_error_notify_register);
+
+/**
+ * ghes_error_notify_unregister - unregister an error handling function.
+ * @sec_type: sec_type of the corresponding CPER.
+ * @handle: pointer to the error handling function.
+ *
+ * return none.
+ */
+void ghes_error_notify_unregister(guid_t sec_type, error_handle handle)
+{
+   struct ghes_error_notify *err_notify;
+   bool found = 0;
+
+   mutex_lock(_error_notify_mutex);
+   rcu_read_lock();
+   list_for_each_entry_rcu(err_notify, _error_notify_list, list) {
+   if (guid_equal(_notify->sec_type, _type) &&
+   err_notify->handle == handle) {
+   list_del_rcu(_notify->list);
+   found = 1;
+   break;
+   }
+   }
+   rcu_read_unlock();
+   synchronize_rcu();
+   mutex_unlock(_error_notify_mutex);
+   if (found)
+   kfree(err_notify);
+}
+EXPORT_SYMBOL_GPL(ghes_error_notify_unregister);
+
 static void ghes_do_proc(struct ghes *ghes,
 const struct acpi_hest_generic_status *estatus)
 {
@@ -485,6 +556,8 @@ static void ghes_do_proc(struct ghes *ghes,
guid_t *sec_type;
guid_t *fru_id = _UUID_LE;
char *fru_text = "";
+   bool is_notify = 0;
+   struct ghes_error_notify *err_notify;
 
sev = ghes_severity(estatus->error_severity);
apei_estatus_for_each_section(estatus, gdata) {
@@ -512,11 +585,29 @@ static void ghes_do_proc(struct ghes *ghes,
 
log_arm_hw_error(err);
} else {
-   void *err = acpi_hest_get_payload(gdata);
-
-   log_non_standard_event(sec_type, fru_id, fru_text,
-  sec_sev, err,
-  gdata->error_data_length);
+   rcu_read_lock();
+   list_for_each_entry_rcu(err_notify,
+   _error_notify_list, list) {
+   if (guid_equal(_notify->sec_type,
+  sec_type)) {
+   /* The notification is called in the
+* interrupt context, thus the handler
+* functions should be take care of it.
+*/
+   err_notify->handle(gdata, sev,
+  err_notify->data);
+   is_notify = 1;
+   }
+   }
+   rcu_read_unlock();
+
+   if (!is_notify) {
+   void *err = acpi_hest_get_payload(gdata);
+
+

[PATCH RFC 4/4] ACPI: APEI: Add log_arm_hw_error to the new notification method

2019-08-12 Thread Shiju Jose
This patch adds log_arm_hw_error to the new error notification
method.

Signed-off-by: Shiju Jose 
---
 drivers/acpi/apei/ghes.c | 47 ++-
 drivers/ras/ras.c|  5 -
 include/linux/ras.h  |  7 +--
 3 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index ffc309c..013fea0 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -574,34 +574,27 @@ static void ghes_do_proc(struct ghes *ghes,
if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
fru_text = gdata->fru_text;
 
-   if (guid_equal(sec_type, _SEC_PROC_ARM)) {
-   struct cper_sec_proc_arm *err = 
acpi_hest_get_payload(gdata);
-
-   log_arm_hw_error(err);
-   } else {
-   rcu_read_lock();
-   list_for_each_entry_rcu(err_notify,
-   _error_notify_list, list) {
-   if (guid_equal(_notify->sec_type,
-  sec_type)) {
-   /* The notification is called in the
-* interrupt context, thus the handler
-* functions should be take care of it.
-*/
-   err_notify->handle(gdata, sev,
-  err_notify->data);
-   is_notify = 1;
-   }
+   rcu_read_lock();
+   list_for_each_entry_rcu(err_notify, _error_notify_list,
+   list) {
+   if (guid_equal(_notify->sec_type, sec_type)) {
+   /* The notification is called in the
+* interrupt context, thus the handler
+* functions should be take care of it.
+*/
+   err_notify->handle(gdata, sev,
+  err_notify->data);
+   is_notify = 1;
}
-   rcu_read_unlock();
+   }
+   rcu_read_unlock();
 
-   if (!is_notify) {
-   void *err = acpi_hest_get_payload(gdata);
+   if (!is_notify) {
+   void *err = acpi_hest_get_payload(gdata);
 
-   log_non_standard_event(sec_type, fru_id,
-  fru_text, sec_sev, err,
-  
gdata->error_data_length);
-   }
+   log_non_standard_event(sec_type, fru_id,
+  fru_text, sec_sev, err,
+  gdata->error_data_length);
}
}
 }
@@ -1198,6 +1191,10 @@ struct ghes_err_handler_tab {
.sec_type = CPER_SEC_PCIE,
.handle = ghes_handle_aer,
},
+   {
+   .sec_type = CPER_SEC_PROC_ARM,
+   .handle = log_arm_hw_error,
+   },
{ /* sentinel */ }
 };
 
diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
index 95540ea..7ec3eeb 100644
--- a/drivers/ras/ras.c
+++ b/drivers/ras/ras.c
@@ -21,8 +21,11 @@ void log_non_standard_event(const guid_t *sec_type, const 
guid_t *fru_id,
trace_non_standard_event(sec_type, fru_id, fru_text, sev, err, len);
 }
 
-void log_arm_hw_error(struct cper_sec_proc_arm *err)
+void log_arm_hw_error(struct acpi_hest_generic_data *gdata,
+ int sev, void *data)
 {
+   struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
+
trace_arm_event(err);
 }
 
diff --git a/include/linux/ras.h b/include/linux/ras.h
index 7c3debb..05b662d 100644
--- a/include/linux/ras.h
+++ b/include/linux/ras.h
@@ -5,6 +5,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_DEBUG_FS
 int ras_userspace_consumers(void);
@@ -29,7 +30,8 @@ static inline void __init cec_init(void)  { }
 void log_non_standard_event(const guid_t *sec_type,
const guid_t *fru_id, const char *fru_text,
const u8 sev, const u8 *err, const u32 len);
-void log_arm_hw_error(struct cper_sec_proc_arm *err);
+void log_arm_hw_error(struct acpi_hest_generic_data *gdata,
+ int sev, void *data);
 #else
 static inline void
 log_non_standard_event(const guid_t *sec_type,
@@ -37,7 +39,8 @@ void log_non_standard_event(const guid_t *sec_type,
   const u8 sev, const u8 *err, const u32 len

[PATCH RFC 0/4] ACPI: APEI: Add support to notify the vendor specific HW errors

2019-08-12 Thread Shiju Jose
Presently kernel does not support reporting the vendor specific HW errors,
in the non-standard format, to the vendor drivers for the recovery.

This patch set add this support and also move the existing handler
functions for the standard errors to the new callback method.
Also the CCIX RAS patches could be move to the proposed callback method.
https://www.spinics.net/lists/linux-edac/msg10508.html
https://patchwork.kernel.org/patch/10979491/

Shiju Jose (4):
  ACPI: APEI: Add support to notify the vendor specific HW errors
  ACPI: APEI: Add ghes_handle_memory_failure to the new notification
method
  ACPI: APEI: Add ghes_handle_aer to the new notification method
  ACPI: APEI: Add log_arm_hw_error to the new notification method

 drivers/acpi/apei/ghes.c | 170 +--
 drivers/ras/ras.c|   5 +-
 include/acpi/ghes.h  |  47 +
 include/linux/ras.h  |   7 +-
 4 files changed, 205 insertions(+), 24 deletions(-)

-- 
1.9.1




RE: [PATCH RFC 1/4] ACPI/AEST: Initial AEST driver

2019-07-04 Thread Shiju Jose
Hi Tyler,

>-Original Message-
>From: linux-acpi-ow...@vger.kernel.org [mailto:linux-acpi-
>ow...@vger.kernel.org] On Behalf Of Tyler Baicar OS
>Sent: 02 July 2019 17:52
>To: Open Source Submission ; linux-arm-
>ker...@lists.infradead.org; linux-kernel@vger.kernel.org; linux-
>a...@vger.kernel.org; linux-e...@vger.kernel.org; james.mo...@arm.com;
>catalin.mari...@arm.com; w...@kernel.org; lorenzo.pieral...@arm.com;
>Guohanjun (Hanjun Guo) ; sudeep.ho...@arm.com;
>r...@rjwysocki.net; l...@kernel.org; mark.rutl...@arm.com;
>tony.l...@intel.com; b...@alien8.de; matteo.carl...@arm.com;
>andrew.mur...@arm.com
>Cc: Tyler Baicar OS 
>Subject: [PATCH RFC 1/4] ACPI/AEST: Initial AEST driver
>
>Add support for parsing the ARM Error Source Table and basic handling of
>errors reported through both memory mapped and system register interfaces.
>
>Signed-off-by: Tyler Baicar 
>---
> arch/arm64/include/asm/ras.h |  41 +
> arch/arm64/kernel/Makefile   |   2 +-
> arch/arm64/kernel/ras.c  |  67 
> drivers/acpi/arm64/Kconfig   |   3 +
> drivers/acpi/arm64/Makefile  |   1 +
> drivers/acpi/arm64/aest.c| 362
>+++
> include/linux/acpi_aest.h|  94 +++
> 7 files changed, 569 insertions(+), 1 deletion(-)  create mode 100644
>arch/arm64/include/asm/ras.h  create mode 100644 arch/arm64/kernel/ras.c
>create mode 100644 drivers/acpi/arm64/aest.c  create mode 100644
>include/linux/acpi_aest.h
>
>diff --git a/arch/arm64/include/asm/ras.h b/arch/arm64/include/asm/ras.h
>new file mode 100644 index 000..36bfff4
>--- /dev/null
>+++ b/arch/arm64/include/asm/ras.h
>@@ -0,0 +1,41 @@
>+/* SPDX-License-Identifier: GPL-2.0 */
>+#ifndef __ASM_RAS_H
>+#define __ASM_RAS_H
>+
>+#define ERR_STATUS_AV BIT(31)
>+#define ERR_STATUS_V  BIT(30)
>+#define ERR_STATUS_UE BIT(29)
>+#define ERR_STATUS_ER BIT(28)
>+#define ERR_STATUS_OF BIT(27)
>+#define ERR_STATUS_MV BIT(26)
>+#define ERR_STATUS_CE_SHIFT   24
>+#define ERR_STATUS_CE_MASK0x3
>+#define ERR_STATUS_DE BIT(23)
>+#define ERR_STATUS_PN BIT(22)
>+#define ERR_STATUS_UET_SHIFT  20
>+#define ERR_STATUS_UET_MASK   0x3
>+#define ERR_STATUS_IERR_SHIFT 8
>+#define ERR_STATUS_IERR_MASK  0xff
>+#define ERR_STATUS_SERR_SHIFT 0
>+#define ERR_STATUS_SERR_MASK  0xff
>+
>+#define ERR_FR_CEC_SHIFT  12
>+#define ERR_FR_CEC_MASK   0x7
>+
>+#define ERR_FR_8B_CEC BIT(1)
>+#define ERR_FR_16B_CECBIT(2)
>+
>+struct ras_ext_regs {
>+  u64 err_fr;
>+  u64 err_ctlr;
>+  u64 err_status;
>+  u64 err_addr;
>+  u64 err_misc0;
>+  u64 err_misc1;
>+  u64 err_misc2;
>+  u64 err_misc3;
err_misc2 and err_misc3 are not used. Are they for the future purpose?

>+};
>+
>+void arch_arm_ras_report_error(void);
>+
>+#endif/* __ASM_RAS_H */
[...]
>+
>+int __init acpi_aest_init(void)
>+{
>+  struct acpi_table_aest *aest;
>+  struct aest_type_header *aest_node, *aest_end;
>+  int i, ret = 0;
>+
>+  if (acpi_disabled)
>+  return 0;
>+
>+  if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_AEST, 0, _table)))
>+  return -EINVAL;
>+
>+  aest = (struct acpi_table_aest *)aest_table;
>+
>+  /* Get the first AEST node */
>+  aest_node = ACPI_ADD_PTR(struct aest_type_header, aest,
>+   sizeof(struct acpi_table_aest));
>+  /* Pointer to the end of the AEST table */
>+  aest_end = ACPI_ADD_PTR(struct aest_type_header, aest,
>+  aest_table->length);
>+
>+  while (aest_node < aest_end) {
>+  if (((u64)aest_node + aest_node->length) > (u64)aest_end) {
>+  pr_err("AEST node pointer overflow, bad table\n");
>+  return -EINVAL;
>+  }
>+
>+  aest_count_ppi(aest_node);
>+
>+  aest_node = ACPI_ADD_PTR(struct aest_type_header,
>aest_node,
>+   aest_node->length);
>+  }
>+
>+  if (num_ppi > AEST_MAX_PPI) {
>+  pr_err("Limiting PPI support to %d PPIs\n", AEST_MAX_PPI);
>+  num_ppi = AEST_MAX_PPI;
>+  }
>+
>+  ppi_data = kcalloc(num_ppi, sizeof(struct aest_node_data *),
>+ GFP_KERNEL);
>+
>+  for (i = 0; i < num_ppi; i++) {
>+  ppi_data[i] = alloc_percpu(struct aest_node_data);
>+  if (!ppi_data[i]) {
>+  ret = -ENOMEM;
>+  break;
>+  }
>+  }
>+
>+  if (ret) {
>+  pr_err("Failed percpu allocation\n");
>+  for (i = 0; i < num_ppi; i++)
>+  free_percpu(ppi_data[i]);
I think 'ppi_data' to be freed here?

>+  return ret;
[...]
>+
>+#endif /* AEST_H */
>--
>1.8.3.1

Thanks,
Shiju



RE: [RFC PATCH v4 2/3] acpi: apei: Rename ghes_severity() to ghes_cper_severity()

2018-05-04 Thread Shiju Jose
Hi Alex,

> -Original Message-
> From: Alexandru Gagniuc [mailto:mr.nuke...@gmail.com]
> Sent: 30 April 2018 22:34
> To: b...@alien8.de
> Cc: alex_gagn...@dellteam.com; austin_bo...@dell.com;
> shyam_i...@dell.com; Alexandru Gagniuc; Rafael J. Wysocki; Len Brown;
> Tony Luck; Mauro Carvalho Chehab; Robert Moore; Erik Schmauss; Tyler
> Baicar; Will Deacon; James Morse; Shiju Jose; Jonathan (Zhixiong) Zhang;
> gengdongjiu; linux-a...@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-e...@vger.kernel.org; de...@acpica.org
> Subject: [RFC PATCH v4 2/3] acpi: apei: Rename ghes_severity() to
> ghes_cper_severity()
> 
> ghes_severity() is a misnomer in this case, as it implies the severity
> of the entire GHES structure. Instead, it maps one CPER value to a
> monotonically increasing number. ghes_cper_severity() is clearer.
> 
> Signed-off-by: Alexandru Gagniuc <mr.nuke...@gmail.com>
> ---
>  drivers/acpi/apei/ghes.c | 17 -
>  1 file changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index f9b53a6f55f3..c9f1971333c1 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -271,7 +271,7 @@ static void ghes_fini(struct ghes *ghes)
>   unmap_gen_v2(ghes);
>  }
> 
> -static inline int ghes_severity(int severity)
> +static inline int ghes_cper_severity(int severity)

[...]
>   else
>   ratelimit = _uncorrected;
> @@ -705,9 +705,8 @@ static int ghes_proc(struct ghes *ghes)
>   if (rc)
>   goto out;
> 
> - if (ghes_severity(ghes->estatus->error_severity) >=
> GHES_SEV_PANIC) {
> + if (ghes_cper_severity(ghes->estatus->error_severity) >=
> GHES_SEV_PANIC)
>   __ghes_panic(ghes);

PCIe AER fatal errors result panic here.
I think ghes_cper_severity to be replaced with ghes_severity in the ghes_proc 
function as well in the patch 
"acpi: apei: Do not panic() on PCIe errors reported through GHES"?
> - }
> 
[...]
> 2.14.3

Thanks,
Shiju



RE: [RFC PATCH v4 2/3] acpi: apei: Rename ghes_severity() to ghes_cper_severity()

2018-05-04 Thread Shiju Jose
Hi Alex,

> -Original Message-
> From: Alexandru Gagniuc [mailto:mr.nuke...@gmail.com]
> Sent: 30 April 2018 22:34
> To: b...@alien8.de
> Cc: alex_gagn...@dellteam.com; austin_bo...@dell.com;
> shyam_i...@dell.com; Alexandru Gagniuc; Rafael J. Wysocki; Len Brown;
> Tony Luck; Mauro Carvalho Chehab; Robert Moore; Erik Schmauss; Tyler
> Baicar; Will Deacon; James Morse; Shiju Jose; Jonathan (Zhixiong) Zhang;
> gengdongjiu; linux-a...@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-e...@vger.kernel.org; de...@acpica.org
> Subject: [RFC PATCH v4 2/3] acpi: apei: Rename ghes_severity() to
> ghes_cper_severity()
> 
> ghes_severity() is a misnomer in this case, as it implies the severity
> of the entire GHES structure. Instead, it maps one CPER value to a
> monotonically increasing number. ghes_cper_severity() is clearer.
> 
> Signed-off-by: Alexandru Gagniuc 
> ---
>  drivers/acpi/apei/ghes.c | 17 -
>  1 file changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index f9b53a6f55f3..c9f1971333c1 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -271,7 +271,7 @@ static void ghes_fini(struct ghes *ghes)
>   unmap_gen_v2(ghes);
>  }
> 
> -static inline int ghes_severity(int severity)
> +static inline int ghes_cper_severity(int severity)

[...]
>   else
>   ratelimit = _uncorrected;
> @@ -705,9 +705,8 @@ static int ghes_proc(struct ghes *ghes)
>   if (rc)
>   goto out;
> 
> - if (ghes_severity(ghes->estatus->error_severity) >=
> GHES_SEV_PANIC) {
> + if (ghes_cper_severity(ghes->estatus->error_severity) >=
> GHES_SEV_PANIC)
>   __ghes_panic(ghes);

PCIe AER fatal errors result panic here.
I think ghes_cper_severity to be replaced with ghes_severity in the ghes_proc 
function as well in the patch 
"acpi: apei: Do not panic() on PCIe errors reported through GHES"?
> - }
> 
[...]
> 2.14.3

Thanks,
Shiju



RE: [PATCH]arm64:defconfig:enable ACPI_APEI_SEA

2018-03-21 Thread Shiju Jose
Hi Gengdongjiu,

Ok got it. Please ignore this patch.

Thanks,
Shiju 

> -Original Message-
> From: gengdongjiu
> Sent: 21 March 2018 01:49
> To: Shiju Jose; xuwei (O)
> Cc: a...@arndb.de; james.mo...@arm.com; tbai...@codeaurora.org;
> Xiexiuqi; Zhengqiang (turing); Linuxarm; linux-kernel@vger.kernel.org;
> linux-arm-ker...@lists.infradead.org
> Subject: Re: [PATCH]arm64:defconfig:enable ACPI_APEI_SEA
> 
> Hi Shiju,
>The configuration "CONFIG_ACPI_APEI_SEA" is needed to manually
> enable?
> In the "drivers/acpi/apei/Kconfig" file, the default value of
> ACPI_APEI_SEA is "y"
> 
> config ACPI_APEI_SEA
> bool "APEI Synchronous External Abort logging/recovering
> support"
> depends on ARM64 && ACPI_APEI_GHES
> default y
> 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 from 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 hardware error record,
> and
>   take appropriate action.
> 
> 
> On 2018/3/20 20:23, Shiju Jose wrote:
> > Enable ACPI APEI SEA option for arm64, to handle
> > ARMv8 SEA(Synchronous External Abort).
> >
> > Signed-off-by: Shiju Jose <shiju.j...@huawei.com>
> > Cc: Tyler Baicar <tbai...@codeaurora.org>
> > Cc: James Morse <james.mo...@arm.com>
> > Cc: Dongjiu Geng <gengdong...@huawei.com>
> > Cc: Xie XiuQi <xiexi...@huawei.com>
> > Cc: Qiang Zheng <zhengqian...@huawei.com>
> > ---
> >  arch/arm64/configs/defconfig | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/arm64/configs/defconfig
> > b/arch/arm64/configs/defconfig index 634b373..5ddf25c 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -574,6 +574,7 @@ CONFIG_ACPI_APEI_GHES=y
> > CONFIG_ACPI_APEI_PCIEAER=y  CONFIG_ACPI_APEI_MEMORY_FAILURE=y
> > CONFIG_ACPI_APEI_EINJ=y
> > +CONFIG_ACPI_APEI_SEA=y
> >  CONFIG_EXT2_FS=y
> >  CONFIG_EXT3_FS=y
> >  CONFIG_EXT4_FS_POSIX_ACL=y
> >



RE: [PATCH]arm64:defconfig:enable ACPI_APEI_SEA

2018-03-21 Thread Shiju Jose
Hi Gengdongjiu,

Ok got it. Please ignore this patch.

Thanks,
Shiju 

> -Original Message-
> From: gengdongjiu
> Sent: 21 March 2018 01:49
> To: Shiju Jose; xuwei (O)
> Cc: a...@arndb.de; james.mo...@arm.com; tbai...@codeaurora.org;
> Xiexiuqi; Zhengqiang (turing); Linuxarm; linux-kernel@vger.kernel.org;
> linux-arm-ker...@lists.infradead.org
> Subject: Re: [PATCH]arm64:defconfig:enable ACPI_APEI_SEA
> 
> Hi Shiju,
>The configuration "CONFIG_ACPI_APEI_SEA" is needed to manually
> enable?
> In the "drivers/acpi/apei/Kconfig" file, the default value of
> ACPI_APEI_SEA is "y"
> 
> config ACPI_APEI_SEA
> bool "APEI Synchronous External Abort logging/recovering
> support"
> depends on ARM64 && ACPI_APEI_GHES
> default y
> 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 from 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 hardware error record,
> and
>   take appropriate action.
> 
> 
> On 2018/3/20 20:23, Shiju Jose wrote:
> > Enable ACPI APEI SEA option for arm64, to handle
> > ARMv8 SEA(Synchronous External Abort).
> >
> > Signed-off-by: Shiju Jose 
> > Cc: Tyler Baicar 
> > Cc: James Morse 
> > Cc: Dongjiu Geng 
> > Cc: Xie XiuQi 
> > Cc: Qiang Zheng 
> > ---
> >  arch/arm64/configs/defconfig | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/arm64/configs/defconfig
> > b/arch/arm64/configs/defconfig index 634b373..5ddf25c 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -574,6 +574,7 @@ CONFIG_ACPI_APEI_GHES=y
> > CONFIG_ACPI_APEI_PCIEAER=y  CONFIG_ACPI_APEI_MEMORY_FAILURE=y
> > CONFIG_ACPI_APEI_EINJ=y
> > +CONFIG_ACPI_APEI_SEA=y
> >  CONFIG_EXT2_FS=y
> >  CONFIG_EXT3_FS=y
> >  CONFIG_EXT4_FS_POSIX_ACL=y
> >



  1   2   >