aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2013-04-02 12:38:15 +0200
committerJan Beulich <jbeulich@suse.com>2013-04-02 12:38:15 +0200
commit39fbe392cfd5c7df08cc2299a9baebf02edbad74 (patch)
tree9776d1e32218dcf40de392573b6a7097f79f7998
parent1745fb53ae0bb483767473e3c95d3420a5fb10e3 (diff)
downloadxen-39fbe392cfd5c7df08cc2299a9baebf02edbad74.tar.gz
xen-39fbe392cfd5c7df08cc2299a9baebf02edbad74.tar.bz2
xen-39fbe392cfd5c7df08cc2299a9baebf02edbad74.zip
ACPI, APEI: Add apei_exec_run_optional
Some actions in APEI ERST and EINJ tables are optional, for example, ACPI_EINJ_BEGIN_OPERATION action is used to do some preparation for error injection, and firmware may choose to do nothing here. While some other actions are mandatory, for example, firmware must provide ACPI_EINJ_GET_ERROR_TYPE implementation. Original implementation treats all actions as optional (that is, can have no instructions), that may cause issue if firmware does not provide some mandatory actions. To fix this, this patch adds apei_exec_run_optional, which should be used for optional actions. The original apei_exec_run should be used for mandatory actions. Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Tested-by: Andrew Cooper <andrew.cooper3@citrix.com> master commit: 72af01bf6f7489e54ad59270222a29d3e8c501d1 master date: 2013-03-22 12:46:25 +0100
-rw-r--r--xen/drivers/acpi/apei/apei-base.c7
-rw-r--r--xen/drivers/acpi/apei/apei-internal.h13
2 files changed, 16 insertions, 4 deletions
diff --git a/xen/drivers/acpi/apei/apei-base.c b/xen/drivers/acpi/apei/apei-base.c
index 0a365b7197..43f8f984df 100644
--- a/xen/drivers/acpi/apei/apei-base.c
+++ b/xen/drivers/acpi/apei/apei-base.c
@@ -154,9 +154,10 @@ int apei_exec_noop(struct apei_exec_context *ctx,
* Interpret the specified action. Go through whole action table,
* execute all instructions belong to the action.
*/
-int apei_exec_run(struct apei_exec_context *ctx, u8 action)
+int __apei_exec_run(struct apei_exec_context *ctx, u8 action,
+ bool_t optional)
{
- int rc;
+ int rc = -ENOENT;
u32 i, ip;
struct acpi_whea_header *entry;
apei_exec_ins_func_t run;
@@ -195,7 +196,7 @@ rewind:
goto rewind;
}
- return 0;
+ return !optional && rc < 0 ? rc : 0;
}
typedef int (*apei_exec_entry_func_t)(struct apei_exec_context *ctx,
diff --git a/xen/drivers/acpi/apei/apei-internal.h b/xen/drivers/acpi/apei/apei-internal.h
index 77f31fb993..b813d55b92 100644
--- a/xen/drivers/acpi/apei/apei-internal.h
+++ b/xen/drivers/acpi/apei/apei-internal.h
@@ -48,7 +48,18 @@ static inline u64 apei_exec_ctx_get_output(struct apei_exec_context *ctx)
return ctx->value;
}
-int apei_exec_run(struct apei_exec_context *ctx, u8 action);
+int __apei_exec_run(struct apei_exec_context *ctx, u8 action, bool_t optional);
+
+static inline int apei_exec_run(struct apei_exec_context *ctx, u8 action)
+{
+ return __apei_exec_run(ctx, action, 0);
+}
+
+/* It is optional whether the firmware provides the action */
+static inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 action)
+{
+ return __apei_exec_run(ctx, action, 1);
+}
/* Common instruction implementation */