On 2024-12-09 11:27 am, Sasha Levin wrote:
This is a note to let you know that I've just added the patch titled
iommu/arm-smmu: Defer probe of clients after smmu device bound
to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: iommu-arm-smmu-defer-probe-of-clients-after-smmu-dev.patch and it can be found in the queue-6.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
FWIW the correct resolution for cherry-picking this directly is the logically-straightforward one, as below (git is mostly just confused by the context)
Cheers, Robin.
----->8----- diff --cc drivers/iommu/arm/arm-smmu/arm-smmu.c index d6d1a2a55cc0,14618772a3d6..000000000000 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@@ -1357,10 -1435,19 +1357,21 @@@ static struct iommu_device *arm_smmu_pr fwspec = dev_iommu_fwspec_get(dev); if (ret) goto out_free; - } else { + } else if (fwspec && fwspec->ops == &arm_smmu_ops) { smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode); + + /* + * Defer probe if the relevant SMMU instance hasn't finished + * probing yet. This is a fragile hack and we'd ideally + * avoid this race in the core code. Until that's ironed + * out, however, this is the most pragmatic option on the + * table. + */ + if (!smmu) + return ERR_PTR(dev_err_probe(dev, -EPROBE_DEFER, + "smmu dev has not bound yet\n")); + } else { + return ERR_PTR(-ENODEV); }
ret = -EINVAL;
commit 62dc845a353efab2254480df8ae7d06175627313 Author: Pratyush Brahma quic_pbrahma@quicinc.com Date: Fri Oct 4 14:34:28 2024 +0530
iommu/arm-smmu: Defer probe of clients after smmu device bound [ Upstream commit 229e6ee43d2a160a1592b83aad620d6027084aad ] Null pointer dereference occurs due to a race between smmu driver probe and client driver probe, when of_dma_configure() for client is called after the iommu_device_register() for smmu driver probe has executed but before the driver_bound() for smmu driver has been called. Following is how the race occurs: T1:Smmu device probe T2: Client device probe really_probe() arm_smmu_device_probe() iommu_device_register() really_probe() platform_dma_configure() of_dma_configure() of_dma_configure_id() of_iommu_configure() iommu_probe_device() iommu_init_device() arm_smmu_probe_device() arm_smmu_get_by_fwnode() driver_find_device_by_fwnode() driver_find_device() next_device() klist_next() /* null ptr assigned to smmu */ /* null ptr dereference while smmu->streamid_mask */ driver_bound() klist_add_tail() When this null smmu pointer is dereferenced later in arm_smmu_probe_device, the device crashes. Fix this by deferring the probe of the client device until the smmu device has bound to the arm smmu driver. Fixes: 021bb8420d44 ("iommu/arm-smmu: Wire up generic configuration support") Cc: stable@vger.kernel.org Co-developed-by: Prakash Gupta <quic_guptap@quicinc.com> Signed-off-by: Prakash Gupta <quic_guptap@quicinc.com> Signed-off-by: Pratyush Brahma <quic_pbrahma@quicinc.com> Link: https://lore.kernel.org/r/20241004090428.2035-1-quic_pbrahma@quicinc.com [will: Add comment] Signed-off-by: Will Deacon <will@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 8203a06014d71..b40ffa1ec2db6 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1354,6 +1354,17 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev) goto out_free; } else { smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
/*
* Defer probe if the relevant SMMU instance hasn't finished
* probing yet. This is a fragile hack and we'd ideally
* avoid this race in the core code. Until that's ironed
* out, however, this is the most pragmatic option on the
* table.
*/
if (!smmu)
return ERR_PTR(dev_err_probe(dev, -EPROBE_DEFER,
}"smmu dev has not bound yet\n"));
ret = -EINVAL;
On Tue, Dec 10, 2024 at 12:14:44PM +0000, Robin Murphy wrote:
On 2024-12-09 11:27 am, Sasha Levin wrote:
This is a note to let you know that I've just added the patch titled
iommu/arm-smmu: Defer probe of clients after smmu device bound
to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: iommu-arm-smmu-defer-probe-of-clients-after-smmu-dev.patch and it can be found in the queue-6.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
FWIW the correct resolution for cherry-picking this directly is the logically-straightforward one, as below (git is mostly just confused by the context)
Cheers, Robin.
----->8----- diff --cc drivers/iommu/arm/arm-smmu/arm-smmu.c index d6d1a2a55cc0,14618772a3d6..000000000000 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@@ -1357,10 -1435,19 +1357,21 @@@ static struct iommu_device *arm_smmu_pr fwspec = dev_iommu_fwspec_get(dev); if (ret) goto out_free;
- } else {
- } else if (fwspec && fwspec->ops == &arm_smmu_ops) { smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
/*
* Defer probe if the relevant SMMU instance hasn't finished
* probing yet. This is a fragile hack and we'd ideally
* avoid this race in the core code. Until that's ironed
* out, however, this is the most pragmatic option on the
* table.
*/
if (!smmu)
return ERR_PTR(dev_err_probe(dev, -EPROBE_DEFER,
"smmu dev has not bound yet\n"));
- } else {
} ret = -EINVAL;areturn ERR_PTR(-ENODEV);
Can you resend this in a patch that we can apply as-is?
thanks,
greg k-h
On 2024-12-10 12:18 pm, Greg KH wrote:
On Tue, Dec 10, 2024 at 12:14:44PM +0000, Robin Murphy wrote:
On 2024-12-09 11:27 am, Sasha Levin wrote:
This is a note to let you know that I've just added the patch titled
iommu/arm-smmu: Defer probe of clients after smmu device bound
to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: iommu-arm-smmu-defer-probe-of-clients-after-smmu-dev.patch and it can be found in the queue-6.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
FWIW the correct resolution for cherry-picking this directly is the logically-straightforward one, as below (git is mostly just confused by the context)
Cheers, Robin.
----->8----- diff --cc drivers/iommu/arm/arm-smmu/arm-smmu.c index d6d1a2a55cc0,14618772a3d6..000000000000 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@@ -1357,10 -1435,19 +1357,21 @@@ static struct iommu_device *arm_smmu_pr fwspec = dev_iommu_fwspec_get(dev); if (ret) goto out_free;
- } else {
- } else if (fwspec && fwspec->ops == &arm_smmu_ops) { smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
/*
* Defer probe if the relevant SMMU instance hasn't finished
* probing yet. This is a fragile hack and we'd ideally
* avoid this race in the core code. Until that's ironed
* out, however, this is the most pragmatic option on the
* table.
*/
if (!smmu)
return ERR_PTR(dev_err_probe(dev, -EPROBE_DEFER,
"smmu dev has not bound yet\n"));
} ret = -EINVAL;a
- } else {
return ERR_PTR(-ENODEV);
Can you resend this in a patch that we can apply as-is?
Hope I got the tagging right :)
https://lore.kernel.org/stable/acd8068372673fb881aa9e13531470669c985519.1733...
Cheers, Robin.
thanks,
greg k-h
linux-stable-mirror@lists.linaro.org