Skip to content

Commit

Permalink
Merge branch 'apei-release' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/lenb/linux-acpi-2.6

* 'apei-release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
  ACPI, APEI, EINJ Param support is disabled by default
  APEI GHES: 32-bit buildfix
  ACPI: APEI build fix
  ACPI, APEI, GHES: Add hardware memory error recovery support
  HWPoison: add memory_failure_queue()
  ACPI, APEI, GHES, Error records content based throttle
  ACPI, APEI, GHES, printk support for recoverable error via NMI
  lib, Make gen_pool memory allocator lockless
  lib, Add lock-less NULL terminated single list
  Add Kconfig option ARCH_HAVE_NMI_SAFE_CMPXCHG
  ACPI, APEI, Add WHEA _OSC support
  ACPI, APEI, Add APEI bit support in generic _OSC call
  ACPI, APEI, GHES, Support disable GHES at boot time
  ACPI, APEI, GHES, Prevent GHES to be built as module
  ACPI, APEI, Use apei_exec_run_optional in APEI EINJ and ERST
  ACPI, APEI, Add apei_exec_run_optional
  ACPI, APEI, GHES, Do not ratelimit fatal error printk before panic
  ACPI, APEI, ERST, Fix erst-dbg long record reading issue
  ACPI, APEI, ERST, Prevent erst_dbg from loading if ERST is disabled
  • Loading branch information
torvalds committed Aug 4, 2011
2 parents a9e4e6e + d0e323b commit c0c770e
Show file tree
Hide file tree
Showing 35 changed files with 1,172 additions and 135 deletions.
11 changes: 9 additions & 2 deletions Documentation/acpi/apei/einj.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,19 @@ directory apei/einj. The following files are provided.
- param1
This file is used to set the first error parameter value. Effect of
parameter depends on error_type specified. For memory error, this is
physical memory address.
physical memory address. Only available if param_extension module
parameter is specified.

- param2
This file is used to set the second error parameter value. Effect of
parameter depends on error_type specified. For memory error, this is
physical memory address mask.
physical memory address mask. Only available if param_extension
module parameter is specified.

Injecting parameter support is a BIOS version specific extension, that
is, it only works on some BIOS version. If you want to use it, please
make sure your BIOS version has the proper support and specify
"param_extension=y" in module parameter.

For more information about EINJ, please refer to ACPI specification
version 4.0, section 17.5.
3 changes: 3 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,7 @@ config HAVE_ARCH_MUTEX_CPU_RELAX
config HAVE_RCU_TABLE_FREE
bool

config ARCH_HAVE_NMI_SAFE_CMPXCHG
bool

source "kernel/gcov/Kconfig"
1 change: 1 addition & 0 deletions arch/alpha/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ config ALPHA
select AUTO_IRQ_AFFINITY if SMP
select GENERIC_IRQ_SHOW
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARCH_HAVE_NMI_SAFE_CMPXCHG
help
The Alpha is a 64-bit general-purpose processor designed and
marketed by the Digital Equipment Corporation of blessed memory,
Expand Down
1 change: 1 addition & 0 deletions arch/avr32/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config AVR32
select GENERIC_IRQ_PROBE
select HARDIRQS_SW_RESEND
select GENERIC_IRQ_SHOW
select ARCH_HAVE_NMI_SAFE_CMPXCHG
help
AVR32 is a high-performance 32-bit RISC microprocessor core,
designed for cost-sensitive embedded applications, with particular
Expand Down
1 change: 1 addition & 0 deletions arch/frv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ config FRV
select HAVE_PERF_EVENTS
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
select ARCH_HAVE_NMI_SAFE_CMPXCHG

config ZONE_DMA
bool
Expand Down
1 change: 1 addition & 0 deletions arch/ia64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ config IA64
select IRQ_PER_CPU
select GENERIC_IRQ_SHOW
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARCH_HAVE_NMI_SAFE_CMPXCHG
default y
help
The Itanium Processor Family is Intel's 64-bit successor to
Expand Down
1 change: 1 addition & 0 deletions arch/m68k/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ config M68K
select GENERIC_ATOMIC64 if MMU
select HAVE_GENERIC_HARDIRQS if !MMU
select GENERIC_IRQ_SHOW if !MMU
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS

