DF-3952 / fix.diff
--- a/sys/dev/raid/mlx/mlx.c +++ b/sys/dev/raid/mlx/mlx.c @@ -1870,8 +1870,17 @@ /* if we need a buffer for data transfer, allocate one and copy in its initial contents */ if (mu->mu_datasize > 0) { - if (mu->mu_datasize > MAXPHYS) - return (EINVAL); + if (mu->mu_datasize > MAXPHYS) + return (EINVAL); + /* + * The s/g budget comes from the firmware (me_max_sg); the DMA tag + * allows MLX_NSEG segments regardless, and exceeding the firmware + * budget panics in mlx_setup_dmamap(). Keep the passthrough buffer + * within what the controller can actually map. + */ + if (sc->mlx_enq2 != NULL && + mu->mu_datasize > (sc->mlx_enq2->me_max_sg - 1) * PAGE_SIZE) + return (EINVAL); if (((kbuf = kmalloc(mu->mu_datasize, M_DEVBUF, M_WAITOK)) == NULL) || (error = copyin(mu->mu_buf, kbuf, mu->mu_datasize))) goto out; |