Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: b47610296d17 ("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>

authored by

Tony Luck and committed by
Rafael J. Wysocki
0c00cfbc 1f600853

+30 -25
+30 -25
drivers/acpi/apei/einj-core.c
··· 401 401 402 402 return NULL; 403 403 } 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 + 404 414 /* 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, 406 416 u64 param1, u64 param2) 407 417 { 408 418 struct acpi_einj_trigger trigger_tab; ··· 490 480 * This will cause resource conflict with regular memory. So 491 481 * remove it from trigger table resources. 492 482 */ 493 - if ((param_extension || acpi5) && (type & MEM_ERROR_MASK) && param2) { 483 + if ((param_extension || acpi5) && is_memory_injection(type, flags)) { 494 484 struct apei_resources addr_resources; 495 485 496 486 apei_resources_init(&addr_resources); ··· 670 660 return rc; 671 661 trigger_paddr = apei_exec_ctx_get_output(&ctx); 672 662 if (notrigger == 0) { 673 - rc = __einj_error_trigger(trigger_paddr, type, param1, param2); 663 + rc = __einj_error_trigger(trigger_paddr, type, flags, param1, param2); 674 664 if (rc) 675 665 return rc; 676 666 } ··· 728 718 SETWA_FLAGS_PCIE_SBDF | SETWA_FLAGS_EINJV2))) 729 719 return -EINVAL; 730 720 731 - /* check if type is a valid EINJv2 error type */ 732 - if (is_v2) { 733 - if (!(type & available_error_type_v2)) 734 - return -EINVAL; 735 - } 736 - /* 737 - * We need extra sanity checks for memory errors. 738 - * Other types leap directly to injection. 739 - */ 740 - 741 - /* ensure param1/param2 existed */ 742 - if (!(param_extension || acpi5)) 743 - goto inject; 744 - 745 - /* ensure injection is memory related */ 746 - if (type & ACPI5_VENDOR_BIT) { 747 - if (vendor_flags != SETWA_FLAGS_MEM) 748 - goto inject; 749 - } else if (!(type & MEM_ERROR_MASK) && !(flags & SETWA_FLAGS_MEM)) { 750 - goto inject; 751 - } 752 - 753 721 /* 754 722 * Injections targeting a CXL 1.0/1.1 port have to be injected 755 723 * via the einj_cxl_rch_error_inject() path as that does the proper ··· 735 747 */ 736 748 if (einj_is_cxl_error_type(type) && (flags & SETWA_FLAGS_MEM)) 737 749 return -EINVAL; 750 + 751 + /* check if type is a valid EINJv2 error type */ 752 + if (is_v2) { 753 + if (!(type & available_error_type_v2)) 754 + return -EINVAL; 755 + } 756 + 757 + /* ensure param1/param2 existed */ 758 + if (!(param_extension || acpi5)) 759 + goto inject; 760 + 761 + /* 762 + * We need extra sanity checks for memory errors. 763 + * Other types leap directly to injection. 764 + */ 765 + if (!is_memory_injection(type, flags)) 766 + goto inject; 738 767 739 768 /* 740 769 * Disallow crazy address masks that give BIOS leeway to pick