Message ID | 20170220011343.6736-1-ying.huang@intel.com (mailing list archive) |
---|---|
State | Accepted, archived |
Delegated to: | Rafael Wysocki |
Headers | show |
On Mon, Feb 20, 2017 at 09:12:58AM +0800, Huang, Ying wrote: > From: Huang Ying <ying.huang@intel.com> > > 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: "Huang, Ying" <ying.huang@intel.com> > --- > drivers/acpi/apei/bert.c | 20 ++++++++++++-------- > 1 file changed, 12 insertions(+), 8 deletions(-) Acked-by: Borislav Petkov <bp@suse.de>
diff --git a/drivers/acpi/apei/bert.c b/drivers/acpi/apei/bert.c index a05b5c0cf181..12771fcf0417 100644 --- a/drivers/acpi/apei/bert.c +++ b/drivers/acpi/apei/bert.c @@ -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; @@ -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); @@ -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; }