Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 286482
b: refs/heads/master
c: fdea163
h: refs/heads/master
v: v3
  • Loading branch information
Huang Ying authored and Len Brown committed Jan 17, 2012
1 parent 7d0e24b commit 6a81066
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 76da3fb3575e39fb23b2c072997ccd1187a2ce9d
refs/heads/master: fdea163d8c17ba08814142259a467ba3e899010d
11 changes: 11 additions & 0 deletions trunk/drivers/acpi/apei/apei-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,17 @@ static int apei_resources_merge(struct apei_resources *resources1,
return 0;
}

int apei_resources_add(struct apei_resources *resources,
unsigned long start, unsigned long size,
bool iomem)
{
if (iomem)
return apei_res_add(&resources->iomem, start, size);
else
return apei_res_add(&resources->ioport, start, size);
}
EXPORT_SYMBOL_GPL(apei_resources_add);

/*
* EINJ has two groups of GARs (EINJ table entry and trigger table
* entry), so common resources are subtracted from the trigger table
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/acpi/apei/apei-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ static inline void apei_resources_init(struct apei_resources *resources)
}

void apei_resources_fini(struct apei_resources *resources);
int apei_resources_add(struct apei_resources *resources,
unsigned long start, unsigned long size,
bool iomem);
int apei_resources_sub(struct apei_resources *resources1,
struct apei_resources *resources2);
int apei_resources_request(struct apei_resources *resources,
Expand Down
24 changes: 22 additions & 2 deletions trunk/drivers/acpi/apei/einj.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab)
}

/* Execute instructions in trigger error action table */
static int __einj_error_trigger(u64 trigger_paddr)
static int __einj_error_trigger(u64 trigger_paddr, u32 type,
u64 param1, u64 param2)
{
struct acpi_einj_trigger *trigger_tab = NULL;
struct apei_exec_context trigger_ctx;
Expand Down Expand Up @@ -256,6 +257,25 @@ static int __einj_error_trigger(u64 trigger_paddr)
rc = apei_resources_sub(&trigger_resources, &einj_resources);
if (rc)
goto out_fini;
/*
* Some firmware will access target address specified in
* param1 to trigger the error when injecting memory error.
* This will cause resource conflict with regular memory. So
* remove it from trigger table resources.
*/
if (param_extension && (type & 0x0038) && param2) {
struct apei_resources addr_resources;
apei_resources_init(&addr_resources);
rc = apei_resources_add(&addr_resources,
param1 & param2,
~param2 + 1, true);
if (rc)
goto out_fini;
rc = apei_resources_sub(&trigger_resources, &addr_resources);
apei_resources_fini(&addr_resources);
if (rc)
goto out_fini;
}
rc = apei_resources_request(&trigger_resources, "APEI EINJ Trigger");
if (rc)
goto out_fini;
Expand Down Expand Up @@ -325,7 +345,7 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
if (rc)
return rc;
trigger_paddr = apei_exec_ctx_get_output(&ctx);
rc = __einj_error_trigger(trigger_paddr);
rc = __einj_error_trigger(trigger_paddr, type, param1, param2);
if (rc)
return rc;
rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION);
Expand Down

0 comments on commit 6a81066

Please sign in to comment.