summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-01 07:27:10 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-01 07:27:10 -0400
commit17fb56cf38195a6a8ef8ed733b1ad53e0e9dd4ae (patch)
tree739416253fb298700d05210602d587f46eca7762 /kernel
parente7c068e2e831c6c85e233578767fffe591876a88 (diff)
downloadopen-iov-17fb56cf38195a6a8ef8ed733b1ad53e0e9dd4ae.tar.gz
open-iov-17fb56cf38195a6a8ef8ed733b1ad53e0e9dd4ae.zip
gsp-phys: correct the FWSEC interface-patch size and staging logging
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_fwsec.c52
-rw-r--r--kernel/gsp_phys_vbios.c4
2 files changed, 39 insertions, 17 deletions
diff --git a/kernel/gsp_phys_fwsec.c b/kernel/gsp_phys_fwsec.c
index bf422df..c4b0424 100644
--- a/kernel/gsp_phys_fwsec.c
+++ b/kernel/gsp_phys_fwsec.c
@@ -162,7 +162,14 @@ bool gsp_phys_fwsec_dryrun_enabled(void)
#define GSP_PHYS_BOOTER_UNLOAD_MBOX 0xff
#define GSP_PHYS_BOOTER_UNLOAD_IMAGE_SIZE 0x9900
-/* Packed command structures consumed by the FWSEC ucode (little endian). */
+/*
+ * Command structures consumed by the FWSEC ucode (little endian, natural
+ * alignment). The reference's sizeof(FWSECLIC_READ_VBIOS_DESC) is 24 and
+ * sizeof(FWSECLIC_FRTS_REGION_DESC) is 20; the combined FRTS command is
+ * 24 + 20 = 44 bytes of payload rounded up to 48 by the 8-byte alignment
+ * of its u64 field, and the reference copies all 48 bytes (the last four
+ * are padding the ucode does not read).
+ */
struct gsp_phys_fwsec_read_vbios_desc {
u32 version;
u32 size;
@@ -1259,8 +1266,9 @@ int gsp_phys_fwsec_dryrun_run(struct gsp_phys_boot *boot, struct pci_dev *pdev,
frts.frts_region_desc.frts_region_media_type,
frts.read_vbios_desc.version, frts.read_vbios_desc.size,
frts.read_vbios_desc.flags);
- pr_info("gsp-phys-fwsec-dryrun: 44-byte interface-patch block at DMEM 0x%x: %*ph\n",
- cmd_off, (int)sizeof(frts), (const u8 *)u.data_va + cmd_off);
+ pr_info("gsp-phys-fwsec-dryrun: interface-patch block at DMEM 0x%x (0x%zx bytes): %*ph\n",
+ cmd_off, sizeof(frts), (int)sizeof(frts),
+ (const u8 *)u.data_va + cmd_off);
pr_info("gsp-phys-fwsec-dryrun: expected WPR2 after a real run: HI VAL nonzero; LO VAL=0x%x raw encoding=0x%08x\n",
(u32)(boot->frts_offset >> 12),
(u32)((boot->frts_offset >> 12) << 4));
@@ -1346,17 +1354,29 @@ int gsp_phys_fwsec_release(struct gsp_phys_boot *boot, struct pci_dev *pdev,
* ABI shape checks for the FWSEC structures and the embedded bindata. These
* must match the generations the boot path was derived for; a mismatch means
* the structures or the extracted images changed, which must not be ignored.
+ *
+ * File-scope static_assert()s on purpose: BUILD_BUG_ON() inside an unused
+ * static function is discarded before the compiler checks it, so it would
+ * silently pass no matter what the sizes are. The FRTS command is the
+ * reference's 44-byte payload plus its 4-byte tail padding = 48, which is
+ * exactly what s_vbiosPatchInterfaceData copies.
*/
-static void __maybe_unused gsp_phys_fwsec_abi_check(void)
-{
- BUILD_BUG_ON(sizeof(struct gsp_phys_fwsec_read_vbios_desc) != 24);
- BUILD_BUG_ON(sizeof(struct gsp_phys_fwsec_frts_region_desc) != 20);
- BUILD_BUG_ON(sizeof(struct gsp_phys_fwsec_frts_cmd) != 44);
- BUILD_BUG_ON(sizeof(struct gsp_phys_fwsec_bl_dmem_desc) != 84);
- BUILD_BUG_ON(sizeof(struct gsp_phys_fwsec_intf_header) != 4);
- BUILD_BUG_ON(sizeof(struct gsp_phys_fwsec_intf_entry) != 8);
- BUILD_BUG_ON(sizeof(gsp_phys_sec2_bl_image) != 0x300);
- BUILD_BUG_ON(GSP_PHYS_SEC2_BL_CODE_SIZE != 0x200);
- BUILD_BUG_ON(sizeof(gsp_phys_booter_unload_image) !=
- GSP_PHYS_BOOTER_UNLOAD_IMAGE_SIZE);
-}
+static_assert(sizeof(struct gsp_phys_fwsec_read_vbios_desc) == 24,
+ "FWSEC readVbiosDesc must be 24 bytes (reference ABI)");
+static_assert(sizeof(struct gsp_phys_fwsec_frts_region_desc) == 20,
+ "FWSEC frtsRegionDesc must be 20 bytes (reference ABI)");
+static_assert(sizeof(struct gsp_phys_fwsec_frts_cmd) == 48,
+ "FWSEC frtsCmd must be 48 bytes: 44 payload + 4 tail padding (reference ABI)");
+static_assert(sizeof(struct gsp_phys_fwsec_bl_dmem_desc) == 84,
+ "FWSEC BL DMEM descriptor must be 84 bytes (reference ABI)");
+static_assert(sizeof(struct gsp_phys_fwsec_intf_header) == 4,
+ "FWSEC interface header must be 4 bytes (reference ABI)");
+static_assert(sizeof(struct gsp_phys_fwsec_intf_entry) == 8,
+ "FWSEC interface entry must be 8 bytes (reference ABI)");
+static_assert(sizeof(gsp_phys_sec2_bl_image) == 0x300,
+ "generic SEC2 BL bindata image must be 0x300 bytes");
+static_assert(GSP_PHYS_SEC2_BL_CODE_SIZE == 0x200,
+ "generic SEC2 BL code section must be 0x200 bytes");
+static_assert(sizeof(gsp_phys_booter_unload_image) ==
+ GSP_PHYS_BOOTER_UNLOAD_IMAGE_SIZE,
+ "Booter-Unload bindata image must match its header size");
diff --git a/kernel/gsp_phys_vbios.c b/kernel/gsp_phys_vbios.c
index 33fb389..50b17df 100644
--- a/kernel/gsp_phys_vbios.c
+++ b/kernel/gsp_phys_vbios.c
@@ -719,8 +719,10 @@ int gsp_phys_vbios_parse_fwsec(struct gsp_phys_vbios *img,
if (gsp_phys_img_read(img, data_ptr, 4,
&binver) &&
gsp_phys_img_read(img, data_ptr + 4, 1,
- &oem))
+ &oem)) {
version = ((u64)binver << 8) | oem;
+ img->version = version;
+ }
}
if (token_id != GSP_PHYS_BIT_TOKEN_FALCON_DATA ||