mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-08-18 02:22:47 -07:00
Merge branch 'apei-release' of git://git.kernel.org/pub/scm/linux/kernel/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
This commit is contained in:
commit
c0c770e610
35 files changed
+1172
-135
No files matched your search
@@ -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.
|
||||
@@ -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"
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -198,9 +199,9 @@ rewind:
|
||||
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,
|
||||
@@ -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);
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
+26
-17
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
@@ -513,12 +509,23 @@ 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");
|
||||
@@ -526,6 +533,8 @@ static int __init einj_init(void)
|
||||
return 0;
|
||||
|
||||
err_unmap:
|
||||
if (einj_param)
|
||||
iounmap(einj_param);
|
||||
apei_exec_post_unmap_gars(&ctx);
|
||||
err_release:
|
||||
apei_resources_release(&einj_resources);
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -642,7 +642,7 @@ static int __erst_write_to_storage(u64 offset)
|
||||
int rc;
|
||||
|
||||
erst_exec_ctx_init(&ctx);
|
||||
rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_WRITE);
|
||||
rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_WRITE);
|
||||
if (rc)
|
||||
return rc;
|
||||
apei_exec_ctx_set_input(&ctx, offset);
|
||||
@@ -666,7 +666,7 @@ static int __erst_write_to_storage(u64 offset)
|
||||
if (rc)
|
||||
return rc;
|
||||
val = apei_exec_ctx_get_output(&ctx);
|
||||
rc = apei_exec_run(&ctx, ACPI_ERST_END);
|
||||
rc = apei_exec_run_optional(&ctx, ACPI_ERST_END);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -681,7 +681,7 @@ static int __erst_read_from_storage(u64 record_id, u64 offset)
|
||||
int rc;
|
||||
|
||||
erst_exec_ctx_init(&ctx);
|
||||
rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_READ);
|
||||
rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_READ);
|
||||
if (rc)
|
||||
return rc;
|
||||
apei_exec_ctx_set_input(&ctx, offset);
|
||||
@@ -709,7 +709,7 @@ static int __erst_read_from_storage(u64 record_id, u64 offset)
|
||||
if (rc)
|
||||
return rc;
|
||||
val = apei_exec_ctx_get_output(&ctx);
|
||||
rc = apei_exec_run(&ctx, ACPI_ERST_END);
|
||||
rc = apei_exec_run_optional(&ctx, ACPI_ERST_END);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -724,7 +724,7 @@ static int __erst_clear_from_storage(u64 record_id)
|
||||
int rc;
|
||||
|
||||
erst_exec_ctx_init(&ctx);
|
||||
rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_CLEAR);
|
||||
rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_CLEAR);
|
||||
if (rc)
|
||||
return rc;
|
||||
apei_exec_ctx_set_input(&ctx, record_id);
|
||||
@@ -748,7 +748,7 @@ static int __erst_clear_from_storage(u64 record_id)
|
||||
if (rc)
|
||||
return rc;
|
||||
val = apei_exec_ctx_get_output(&ctx);
|
||||
rc = apei_exec_run(&ctx, ACPI_ERST_END);
|
||||
rc = apei_exec_run_optional(&ctx, ACPI_ERST_END);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
||||
Loaded 20 of 35 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user