Skip to content

Commit

Permalink
ACPI: APEI: Fix BERT resources conflict with ACPI NVS area
Browse files Browse the repository at this point in the history
It was reported that on some machines, there is overlap between ACPI
NVS area and BERT address range.  This appears reasonable because BERT
contents need to be non-volatile across reboot.  But this will cause
resources conflict in current Linux kernel implementation because the
ACPI NVS area is marked as busy.  The resource conflict is fixed via
excluding the ACPI NVS area when requesting IO resources for BERT.
When accessing the BERT contents, the whole BERT address range will be
ioremapped and accessed.

Reported-and-tested-by: Hans Kristian Rosbach <hansr@raskesider.no>
Signed-off-by: Ying Huang <ying.huang@intel.com>
Acked-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Huang Ying authored and Rafael J. Wysocki committed Feb 27, 2017
1 parent d222678 commit 41139ac
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions drivers/acpi/apei/bert.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ static int __init bert_check_table(struct acpi_table_bert *bert_tab)

static int __init bert_init(void)
{
struct apei_resources bert_resources;
struct acpi_bert_region *boot_error_region;
struct acpi_table_bert *bert_tab;
unsigned int region_len;
Expand Down Expand Up @@ -127,13 +128,14 @@ static int __init bert_init(void)
}

region_len = bert_tab->region_length;
if (!request_mem_region(bert_tab->address, region_len, "APEI BERT")) {
pr_err("Can't request iomem region <%016llx-%016llx>.\n",
(unsigned long long)bert_tab->address,
(unsigned long long)bert_tab->address + region_len - 1);
return -EIO;
}

apei_resources_init(&bert_resources);
rc = apei_resources_add(&bert_resources, bert_tab->address,
region_len, true);
if (rc)
return rc;
rc = apei_resources_request(&bert_resources, "APEI BERT");
if (rc)
goto out_fini;
boot_error_region = ioremap_cache(bert_tab->address, region_len);
if (boot_error_region) {
bert_print_all(boot_error_region, region_len);
Expand All @@ -142,7 +144,9 @@ static int __init bert_init(void)
rc = -ENOMEM;
}

release_mem_region(bert_tab->address, region_len);
apei_resources_release(&bert_resources);
out_fini:
apei_resources_fini(&bert_resources);

return rc;
}
Expand Down

0 comments on commit 41139ac

Please sign in to comment.