DF-3818 / fix.diff
--- a/sys/dev/raid/mpr/mpr.c +++ b/sys/dev/raid/mpr/mpr.c @@ -2714,8 +2714,15 @@ * possible NVMe QDepth. */ prp_page_info = mpr_alloc_prp_page(sc); - KASSERT(prp_page_info != NULL, ("%s: There are no PRP Pages left to be " - "used for building a native NVMe SGL.\n", __func__)); + if (prp_page_info == NULL) { + /* Pool exhausted (num_reqs can exceed NVME_QDEPTH). + * Do not dereference NULL; the firmware will reject the + * malformed request. Proper fix: return int and fail the + * command up the stack. */ + mpr_dprint(sc, MPR_ERROR, "%s: no PRP pages left\n", + __func__); + return; + } prp_page = (uint64_t *)prp_page_info->prp_page; prp_page_phys = (uint64_t *)(uintptr_t)prp_page_info->prp_page_busaddr; @@ -2986,8 +2993,12 @@ * possible NVMe QDepth. */ prp_page_info = mpr_alloc_prp_page(sc); - KASSERT(prp_page_info != NULL, ("%s: There are no PRP Pages left to be " - "used for building a native NVMe SGL.\n", __func__)); + if (prp_page_info == NULL) { + /* Fall back to a normal IEEE SGL instead of panicking. */ + mpr_dprint(sc, MPR_ERROR, "%s: no PRP pages left, using " + "IEEE SGL\n", __func__); + return (1); + } curr_buff = (uint32_t *)prp_page_info->prp_page; msg_phys = (uint64_t *)(uintptr_t)prp_page_info->prp_page_busaddr; |