diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-28 17:13:39 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-28 17:13:39 -0400 |
| commit | 717997bc93aab02ac868cc23ada4eabc79285b94 (patch) | |
| tree | 93a35cb05e212065870740b2ec93bed5d08afbd1 | |
| parent | 7dddb85c888c57b6b125ce0487d599500ea06769 (diff) | |
| download | open-iov-717997bc93aab02ac868cc23ada4eabc79285b94.tar.gz open-iov-717997bc93aab02ac868cc23ada4eabc79285b94.zip | |
sema: rescue entries anywhere in a pushbuffer slot
Mid-slot entry VAs were rejected by the alignment guard, leaving their
false translations permanent. Candidate 2 (the group's page minus the
push length) is the PA of the entry VA's page regardless of alignment;
pin only the pages the push occupies for mid-slot entries and the whole
1 MB slot for slot-aligned ones. Validation by read-back is unchanged.
| -rw-r--r-- | kernel/gsp_sema_service.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 7681ef6..0a4e723 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -3104,16 +3104,25 @@ static int svc_rescue_push_page(struct nv_vgpu_device *vgpu, u32 want_payload = ch->expected_sem_payload; u64 cand[SVC_MBUF_MAX]; u32 ncand = 0, i; + u32 pin_len; if (!ch->engine_type || ch->ce_index >= 32 || !want_payload) return -ENOENT; - if ((entry_va & 0xfffff) || entry_va < SEMA_VA_LO || - entry_va >= SEMA_VA_HI) + if (entry_va < SEMA_VA_LO || entry_va >= SEMA_VA_HI) return -EINVAL; if (time_before(jiffies, ch->rescue_last + 5 * HZ)) return -EAGAIN; ch->rescue_last = jiffies; + /* + * Slot-aligned entries pin the whole 1 MB slot at once (all of its + * pushes share the mapping); an entry in the middle of a slot only + * needs the pages its own push occupies - candidate 2 below is the + * PA of the entry VA's page in both cases. + */ + pin_len = (entry_va & 0xfffff) ? + ALIGN(entry_len + SEMA_PAGE_SIZE, SEMA_PAGE_SIZE) : 0x100000; + buf = kmalloc(SVC_SCAN_CHUNK, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -3181,7 +3190,7 @@ static int svc_rescue_push_page(struct nv_vgpu_device *vgpu, u8 probe[64]; u32 j; - for (j = 0; j < 0x100000; j += SEMA_PAGE_SIZE) { + for (j = 0; j < pin_len; j += SEMA_PAGE_SIZE) { svc_pin_store(entry_va + j, cand[i] + j, SVC_APERTURE_SYS); svc_lat_store(entry_va + j, cand[i] + j, @@ -3190,7 +3199,7 @@ static int svc_rescue_push_page(struct nv_vgpu_device *vgpu, if (!svc_read_va_trusted(vgpu, entry_va, probe, sizeof(probe)) && svc_method_stream_plausible(probe, sizeof(probe))) { - for (j = 0; j < 0x100000; j += SEMA_PAGE_SIZE) + for (j = 0; j < pin_len; j += SEMA_PAGE_SIZE) svc_mark_hot(cand[i] + j); pr_info("sema-svc: content rescue ch=0x%x rank=%u slot=%u entry_va=0x%llx len=%u -> pa=0x%llx (cand %u/%u)\n", ch->h_object, ch->ce_index, slot, entry_va, |
