diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_phys_booter.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 07fb7f9..49e8be9 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -12767,7 +12767,17 @@ EXPORT_SYMBOL_GPL(gsp_phys_backend_guest_ce_copy); #define GSP_PHYS_RMCALL_GR_QMD_INLINE_WORDS 66u #define GSP_PHYS_RMCALL_GR_QMD_REL_PAYLOAD GSP_PHYS_RMCALL_SEM_PAYLOAD #define GSP_PHYS_RMCALL_GR_SEM_PAYLOAD 0xc0ffee02u -/* Method block bound: SET_OBJECT(2) + inline run(67) + REPORT_SEM(8). */ +/* + * PCAS launcher (bisect): the driver's non-IQ2M path schedules a QMD with + * SEND_PCAS_A = (QMD VA >> 8) followed by SEND_SIGNALING_PCAS_B with + * INVALIDATE|SCHEDULE (turing_launch.c:1671-1694, CU_PCAS_TYPE_COPY). Emitted + * after the inline window once the caller has prewritten the QMD words to the + * destination, so the launch can run without the PBDMA inline copy. + */ +#define GSP_PHYS_RMCALL_GR_SEND_PCAS_A 0x2b4u +#define GSP_PHYS_RMCALL_GR_SEND_SIGNALING_PCAS_B 0x2bcu +#define GSP_PHYS_RMCALL_GR_PCAS_INVALIDATE_SCHEDULE 0x3u +/* Method block bound: inline run(67) + PCAS(4) + REPORT_SEM(8). */ #define GSP_PHYS_RMCALL_GR_METHOD_WORDS 96u static u64 gsp_phys_gr_submitted; @@ -12813,6 +12823,11 @@ static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb, const u32 *qmd, *p++ = (u32)((qmd_va >> 8) & 0xffffffffu); memcpy(p, qmd, GSP_PHYS_GR_QMD_WORDS * 4); p += GSP_PHYS_GR_QMD_WORDS; + p = gsp_phys_rmcall_push_gr(p, GSP_PHYS_RMCALL_GR_SEND_PCAS_A, + (u32)(qmd_va >> 8)); + p = gsp_phys_rmcall_push_gr(p, + GSP_PHYS_RMCALL_GR_SEND_SIGNALING_PCAS_B, + GSP_PHYS_RMCALL_GR_PCAS_INVALIDATE_SCHEDULE); p = gsp_phys_rmcall_push_gr(p, GSP_PHYS_RMCALL_GR_SET_REPORT_SEMAPHORE_A, (u32)(sem_va >> 32)); p = gsp_phys_rmcall_push_gr(p, GSP_PHYS_RMCALL_GR_SET_REPORT_SEMAPHORE_B, @@ -13070,6 +13085,7 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req, u64 qmd_rel_hpa = 0, ch_rel_hpa = 0; u64 ch_sem_va = GSP_PHYS_RMCALL_VA_SEM + 4; u64 qmd_dst = GSP_PHYS_RMCALL_VA_SRC; + u8 *qmd_dst_mem = NULL; u32 qmd_rel_off = 0, ch_rel_off = 0; u32 poll = 0, w0 = 0, w1 = 0, grpoll_n = 0; int ret = 0; @@ -13407,21 +13423,24 @@ gr_page_unmapped: */ if (req->qmd_hpa) { u64 qmd_page = req->qmd_va & ~(u64)(GSP_PHYS_PAGE_SIZE - 1); + u32 qmd_off = (u32)(req->qmd_va & (GSP_PHYS_PAGE_SIZE - 1)); if (qmd_page && !gsp_phys_rmcall_gr_map_va_locked(bar0, qmd_page, req->qmd_hpa, epoch)) { qmd_dst = qmd_page; + qmd_dst_mem = (u8 *)__va(req->qmd_hpa) + qmd_off; } else { u64 sh_va = 0; if (n_shadow < GSP_PHYS_RMCALL_GR_SHADOW_PAGES && !gsp_phys_rmcall_gr_map_shadow_locked( n_shadow, req->qmd_hpa, &sh_va)) { + qmd_dst_mem = (u8 *)gsp_phys_chunk_page_va( + &boot_stage.rmcall_gr_shadow, + n_shadow) + qmd_off; n_shadow++; - qmd_dst = sh_va + - (req->qmd_va & - (GSP_PHYS_PAGE_SIZE - 1)); + qmd_dst = sh_va + qmd_off; } } pr_info("vgsp-gr: inline-QMD dest va=0x%llx hpa=0x%llx -> 0x%llx (shadow=%u)\n", @@ -13457,6 +13476,18 @@ gr_page_unmapped: WRITE_ONCE(*(u32 *)(sem_va + 4), 0); wmb(); + /* + * IQ2M bisect: prewrite the exact QMD words into the destination + * memory so the explicit PCAS in the method block can schedule the + * launch even when the PBDMA inline copy never lands. + */ + if (qmd_dst_mem) { + memcpy(qmd_dst_mem, qmd, GSP_PHYS_GR_QMD_WORDS * 4); + wmb(); + pr_info("vgsp-gr: QMD prewritten to dest 0x%llx (%u words)\n", + qmd_dst, GSP_PHYS_GR_QMD_WORDS); + } + words = gsp_phys_rmcall_build_gr_launch(methods, qmd, qmd_dst, ch_sem_va, want_ch); |
