From b6a60cd1c7e188325c7b2e0c1ceb7e86ad5e9e74 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 7 Oct 2026 11:46:14 -0400 Subject: 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. --- kernel/gsp_phys_booter.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'kernel/gsp_phys_booter.c') 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); -- cgit v1.2.3