config RWSEM_GENERIC_SPINLOCK
bool
Expand Down
1 change: 1 addition & 0 deletions arch/parisc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ config PARISC
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select IRQ_PER_CPU
select ARCH_HAVE_NMI_SAFE_CMPXCHG

help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ config PPC
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_BPF_JIT if (PPC64 && NET)
select HAVE_ARCH_JUMP_LABEL
select ARCH_HAVE_NMI_SAFE_CMPXCHG

config EARLY_PRINTK
bool
Expand Down
1 change: 1 addition & 0 deletions arch/s390/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ config S390
select INIT_ALL_POSSIBLE
select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
Expand Down
1 change: 1 addition & 0 deletions arch/sh/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ config SUPERH
select HAVE_DMA_ATTRS
select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
select PERF_USE_VMALLOC
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
Expand Down
1 change: 1 addition & 0 deletions arch/sparc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ config SPARC64
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select IRQ_PREFLOW_FASTEOI
select ARCH_HAVE_NMI_SAFE_CMPXCHG

config ARCH_DEFCONFIG
string
Expand Down
1 change: 1 addition & 0 deletions arch/tile/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ config TILE
select GENERIC_PENDING_IRQ if SMP
select GENERIC_IRQ_SHOW
select SYS_HYPERVISOR
select ARCH_HAVE_NMI_SAFE_CMPXCHG if !M386

# FIXME: investigate whether we need/want these options.
# select HAVE_IOREMAP_PROT
Expand Down
1 change: 1 addition & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ config X86
select USE_GENERIC_SMP_HELPERS if SMP
select HAVE_BPF_JIT if (X86_64 && NET)
select CLKEVT_I8253
select ARCH_HAVE_NMI_SAFE_CMPXCHG

config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS)
Expand Down
11 changes: 10 additions & 1 deletion drivers/acpi/apei/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ config ACPI_APEI
error injection.

config ACPI_APEI_GHES
tristate "APEI Generic Hardware Error Source"
bool "APEI Generic Hardware Error Source"
depends on ACPI_APEI && X86
select ACPI_HED
select LLIST
select GENERIC_ALLOCATOR
help
Generic Hardware Error Source provides a way to report
platform hardware errors (such as that from chipset). It
Expand All @@ -30,6 +32,13 @@ config ACPI_APEI_PCIEAER
PCIe AER errors may be reported via APEI firmware first mode.
Turn on this option to enable the corresponding support.

config ACPI_APEI_MEMORY_FAILURE
bool "APEI memory error recovering support"
depends on ACPI_APEI && MEMORY_FAILURE
help
Memory errors may be reported via APEI firmware first mode.
Turn on this option to enable the memory recovering support.

config ACPI_APEI_EINJ
tristate "APEI Error INJection (EINJ)"
depends on ACPI_APEI && DEBUG_FS
Expand Down
35 changes: 31 additions & 4 deletions drivers/acpi/apei/apei-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,10 @@ EXPORT_SYMBOL_GPL(apei_exec_noop);
* 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 optional)
{
int rc;
int rc = -ENOENT;
u32 i, ip;
struct acpi_whea_header *entry;
apei_exec_ins_func_t run;
Expand Down Expand Up @@ -198,9 +199,9 @@ int apei_exec_run(struct apei_exec_context *ctx, u8 action)
goto rewind;
}

return 0;
return !optional && rc < 0 ? rc : 0;
}
EXPORT_SYMBOL_GPL(apei_exec_run);
EXPORT_SYMBOL_GPL(__apei_exec_run);

typedef int (*apei_exec_entry_func_t)(struct apei_exec_context *ctx,
struct acpi_whea_header *entry,
Expand Down Expand Up @@ -603,3 +604,29 @@ struct dentry *apei_get_debugfs_dir(void)
return dapei;
}
EXPORT_SYMBOL_GPL(apei_get_debugfs_dir);

int apei_osc_setup(void)
{
static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c";
acpi_handle handle;
u32 capbuf[3];
struct acpi_osc_context context = {
.uuid_str = whea_uuid_str,
.rev = 1,
.cap.length = sizeof(capbuf),
.cap.pointer = capbuf,
};

capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
capbuf[OSC_SUPPORT_TYPE] = 0;
capbuf[OSC_CONTROL_TYPE] = 0;

if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))
|| ACPI_FAILURE(acpi_run_osc(handle, &context)))
return -EIO;
else {
kfree(context.ret.pointer);
return 0;
}
}
EXPORT_SYMBOL_GPL(apei_osc_setup);
15 changes: 14 additions & 1 deletion drivers/acpi/apei/apei-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,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 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 */

