]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RAS/AMD/ATL: Require PRM support for future systems
authorYazen Ghannam <yazen.ghannam@amd.com>
Fri, 17 Oct 2025 13:26:29 +0000 (13:26 +0000)
committerBorislav Petkov (AMD) <bp@alien8.de>
Mon, 27 Oct 2025 18:56:41 +0000 (19:56 +0100)
Currently, the AMD Address Translation Library will fail to load for new,
unrecognized systems (based on Data Fabric revision). The intention is to
prevent the code from executing on new systems and returning incorrect
results.

Recent AMD systems, however, may provide UEFI PRM handlers for address
translation. This is code provided by the platform through BIOS tables.  These
are the preferred method for translation, and the Linux native code can be
used as a fallback.

Future AMD systems are expected to provide PRM handlers by default. And Linux
native code will not be used.

Adjust the ATL init code so that new, unrecognized systems will default to
using PRM handlers only.

Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: "Mario Limonciello (AMD)" <superm1@kernel.org>
Link: https://patch.msgid.link/all/20251017-wip-atl-prm-v2-2-7ab1df4a5fbc@amd.com
drivers/ras/amd/atl/internal.h
drivers/ras/amd/atl/prm.c
drivers/ras/amd/atl/system.c
drivers/ras/amd/atl/umc.c

index 2b6279d32774ac7040e1be79d55446ca3028283a..82a56d9c2be1531c920f7fe9a6a179c6d68ef69a 100644 (file)
@@ -138,7 +138,8 @@ struct df_flags {
        __u8    legacy_ficaa            : 1,
                socket_id_shift_quirk   : 1,
                heterogeneous           : 1,
-               __reserved_0            : 5;
+               prm_only                : 1,
+               __reserved_0            : 4;
 };
 
 struct df_config {
@@ -283,6 +284,9 @@ unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err);
 u64 add_base_and_hole(struct addr_ctx *ctx, u64 addr);
 u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr);
 
+/* GUIDs for PRM handlers */
+extern const guid_t norm_to_sys_guid;
+
 #ifdef CONFIG_AMD_ATL_PRM
 unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 umc_bank_inst_id, unsigned long addr);
 #else
index 0931a20d213b61be748007659e6de28745c0105a..0f9bfa96e16a4b7838bada99902ceb8e61e570ae 100644 (file)
@@ -29,10 +29,6 @@ struct norm_to_sys_param_buf {
        void *out_buf;
 } __packed;
 
-static const guid_t norm_to_sys_guid = GUID_INIT(0xE7180659, 0xA65D, 0x451D,
-                                                0x92, 0xCD, 0x2B, 0x56, 0xF1,
-                                                0x2B, 0xEB, 0xA6);
-
 unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
 {
        struct norm_to_sys_param_buf p_buf;
index 099841433cf929299d484d1f0e95425459b480d5..812a30e21d3ad0321d5b80c9f31fbae233d82d18 100644 (file)
 
 #include "internal.h"
 
+#include <linux/prmt.h>
+
+const guid_t norm_to_sys_guid = GUID_INIT(0xE7180659, 0xA65D, 0x451D,
+                                         0x92, 0xCD, 0x2B, 0x56, 0xF1,
+                                         0x2B, 0xEB, 0xA6);
+
 int determine_node_id(struct addr_ctx *ctx, u8 socket_id, u8 die_id)
 {
        u16 socket_id_bits, die_id_bits;
@@ -212,15 +218,17 @@ static int determine_df_rev(void)
        if (!rev)
                return determine_df_rev_legacy();
 
-       /*
-        * Fail out for major revisions other than '4'.
-        *
-        * Explicit support should be added for newer systems to avoid issues.
-        */
        if (rev == 4)
                return df4_determine_df_rev(reg);
 
-       return -EINVAL;
+       /* All other systems should have PRM handlers. */
+       if (!acpi_prm_handler_available(&norm_to_sys_guid)) {
+               pr_debug("PRM not available\n");
+               return -ENODEV;
+       }
+
+       df_cfg.flags.prm_only = true;
+       return 0;
 }
 
 static int get_dram_hole_base(void)
@@ -297,6 +305,9 @@ int get_df_system_info(void)
                return ret;
        }
 
+       if (df_cfg.flags.prm_only)
+               return 0;
+
        apply_node_id_shift();
 
        get_num_maps();
index 6e072b7667e98b73956413acbc85e75db1f4ddc2..18ce419236a5d46c8b3880223e5cf8611ae7380b 100644 (file)
@@ -422,7 +422,7 @@ unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
                 socket_id, die_id, coh_st_inst_id, addr);
 
        ret_addr = prm_umc_norm_to_sys_addr(socket_id, err->ipid, addr);
-       if (!IS_ERR_VALUE(ret_addr))
+       if (!IS_ERR_VALUE(ret_addr) || df_cfg.flags.prm_only)
                return ret_addr;
 
        return norm_to_sys_addr(socket_id, die_id, coh_st_inst_id, addr);