Re: [PATCH] PCI: dwc: Set DMA mask to 32 only if ZONE_DMA32 is enabled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ajay

On Thu, Dec 21, 2023 at 11:10:51PM +0530, Ajay Agarwal wrote:
> If CONFIG_ZONE_DMA32 is disabled, then the dmam_alloc_coherent
> will fail to allocate the memory if there are no 32-bit addresses
> available. This will lead to the PCIe RC probe failure.
> Fix this by setting the DMA mask to 32 bits only if the kernel
> configuration enables DMA32 zone. Else, leave the mask as is.
> 
> Signed-off-by: Ajay Agarwal <ajayagarwal@xxxxxxxxxx>
> ---
>  drivers/pci/controller/dwc/pcie-designware-host.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 7991f0e179b2..163a78c5f9d8 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -377,10 +377,17 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
>  	 * Note until there is a better alternative found the reservation is
>  	 * done by allocating from the artificially limited DMA-coherent
>  	 * memory.
> +	 *
> +	 * Set the coherent DMA mask to 32 bits only if the DMA32 zone is
> +	 * supported. Otherwise, leave the mask as is.
> +	 * This ensures that the dmam_alloc_coherent is successful in
> +	 * allocating the memory.
>  	 */
> +#ifdef CONFIG_ZONE_DMA32
>  	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
>  	if (ret)
>  		dev_warn(dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n");
> +#endif

Without setting the mask the allocation below may cause having MSI
data from above 4GB which in its turn will cause MSI not working for
peripheral PCI-devices supporting 32-bit MSI only. That's the gist of
this questionable code above and below.

The discussion around it can be found here:
https://lore.kernel.org/linux-pci/20220825185026.3816331-2-willmcvicker@xxxxxxxxxx
and a problem similar to what you described was reported here:
https://lore.kernel.org/linux-pci/decae9e4-3446-2384-4fc5-4982b747ac03@xxxxxxxxx/

The easiest solution in this case is to somehow pre-define
pp->msi_data with a PCI-bus address free from RAM behind and avoid
allocation below at all. The only question is how to do that. See the
discussions above for details.

-Serge(y)

>  
>  	msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
>  					GFP_KERNEL);
> -- 
> 2.43.0.195.gebba966016-goog
> 
> 




[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux