Skip to content

Commit 34ddeb0

Browse files
yhuang-intellenb
authored andcommitted
ACPI, APEI, Avoid too much error reporting in runtime
This patch fixed the following bug. https://bugzilla.kernel.org/show_bug.cgi?id=43282 This is caused by a firmware bug checking (checking generic address register provided by firmware) in runtime. The checking should be done in address mapping time instead of runtime to avoid too much error reporting in runtime. Reported-by: Pawel Sikora <[email protected]> Signed-off-by: Huang Ying <[email protected]> Tested-by: Jean Delvare <[email protected]> Cc: [email protected] Signed-off-by: Len Brown <[email protected]>
1 parent cfaf025 commit 34ddeb0

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

drivers/acpi/apei/apei-base.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ static int pre_map_gar_callback(struct apei_exec_context *ctx,
243243
u8 ins = entry->instruction;
244244

245245
if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)
246-
return acpi_os_map_generic_address(&entry->register_region);
246+
return apei_map_generic_address(&entry->register_region);
247247

248248
return 0;
249249
}
@@ -276,7 +276,7 @@ static int post_unmap_gar_callback(struct apei_exec_context *ctx,
276276
u8 ins = entry->instruction;
277277

278278
if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)
279-
acpi_os_unmap_generic_address(&entry->register_region);
279+
apei_unmap_generic_address(&entry->register_region);
280280

281281
return 0;
282282
}
@@ -606,6 +606,19 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr,
606606
return 0;
607607
}
608608

609+
int apei_map_generic_address(struct acpi_generic_address *reg)
610+
{
611+
int rc;
612+
u32 access_bit_width;
613+
u64 address;
614+
615+
rc = apei_check_gar(reg, &address, &access_bit_width);
616+
if (rc)
617+
return rc;
618+
return acpi_os_map_generic_address(reg);
619+
}
620+
EXPORT_SYMBOL_GPL(apei_map_generic_address);
621+
609622
/* read GAR in interrupt (including NMI) or process context */
610623
int apei_read(u64 *val, struct acpi_generic_address *reg)
611624
{

drivers/acpi/apei/apei-internal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#define APEI_INTERNAL_H
88

99
#include <linux/cper.h>
10+
#include <linux/acpi.h>
11+
#include <linux/acpi_io.h>
1012

1113
struct apei_exec_context;
1214

@@ -68,6 +70,13 @@ static inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 actio
6870
/* IP has been set in instruction function */
6971
#define APEI_EXEC_SET_IP 1
7072

73+
int apei_map_generic_address(struct acpi_generic_address *reg);
74+
75+
static inline void apei_unmap_generic_address(struct acpi_generic_address *reg)
76+
{
77+
acpi_os_unmap_generic_address(reg);
78+
}
79+
7180
int apei_read(u64 *val, struct acpi_generic_address *reg);
7281
int apei_write(u64 val, struct acpi_generic_address *reg);
7382

drivers/acpi/apei/ghes.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic)
301301
if (!ghes)
302302
return ERR_PTR(-ENOMEM);
303303
ghes->generic = generic;
304-
rc = acpi_os_map_generic_address(&generic->error_status_address);
304+
rc = apei_map_generic_address(&generic->error_status_address);
305305
if (rc)
306306
goto err_free;
307307
error_block_length = generic->error_block_length;
@@ -321,7 +321,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic)
321321
return ghes;
322322

323323
err_unmap:
324-
acpi_os_unmap_generic_address(&generic->error_status_address);
324+
apei_unmap_generic_address(&generic->error_status_address);
325325
err_free:
326326
kfree(ghes);
327327
return ERR_PTR(rc);
@@ -330,7 +330,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic)
330330
static void ghes_fini(struct ghes *ghes)
331331
{
332332
kfree(ghes->estatus);
333-
acpi_os_unmap_generic_address(&ghes->generic->error_status_address);
333+
apei_unmap_generic_address(&ghes->generic->error_status_address);
334334
}
335335

336336
enum {

0 commit comments

Comments
 (0)