summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-05 16:04:33 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-05 16:04:33 -0400
commit7c1fceb5654cda3628531214934b93e96a507700 (patch)
tree3b04c1db569cdbaad065eff242ff47c7e6fdcd89 /kernel/gsp_phys_booter.c
parent9554ca1f344192e27bdc58e5b9ab1bd795e3be32 (diff)
downloadopen-iov-7c1fceb5654cda3628531214934b93e96a507700.tar.gz
open-iov-7c1fceb5654cda3628531214934b93e96a507700.zip
vgsp: FWCLIENT entry-selection mask and golden-replay hardening
- gsp_phys_rmcall_fwclient_mask (default 0x3f): per-entry selection for the mode-24 FWCLIENT promote set; bit6 selects the MAIN UVM VA-only shape. - golden replay: tolerate the client-local system-memory PB step and continue with hObjectBuffer=0; on-ladder TURING_A 3D object retained best-effort. Live bisection on the KMD channel: MAIN alone reaches the per-buffer commit and stops at the engine-context memdesc state; PM-only and PATCH-only are accepted; any multi-entry control containing MAIN is refused 0x1f. All cycles release clean.
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c115
1 files changed, 75 insertions, 40 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index e434910..b985541 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -7693,6 +7693,7 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
struct gsp_phys_rmcall_channel_params ch;
struct gsp_phys_rmcall_mem_obj_shape shape;
u32 rpc = 0, status = 0;
+ bool pb_ok = true;
int ret;
/* 1. Golden VAS: PTETABLE_HEAP_MANAGED only (kernel_graphics.c:2194-2200). */
@@ -7725,17 +7726,25 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
shape.attr = GSP_PHYS_RMCALL_OS32_ATTR_PCI;
shape.attr2 = GSP_PHYS_RMCALL_OS32_ATTR2_PROT_UNPROTECTED;
ret = gsp_phys_rmcall_golden_mem(bar0, &shape, "PB physical");
- if (ret)
- return ret;
+ if (ret) {
+ pr_warn("vgsp-boot: rm-call: GOLDEN PB physical unavailable (%d); continuing the golden replay with hObjectBuffer=0 (system memory is client-local on GSP; the class-0x3e server alloc is not available)\n",
+ ret);
+ pb_ok = false;
+ }
/* 3. Its virtual mapping on the golden VAS (kernel_graphics.c:2224-2235). */
- shape.handle = GSP_PHYS_RMCALL_HANDLE_GOLDEN_PB_VIRT;
- shape.h_class = GSP_PHYS_RMCALL_CLASS_MEMORY_VIRTUAL_50;
- shape.flags = GSP_PHYS_RMCALL_OS32_FLAG_VIRTUAL;
- shape.h_va_space = GSP_PHYS_RMCALL_HANDLE_GOLDEN_VAS;
- ret = gsp_phys_rmcall_golden_mem(bar0, &shape, "PB virtual");
- if (ret)
- return ret;
+ if (pb_ok) {
+ shape.handle = GSP_PHYS_RMCALL_HANDLE_GOLDEN_PB_VIRT;
+ shape.h_class = GSP_PHYS_RMCALL_CLASS_MEMORY_VIRTUAL_50;
+ shape.flags = GSP_PHYS_RMCALL_OS32_FLAG_VIRTUAL;
+ shape.h_va_space = GSP_PHYS_RMCALL_HANDLE_GOLDEN_VAS;
+ ret = gsp_phys_rmcall_golden_mem(bar0, &shape, "PB virtual");
+ if (ret) {
+ pr_warn("vgsp-boot: rm-call: GOLDEN PB virtual unavailable (%d); continuing with hObjectBuffer=0\n",
+ ret);
+ pb_ok = false;
+ }
+ }
/* 4. Client USERD, internal reserved-heap VIDMEM (kernel_graphics.c:2237-2313). */
shape.handle = GSP_PHYS_RMCALL_HANDLE_GOLDEN_USERD;
@@ -7757,7 +7766,8 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
*/
memset(&ch, 0, sizeof(ch));
ch.h_va_space = cpu_to_le32(GSP_PHYS_RMCALL_HANDLE_GOLDEN_VAS);
- ch.h_object_buffer = cpu_to_le32(GSP_PHYS_RMCALL_HANDLE_GOLDEN_PB_VIRT);
+ ch.h_object_buffer = cpu_to_le32(pb_ok ?
+ GSP_PHYS_RMCALL_HANDLE_GOLDEN_PB_VIRT : 0);
ch.gp_fifo_entries =
cpu_to_le32(GSP_PHYS_RMCALL_GOLDEN_GPFIFO_ENTRIES);
ch.gp_fifo_offset = cpu_to_le64(0);
@@ -9417,34 +9427,57 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
*/
u32 attr = GSP_PHYS_RMCALL_GR_CTX_PHYS_ATTR;
u64 bk = GSP_PHYS_RMCALL_VA_GR_CTX + 0x400000ULL;
+ u32 mask = gsp_phys_rmcall_fwclient_mask_value();
u32 n = 0;
+ pr_info("vgsp-boot: rm-call: PROMOTE_CTX fwclient: entry mask=0x%x (bit0 MAIN, bit1 PM, bit2 PATCH, bit3 FECS_EVENT, bit4 PRIV_ACCESS_MAP, bit5 UNRESTRICTED_PRIV_ACCESS_MAP)\n",
+ mask);
+
/*
* PATCH is always present in the reference set; a failed
- * prepare aborts before any control is sent.
+ * prepare aborts before any control is sent. The mask (mode-24
+ * bisection) may deselect it without preparing.
*/
- ret = gsp_phys_rmcall_gr_patch_prepare(bar0);
- if (ret) {
- pr_err("vgsp-boot: rm-call: PROMOTE_CTX fwclient aborted: PATCH prepare failed (%d); the reference set always carries PATCH, so no promote is sent and the ladder aborts with no retry\n",
- ret);
- kvfree(p);
- return ret;
+ if (mask & BIT(2)) {
+ ret = gsp_phys_rmcall_gr_patch_prepare(bar0);
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: PROMOTE_CTX fwclient aborted: PATCH prepare failed (%d); the reference set always carries PATCH, so no promote is sent and the ladder aborts with no retry\n",
+ ret);
+ kvfree(p);
+ return ret;
+ }
}
if (gsp_phys_rmcall_gr_pm_prepare(bar0))
pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: PM prepare failed; omitting the PM entry and continuing (mode 24 treats PM as best-effort; the reference set pre-allocates it for an externally-owned VAS)\n");
gsp_phys_rmcall_gr_fwclient_small_prepare();
/* Entry 0: MAIN - combined PA+VA, PDB-mapped ctx VA. */
- gsp_phys_rmcall_promote_entry_fill(p, n,
- GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_MAIN,
- boot_stage.rmcall_ctx_pa, boot_stage.rmcall_ctx_va,
- boot_stage.rmcall_ctx_size, attr, 1, 0);
- gsp_phys_rmcall_gr_promote_log_entry(n, &p->entry[n],
- "combined (PDB-mapped ctx VA)");
- n++;
+ if (mask & BIT(0)) {
+ if (mask & BIT(6)) {
+ gsp_phys_rmcall_promote_entry_fill(p, n,
+ GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_MAIN,
+ 0, boot_stage.rmcall_ctx_va, 0, 0,
+ 0, 0);
+ gsp_phys_rmcall_gr_promote_log_entry(n,
+ &p->entry[n],
+ "VA-only (UVM shape, mask bit6)");
+ } else {
+ gsp_phys_rmcall_promote_entry_fill(p, n,
+ GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_MAIN,
+ boot_stage.rmcall_ctx_pa,
+ boot_stage.rmcall_ctx_va,
+ boot_stage.rmcall_ctx_size, attr, 1, 0);
+ gsp_phys_rmcall_gr_promote_log_entry(n,
+ &p->entry[n],
+ "combined (PDB-mapped ctx VA)");
+ }
+ n++;
+ } else {
+ pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: MAIN omitted by mask\n");
+ }
/* Entry 1: PM - init-only, no PM VA source in the ladder. */
- if (boot_stage.rmcall_pm_prepared &&
+ if ((mask & BIT(1)) && boot_stage.rmcall_pm_prepared &&
boot_stage.rmcall_pm_pa && boot_stage.rmcall_pm_size) {
gsp_phys_rmcall_promote_entry_fill(p, n,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PM,
@@ -9453,22 +9486,24 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
gsp_phys_rmcall_gr_promote_log_entry(n, &p->entry[n],
"init-only, no PM VA source (reference external-VAS shape)");
n++;
- } else {
+ } else if (mask & BIT(1)) {
pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: PM omitted (no queried buffer; the reference external-VAS client pre-allocates it)\n");
}
/* Entry 2: PATCH - combined, booking-only VA. */
- gsp_phys_rmcall_promote_entry_fill(p, n,
- GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PATCH,
- boot_stage.rmcall_patch_pa,
- GSP_PHYS_RMCALL_VA_GR_PATCH,
- boot_stage.rmcall_patch_size, attr, 1, 0);
- gsp_phys_rmcall_gr_promote_log_entry(n, &p->entry[n],
- "combined (booking-only VA, not PDB-mapped)");
- n++;
+ if (mask & BIT(2)) {
+ gsp_phys_rmcall_promote_entry_fill(p, n,
+ GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PATCH,
+ boot_stage.rmcall_patch_pa,
+ GSP_PHYS_RMCALL_VA_GR_PATCH,
+ boot_stage.rmcall_patch_size, attr, 1, 0);
+ gsp_phys_rmcall_gr_promote_log_entry(n, &p->entry[n],
+ "combined (booking-only VA, not PDB-mapped)");
+ n++;
+ }
/* Entry 3: FECS_EVENT - combined, booking-only VA. */
- if (boot_stage.rmcall_fecs_pa) {
+ if ((mask & BIT(3)) && boot_stage.rmcall_fecs_pa) {
gsp_phys_rmcall_promote_entry_fill(p, n,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_FECS_EVENT,
boot_stage.rmcall_fecs_pa, bk + 0x6000ULL,
@@ -9476,12 +9511,12 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
gsp_phys_rmcall_gr_promote_log_entry(n, &p->entry[n],
"combined (booking-only VA, not PDB-mapped)");
n++;
- } else {
+ } else if (mask & BIT(3)) {
pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: FECS_EVENT omitted (allocation unavailable)\n");
}
/* Entry 4: PRIV_ACCESS_MAP - init-only, captured stock shape. */
- if (boot_stage.rmcall_priv_pa) {
+ if ((mask & BIT(4)) && boot_stage.rmcall_priv_pa) {
gsp_phys_rmcall_promote_entry_fill(p, n,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PRIV_MAP,
boot_stage.rmcall_priv_pa, 0, 0x1000u, attr,
@@ -9489,12 +9524,12 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
gsp_phys_rmcall_gr_promote_log_entry(n, &p->entry[n],
"init-only (captured stock shape; sysmem attr 0x6, reference FB uncached 0x4)");
n++;
- } else {
+ } else if (mask & BIT(4)) {
pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: PRIV_ACCESS_MAP omitted (allocation unavailable)\n");
}
/* Entry 5: UNRESTRICTED_PRIV_ACCESS_MAP - combined. */
- if (boot_stage.rmcall_unrestricted_pa) {
+ if ((mask & BIT(5)) && boot_stage.rmcall_unrestricted_pa) {
gsp_phys_rmcall_promote_entry_fill(p, n,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_UNR_PRIV_MAP,
boot_stage.rmcall_unrestricted_pa,
@@ -9502,7 +9537,7 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
gsp_phys_rmcall_gr_promote_log_entry(n, &p->entry[n],
"combined (booking-only VA, not PDB-mapped)");
n++;
- } else {
+ } else if (mask & BIT(5)) {
pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: UNRESTRICTED_PRIV_ACCESS_MAP omitted (allocation unavailable)\n");
}