summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-13 10:20:00 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-13 10:20:00 -0500
commit436cbf9d39677d17bc340b7dc35bd8ad3e601606 (patch)
tree41f77009b41a7a4df5c42a640125414f4004c689 /kernel/gsp_sema_service.c
parent7d27df77ac1f52816a7a741b39674e99e9c5f7bd (diff)
downloadopen-iov-436cbf9d39677d17bc340b7dc35bd8ad3e601606.tar.gz
open-iov-436cbf9d39677d17bc340b7dc35bd8ad3e601606.zip
vgsp: extend the live PA acceptance bound to the registered guest-RAM top (svc_pa_max/svc_push_pa_ceiling)
The direct-GL client parks its VAS page directory and push pages in the 4-14 GiB high RAM band while the runtime bound stopped at 10 GiB (param/compile), so svc_ap_ok rejected every walk read above 10 GiB before vfio_dma_rw could answer: the client ring walk reported 'L0 read fail' / 'walk rc=-2' on the one boot the RAM content scan latched the real ring (c296), and the push bodies stayed unreadable (src=3 window garbage / src=255). svc_pa_max() now never shrinks below the registered guest-RAM top (sanity-clamped to the scan max), and svc_push_pa_ceiling() floors on the same live bound. c297 (first boot with the fix): 'RING-VAS h=0xbeef0100 gpfifo=0x4020000 mapped by VAS 0xbeef0300 (pdb=0x110aae000) -> pa=0x23771f000' and pushdec 'src=4 plausible=1' with the read ceiling witness ceil=0x380000000.
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 83ab2db..9730c58 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -283,9 +283,30 @@ static bool gsp_sema_ce_ram;
static inline u64 svc_pa_max(void)
{
u64 top = READ_ONCE(gsp_sema_gr_scan_top);
+ u64 reg = gsp_phys_guest_ram_top();
if (!top || top > SEMA_PA_MAX)
- return SEMA_PA_MAX;
+ top = SEMA_PA_MAX;
+ /*
+ * CONT.478: the registered guest-RAM ranges are readable content
+ * truth - extend (never shrink) the live bound to the registered top.
+ * On the 12 GiB boot the guest's system RAM reaches GPA 0x380000000
+ * (the 4-14 GiB high band) while the param/compile bounds stopped at
+ * 10 GiB, so svc_ap_ok rejected every page-table walk and push read
+ * above 10 GiB before vfio_dma_rw could answer: the direct-GL client
+ * parks its VAS page directory at 0x33e537000 (13.9 GiB) and its
+ * push pages in the same band, so every walk missed with "L0 read
+ * fail" / "walk rc=-2" while the ring page (4.3 GiB, below the old
+ * bound) resolved fine - entries decoded, bodies stayed unreadable.
+ * A read above the registered top can only return padding zeros, so
+ * the extension never invents content; the sanity clamp keeps a
+ * misregistered range from unbounding the scans.
+ */
+ if (reg > top) {
+ if (reg > SVC_GR_SCAN_TOP_MAX)
+ reg = SVC_GR_SCAN_TOP_MAX;
+ top = reg;
+ }
return top;
}
@@ -25947,8 +25968,17 @@ static u64 svc_push_pa_ceiling(void)
if (top > SVC_GR_SCAN_TOP_MAX)
top = SVC_GR_SCAN_TOP_MAX;
- if (top < SEMA_PA_MAX)
- top = SEMA_PA_MAX;
+ /*
+ * CONT.478: the floor is the live acceptance bound, not the old
+ * compile-time 10 GiB - svc_pa_max() now follows the registered
+ * guest-RAM top, so the read ceiling covers the same 4-14 GiB high
+ * band the direct-GL client's push pages live in. Without this the
+ * walk could resolve a push above 10 GiB and the read path would
+ * still reject it ("sema-pinrej ... ceiling") - the same bound bug
+ * on the other side of the source chain.
+ */
+ if (top < svc_pa_max())
+ top = svc_pa_max();
/*
* SESSION 153-CONTINUED-67: never let the ceiling exceed the highest
* GPA any registered guest-RAM range covers - a read above it can