mirror of
https://github.com/torvalds/linux.git
synced 2024-12-24 20:01:55 +00:00
Add more flexibility to debugfs i/f to error injection (EINJ)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJSsOjTAAoJEKurIx+X31iBaJIP/jCM0wZBAxKTSVWIqDAY1Ey+ eYSIpq+X+t/Mfi9MZ0+BAFhsGPg3rJf04pc73E7GNnq0Cq/ROGHGaruRRnubhW7u c/jEFeuwFdD++82r+VnhuTngUN+l527tjRvv/ZrgfLu5ZPjtoHypb76L63Y1UvIB HgIPePuzR1mc7wFoU0lsBzRaGQQwBMUWrLiU0sH4La496VlSi/OINa8/EVRBfqCK xlrnOHRG2SHyxmplntBAIS1kikl8tESRbmOgVZYAAtK/S2RxOSMJT22MVh199Cnb xo6ytpf1VlTwL+/gxLm0tnn03K48NoTNyPlyfazldFEZKKcUwdb6ZpYTux5EdBQd HrDLQxKzC40DntX3fnxDF936JwnewD4q9IE2tqOne+T36xXjuZNahSDnaXwIW6Kh nAKOhm9cRvogaGUp//Ehxk4Tou0Vl/To47FKOHOMLmgTxJS7ttKb9yYCQovYLAsP 6JTbvRsQGZJK1pgPaY3gr13KAGDmUKKPXtNfo4170QKN60i8iTOPfAx+hvjHZ1fA 4NYchPIVMrJLwz6hEsKlJ8oD8qj3ByjbjYPTqQYp/oBhccd0e+c51H3F1vxLg64z 9xsXcfCF1n0k0EpAIvThJCqCvW1mnfP98r+fPOyT/y+BqrSZQ9K4yyhrk0Gbsf7B CBp83ag4spimjdCeV0Ao =4pTC -----END PGP SIGNATURE----- Merge tag 'please-pull-einj' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras into x86/ras Pull error injection update from Tony Luck: * Add more flexibility to the error injection (EINJ) debugfs interface Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
cc131eef1c
@ -45,11 +45,22 @@ directory apei/einj. The following files are provided.
|
||||
injection. Before this, please specify all necessary error
|
||||
parameters.
|
||||
|
||||
- flags
|
||||
Present for kernel version 3.13 and above. Used to specify which
|
||||
of param{1..4} are valid and should be used by BIOS during injection.
|
||||
Value is a bitmask as specified in ACPI5.0 spec for the
|
||||
SET_ERROR_TYPE_WITH_ADDRESS data structure:
|
||||
Bit 0 - Processor APIC field valid (see param3 below)
|
||||
Bit 1 - Memory address and mask valid (param1 and param2)
|
||||
Bit 2 - PCIe (seg,bus,dev,fn) valid (param4 below)
|
||||
If set to zero, legacy behaviour is used where the type of injection
|
||||
specifies just one bit set, and param1 is multiplexed.
|
||||
|
||||
- param1
|
||||
This file is used to set the first error parameter value. Effect of
|
||||
parameter depends on error_type specified. For example, if error
|
||||
type is memory related type, the param1 should be a valid physical
|
||||
memory address.
|
||||
memory address. [Unless "flag" is set - see above]
|
||||
|
||||
- param2
|
||||
This file is used to set the second error parameter value. Effect of
|
||||
@ -58,6 +69,12 @@ directory apei/einj. The following files are provided.
|
||||
address mask. Linux requires page or narrower granularity, say,
|
||||
0xfffffffffffff000.
|
||||
|
||||
- param3
|
||||
Used when the 0x1 bit is set in "flag" to specify the APIC id
|
||||
|
||||
- param4
|
||||
Used when the 0x4 bit is set in "flag" to specify target PCIe device
|
||||
|
||||
- notrigger
|
||||
The EINJ mechanism is a two step process. First inject the error, then
|
||||
perform some actions to trigger it. Setting "notrigger" to 1 skips the
|
||||
|
@ -416,7 +416,8 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __einj_error_inject(u32 type, u64 param1, u64 param2)
|
||||
static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
|
||||
u64 param3, u64 param4)
|
||||
{
|
||||
struct apei_exec_context ctx;
|
||||
u64 val, trigger_paddr, timeout = FIRMWARE_TIMEOUT;
|
||||
@ -446,6 +447,12 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
|
||||
break;
|
||||
}
|
||||
v5param->flags = vendor_flags;
|
||||
} else if (flags) {
|
||||
v5param->flags = flags;
|
||||
v5param->memory_address = param1;
|
||||
v5param->memory_address_range = param2;
|
||||
v5param->apicid = param3;
|
||||
v5param->pcie_sbdf = param4;
|
||||
} else {
|
||||
switch (type) {
|
||||
case ACPI_EINJ_PROCESSOR_CORRECTABLE:
|
||||
@ -514,11 +521,17 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
|
||||
}
|
||||
|
||||
/* Inject the specified hardware error */
|
||||
static int einj_error_inject(u32 type, u64 param1, u64 param2)
|
||||
static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
|
||||
u64 param3, u64 param4)
|
||||
{
|
||||
int rc;
|
||||
unsigned long pfn;
|
||||
|
||||
/* If user manually set "flags", make sure it is legal */
|
||||
if (flags && (flags &
|
||||
~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF)))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* We need extra sanity checks for memory errors.
|
||||
* Other types leap directly to injection.
|
||||
@ -532,7 +545,7 @@ static int einj_error_inject(u32 type, u64 param1, u64 param2)
|
||||
if (type & ACPI5_VENDOR_BIT) {
|
||||
if (vendor_flags != SETWA_FLAGS_MEM)
|
||||
goto inject;
|
||||
} else if (!(type & MEM_ERROR_MASK))
|
||||
} else if (!(type & MEM_ERROR_MASK) && !(flags & SETWA_FLAGS_MEM))
|
||||
goto inject;
|
||||
|
||||
/*
|
||||
@ -546,15 +559,18 @@ static int einj_error_inject(u32 type, u64 param1, u64 param2)
|
||||
|
||||
inject:
|
||||
mutex_lock(&einj_mutex);
|
||||
rc = __einj_error_inject(type, param1, param2);
|
||||
rc = __einj_error_inject(type, flags, param1, param2, param3, param4);
|
||||
mutex_unlock(&einj_mutex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static u32 error_type;
|
||||
static u32 error_flags;
|
||||
static u64 error_param1;
|
||||
static u64 error_param2;
|
||||
static u64 error_param3;
|
||||
static u64 error_param4;
|
||||
static struct dentry *einj_debug_dir;
|
||||
|
||||
static int available_error_type_show(struct seq_file *m, void *v)
|
||||
@ -648,7 +664,8 @@ static int error_inject_set(void *data, u64 val)
|
||||
if (!error_type)
|
||||
return -EINVAL;
|
||||
|
||||
return einj_error_inject(error_type, error_param1, error_param2);
|
||||
return einj_error_inject(error_type, error_flags, error_param1, error_param2,
|
||||
error_param3, error_param4);
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL,
|
||||
@ -729,6 +746,10 @@ static int __init einj_init(void)
|
||||
rc = -ENOMEM;
|
||||
einj_param = einj_get_parameter_address();
|
||||
if ((param_extension || acpi5) && einj_param) {
|
||||
fentry = debugfs_create_x32("flags", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &error_flags);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &error_param1);
|
||||
if (!fentry)
|
||||
@ -737,6 +758,14 @@ static int __init einj_init(void)
|
||||
einj_debug_dir, &error_param2);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
fentry = debugfs_create_x64("param3", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &error_param3);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
fentry = debugfs_create_x64("param4", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &error_param4);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
|
||||
fentry = debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, ¬rigger);
|
||||
|
Loading…
Reference in New Issue
Block a user