diff options
Diffstat (limited to 'kernel/gsp_phys_booter.c')
| -rw-r--r-- | kernel/gsp_phys_booter.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 47068c4..8de8408 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -15990,6 +15990,41 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req, (qmd[pg->qmd_word + 1] & ~0x1ffffu) | ((u32)(ptr_va >> 32) & 0x1ffffu); + /* + * m68: the program-prefetch pair (w8 + * LO32(prefetch>>8), w31[8:0] + * HI32(prefetch>>8)) still carried the + * guest VA; a prefetch into our unmapped + * VAS may be what cancels the QMD after + * SKED schedules it. If the original + * prefetch address lies in the page we + * just shadowed, point it at the same + * shadow copy (preserving SASS_VERSION / + * prefetch size in w31). + */ + if (pg->qmd_word == 48) { + u64 orig_pref = + ((u64)(qmd[31] & + 0x1ffu) << 40) | + ((u64)qmd[8] << 8); + + if ((orig_pref & + ~(u64)(GSP_PHYS_PAGE_SIZE - 1)) == + pg_va) { + u64 new_pref = ptr_va | + (orig_pref & + (GSP_PHYS_PAGE_SIZE - 1)); + + qmd[8] = (u32)(new_pref >> 8); + qmd[31] = (qmd[31] & + ~0x1ffu) | + ((u32)((new_pref >> 40)) & + 0x1ffu); + pr_info("vgsp-gr: program prefetch rewritten to shadow 0x%llx (was 0x%llx)\n", + new_pref, + orig_pref); + } + } mapped = true; if (n_sh_rec < ARRAY_SIZE(sh_rec)) { sh_rec[n_sh_rec].guest_va = @@ -16350,6 +16385,41 @@ gr_page_unmapped: get_unaligned_le32(qp2 + 116), get_unaligned_le32(qp2 + 120), get_unaligned_le32(qp2 + 124)); + if (qp2) { + u64 pva = ((u64)(get_unaligned_le32(qp2 + 196) & + 0x1ffffu) << 32) | + get_unaligned_le32(qp2 + 192); + u64 sb = boot_stage.rmcall_va_guest_pt; + + if (pva >= sb) { + u32 slot = (u32)(((pva - sb) >> 16) & 0x1fu); + u32 poff = (u32)(pva & (GSP_PHYS_PAGE_SIZE - 1)); + const u32 *sp = + gsp_phys_chunk_page_va( + &boot_stage.rmcall_gr_shadow, + slot); + + if (sp && poff + 64 <= GSP_PHYS_PAGE_SIZE) + pr_info("vgsp-gr: post-mortem program target va=0x%llx slot=%u off=0x%x w0..15 = %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", + pva, slot, poff, + get_unaligned_le32((u8 *)sp + poff), + get_unaligned_le32((u8 *)sp + poff + 4), + get_unaligned_le32((u8 *)sp + poff + 8), + get_unaligned_le32((u8 *)sp + poff + 12), + get_unaligned_le32((u8 *)sp + poff + 16), + get_unaligned_le32((u8 *)sp + poff + 20), + get_unaligned_le32((u8 *)sp + poff + 24), + get_unaligned_le32((u8 *)sp + poff + 28), + get_unaligned_le32((u8 *)sp + poff + 32), + get_unaligned_le32((u8 *)sp + poff + 36), + get_unaligned_le32((u8 *)sp + poff + 40), + get_unaligned_le32((u8 *)sp + poff + 44), + get_unaligned_le32((u8 *)sp + poff + 48), + get_unaligned_le32((u8 *)sp + poff + 52), + get_unaligned_le32((u8 *)sp + poff + 56), + get_unaligned_le32((u8 *)sp + poff + 60)); + } + } for (i = 0; i < req->n_pages && i < 16; i++) pr_info("vgsp-gr: post-mortem page[%u] va=0x%llx hpa=0x%llx qmd_word=%u\n", i, req->pages[i].guest_va, |
