diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-01 01:06:14 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-01 01:06:14 -0400 |
| commit | b9264c40ad9f27f31176a9f8fe718196abde1800 (patch) | |
| tree | 9739d73b3b4fc6fcb1dd1a8638e1c23f92df3c4e /kernel/gsp_phys_gpu.c | |
| parent | 8065d67e9a7e2f22490406755e4df429b89136d0 (diff) | |
| download | open-iov-b9264c40ad9f27f31176a9f8fe718196abde1800.tar.gz open-iov-b9264c40ad9f27f31176a9f8fe718196abde1800.zip | |
gsp-phys: stage 3c FWSEC via VBIOS BIT image plus failure recovery
Diffstat (limited to 'kernel/gsp_phys_gpu.c')
| -rw-r--r-- | kernel/gsp_phys_gpu.c | 62 |
1 files changed, 56 insertions, 6 deletions
diff --git a/kernel/gsp_phys_gpu.c b/kernel/gsp_phys_gpu.c index a0f564f..a7c8e57 100644 --- a/kernel/gsp_phys_gpu.c +++ b/kernel/gsp_phys_gpu.c @@ -61,6 +61,7 @@ #include "gsp_phys_gpu.h" #include "gsp_phys_boot.h" +#include "gsp_phys_fwsec.h" #define GSP_PHYS_VENDOR 0x10de #define GSP_PHYS_DEVICE 0x1ed3 @@ -695,11 +696,24 @@ int gsp_phys_gpu_claim(void) } else { pr_info("gsp-phys: real GSP firmware staged (backend rung 2)\n"); - if (gsp_phys_layout_enabled() && - gsp_phys_boot_layout_init(&phys.boot, phys.pdev, phys.bar0, - phys.fw_image_size, phys.bar1_len)) - pr_warn("gsp-phys: boot layout/allocation failed; " - "backend stays at rung 2\n"); + if (gsp_phys_layout_enabled()) { + if (gsp_phys_boot_layout_init(&phys.boot, phys.pdev, + phys.bar0, + phys.fw_image_size, + phys.bar1_len)) { + pr_warn("gsp-phys: boot layout/allocation failed; " + "backend stays at rung 2\n"); + } else if (gsp_phys_fwsec_enabled()) { + if (gsp_phys_fwsec_run(&phys.boot, phys.pdev, + phys.bar0)) + pr_warn("gsp-phys: stage 3c FWSEC failed " + "(see recovery log above)\n"); + else + pr_info("gsp-phys: stage 3c FWSEC complete " + "(WPR2 up; release will tear it " + "down)\n"); + } + } } return 0; @@ -731,11 +745,30 @@ void gsp_phys_gpu_release(void) { struct pci_dev *pdev; struct device_driver *drv; - int ret; + int ret, wpr2_ret = 0; if (!phys.drv_registered && !phys.claimed && !phys.nr_locks) return; + /* + * WPR2 teardown must run while this module still owns BAR0. A + * successful stage 3c leaves WPR2 carved in FB; the distribution + * driver refuses to boot against an unexpected WPR2, so it has to be + * removed (FWSEC-SB + booter unload) before the hand-back. If the + * board stopped answering, skip the teardown (writes to a dead + * device are pointless) and let the fail-safe below refuse the + * hand-back. + */ + if (phys.pdev) { + if (gsp_phys_board_check(phys.pdev, "before WPR2 teardown")) { + wpr2_ret = -EIO; + } else { + wpr2_ret = gsp_phys_fwsec_release(&phys.boot, + phys.pdev, + phys.bar0); + } + } + if (phys.pdev) gsp_phys_boot_layout_fini(&phys.boot, phys.pdev); @@ -751,6 +784,23 @@ void gsp_phys_gpu_release(void) if (pdev) { /* + * Fail-safe: a WPR2 that survived the teardown makes the + * distribution driver's boot path fail (or worse), so never + * hand the device back in that state. Keep the D0 locks and + * the runtime-PM reference, as with the unresponsive-board + * abort. + */ + if (wpr2_ret) { + pr_err("gsp-phys: NOT rebinding %s: WPR2 teardown did not complete (WPR2 still up or board unresponsive); do not boot the distribution driver against it; power domain stays LOCKED (reboot with approval; do not retry in this boot)\n", + pci_name(pdev)); + if (phys.runtime_ref_held) + pr_debug("gsp-phys: keeping the runtime-PM reference on %s held (WPR2 still up)\n", + pci_name(pdev)); + pci_dev_put(pdev); + return; + } + + /* * Abort signal before handing the GPU back: if the board no * longer answers config reads, do not run the distribution * driver's power-up path. Keep the D0 locks so that a |
