Skip to content

Commit 0c00cfb

Browse files
aeglrafaeljw
authored andcommitted
ACPI: APEI: EINJ: Fix EINJV2 memory error injection
Error types in EINJV2 use different bit positions for each flavor of injection from legacy EINJ. Two issues: 1) The address sanity checks in einj_error_inject() were skipped for EINJV2 injections. Noted by sashiko[1] 2) __einj_error_trigger() failed to drop the entry of the target physical address from the list of resources that need to be requested. Add a helper function that checks if an injection is to memory and use it to solve each of these issues. Note that the old test in __einj_error_trigger() checked that param2 was not zero. This isn't needed because the sanity checks in einj_error_inject() reject memory injections with param2 == 0. Fixes: b476102 ("ACPI: APEI: EINJ: Enable EINJv2 error injections") Reported-by: sashiko <sashiko@sashiko.dev> Reported-by: Herman Li <herman.li@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com> Tested-by: "Lai, Yi1" <yi1.lai@intel.com> Link: https://sashiko.dev/#/patchset/20260415163620.12957-1-tony.luck%40intel.com # [1] Reviewed-by: Jiaqi Yan <jiaqiyan@google.com> Reviewed-by: Zaid Alali <zaidal@os.amperecomputing.com> Link: https://patch.msgid.link/20260421150216.11666-3-tony.luck@intel.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 1f60085 commit 0c00cfb

1 file changed

Lines changed: 25 additions & 20 deletions

File tree

drivers/acpi/apei/einj-core.c

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,18 @@ static struct acpi_generic_address *einj_get_trigger_parameter_region(
401401

402402
return NULL;
403403
}
404+
405+
static bool is_memory_injection(u32 type, u32 flags)
406+
{
407+
if (flags & SETWA_FLAGS_EINJV2)
408+
return !!(type & ACPI_EINJV2_MEMORY);
409+
if (type & ACPI5_VENDOR_BIT)
410+
return !!(vendor_flags & SETWA_FLAGS_MEM);
411+
return !!(type & MEM_ERROR_MASK) || !!(flags & SETWA_FLAGS_MEM);
412+
}
413+
404414
/* Execute instructions in trigger error action table */
405-
static int __einj_error_trigger(u64 trigger_paddr, u32 type,
415+
static int __einj_error_trigger(u64 trigger_paddr, u32 type, u32 flags,
406416
u64 param1, u64 param2)
407417
{
408418
struct acpi_einj_trigger trigger_tab;
@@ -480,7 +490,7 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
480490
* This will cause resource conflict with regular memory. So
481491
* remove it from trigger table resources.
482492
*/
483-
if ((param_extension || acpi5) && (type & MEM_ERROR_MASK) && param2) {
493+
if ((param_extension || acpi5) && is_memory_injection(type, flags)) {
484494
struct apei_resources addr_resources;
485495

486496
apei_resources_init(&addr_resources);
@@ -660,7 +670,7 @@ static int __einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
660670
return rc;
661671
trigger_paddr = apei_exec_ctx_get_output(&ctx);
662672
if (notrigger == 0) {
663-
rc = __einj_error_trigger(trigger_paddr, type, param1, param2);
673+
rc = __einj_error_trigger(trigger_paddr, type, flags, param1, param2);
664674
if (rc)
665675
return rc;
666676
}
@@ -718,35 +728,30 @@ int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, u64 param3,
718728
SETWA_FLAGS_PCIE_SBDF | SETWA_FLAGS_EINJV2)))
719729
return -EINVAL;
720730

731+
/*
732+
* Injections targeting a CXL 1.0/1.1 port have to be injected
733+
* via the einj_cxl_rch_error_inject() path as that does the proper
734+
* validation of the given RCRB base (MMIO) address.
735+
*/
736+
if (einj_is_cxl_error_type(type) && (flags & SETWA_FLAGS_MEM))
737+
return -EINVAL;
738+
721739
/* check if type is a valid EINJv2 error type */
722740
if (is_v2) {
723741
if (!(type & available_error_type_v2))
724742
return -EINVAL;
725743
}
726-
/*
727-
* We need extra sanity checks for memory errors.
728-
* Other types leap directly to injection.
729-
*/
730744

731745
/* ensure param1/param2 existed */
732746
if (!(param_extension || acpi5))
733747
goto inject;
734748

735-
/* ensure injection is memory related */
736-
if (type & ACPI5_VENDOR_BIT) {
737-
if (vendor_flags != SETWA_FLAGS_MEM)
738-
goto inject;
739-
} else if (!(type & MEM_ERROR_MASK) && !(flags & SETWA_FLAGS_MEM)) {
740-
goto inject;
741-
}
742-
743749
/*
744-
* Injections targeting a CXL 1.0/1.1 port have to be injected
745-
* via the einj_cxl_rch_error_inject() path as that does the proper
746-
* validation of the given RCRB base (MMIO) address.
750+
* We need extra sanity checks for memory errors.
751+
* Other types leap directly to injection.
747752
*/
748-
if (einj_is_cxl_error_type(type) && (flags & SETWA_FLAGS_MEM))
749-
return -EINVAL;
753+
if (!is_memory_injection(type, flags))
754+
goto inject;
750755

751756
/*
752757
* Disallow crazy address masks that give BIOS leeway to pick

0 commit comments

Comments
 (0)