Expand Down Expand Up @@ -113,4 +124,6 @@ void apei_estatus_print(const char *pfx,
const struct acpi_hest_generic_status *estatus);
int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
int apei_estatus_check(const struct acpi_hest_generic_status *estatus);

int apei_osc_setup(void);
#endif
43 changes: 26 additions & 17 deletions drivers/acpi/apei/einj.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
* Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the
* EINJ table through an unpublished extension. Use with caution as
* most will ignore the parameter and make their own choice of address
* for error injection.
* for error injection. This extension is used only if
* param_extension module parameter is specified.
*/
struct einj_parameter {
u64 type;
Expand All @@ -65,6 +66,9 @@ struct einj_parameter {
((struct acpi_whea_header *)((char *)(tab) + \
sizeof(struct acpi_table_einj)))

static bool param_extension;
module_param(param_extension, bool, 0);

static struct acpi_table_einj *einj_tab;

static struct apei_resources einj_resources;
Expand Down Expand Up @@ -285,7 +289,7 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)

einj_exec_ctx_init(&ctx);

rc = apei_exec_run(&ctx, ACPI_EINJ_BEGIN_OPERATION);
rc = apei_exec_run_optional(&ctx, ACPI_EINJ_BEGIN_OPERATION);
if (rc)
return rc;
apei_exec_ctx_set_input(&ctx, type);
Expand Down Expand Up @@ -323,7 +327,7 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
rc = __einj_error_trigger(trigger_paddr);
if (rc)
return rc;
rc = apei_exec_run(&ctx, ACPI_EINJ_END_OPERATION);
rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION);

return rc;
}
Expand Down Expand Up @@ -489,14 +493,6 @@ static int __init einj_init(void)
einj_debug_dir, NULL, &error_type_fops);
if (!fentry)
goto err_cleanup;
fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
einj_debug_dir, &error_param1);
if (!fentry)
goto err_cleanup;
fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR,
einj_debug_dir, &error_param2);
if (!fentry)
goto err_cleanup;
fentry = debugfs_create_file("error_inject", S_IWUSR,
einj_debug_dir, NULL, &error_inject_fops);
if (!fentry)
Expand All @@ -513,19 +509,32 @@ static int __init einj_init(void)
rc = apei_exec_pre_map_gars(&ctx);
if (rc)
goto err_release;
param_paddr = einj_get_parameter_address();
if (param_paddr) {
einj_param = ioremap(param_paddr, sizeof(*einj_param));
rc = -ENOMEM;
if (!einj_param)
goto err_unmap;
if (param_extension) {
param_paddr = einj_get_parameter_address();
if (param_paddr) {
einj_param = ioremap(param_paddr, sizeof(*einj_param));
rc = -ENOMEM;
if (!einj_param)
goto err_unmap;
fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
einj_debug_dir, &error_param1);
if (!fentry)
goto err_unmap;
fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR,
einj_debug_dir, &error_param2);
if (!fentry)
goto err_unmap;
} else
pr_warn(EINJ_PFX "Parameter extension is not supported.\n");
}

pr_info(EINJ_PFX "Error INJection is initialized.\n");

return 0;

err_unmap:
if (einj_param)
iounmap(einj_param);
apei_exec_post_unmap_gars(&ctx);
err_release:
apei_resources_release(&einj_resources);
Expand Down
6 changes: 5 additions & 1 deletion drivers/acpi/apei/erst-dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

#define ERST_DBG_PFX "ERST DBG: "

#define ERST_DBG_RECORD_LEN_MAX 4096
#define ERST_DBG_RECORD_LEN_MAX 0x4000

static void *erst_dbg_buf;
static unsigned int erst_dbg_buf_len;
Expand Down Expand Up @@ -213,6 +213,10 @@ static struct miscdevice erst_dbg_dev = {

static __init int erst_dbg_init(void)
{
if (erst_disable) {
pr_info(ERST_DBG_PFX "ERST support is disabled.\n");
return -ENODEV;
}
return misc_register(&erst_dbg_dev);
}

Expand Down
Loading

0 comments on commit c0c770e

Please sign in to comment.