From 11ca0d6b54cd1d7e431b37128d8ad19ea5a8bd47 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 20 Sep 2021 19:50:28 +0100 Subject: [PATCH 1/5] Documentation: ACPI: Fix spelling mistake "Millenium" -> "Millennium" There is a spelling mistake in the documentation with the Windows Millennium edition. Fix it. Signed-off-by: Colin Ian King Signed-off-by: Rafael J. Wysocki --- Documentation/firmware-guide/acpi/osi.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/firmware-guide/acpi/osi.rst b/Documentation/firmware-guide/acpi/osi.rst index 29e9ef79ebc0..05869c0045d7 100644 --- a/Documentation/firmware-guide/acpi/osi.rst +++ b/Documentation/firmware-guide/acpi/osi.rst @@ -74,7 +74,7 @@ The ACPI BIOS flow would include an evaluation of _OS, and the AML interpreter in the kernel would return to it a string identifying the OS: Windows 98, SE: "Microsoft Windows" -Windows ME: "Microsoft WindowsME:Millenium Edition" +Windows ME: "Microsoft WindowsME:Millennium Edition" Windows NT: "Microsoft Windows NT" The idea was on a platform tasked with running multiple OS's, From caa2bd07f5c5f09acf62072906daeaa667e2b645 Mon Sep 17 00:00:00 2001 From: Aubrey Li Date: Wed, 20 Oct 2021 11:23:16 +0800 Subject: [PATCH 2/5] ACPI: PRM: Remove unnecessary blank lines Just remove unnecessary blank lines, no other code changes Signed-off-by: Aubrey Li Signed-off-by: Rafael J. Wysocki --- drivers/acpi/prmt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index 89c22bc55057..aa02221f6ade 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -49,7 +49,6 @@ struct prm_context_buffer { }; #pragma pack() - static LIST_HEAD(prm_module_list); struct prm_handler_info { @@ -73,7 +72,6 @@ struct prm_module_info { struct prm_handler_info handlers[]; }; - static u64 efi_pa_va_lookup(u64 pa) { efi_memory_desc_t *md; @@ -88,7 +86,6 @@ static u64 efi_pa_va_lookup(u64 pa) return 0; } - #define get_first_handler(a) ((struct acpi_prmt_handler_info *) ((char *) (a) + a->handler_info_offset)) #define get_next_handler(a) ((struct acpi_prmt_handler_info *) (sizeof(struct acpi_prmt_handler_info) + (char *) a)) @@ -171,7 +168,6 @@ static void *find_guid_info(const guid_t *guid, u8 mode) return NULL; } - static struct prm_module_info *find_prm_module(const guid_t *guid) { return (struct prm_module_info *)find_guid_info(guid, GET_MODULE); From c52ca713279da78881d36b49acd36288a46bbec8 Mon Sep 17 00:00:00 2001 From: Aubrey Li Date: Wed, 20 Oct 2021 11:23:17 +0800 Subject: [PATCH 3/5] ACPI: PRM: Handle memory allocation and memory remap failure Handle memory allocation and memory remap failure in acpi_parse_prmt() when system runs out of memory to avoid the potential NULL pointer dereference errors. Signed-off-by: Aubrey Li Signed-off-by: Rafael J. Wysocki --- drivers/acpi/prmt.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index aa02221f6ade..4d3a219c67f8 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -96,7 +96,7 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) struct acpi_prmt_handler_info *handler_info; struct prm_handler_info *th; struct prm_module_info *tm; - u64 mmio_count = 0; + u64 *mmio_count; u64 cur_handler = 0; u32 module_info_size = 0; u64 mmio_range_size = 0; @@ -105,6 +105,8 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) module_info = (struct acpi_prmt_module_info *) header; module_info_size = struct_size(tm, handlers, module_info->handler_info_count); tm = kmalloc(module_info_size, GFP_KERNEL); + if (!tm) + goto parse_prmt_out1; guid_copy(&tm->guid, (guid_t *) module_info->module_guid); tm->major_rev = module_info->major_rev; @@ -117,14 +119,24 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) * Each module is associated with a list of addr * ranges that it can use during the service */ - mmio_count = *(u64 *) memremap(module_info->mmio_list_pointer, 8, MEMREMAP_WB); - mmio_range_size = struct_size(tm->mmio_info, addr_ranges, mmio_count); + mmio_count = (u64 *) memremap(module_info->mmio_list_pointer, 8, MEMREMAP_WB); + if (!mmio_count) + goto parse_prmt_out2; + + mmio_range_size = struct_size(tm->mmio_info, addr_ranges, *mmio_count); tm->mmio_info = kmalloc(mmio_range_size, GFP_KERNEL); + if (!tm->mmio_info) + goto parse_prmt_out3; + temp_mmio = memremap(module_info->mmio_list_pointer, mmio_range_size, MEMREMAP_WB); + if (!temp_mmio) + goto parse_prmt_out4; memmove(tm->mmio_info, temp_mmio, mmio_range_size); } else { - mmio_range_size = struct_size(tm->mmio_info, addr_ranges, mmio_count); - tm->mmio_info = kmalloc(mmio_range_size, GFP_KERNEL); + tm->mmio_info = kmalloc(sizeof(*tm->mmio_info), GFP_KERNEL); + if (!tm->mmio_info) + goto parse_prmt_out2; + tm->mmio_info->mmio_count = 0; } @@ -142,6 +154,15 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) } while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info))); return 0; + +parse_prmt_out4: + kfree(tm->mmio_info); +parse_prmt_out3: + memunmap(mmio_count); +parse_prmt_out2: + kfree(tm); +parse_prmt_out1: + return -ENOMEM; } #define GET_MODULE 0 From bf7fc0c369585e34652d5666ed590d5cac07c2e2 Mon Sep 17 00:00:00 2001 From: Shuai Xue Date: Tue, 26 Oct 2021 15:28:29 +0800 Subject: [PATCH 4/5] ACPI: APEI: EINJ: Relax platform response timeout to 1 second When injecting an error into the platform, the OSPM executes an EXECUTE_OPERATION action to instruct the platform to begin the injection operation. And then, the OSPM busy waits for a while by continually executing CHECK_BUSY_STATUS action until the platform indicates that the operation is complete. More specifically, the platform is limited to respond within 1 millisecond right now. This is too strict for some platforms. For example, in Arm platform, when injecting a Processor Correctable error, the OSPM will warn: Firmware does not respond in time. And a message is printed on the console: echo: write error: Input/output error We observe that the waiting time for DDR error injection is about 10 ms and that for PCIe error injection is about 500 ms in Arm platform. In this patch, we relax the response timeout to 1 second. Signed-off-by: Shuai Xue Reviewed-by: Tony Luck Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/einj.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 2882450c443e..edb2622fd35f 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -28,9 +28,10 @@ #undef pr_fmt #define pr_fmt(fmt) "EINJ: " fmt -#define SPIN_UNIT 100 /* 100ns */ -/* Firmware should respond within 1 milliseconds */ -#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) +#define SLEEP_UNIT_MIN 1000 /* 1ms */ +#define SLEEP_UNIT_MAX 5000 /* 5ms */ +/* Firmware should respond within 1 seconds */ +#define FIRMWARE_TIMEOUT (1 * USEC_PER_SEC) #define ACPI5_VENDOR_BIT BIT(31) #define MEM_ERROR_MASK (ACPI_EINJ_MEMORY_CORRECTABLE | \ ACPI_EINJ_MEMORY_UNCORRECTABLE | \ @@ -171,13 +172,13 @@ static int einj_get_available_error_type(u32 *type) static int einj_timedout(u64 *t) { - if ((s64)*t < SPIN_UNIT) { + if ((s64)*t < SLEEP_UNIT_MIN) { pr_warn(FW_WARN "Firmware does not respond in time\n"); return 1; } - *t -= SPIN_UNIT; - ndelay(SPIN_UNIT); - touch_nmi_watchdog(); + *t -= SLEEP_UNIT_MIN; + usleep_range(SLEEP_UNIT_MIN, SLEEP_UNIT_MAX); + return 0; } From 06606646af97fa9aa0c36a723f4615157e41400a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 27 Oct 2021 08:54:38 +0200 Subject: [PATCH 5/5] ACPI: APEI: mark apei_hest_parse() static apei_hest_parse() is only used in hest.c, so mark it static. Signed-off-by: Christoph Hellwig [ rjw: Minor subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/hest.c | 5 +++-- include/acpi/apei.h | 3 --- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 277f00b288d1..0edc1ed47673 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -86,7 +86,9 @@ static int hest_esrc_len(struct acpi_hest_header *hest_hdr) return len; }; -int apei_hest_parse(apei_hest_func_t func, void *data) +typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data); + +static int apei_hest_parse(apei_hest_func_t func, void *data) { struct acpi_hest_header *hest_hdr; int i, rc, len; @@ -121,7 +123,6 @@ int apei_hest_parse(apei_hest_func_t func, void *data) return 0; } -EXPORT_SYMBOL_GPL(apei_hest_parse); /* * Check if firmware advertises firmware first mode. We need FF bit to be set diff --git a/include/acpi/apei.h b/include/acpi/apei.h index 680f80960c3d..ece0a8af2bae 100644 --- a/include/acpi/apei.h +++ b/include/acpi/apei.h @@ -37,9 +37,6 @@ void __init acpi_hest_init(void); static inline void acpi_hest_init(void) { return; } #endif -typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data); -int apei_hest_parse(apei_hest_func_t func, void *data); - int erst_write(const struct cper_record_header *record); ssize_t erst_get_record_count(void); int erst_get_record_id_begin(int *pos);