[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [patch-4.16] arm/smmuv1,v2: Protect smmu master list with a lock
Hi Julien, On 27.10.2021 19:02, Julien Grall wrote: > > > On 27/10/2021 11:41, Michal Orzel wrote: >> Hi Julien, > > Hi Michal, > >> On 26.10.2021 18:56, Julien Grall wrote: >>> Hi, >>> >>> On 26/10/2021 17:28, Julien Grall wrote: >>>> On 26/10/2021 13:29, Michal Orzel wrote: >>>>> If a device is added to SMMUv1/v2 from DT and PCI >>>>> at the same time, there is a concurrent access >>>>> to a smmu master list. This could lead to a >>>>> scenario where one is looking into a list that >>>>> is being modified at the same time. Add a lock >>>>> to prevent this issue. >>>> >>>> Did you intend to say "Hold" rather than "Add"? >>>> >> Yes, this is what I meant. I will change it. >> >>>>> >>>>> Reuse the existing spinlock arm_smmu_devices_lock >>>>> as it is already protecting find_smmu_master. >>>>> >>>>> ipmmu-smmu and smmuv3 are not impacted by this >>>>> issue as there is no access or modification of >>>>> a global resource during add_device. >>>>> >>>>> Signed-off-by: Michal Orzel <michal.orzel@xxxxxxx> >>>>> --- >>>>> This patch aims for 4.16 release. >>>>> Benefits: >>>>> Remove a bug that could lead to a corruption of the >>>>> smmu master list, which would be very hard to debug. >>>> >>>> From my understanding, this corruption would only happen with >>>> CONFIG_HAS_PCI. At the moment, this is a experimental feature as it is not >>>> fully complete. >>> >>> Actually, digging through the code, I noticed that iommu_add_device() >>> assume that it can only be called with platform/DT. Thankfully, AFAICT, the >>> function would return -ENXIO because the fwspec would not be allocated for >>> PCI device. >>> >>> So was this patch tested with additional patch on top? >>> >> The purpose of this patch is to fix the issue that is present and which you >> thankfully noticed. >> There is still a lot of patches to be added that aim to support PCI >> passthrough. >> The complete PCI series is tested with SMMU and it works. >> But there is no chance to test this patch standalone as iommu_add_device is >> not in the correct form for PCI as of now. > > Ok. I would suggest to say this is a latent bug so it make clear that the > patch is more for hardening at the moment. > Ok I will mention it in the commit msg. >>>>> xen/drivers/passthrough/arm/smmu.c | 25 +++++++++++++++++++------ >>>>> 1 file changed, 19 insertions(+), 6 deletions(-) >>>>> >>>>> diff --git a/xen/drivers/passthrough/arm/smmu.c >>>>> b/xen/drivers/passthrough/arm/smmu.c >>>>> index c9dfc4caa0..be62a66a28 100644 >>>>> --- a/xen/drivers/passthrough/arm/smmu.c >>>>> +++ b/xen/drivers/passthrough/arm/smmu.c >>>>> @@ -820,21 +820,25 @@ static int arm_smmu_dt_add_device_legacy(struct >>>>> arm_smmu_device *smmu, >>>>> struct device *dev, >>>>> struct iommu_fwspec *fwspec) >>>>> { >>>>> - int i; >>>>> + int i, ret; >>>>> struct arm_smmu_master *master; >>>>> struct device_node *dev_node = dev_get_dev_node(dev); >>>>> + spin_lock(&arm_smmu_devices_lock); >>>>> master = find_smmu_master(smmu, dev_node); >>>>> if (master) { >>>>> dev_err(dev, >>>>> "rejecting multiple registrations for master device %s\n", >>>>> dev_node->name); >>>>> - return -EBUSY; >>>>> + ret = -EBUSY; >>>>> + goto out_unlock; >>>>> } >>>>> master = devm_kzalloc(dev, sizeof(*master), GFP_KERNEL); >>>>> - if (!master) >>>>> - return -ENOMEM; >>>>> + if (!master) { >>>>> + ret = -ENOMEM; >>>>> + goto out_unlock; >>>>> + } >>>>> master->of_node = dev_node; >>>>> /* Xen: Let Xen know that the device is protected by an SMMU */ >>>>> @@ -846,11 +850,17 @@ static int arm_smmu_dt_add_device_legacy(struct >>>>> arm_smmu_device *smmu, >>>>> dev_err(dev, >>>>> "stream ID for master device %s greater than maximum >>>>> allowed (%d)\n", >>>>> dev_node->name, smmu->num_mapping_groups); >>>>> - return -ERANGE; >>>>> + ret = -ERANGE; >>>>> + goto out_unlock; >>>>> } >>>>> master->cfg.smendx[i] = INVALID_SMENDX; >>>>> } >>>>> - return insert_smmu_master(smmu, master); >>>>> + >>>>> + ret = insert_smmu_master(smmu, master); >>>>> + >>>>> +out_unlock: >>>>> + spin_unlock(&arm_smmu_devices_lock); >>>> >>>> Please add a newline here. >>>> >> Ok. >> >>>>> + return ret; >>>>> } >>>>> static int register_smmu_master(struct arm_smmu_device *smmu, >>>>> @@ -2056,7 +2066,10 @@ static int arm_smmu_add_device(struct device *dev) >>>>> } else { >>>>> struct arm_smmu_master *master; >>>>> + spin_lock(&arm_smmu_devices_lock); >>>>> master = find_smmu_master(smmu, dev->of_node); >>>>> + spin_unlock(&arm_smmu_devices_lock); >>>> >>>> At the moment, unlocking here is fine because we don't remove the device. >>>> However, there are a series to supporting removing a device (see [1]). So >>>> I think it would be preferable to unlock after the last use of 'cfg'. >>>> >> Ok. I will move unlocking to the end of this else {} block. I was not aware >> of the patch you are referring to. > > I think the end of the else is still too early. This needs to at least be > past iommu_group_set_iommudata() because we store cfg. > > Potentially, the lock wants to also englobe arm_smmu_master_alloc_smes(). So > I am wondering whether it would be simpler to hold the lock for the whole > duration of arm_smmu_add_device() (I can see value when we will want to > interlock with the remove code). > >> >>>> Looking at the code, I also noticed that the error path is not correct for >>>> at least the PCI device and we would leak memory. We also assume that >>>> Stream ID == Requester ID. Are both of them in your radar for PCI >>>> passthrough? >>>> >> I agree with you. I also noticed it. However this is going to be fixed with >> the next patch series when Rahul gets back. > > Good. Do you have a todo list for PCI passthrough that can be shared? > As I am not working on the PCI stuff, I do not have such a list but I can point you to the branch on which both ARM and EPAM are working: https://gitlab.com/xen-project/fusa/xen-integration/-/tree/integration/pci-passthrough > Cheers, > Cheers, Michal
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |