summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 11:46:14 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 11:46:14 -0400
commitb6a60cd1c7e188325c7b2e0c1ceb7e86ad5e9e74 (patch)
tree8fe71d17244953695d161982527c0b3010ce004c
parentebe1ed7717e55e5372d90ea56711d4073b5c9cd4 (diff)
downloadopen-iov-b6a60cd1c7e188325c7b2e0c1ceb7e86ad5e9e74.tar.gz
open-iov-b6a60cd1c7e188325c7b2e0c1ceb7e86ad5e9e74.zip
vgsp: m86 - gsp-phys-gr-override SASS injection into the forwarded launch's program page
debugfs gsp-phys-gr-override (write-only, <= 1 page) stores bytes that the forwarded launch places at the QMD's program offset inside the shadowed program page, before any relocation. Intended use: a hand-assembled minimal SM75 kernel (MOV R1, c[0x0][0x28]; EXIT) to prove native GR execution and the release path independent of the guest kernel's SASS; the guest kernel's own entry words observed in the shadow (00017a02 00000a00) are the same standard prologue MOV encoding, so this isolates execution-path faults from code content.
-rw-r--r--kernel/gsp_phys_booter.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index de546d4..bc0156f 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -15518,6 +15518,9 @@ static u64 gsp_phys_gr_ok;
static u64 gsp_phys_gr_refused;
static u64 gsp_phys_gr_timed_out;
static u64 gsp_phys_gr_pool_exhausted;
+/* m86: program-page override blob (see gsp-phys-gr-override). */
+static u8 gsp_phys_gr_override[GSP_PHYS_PAGE_SIZE];
+static u32 gsp_phys_gr_override_len;
void gsp_phys_backend_gr_counters(u64 *submitted, u64 *ok, u64 *refused,
u64 *timed_out, u64 *pool_exhausted)
@@ -16365,6 +16368,31 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
boot_stage.rmcall_gr_shadow_win0_used <
GSP_PHYS_RMCALL_GR_SHADOW0_SLOTS;
+ /*
+ * m86: SASS override. When gsp-phys-gr-override
+ * holds bytes, they replace the program page's
+ * content at the QMD's program offset (the pair
+ * still carries the original guest VA here).
+ * Used with a hand-assembled minimal SM75 kernel
+ * to prove native GR execution independent of the
+ * guest kernel's SASS.
+ */
+ if (pg->qmd_word == 48u &&
+ READ_ONCE(gsp_phys_gr_override_len)) {
+ u32 off = qmd[48] &
+ (GSP_PHYS_PAGE_SIZE - 1);
+ u32 l = READ_ONCE(gsp_phys_gr_override_len);
+
+ if (off + l > GSP_PHYS_PAGE_SIZE)
+ l = GSP_PHYS_PAGE_SIZE - off;
+ memcpy(sh_page + off,
+ gsp_phys_gr_override, l);
+ pr_info("vgsp-gr: SASS override applied: %u bytes at program page +0x%x (w48=0x%08x; original first words %08x %08x)\n",
+ l, off, qmd[48],
+ get_unaligned_le32(sh_page + off + 8),
+ get_unaligned_le32(sh_page + off + 12));
+ }
+
if (win0) {
u8 *dst = gsp_phys_chunk_page_va(
&boot_stage.rmcall_gr_shadow_win0,
@@ -18612,6 +18640,38 @@ static const struct file_operations gsp_phys_rm_probe_fops = {
* unload/probe triggers by gsp_phys_rm_lock; at most one run per write; WPR2
* is never touched.
*/
+/*
+ * m86 SASS override channel (debugfs gsp-phys-gr-override): a write of up to
+ * one page is stored and, on the next forwarded launch, replaces the
+ * program-page content at the QMD's program offset. Writing zero bytes
+ * clears the override. Diagnostic only.
+ */
+static ssize_t gsp_phys_gr_override_write(struct file *file,
+ const char __user *ubuf,
+ size_t len, loff_t *off)
+{
+ if (len > GSP_PHYS_PAGE_SIZE)
+ return -EINVAL;
+ if (len == 0) {
+ WRITE_ONCE(gsp_phys_gr_override_len, 0);
+ pr_info("vgsp-boot: gsp-phys-gr-override: cleared\n");
+ return 0;
+ }
+ if (copy_from_user(gsp_phys_gr_override, ubuf, len))
+ return -EFAULT;
+ WRITE_ONCE(gsp_phys_gr_override_len, (u32)len);
+ pr_info("vgsp-boot: gsp-phys-gr-override: %zu bytes stored; the next forwarded launch's program page carries them at the QMD program offset\n",
+ len);
+ return (ssize_t)len;
+}
+
+static const struct file_operations gsp_phys_gr_override_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .write = gsp_phys_gr_override_write,
+ .llseek = no_llseek,
+};
+
static ssize_t gsp_phys_rm_call_write(struct file *file,
const char __user *ubuf, size_t len,
loff_t *ppos)
@@ -19162,6 +19222,16 @@ int gsp_phys_boot_debugfs_init(void)
err);
return (int)err;
}
+ file = debugfs_create_file("gsp-phys-gr-override", 0200,
+ gsp_phys_debugfs_root, NULL,
+ &gsp_phys_gr_override_fops);
+ if (IS_ERR_OR_NULL(file)) {
+ long err = IS_ERR(file) ? PTR_ERR(file) : -ENODEV;
+
+ pr_warn("vgsp-boot: debugfs file gsp-phys-gr-override creation failed: %ld (other triggers and state snapshot stay available)\n",
+ err);
+ return (int)err;
+ }
file = debugfs_create_file("gsp-phys-guest-gpa", 0200,
gsp_phys_debugfs_root, NULL,
&gsp_phys_guest_gpa_fops);