diff options
author | Huang Ying <ying.huang@intel.com> | 2011-07-13 01:14:20 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-07-13 23:38:20 -0400 |
commit | eccddd32ced0df8f9130024157bf8d37df860d76 (patch) | |
tree | 6e4372e5096fde4d2ffea12a0b992bef06ad589f | |
parent | b6a9501658530d8b8374e37f1edb549039a8a260 (diff) |
ACPI, APEI, Add APEI bit support in generic _OSC call
In APEI firmware first mode, hardware error is reported by hardware to
firmware firstly, then firmware reports the error to Linux in a GHES
error record via POLL/SCI/IRQ/NMI etc.
This may result in some issues if OS has no full APEI support. So
some firmware implementation will work in a back-compatible mode by
default. Where firmware will only notify OS in old-fashion, without
GHES record. For example, for a fatal hardware error, only NMI is
signaled, no GHES record.
To gain full APEI power on these machines, APEI bit in generic _OSC
call can be specified to tell firmware that Linux has full APEI
support. This patch adds the APEI bit support in generic _OSC call.
Signed-off-by: Huang Ying <ying.huang@intel.com>
Reviewed-by: Andi Kleen <ak@linux.intel.com>
Reviewed-by: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/bus.c | 16 | ||||
-rw-r--r-- | include/linux/acpi.h | 2 |
2 files changed, 16 insertions, 2 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index d1e06c182cdb..43ce3b0c4921 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <acpi/acpi_bus.h> | 40 | #include <acpi/acpi_bus.h> |
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | #include <acpi/apei.h> | ||
42 | #include <linux/dmi.h> | 43 | #include <linux/dmi.h> |
43 | #include <linux/suspend.h> | 44 | #include <linux/suspend.h> |
44 | 45 | ||
@@ -519,6 +520,7 @@ out_kfree: | |||
519 | } | 520 | } |
520 | EXPORT_SYMBOL(acpi_run_osc); | 521 | EXPORT_SYMBOL(acpi_run_osc); |
521 | 522 | ||
523 | bool osc_sb_apei_support_acked; | ||
522 | static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48"; | 524 | static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48"; |
523 | static void acpi_bus_osc_support(void) | 525 | static void acpi_bus_osc_support(void) |
524 | { | 526 | { |
@@ -541,11 +543,21 @@ static void acpi_bus_osc_support(void) | |||
541 | #if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) | 543 | #if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) |
542 | capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT; | 544 | capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT; |
543 | #endif | 545 | #endif |
546 | |||
547 | #ifdef CONFIG_ACPI_APEI_GHES | ||
548 | if (!ghes_disable) | ||
549 | capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_APEI_SUPPORT; | ||
550 | #endif | ||
544 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) | 551 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) |
545 | return; | 552 | return; |
546 | if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) | 553 | if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) { |
554 | u32 *capbuf_ret = context.ret.pointer; | ||
555 | if (context.ret.length > OSC_SUPPORT_TYPE) | ||
556 | osc_sb_apei_support_acked = | ||
557 | capbuf_ret[OSC_SUPPORT_TYPE] & OSC_SB_APEI_SUPPORT; | ||
547 | kfree(context.ret.pointer); | 558 | kfree(context.ret.pointer); |
548 | /* do we need to check the returned cap? Sounds no */ | 559 | } |
560 | /* do we need to check other returned cap? Sounds no */ | ||
549 | } | 561 | } |
550 | 562 | ||
551 | /* -------------------------------------------------------------------------- | 563 | /* -------------------------------------------------------------------------- |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 1deb2a73c2da..e19527de6a93 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -280,6 +280,8 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); | |||
280 | #define OSC_SB_CPUHP_OST_SUPPORT 8 | 280 | #define OSC_SB_CPUHP_OST_SUPPORT 8 |
281 | #define OSC_SB_APEI_SUPPORT 16 | 281 | #define OSC_SB_APEI_SUPPORT 16 |
282 | 282 | ||
283 | extern bool osc_sb_apei_support_acked; | ||
284 | |||
283 | /* PCI defined _OSC bits */ | 285 | /* PCI defined _OSC bits */ |
284 | /* _OSC DW1 Definition (OS Support Fields) */ | 286 | /* _OSC DW1 Definition (OS Support Fields) */ |
285 | #define OSC_EXT_PCI_CONFIG_SUPPORT 1 | 287 | #define OSC_EXT_PCI_CONFIG_SUPPORT 1 |