diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-13 10:20:00 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-13 10:20:00 -0500 |
| commit | 436cbf9d39677d17bc340b7dc35bd8ad3e601606 (patch) | |
| tree | 41f77009b41a7a4df5c42a640125414f4004c689 /kernel/gsp_sema_service.c | |
| parent | 7d27df77ac1f52816a7a741b39674e99e9c5f7bd (diff) | |
| download | open-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.c | 36 |
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 |
