diff mbox

APEI: Can not request iomem region for GARs

Message ID 4E520149.3010802@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Huang, Ying Aug. 22, 2011, 7:12 a.m. UTC
Hi, Pavel,

Do you have time to try the patch attached with the mail?
acpi_nvs.patch should go first.

Best Regards,
Huang Ying

Comments

Bjorn Helgaas Aug. 22, 2011, 4:45 p.m. UTC | #1
On Mon, Aug 22, 2011 at 1:12 AM, Huang Ying <ying.huang@intel.com> wrote:
> Do you have time to try the patch attached with the mail?
> acpi_nvs.patch should go first.

I'm sure these patches make the messages go away, but I think this is
the wrong way to fix the problem.

We mark things "busy" in the resource trees as a mutual exclusion
mechanism -- normally when a driver claims a resource and nothing else
should be allowed to touch it.

e820_reserve_resources() marks everything (except "reserved" regions)
as busy.  That probably makes sense for available RAM, since RAM is
allocated and managed via other mechanisms.  But I think it's wrong in
this case because e820 is not a driver that is using the ACPI NVS
region.

In this case, we have an ACPI NVS region, and the APEI code is
essentially a driver for some registers that reside there.  APEI is
the entity that manages those registers, and it needs to enforce
mutual exclusion so nobody else touches them behind its back, so I
think it makes sense for it to request the register regions and mark
them busy.

My proposal is to change e820 so it either leaves ACPI NVS out of the
iomem_resource tree or puts it in but leaves it non-busy.

Bjorn
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

Subject: [BUGFIX] ACPI, APEI, Resolve false conflict between ACPI NVS and APEI

Some firmware will access memory in ACPI NVS region via APEI.  That
is, instructions in APEI ERST/EINJ table will read/write ACPI NVS
region.  The original resource conflict checking in APEI code will
check memory/ioport accessed by APEI via general resource management
mech.  But ACPI NVS region is marked as busy already, so that the
false resource conflict will prevent APEI ERST/EINJ to work.

To fix this, this patch excludes ACPI NVS regions when APEI components
request resources.  So that they will not conflict with ACPI NVS
regions.

Reported-by: Pavel Ivanov <paivanof@gmail.com>
Signed-off-by: Huang Ying <ying.huang@intel.com>
---
 drivers/acpi/apei/apei-base.c |   27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -449,8 +449,19 @@  int apei_resources_sub(struct apei_resou
 }
 EXPORT_SYMBOL_GPL(apei_resources_sub);
 
+static int apei_get_nvs_callback(__u64 start, __u64 size, void *data)
+{
+	struct apei_resources *resources = data;
+	return apei_res_add(&resources->iomem, start, size);
+}
+
+static int apei_get_nvs_resources(struct apei_resources *resources)
+{
+	return acpi_nvs_for_each_region(apei_get_nvs_callback, resources);
+}
+
 /*
- * IO memory/port rersource management mechanism is used to check
+ * IO memory/port resource management mechanism is used to check
  * whether memory/port area used by GARs conflicts with normal memory
  * or IO memory/port of devices.
  */
@@ -459,12 +470,24 @@  int apei_resources_request(struct apei_r
 {
 	struct apei_res *res, *res_bak = NULL;
 	struct resource *r;
+	struct apei_resources nvs_resources;
 	int rc;
 
 	rc = apei_resources_sub(resources, &apei_resources_all);
 	if (rc)
 		return rc;
 
+	/*
+	 * Some firmware uses ACPI NVS region, that has been marked as
+	 * busy, so exclude it from APEI resources to avoid false
+	 * conflict.
+	 */
+	apei_resources_init(&nvs_resources);
+	apei_get_nvs_resources(&nvs_resources);
+	rc = apei_resources_sub(resources, &nvs_resources);
+	if (rc)
+		goto res_fini;
+
 	rc = -EINVAL;
 	list_for_each_entry(res, &resources->iomem, list) {
 		r = request_mem_region(res->start, res->end - res->start,
@@ -511,6 +534,8 @@  err_unmap_iomem:
 			break;
 		release_mem_region(res->start, res->end - res->start);
 	}
+res_fini:
+	apei_resources_fini(&nvs_resources);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(apei_resources_request);