Re: [PATCH v4 1/3] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
03.10.2020 02:53, Nicolin Chen пишет: > On Fri, Oct 02, 2020 at 11:12:18PM +0300, Dmitry Osipenko wrote: >> 02.10.2020 22:45, Nicolin Chen пишет: >>> On Fri, Oct 02, 2020 at 05:41:50PM +0300, Dmitry Osipenko wrote: 02.10.2020 09:08, Nicolin Chen пишет: > static int tegra_smmu_attach_dev(struct iommu_domain *domain, >struct device *dev) > { > + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); > struct tegra_smmu *smmu = dev_iommu_priv_get(dev); > struct tegra_smmu_as *as = to_smmu_as(domain); > - struct device_node *np = dev->of_node; > - struct of_phandle_args args; > unsigned int index = 0; > int err = 0; > > - while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, > -&args)) { > - unsigned int swgroup = args.args[0]; > - > - if (args.np != smmu->dev->of_node) { > - of_node_put(args.np); > - continue; > - } > - > - of_node_put(args.np); > + if (!fwspec) > + return -ENOENT; Could the !fwspec ever be true here as well? >>> >>> There are multiple callers of this function. It's really not that >>> straightforward to track every one of them. So I'd rather have it >>> here as other iommu drivers do. We are human beings, so we could >>> have missed something somewhere, especially callers are not from >>> tegra-* drivers. >>> >> >> I'm looking at the IOMMU core and it requires device to be in IOMMU >> group before attach_dev() could be called. >> >> The group can't be assigned to device without the fwspec, see >> tegra_smmu_device_group(). >> >> Seems majority of IOMMU drivers are checking dev_iommu_priv_get() for >> NULL in attach_dev(), some not checking anything, some check both and >> only arm-smmu checks the fwspec. > > As I said a couple of days ago, I don't like to assume that the > callers won't change. And this time, it's from open code. So I > don't want to assume that there won't be a change. > > If you are confident that there is no need to add such a check, > please send patches to remove those checks in those drivers to > see if others would agree. I would be willing to remove it after > that. Otherwise, I'd like to keep this. > > Thanks for the review. > I haven't tried to check every code path very thoroughly, expecting you to do it since you're making this patch. Maybe there is a real reason why majority of drivers do the checks and it would be good to know why. Although, it's not critical in this particular case and indeed the checks could be improved later on. It looks to me that at least will be a bit better/cleaner to check the dev_iommu_priv_get() for NULL instead of fwspec because the private variable depends on the fwspec presence and there is a similar check in probe_device, hence checks will be more consistent. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: xen-swiotlb vs phys_to_dma
On Fri, 2 Oct 2020, Christoph Hellwig wrote: > Hi Stefano, > > I've looked over xen-swiotlb in linux-next, that is with your recent > changes to take dma offsets into account. One thing that puzzles me > is that xen_swiotlb_map_page passes virt_to_phys(xen_io_tlb_start) as > the tbl_dma_addr argument to swiotlb_tbl_map_single, despite the fact > that the argument is a dma_addr_t and both other callers translate > from a physical to the dma address. Was this an oversight? Hi Christoph, It was not an oversight, it was done on purpose, although maybe I could have been wrong. There was a brief discussion on this topic here: https://marc.info/?l=linux-kernel&m=159011972107683&w=2 https://marc.info/?l=linux-kernel&m=159018047129198&w=2 I'll repeat and summarize here for convenience. swiotlb_init_with_tbl is called by xen_swiotlb_init, passing a virtual address (xen_io_tlb_start), which gets converted to phys and stored in io_tlb_start as a physical address at the beginning of swiotlb_init_with_tbl. Afterwards, xen_swiotlb_map_page calls swiotlb_tbl_map_single. The second parameter, dma_addr_t tbl_dma_addr, is used to calculate the right slot in the swiotlb buffer to use, comparing it against io_tlb_start. Thus, I think it makes sense for xen_swiotlb_map_page to call swiotlb_tbl_map_single passing an address meant to be compared with io_tlb_start, which is __pa(xen_io_tlb_start), so virt_to_phys(xen_io_tlb_start) seems to be what we want. However, you are right that it is strange that tbl_dma_addr is a dma_addr_t, and maybe it shouldn't be? Maybe the tbl_dma_addr parameter to swiotlb_tbl_map_single should be a phys address instead? Or it could be swiotlb_init_with_tbl to be wrong and it should take a dma address to initialize the swiotlb buffer. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 1/3] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
On Fri, Oct 02, 2020 at 11:12:18PM +0300, Dmitry Osipenko wrote: > 02.10.2020 22:45, Nicolin Chen пишет: > > On Fri, Oct 02, 2020 at 05:41:50PM +0300, Dmitry Osipenko wrote: > >> 02.10.2020 09:08, Nicolin Chen пишет: > >>> static int tegra_smmu_attach_dev(struct iommu_domain *domain, > >>>struct device *dev) > >>> { > >>> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); > >>> struct tegra_smmu *smmu = dev_iommu_priv_get(dev); > >>> struct tegra_smmu_as *as = to_smmu_as(domain); > >>> - struct device_node *np = dev->of_node; > >>> - struct of_phandle_args args; > >>> unsigned int index = 0; > >>> int err = 0; > >>> > >>> - while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, > >>> -&args)) { > >>> - unsigned int swgroup = args.args[0]; > >>> - > >>> - if (args.np != smmu->dev->of_node) { > >>> - of_node_put(args.np); > >>> - continue; > >>> - } > >>> - > >>> - of_node_put(args.np); > >>> + if (!fwspec) > >>> + return -ENOENT; > >> > >> Could the !fwspec ever be true here as well? > > > > There are multiple callers of this function. It's really not that > > straightforward to track every one of them. So I'd rather have it > > here as other iommu drivers do. We are human beings, so we could > > have missed something somewhere, especially callers are not from > > tegra-* drivers. > > > > I'm looking at the IOMMU core and it requires device to be in IOMMU > group before attach_dev() could be called. > > The group can't be assigned to device without the fwspec, see > tegra_smmu_device_group(). > > Seems majority of IOMMU drivers are checking dev_iommu_priv_get() for > NULL in attach_dev(), some not checking anything, some check both and > only arm-smmu checks the fwspec. As I said a couple of days ago, I don't like to assume that the callers won't change. And this time, it's from open code. So I don't want to assume that there won't be a change. If you are confident that there is no need to add such a check, please send patches to remove those checks in those drivers to see if others would agree. I would be willing to remove it after that. Otherwise, I'd like to keep this. Thanks for the review. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 1/3] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
02.10.2020 22:45, Nicolin Chen пишет: > On Fri, Oct 02, 2020 at 05:41:50PM +0300, Dmitry Osipenko wrote: >> 02.10.2020 09:08, Nicolin Chen пишет: >>> static int tegra_smmu_attach_dev(struct iommu_domain *domain, >>> struct device *dev) >>> { >>> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); >>> struct tegra_smmu *smmu = dev_iommu_priv_get(dev); >>> struct tegra_smmu_as *as = to_smmu_as(domain); >>> - struct device_node *np = dev->of_node; >>> - struct of_phandle_args args; >>> unsigned int index = 0; >>> int err = 0; >>> >>> - while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, >>> - &args)) { >>> - unsigned int swgroup = args.args[0]; >>> - >>> - if (args.np != smmu->dev->of_node) { >>> - of_node_put(args.np); >>> - continue; >>> - } >>> - >>> - of_node_put(args.np); >>> + if (!fwspec) >>> + return -ENOENT; >> >> Could the !fwspec ever be true here as well? > > There are multiple callers of this function. It's really not that > straightforward to track every one of them. So I'd rather have it > here as other iommu drivers do. We are human beings, so we could > have missed something somewhere, especially callers are not from > tegra-* drivers. > I'm looking at the IOMMU core and it requires device to be in IOMMU group before attach_dev() could be called. The group can't be assigned to device without the fwspec, see tegra_smmu_device_group(). Seems majority of IOMMU drivers are checking dev_iommu_priv_get() for NULL in attach_dev(), some not checking anything, some check both and only arm-smmu checks the fwspec. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 1/3] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
On Fri, Oct 02, 2020 at 05:52:00PM +0300, Dmitry Osipenko wrote: > 02.10.2020 17:22, Dmitry Osipenko пишет: > > 02.10.2020 09:08, Nicolin Chen пишет: > >> static int tegra_smmu_attach_dev(struct iommu_domain *domain, > >> struct device *dev) > >> { > >> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); > >>struct tegra_smmu *smmu = dev_iommu_priv_get(dev); > >>struct tegra_smmu_as *as = to_smmu_as(domain); > >> - struct device_node *np = dev->of_node; > >> - struct of_phandle_args args; > >>unsigned int index = 0; > >>int err = 0; > > > > Looks like there is no need to initialize 'index' and 'err' variables > > anymore. > > > > Same for tegra_smmu_detach_dev(). Can remove them. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
On Fri, Oct 02, 2020 at 05:58:29PM +0300, Dmitry Osipenko wrote: > 02.10.2020 17:22, Dmitry Osipenko пишет: > > 02.10.2020 09:08, Nicolin Chen пишет: > >> -static void tegra_smmu_release_device(struct device *dev) > >> -{ > >> - dev_iommu_priv_set(dev, NULL); > >> -} > >> +static void tegra_smmu_release_device(struct device *dev) {} > > > > Please keep the braces as-is. > > > > I noticed that you borrowed this style from the sun50i-iommu driver, but > this is a bit unusual coding style for the c files. At least to me it's > unusual to see header-style function stub in a middle of c file. But > maybe it's just me. I don't see a rule in ./Documentation/process/coding-style.rst against this, and there're plenty of drivers doing so. If you feel uncomfortable with this style, you may add a rule to that doc so everyone will follow :) ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 1/3] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
On Fri, Oct 02, 2020 at 05:41:50PM +0300, Dmitry Osipenko wrote: > 02.10.2020 09:08, Nicolin Chen пишет: > > static int tegra_smmu_attach_dev(struct iommu_domain *domain, > > struct device *dev) > > { > > + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); > > struct tegra_smmu *smmu = dev_iommu_priv_get(dev); > > struct tegra_smmu_as *as = to_smmu_as(domain); > > - struct device_node *np = dev->of_node; > > - struct of_phandle_args args; > > unsigned int index = 0; > > int err = 0; > > > > - while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, > > - &args)) { > > - unsigned int swgroup = args.args[0]; > > - > > - if (args.np != smmu->dev->of_node) { > > - of_node_put(args.np); > > - continue; > > - } > > - > > - of_node_put(args.np); > > + if (!fwspec) > > + return -ENOENT; > > Could the !fwspec ever be true here as well? There are multiple callers of this function. It's really not that straightforward to track every one of them. So I'd rather have it here as other iommu drivers do. We are human beings, so we could have missed something somewhere, especially callers are not from tegra-* drivers. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
On Fri, Oct 02, 2020 at 06:02:18PM +0300, Dmitry Osipenko wrote: > 02.10.2020 09:08, Nicolin Chen пишет: > > static int tegra_smmu_of_xlate(struct device *dev, > >struct of_phandle_args *args) > > { > > + struct platform_device *iommu_pdev = of_find_device_by_node(args->np); > > + struct tegra_mc *mc = platform_get_drvdata(iommu_pdev); > > u32 id = args->args[0]; > > > > + of_node_put(args->np); > > of_find_device_by_node() takes device reference and not the np > reference. This is a bug, please remove of_node_put(). Looks like so. Replacing it with put_device(&iommu_pdev->dev); Thanks ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 0/6] Add virtio-iommu built-in topology
On 24 Sep 2020 11:54, Auger Eric wrote: > Hi, > > Adding Al in the loop > > On 9/24/20 11:38 AM, Michael S. Tsirkin wrote: > > On Thu, Sep 24, 2020 at 11:21:29AM +0200, Joerg Roedel wrote: > >> On Thu, Sep 24, 2020 at 05:00:35AM -0400, Michael S. Tsirkin wrote: > >>> OK so this looks good. Can you pls repost with the minor tweak > >>> suggested and all acks included, and I will queue this? > >> > >> My NACK still stands, as long as a few questions are open: > >> > >>1) The format used here will be the same as in the ACPI table? I > >> think the answer to this questions must be Yes, so this leads > >> to the real question: > > > > I am not sure it's a must. > > We can always tweak the parser if there are slight differences > > between ACPI and virtio formats. > > > > But we do want the virtio format used here to be approved by the virtio > > TC, so it won't change. > > > > Eric, Jean-Philippe, does one of you intend to create a github issue > > and request a ballot for the TC? It's been posted end of August with no > > changes ... > Jean-Philippe, would you? > > > >>2) Has the ACPI table format stabalized already? If and only if > >> the answer is Yes I will Ack these patches. We don't need to > >> wait until the ACPI table format is published in a > >> specification update, but at least some certainty that it > >> will not change in incompatible ways anymore is needed. > >> > > Al, do you have any news about the the VIOT definition submission to > the UEFI ASWG? > > Thank you in advance > > Best Regards > > Eric A follow-up to my earlier post Hearing no objection, I've submitted the VIOT table description to the ASWG for consideration under what they call the "code first" process. The "first reading" -- a brief discussion on what the table is and why we would like to add it -- was held yesterday. No concerns have been raised as yet. Given the discussions that have already occurred, I don't expect any, either. I have been wrong at least once before, however. At this point, ASWG will revisit the request to add VIOT each week. If there have been no comments in the prior week, and no further discussion during the meeting, then a vote will be taken. Otherwise, there will be discussion and we try again the next week. The ASWG was also told that the likelihood of this definition of the table changing is pretty low, and that it has been thought out pretty well already. ASWG's consideration will therefore start from the assumption that it would be best _not_ to make changes. So, I'll let you know what happens next week. > > > > > Not that I know, but I don't see why it's a must. > > > >> So what progress has been made with the ACPI table specification, is it > >> just a matter of time to get it approved or are there concerns? > >> > >> Regards, > >> > >>Joerg > > > -- ciao, al --- Al Stone Software Engineer Red Hat, Inc. a...@redhat.com --- ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 21:01, Nicolin Chen пишет: > On Fri, Oct 02, 2020 at 05:23:14PM +0300, Dmitry Osipenko wrote: >> 02.10.2020 09:08, Nicolin Chen пишет: >>> static struct iommu_device *tegra_smmu_probe_device(struct device *dev) >>> { >>> - struct device_node *np = dev->of_node; >>> - struct tegra_smmu *smmu = NULL; >>> - struct of_phandle_args args; >>> - unsigned int index = 0; >>> - int err; >>> - >>> - while (of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, >>> - &args) == 0) { >>> - smmu = tegra_smmu_find(args.np); >>> - if (smmu) { >>> - err = tegra_smmu_configure(smmu, dev, &args); >>> - of_node_put(args.np); >>> - >>> - if (err < 0) >>> - return ERR_PTR(err); >>> - >>> - /* >>> -* Only a single IOMMU master interface is currently >>> -* supported by the Linux kernel, so abort after the >>> -* first match. >>> -*/ >>> - dev_iommu_priv_set(dev, smmu); >>> - >>> - break; >>> - } >>> - >>> - of_node_put(args.np); >>> - index++; >>> - } >>> + struct tegra_smmu *smmu = dev_iommu_priv_get(dev); >>> >>> if (!smmu) >>> return ERR_PTR(-ENODEV); >> >> The !smmu can't ever be true now, isn't it? Then please remove it. > > How can you be so sure? Have you read my commit message? The whole > point of removing the hack in tegra_smmu_probe() is to return the > ERR_PTR(-ENODEV) here. The bus_set_iommu() will call this function > when mc->smmu is not assigned it, as it's assigned after we return > tegra_smmu_probe() while bus_set_iommu() is still in the middle of > the tegra_smmu_probe(). > My bad, I probably missed that was looking at the probe_device(), looks good then. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
On Fri, Oct 02, 2020 at 05:23:14PM +0300, Dmitry Osipenko wrote: > 02.10.2020 09:08, Nicolin Chen пишет: > > static struct iommu_device *tegra_smmu_probe_device(struct device *dev) > > { > > - struct device_node *np = dev->of_node; > > - struct tegra_smmu *smmu = NULL; > > - struct of_phandle_args args; > > - unsigned int index = 0; > > - int err; > > - > > - while (of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, > > - &args) == 0) { > > - smmu = tegra_smmu_find(args.np); > > - if (smmu) { > > - err = tegra_smmu_configure(smmu, dev, &args); > > - of_node_put(args.np); > > - > > - if (err < 0) > > - return ERR_PTR(err); > > - > > - /* > > -* Only a single IOMMU master interface is currently > > -* supported by the Linux kernel, so abort after the > > -* first match. > > -*/ > > - dev_iommu_priv_set(dev, smmu); > > - > > - break; > > - } > > - > > - of_node_put(args.np); > > - index++; > > - } > > + struct tegra_smmu *smmu = dev_iommu_priv_get(dev); > > > > if (!smmu) > > return ERR_PTR(-ENODEV); > > The !smmu can't ever be true now, isn't it? Then please remove it. How can you be so sure? Have you read my commit message? The whole point of removing the hack in tegra_smmu_probe() is to return the ERR_PTR(-ENODEV) here. The bus_set_iommu() will call this function when mc->smmu is not assigned it, as it's assigned after we return tegra_smmu_probe() while bus_set_iommu() is still in the middle of the tegra_smmu_probe(). ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 3/3] iommu/tegra-smmu: Add PCI support
02.10.2020 09:08, Nicolin Chen пишет: > This patch simply adds support for PCI devices. > > Signed-off-by: Nicolin Chen > --- Reviewed-by: Dmitry Osipenko ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 3/3] iommu/tegra-smmu: Add PCI support
02.10.2020 20:45, Nicolin Chen пишет: > On Fri, Oct 02, 2020 at 05:35:24PM +0300, Dmitry Osipenko wrote: >> 02.10.2020 09:08, Nicolin Chen пишет: >>> @@ -865,7 +866,11 @@ static struct iommu_group >>> *tegra_smmu_device_group(struct device *dev) >>> group->smmu = smmu; >>> group->soc = soc; >>> >>> - group->group = iommu_group_alloc(); >>> + if (dev_is_pci(dev)) >>> + group->group = pci_device_group(dev); >>> + else >>> + group->group = generic_device_group(dev); >>> + >>> if (IS_ERR(group->group)) { >>> devm_kfree(smmu->dev, group); >>> mutex_unlock(&smmu->lock); >>> @@ -1069,22 +1074,32 @@ struct tegra_smmu *tegra_smmu_probe(struct device >>> *dev, >>> iommu_device_set_fwnode(&smmu->iommu, dev->fwnode); >>> >>> err = iommu_device_register(&smmu->iommu); >>> - if (err) { >>> - iommu_device_sysfs_remove(&smmu->iommu); >>> - return ERR_PTR(err); >>> - } >>> + if (err) >>> + goto err_sysfs; >>> >>> err = bus_set_iommu(&platform_bus_type, &tegra_smmu_ops); >>> - if (err < 0) { >>> - iommu_device_unregister(&smmu->iommu); >>> - iommu_device_sysfs_remove(&smmu->iommu); >>> - return ERR_PTR(err); >>> - } >>> + if (err < 0) >>> + goto err_unregister; >>> + >>> +#ifdef CONFIG_PCI >>> + err = bus_set_iommu(&pci_bus_type, &tegra_smmu_ops); >>> + if (err < 0) >>> + goto err_bus_set; >>> +#endif >>> >>> if (IS_ENABLED(CONFIG_DEBUG_FS)) >>> tegra_smmu_debugfs_init(smmu); >>> >>> return smmu; >>> + >>> +err_bus_set: __maybe_unused; >> >> __maybe_unused? > > In order to mute a build warning when CONFIG_PCI=n... > okay ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 3/3] iommu/tegra-smmu: Add PCI support
On Fri, Oct 02, 2020 at 05:35:24PM +0300, Dmitry Osipenko wrote: > 02.10.2020 09:08, Nicolin Chen пишет: > > @@ -865,7 +866,11 @@ static struct iommu_group > > *tegra_smmu_device_group(struct device *dev) > > group->smmu = smmu; > > group->soc = soc; > > > > - group->group = iommu_group_alloc(); > > + if (dev_is_pci(dev)) > > + group->group = pci_device_group(dev); > > + else > > + group->group = generic_device_group(dev); > > + > > if (IS_ERR(group->group)) { > > devm_kfree(smmu->dev, group); > > mutex_unlock(&smmu->lock); > > @@ -1069,22 +1074,32 @@ struct tegra_smmu *tegra_smmu_probe(struct device > > *dev, > > iommu_device_set_fwnode(&smmu->iommu, dev->fwnode); > > > > err = iommu_device_register(&smmu->iommu); > > - if (err) { > > - iommu_device_sysfs_remove(&smmu->iommu); > > - return ERR_PTR(err); > > - } > > + if (err) > > + goto err_sysfs; > > > > err = bus_set_iommu(&platform_bus_type, &tegra_smmu_ops); > > - if (err < 0) { > > - iommu_device_unregister(&smmu->iommu); > > - iommu_device_sysfs_remove(&smmu->iommu); > > - return ERR_PTR(err); > > - } > > + if (err < 0) > > + goto err_unregister; > > + > > +#ifdef CONFIG_PCI > > + err = bus_set_iommu(&pci_bus_type, &tegra_smmu_ops); > > + if (err < 0) > > + goto err_bus_set; > > +#endif > > > > if (IS_ENABLED(CONFIG_DEBUG_FS)) > > tegra_smmu_debugfs_init(smmu); > > > > return smmu; > > + > > +err_bus_set: __maybe_unused; > > __maybe_unused? In order to mute a build warning when CONFIG_PCI=n... ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 8/8] WIP: add a dma_alloc_contiguous API
Hi Christoph, On Wed, Sep 30, 2020 at 06:09:17PM +0200, Christoph Hellwig wrote: > Add a new API that returns a virtually non-contigous array of pages > and dma address. This API is only implemented for dma-iommu and will > not be implemented for non-iommu DMA API instances that have to allocate > contiguous memory. It is up to the caller to check if the API is > available. Would you mind scheding some more light on what made the previous attempt not work well? I liked the previous API because it was more consistent with the regular dma_alloc_coherent(). > > The intent is that media drivers can use this API if either: FWIW, the USB subsystem also has similar needs, and so do some DRM drivers using DMA API rather than IOMMU API directly. Basically I believe that all the users removed in your previous series relied on custom downstream patches to make DMA_ATTR_NON_CONSISTENT work and could be finally made work in upstream using this API. > > - no kernel mapping or only temporary kernel mappings are required. >That is as a better replacement for DMA_ATTR_NO_KERNEL_MAPPING > - a kernel mapping is required for cached and DMA mapped pages, but >the driver also needs the pages to e.g. map them to userspace. >In that sense it is a replacement for some aspects of the recently >removed and never fully implemented DMA_ATTR_NON_CONSISTENT What's the expected allocation and mapping flow with the latter? Would that be pages = dma_alloc_noncoherent(...) vaddr = vmap(pages, ...); ? Would one just use the usual dma_sync_for_{cpu,device}() for cache invallidate/clean, while keeping the mapping in place? Best regards, Tomasz ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 19:37, Dmitry Osipenko пишет: > 02.10.2020 19:00, Dmitry Osipenko пишет: >> 02.10.2020 18:23, Dmitry Osipenko пишет: >>> 02.10.2020 09:08, Nicolin Chen пишет: Then when a client gets probed, of_iommu_configure() in iommu core will search DTB for swgroup ID and call ->of_xlate() to prepare an fwspec, similar to tegra_smmu_probe_device() and tegra_smmu_configure(). Then it'll call tegra_smmu_probe_device() again, and this time we shall return smmu->iommu pointer properly. >>> >>> I don't quite see where IOMMU core calls of_xlate(). >>> >>> Have tried to at least boot-test this patch? >>> >> >> I don't see how it ever could work because of_xlate() is only invoked from: >> >> fsl_mc_dma_configure()->of_dma_configure_id()->of_iommu_configure() >> >> Looks like the tegra_smmu_configure() is still needed. >> >> I don't know how sun50i driver could work to be honest. Seems IOMMU is >> broken on sun50i, but maybe I'm missing something. >> >> I added Maxime Ripard to this thread, who is the author of the >> sun50i-iommu driver. >> > > Actually, I now see that the other IOMMU drivers (qcom, exynos, etc) do > the same. So obviously I'm missing something and it should work.. > Okay, somehow I was oblivious to that of_dma_configure() invokes of_dma_configure_id(). Should be good :) ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 19:00, Dmitry Osipenko пишет: > 02.10.2020 18:23, Dmitry Osipenko пишет: >> 02.10.2020 09:08, Nicolin Chen пишет: >>> Then when a client gets probed, of_iommu_configure() in >>> iommu core will search DTB for swgroup ID and call ->of_xlate() >>> to prepare an fwspec, similar to tegra_smmu_probe_device() and >>> tegra_smmu_configure(). Then it'll call tegra_smmu_probe_device() >>> again, and this time we shall return smmu->iommu pointer properly. >> >> I don't quite see where IOMMU core calls of_xlate(). >> >> Have tried to at least boot-test this patch? >> > > I don't see how it ever could work because of_xlate() is only invoked from: > > fsl_mc_dma_configure()->of_dma_configure_id()->of_iommu_configure() > > Looks like the tegra_smmu_configure() is still needed. > > I don't know how sun50i driver could work to be honest. Seems IOMMU is > broken on sun50i, but maybe I'm missing something. > > I added Maxime Ripard to this thread, who is the author of the > sun50i-iommu driver. > Actually, I now see that the other IOMMU drivers (qcom, exynos, etc) do the same. So obviously I'm missing something and it should work.. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 18:23, Dmitry Osipenko пишет: > 02.10.2020 09:08, Nicolin Chen пишет: >> Then when a client gets probed, of_iommu_configure() in >> iommu core will search DTB for swgroup ID and call ->of_xlate() >> to prepare an fwspec, similar to tegra_smmu_probe_device() and >> tegra_smmu_configure(). Then it'll call tegra_smmu_probe_device() >> again, and this time we shall return smmu->iommu pointer properly. > > I don't quite see where IOMMU core calls of_xlate(). > > Have tried to at least boot-test this patch? > I don't see how it ever could work because of_xlate() is only invoked from: fsl_mc_dma_configure()->of_dma_configure_id()->of_iommu_configure() Looks like the tegra_smmu_configure() is still needed. I don't know how sun50i driver could work to be honest. Seems IOMMU is broken on sun50i, but maybe I'm missing something. I added Maxime Ripard to this thread, who is the author of the sun50i-iommu driver. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 09:08, Nicolin Chen пишет: > Then when a client gets probed, of_iommu_configure() in > iommu core will search DTB for swgroup ID and call ->of_xlate() > to prepare an fwspec, similar to tegra_smmu_probe_device() and > tegra_smmu_configure(). Then it'll call tegra_smmu_probe_device() > again, and this time we shall return smmu->iommu pointer properly. I don't quite see where IOMMU core calls of_xlate(). Have tried to at least boot-test this patch? ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 09:08, Nicolin Chen пишет: > static int tegra_smmu_of_xlate(struct device *dev, > struct of_phandle_args *args) > { > + struct platform_device *iommu_pdev = of_find_device_by_node(args->np); > + struct tegra_mc *mc = platform_get_drvdata(iommu_pdev); > u32 id = args->args[0]; > > + of_node_put(args->np); of_find_device_by_node() takes device reference and not the np reference. This is a bug, please remove of_node_put(). ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 17:22, Dmitry Osipenko пишет: > 02.10.2020 09:08, Nicolin Chen пишет: >> -static void tegra_smmu_release_device(struct device *dev) >> -{ >> -dev_iommu_priv_set(dev, NULL); >> -} >> +static void tegra_smmu_release_device(struct device *dev) {} > > Please keep the braces as-is. > I noticed that you borrowed this style from the sun50i-iommu driver, but this is a bit unusual coding style for the c files. At least to me it's unusual to see header-style function stub in a middle of c file. But maybe it's just me. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 1/3] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
02.10.2020 17:22, Dmitry Osipenko пишет: > 02.10.2020 09:08, Nicolin Chen пишет: >> static int tegra_smmu_attach_dev(struct iommu_domain *domain, >> struct device *dev) >> { >> +struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); >> struct tegra_smmu *smmu = dev_iommu_priv_get(dev); >> struct tegra_smmu_as *as = to_smmu_as(domain); >> -struct device_node *np = dev->of_node; >> -struct of_phandle_args args; >> unsigned int index = 0; >> int err = 0; > > Looks like there is no need to initialize 'index' and 'err' variables > anymore. > Same for tegra_smmu_detach_dev(). ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 17:22, Dmitry Osipenko пишет: >> static int tegra_smmu_of_xlate(struct device *dev, >> struct of_phandle_args *args) >> { >> +struct platform_device *iommu_pdev = of_find_device_by_node(args->np); >> +struct tegra_mc *mc = platform_get_drvdata(iommu_pdev); >> u32 id = args->args[0]; >> >> +of_node_put(args->np); >> + >> +if (!mc || !mc->smmu) >> +return -EPROBE_DEFER; > platform_get_drvdata(NULL) will crash. > Actually, platform_get_drvdata(NULL) can't happen. I overlooked this. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 1/3] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
02.10.2020 09:08, Nicolin Chen пишет: > static int tegra_smmu_attach_dev(struct iommu_domain *domain, >struct device *dev) > { > + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); > struct tegra_smmu *smmu = dev_iommu_priv_get(dev); > struct tegra_smmu_as *as = to_smmu_as(domain); > - struct device_node *np = dev->of_node; > - struct of_phandle_args args; > unsigned int index = 0; > int err = 0; > > - while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, > -&args)) { > - unsigned int swgroup = args.args[0]; > - > - if (args.np != smmu->dev->of_node) { > - of_node_put(args.np); > - continue; > - } > - > - of_node_put(args.np); > + if (!fwspec) > + return -ENOENT; Could the !fwspec ever be true here as well? ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 3/3] iommu/tegra-smmu: Add PCI support
02.10.2020 09:08, Nicolin Chen пишет: > @@ -865,7 +866,11 @@ static struct iommu_group > *tegra_smmu_device_group(struct device *dev) > group->smmu = smmu; > group->soc = soc; > > - group->group = iommu_group_alloc(); > + if (dev_is_pci(dev)) > + group->group = pci_device_group(dev); > + else > + group->group = generic_device_group(dev); > + > if (IS_ERR(group->group)) { > devm_kfree(smmu->dev, group); > mutex_unlock(&smmu->lock); > @@ -1069,22 +1074,32 @@ struct tegra_smmu *tegra_smmu_probe(struct device > *dev, > iommu_device_set_fwnode(&smmu->iommu, dev->fwnode); > > err = iommu_device_register(&smmu->iommu); > - if (err) { > - iommu_device_sysfs_remove(&smmu->iommu); > - return ERR_PTR(err); > - } > + if (err) > + goto err_sysfs; > > err = bus_set_iommu(&platform_bus_type, &tegra_smmu_ops); > - if (err < 0) { > - iommu_device_unregister(&smmu->iommu); > - iommu_device_sysfs_remove(&smmu->iommu); > - return ERR_PTR(err); > - } > + if (err < 0) > + goto err_unregister; > + > +#ifdef CONFIG_PCI > + err = bus_set_iommu(&pci_bus_type, &tegra_smmu_ops); > + if (err < 0) > + goto err_bus_set; > +#endif > > if (IS_ENABLED(CONFIG_DEBUG_FS)) > tegra_smmu_debugfs_init(smmu); > > return smmu; > + > +err_bus_set: __maybe_unused; __maybe_unused? ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 1/3] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
02.10.2020 09:08, Nicolin Chen пишет: > static void tegra_smmu_detach_dev(struct iommu_domain *domain, struct device > *dev) > { > + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); > struct tegra_smmu_as *as = to_smmu_as(domain); > - struct device_node *np = dev->of_node; > struct tegra_smmu *smmu = as->smmu; > - struct of_phandle_args args; > unsigned int index = 0; > > - while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, > -&args)) { > - unsigned int swgroup = args.args[0]; > - > - if (args.np != smmu->dev->of_node) { > - of_node_put(args.np); > - continue; > - } > - > - of_node_put(args.np); > + if (!fwspec) > + return; When !fwspec could be true? ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 09:08, Nicolin Chen пишет: > static struct iommu_device *tegra_smmu_probe_device(struct device *dev) > { > - struct device_node *np = dev->of_node; > - struct tegra_smmu *smmu = NULL; > - struct of_phandle_args args; > - unsigned int index = 0; > - int err; > - > - while (of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index, > - &args) == 0) { > - smmu = tegra_smmu_find(args.np); > - if (smmu) { > - err = tegra_smmu_configure(smmu, dev, &args); > - of_node_put(args.np); > - > - if (err < 0) > - return ERR_PTR(err); > - > - /* > - * Only a single IOMMU master interface is currently > - * supported by the Linux kernel, so abort after the > - * first match. > - */ > - dev_iommu_priv_set(dev, smmu); > - > - break; > - } > - > - of_node_put(args.np); > - index++; > - } > + struct tegra_smmu *smmu = dev_iommu_priv_get(dev); > > if (!smmu) > return ERR_PTR(-ENODEV); The !smmu can't ever be true now, isn't it? Then please remove it. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 09:08, Nicolin Chen пишет: > static int tegra_smmu_of_xlate(struct device *dev, > struct of_phandle_args *args) > { > + struct platform_device *iommu_pdev = of_find_device_by_node(args->np); > + struct tegra_mc *mc = platform_get_drvdata(iommu_pdev); > u32 id = args->args[0]; > > + of_node_put(args->np); > + > + if (!mc || !mc->smmu) > + return -EPROBE_DEFER; platform_get_drvdata(NULL) will crash. > + dev_iommu_priv_set(dev, mc->smmu); I think put_device(mc->dev) is missed here, doesn't it? Why sun50i-iommu driver doesn't have this error-checking? Is it really needed at all? ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 1/3] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
02.10.2020 09:08, Nicolin Chen пишет: > static int tegra_smmu_attach_dev(struct iommu_domain *domain, >struct device *dev) > { > + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); > struct tegra_smmu *smmu = dev_iommu_priv_get(dev); > struct tegra_smmu_as *as = to_smmu_as(domain); > - struct device_node *np = dev->of_node; > - struct of_phandle_args args; > unsigned int index = 0; > int err = 0; Looks like there is no need to initialize 'index' and 'err' variables anymore. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 2/3] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
02.10.2020 09:08, Nicolin Chen пишет: > -static void tegra_smmu_release_device(struct device *dev) > -{ > - dev_iommu_priv_set(dev, NULL); > -} > +static void tegra_smmu_release_device(struct device *dev) {} Please keep the braces as-is. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 00/13] iommu/amd: Add Generic IO Page Table Framework Support
The framework allows callable implementation of IO page table. This allows AMD IOMMU driver to switch between different types of AMD IOMMU page tables (e.g. v1 vs. v2). This series refactors the current implementation of AMD IOMMU v1 page table to adopt the framework. There should be no functional change. Subsequent series will introduce support for the AMD IOMMU v2 page table. Thanks, Suravee Change from V1 (https://lkml.org/lkml/2020/9/23/251) - Do not specify struct io_pgtable_cfg.coherent_walk, since it is not currently used. (per Robin) - Remove unused struct iommu_flush_ops. (patch 2/13) - Move amd_iommu_setup_io_pgtable_ops to iommu.c instead of io_pgtable.c patch 13/13) Suravee Suthikulpanit (13): iommu/amd: Re-define amd_iommu_domain_encode_pgtable as inline iommu/amd: Prepare for generic IO page table framework iommu/amd: Move pt_root to to struct amd_io_pgtable iommu/amd: Convert to using amd_io_pgtable iommu/amd: Declare functions as extern iommu/amd: Move IO page table related functions iommu/amd: Restructure code for freeing page table iommu/amd: Remove amd_iommu_domain_get_pgtable iommu/amd: Rename variables to be consistent with struct io_pgtable_ops iommu/amd: Refactor fetch_pte to use struct amd_io_pgtable iommu/amd: Introduce iommu_v1_iova_to_phys iommu/amd: Introduce iommu_v1_map_page and iommu_v1_unmap_page iommu/amd: Adopt IO page table framework drivers/iommu/amd/Kconfig | 1 + drivers/iommu/amd/Makefile | 2 +- drivers/iommu/amd/amd_iommu.h | 22 + drivers/iommu/amd/amd_iommu_types.h | 40 +- drivers/iommu/amd/io_pgtable.c | 534 +++ drivers/iommu/amd/iommu.c | 644 +++- drivers/iommu/io-pgtable.c | 3 + include/linux/io-pgtable.h | 2 + 8 files changed, 656 insertions(+), 592 deletions(-) create mode 100644 drivers/iommu/amd/io_pgtable.c -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 04/13] iommu/amd: Convert to using amd_io_pgtable
Make use of the new struct amd_io_pgtable in preparation to remove the struct domain_pgtable. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/amd_iommu.h | 1 + drivers/iommu/amd/iommu.c | 25 ++--- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index da6e09657e00..22ecacb71675 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -47,6 +47,7 @@ extern void amd_iommu_domain_direct_map(struct iommu_domain *dom); extern int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids); extern int amd_iommu_flush_page(struct iommu_domain *dom, int pasid, u64 address); +extern void amd_iommu_update_and_flush_device_table(struct protection_domain *domain); extern int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid); extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, unsigned long cr3); diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index c8b8619cc744..09da37c4c9c4 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -90,8 +90,6 @@ struct kmem_cache *amd_iommu_irq_cache; static void update_domain(struct protection_domain *domain); static void detach_device(struct device *dev); -static void update_and_flush_device_table(struct protection_domain *domain, - struct domain_pgtable *pgtable); / * @@ -1482,7 +1480,7 @@ static bool increase_address_space(struct protection_domain *domain, pgtable.root = pte; pgtable.mode += 1; - update_and_flush_device_table(domain, &pgtable); + amd_iommu_update_and_flush_device_table(domain); domain_flush_complete(domain); /* @@ -1857,17 +1855,16 @@ static void free_gcr3_table(struct protection_domain *domain) } static void set_dte_entry(u16 devid, struct protection_domain *domain, - struct domain_pgtable *pgtable, bool ats, bool ppr) { u64 pte_root = 0; u64 flags = 0; u32 old_domid; - if (pgtable->mode != PAGE_MODE_NONE) - pte_root = iommu_virt_to_phys(pgtable->root); + if (domain->iop.mode != PAGE_MODE_NONE) + pte_root = iommu_virt_to_phys(domain->iop.root); - pte_root |= (pgtable->mode & DEV_ENTRY_MODE_MASK) + pte_root |= (domain->iop.mode & DEV_ENTRY_MODE_MASK) << DEV_ENTRY_MODE_SHIFT; pte_root |= DTE_FLAG_IR | DTE_FLAG_IW | DTE_FLAG_V | DTE_FLAG_TV; @@ -1957,7 +1954,7 @@ static void do_attach(struct iommu_dev_data *dev_data, /* Update device table */ amd_iommu_domain_get_pgtable(domain, &pgtable); - set_dte_entry(dev_data->devid, domain, &pgtable, + set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2); clone_aliases(dev_data->pdev); @@ -2263,22 +2260,20 @@ static int amd_iommu_domain_get_attr(struct iommu_domain *domain, * */ -static void update_device_table(struct protection_domain *domain, - struct domain_pgtable *pgtable) +static void update_device_table(struct protection_domain *domain) { struct iommu_dev_data *dev_data; list_for_each_entry(dev_data, &domain->dev_list, list) { - set_dte_entry(dev_data->devid, domain, pgtable, + set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled, dev_data->iommu_v2); clone_aliases(dev_data->pdev); } } -static void update_and_flush_device_table(struct protection_domain *domain, - struct domain_pgtable *pgtable) +void amd_iommu_update_and_flush_device_table(struct protection_domain *domain) { - update_device_table(domain, pgtable); + update_device_table(domain); domain_flush_devices(domain); } @@ -2288,7 +2283,7 @@ static void update_domain(struct protection_domain *domain) /* Update device table */ amd_iommu_domain_get_pgtable(domain, &pgtable); - update_and_flush_device_table(domain, &pgtable); + amd_iommu_update_and_flush_device_table(domain); /* Flush domain TLB(s) and wait for completion */ domain_flush_tlb_pde(domain); -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 03/13] iommu/amd: Move pt_root to to struct amd_io_pgtable
To better organize the data structure since it contains IO page table related information. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/amd_iommu.h | 2 +- drivers/iommu/amd/amd_iommu_types.h | 2 +- drivers/iommu/amd/iommu.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index 97cdb235ce69..da6e09657e00 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -96,7 +96,7 @@ static inline void *iommu_phys_to_virt(unsigned long paddr) static inline void amd_iommu_domain_set_pt_root(struct protection_domain *domain, u64 root) { - atomic64_set(&domain->pt_root, root); + atomic64_set(&domain->iop.pt_root, root); } static inline diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h index 77cd8d966fbc..5d53b7bec256 100644 --- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -490,6 +490,7 @@ struct amd_io_pgtable { struct io_pgtable iop; int mode; u64 *root; + atomic64_t pt_root; /* pgtable root and pgtable mode */ }; /* @@ -503,7 +504,6 @@ struct protection_domain { struct amd_io_pgtable iop; spinlock_t lock;/* mostly used to lock the page table*/ u16 id; /* the domain id written to the device table */ - atomic64_t pt_root; /* pgtable root and pgtable mode */ int glx;/* Number of levels for GCR3 table */ u64 *gcr3_tbl; /* Guest CR3 table */ unsigned long flags;/* flags to find out type of domain */ diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 2b7eb51dcbb8..c8b8619cc744 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -146,7 +146,7 @@ static struct protection_domain *to_pdomain(struct iommu_domain *dom) static void amd_iommu_domain_get_pgtable(struct protection_domain *domain, struct domain_pgtable *pgtable) { - u64 pt_root = atomic64_read(&domain->pt_root); + u64 pt_root = atomic64_read(&domain->iop.pt_root); pgtable->root = (u64 *)(pt_root & PAGE_MASK); pgtable->mode = pt_root & 7; /* lowest 3 bits encode pgtable mode */ -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 05/13] iommu/amd: Declare functions as extern
And move declaration to header file so that they can be included across multiple files. There is no functional change. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/amd_iommu.h | 3 +++ drivers/iommu/amd/iommu.c | 39 +-- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index 22ecacb71675..8b7be9171030 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -48,6 +48,9 @@ extern int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids); extern int amd_iommu_flush_page(struct iommu_domain *dom, int pasid, u64 address); extern void amd_iommu_update_and_flush_device_table(struct protection_domain *domain); +extern void amd_iommu_domain_update(struct protection_domain *domain); +extern void amd_iommu_domain_flush_complete(struct protection_domain *domain); +extern void amd_iommu_domain_flush_tlb_pde(struct protection_domain *domain); extern int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid); extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, unsigned long cr3); diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 09da37c4c9c4..f91f35edb7ba 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -88,7 +88,6 @@ struct iommu_cmd { struct kmem_cache *amd_iommu_irq_cache; -static void update_domain(struct protection_domain *domain); static void detach_device(struct device *dev); / @@ -1294,12 +1293,12 @@ static void domain_flush_pages(struct protection_domain *domain, } /* Flush the whole IO/TLB for a given protection domain - including PDE */ -static void domain_flush_tlb_pde(struct protection_domain *domain) +void amd_iommu_domain_flush_tlb_pde(struct protection_domain *domain) { __domain_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1); } -static void domain_flush_complete(struct protection_domain *domain) +void amd_iommu_domain_flush_complete(struct protection_domain *domain) { int i; @@ -1324,7 +1323,7 @@ static void domain_flush_np_cache(struct protection_domain *domain, spin_lock_irqsave(&domain->lock, flags); domain_flush_pages(domain, iova, size); - domain_flush_complete(domain); + amd_iommu_domain_flush_complete(domain); spin_unlock_irqrestore(&domain->lock, flags); } } @@ -1481,7 +1480,7 @@ static bool increase_address_space(struct protection_domain *domain, pgtable.root = pte; pgtable.mode += 1; amd_iommu_update_and_flush_device_table(domain); - domain_flush_complete(domain); + amd_iommu_domain_flush_complete(domain); /* * Device Table needs to be updated and flushed before the new root can @@ -1734,8 +1733,8 @@ static int iommu_map_page(struct protection_domain *dom, * Updates and flushing already happened in * increase_address_space(). */ - domain_flush_tlb_pde(dom); - domain_flush_complete(dom); + amd_iommu_domain_flush_tlb_pde(dom); + amd_iommu_domain_flush_complete(dom); spin_unlock_irqrestore(&dom->lock, flags); } @@ -1978,10 +1977,10 @@ static void do_detach(struct iommu_dev_data *dev_data) device_flush_dte(dev_data); /* Flush IOTLB */ - domain_flush_tlb_pde(domain); + amd_iommu_domain_flush_tlb_pde(domain); /* Wait for the flushes to finish */ - domain_flush_complete(domain); + amd_iommu_domain_flush_complete(domain); /* decrease reference counters - needs to happen after the flushes */ domain->dev_iommu[iommu->index] -= 1; @@ -2114,9 +2113,9 @@ static int attach_device(struct device *dev, * left the caches in the IOMMU dirty. So we have to flush * here to evict all dirty stuff. */ - domain_flush_tlb_pde(domain); + amd_iommu_domain_flush_tlb_pde(domain); - domain_flush_complete(domain); + amd_iommu_domain_flush_complete(domain); out: spin_unlock(&dev_data->lock); @@ -2277,7 +2276,7 @@ void amd_iommu_update_and_flush_device_table(struct protection_domain *domain) domain_flush_devices(domain); } -static void update_domain(struct protection_domain *domain) +void amd_iommu_domain_update(struct protection_domain *domain) { struct domain_pgtable pgtable; @@ -2286,8 +2285,8 @@ static void update_domain(struct protection_domain *domain) amd_iommu_update_and_flush_device_table(domain); /* Flush domain TLB(s) and wait for completion */ - domain_flush_tlb_pde(domain); - domain_flush_complete(domain); + amd_iommu_do
[PATCH v2 01/13] iommu/amd: Re-define amd_iommu_domain_encode_pgtable as inline
Move the function to header file to allow inclusion in other files. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/amd_iommu.h | 13 + drivers/iommu/amd/iommu.c | 10 -- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index 57309716fd18..97cdb235ce69 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -93,6 +93,19 @@ static inline void *iommu_phys_to_virt(unsigned long paddr) return phys_to_virt(__sme_clr(paddr)); } +static inline +void amd_iommu_domain_set_pt_root(struct protection_domain *domain, u64 root) +{ + atomic64_set(&domain->pt_root, root); +} + +static inline +void amd_iommu_domain_clr_pt_root(struct protection_domain *domain) +{ + amd_iommu_domain_set_pt_root(domain, 0); +} + + extern bool translation_pre_enabled(struct amd_iommu *iommu); extern bool amd_iommu_is_attach_deferred(struct iommu_domain *domain, struct device *dev); diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index db4fb840c59c..e92b3f744292 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -162,16 +162,6 @@ static void amd_iommu_domain_get_pgtable(struct protection_domain *domain, pgtable->mode = pt_root & 7; /* lowest 3 bits encode pgtable mode */ } -static void amd_iommu_domain_set_pt_root(struct protection_domain *domain, u64 root) -{ - atomic64_set(&domain->pt_root, root); -} - -static void amd_iommu_domain_clr_pt_root(struct protection_domain *domain) -{ - amd_iommu_domain_set_pt_root(domain, 0); -} - static void amd_iommu_domain_set_pgtable(struct protection_domain *domain, u64 *root, int mode) { -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 02/13] iommu/amd: Prepare for generic IO page table framework
Add initial hook up code to implement generic IO page table framework. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/Kconfig | 1 + drivers/iommu/amd/Makefile | 2 +- drivers/iommu/amd/amd_iommu_types.h | 32 + drivers/iommu/amd/io_pgtable.c | 43 + drivers/iommu/amd/iommu.c | 10 --- drivers/iommu/io-pgtable.c | 3 ++ include/linux/io-pgtable.h | 2 ++ 7 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 drivers/iommu/amd/io_pgtable.c diff --git a/drivers/iommu/amd/Kconfig b/drivers/iommu/amd/Kconfig index 626b97d0dd21..a3cbafb603f5 100644 --- a/drivers/iommu/amd/Kconfig +++ b/drivers/iommu/amd/Kconfig @@ -10,6 +10,7 @@ config AMD_IOMMU select IOMMU_API select IOMMU_IOVA select IOMMU_DMA + select IOMMU_IO_PGTABLE depends on X86_64 && PCI && ACPI && HAVE_CMPXCHG_DOUBLE help With this option you can enable support for AMD IOMMU hardware in diff --git a/drivers/iommu/amd/Makefile b/drivers/iommu/amd/Makefile index dc5a2fa4fd37..a935f8f4b974 100644 --- a/drivers/iommu/amd/Makefile +++ b/drivers/iommu/amd/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_AMD_IOMMU) += iommu.o init.o quirks.o +obj-$(CONFIG_AMD_IOMMU) += iommu.o init.o quirks.o io_pgtable.o obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += iommu_v2.o diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h index f696ac7c5f89..77cd8d966fbc 100644 --- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -15,6 +15,7 @@ #include #include #include +#include /* * Maximum number of IOMMUs supported @@ -252,6 +253,19 @@ #define GA_GUEST_NR0x1 +#define IOMMU_IN_ADDR_BIT_SIZE 52 +#define IOMMU_OUT_ADDR_BIT_SIZE 52 + +/* + * This bitmap is used to advertise the page sizes our hardware support + * to the IOMMU core, which will then use this information to split + * physically contiguous memory regions it is mapping into page sizes + * that we support. + * + * 512GB Pages are not supported due to a hardware bug + */ +#define AMD_IOMMU_PGSIZES ((~0xFFFUL) & ~(2ULL << 38)) + /* Bit value definition for dte irq remapping fields*/ #define DTE_IRQ_PHYS_ADDR_MASK (((1ULL << 45)-1) << 6) #define DTE_IRQ_REMAP_INTCTL_MASK (0x3ULL << 60) @@ -461,6 +475,23 @@ struct amd_irte_ops; #define AMD_IOMMU_FLAG_TRANS_PRE_ENABLED (1 << 0) +#define io_pgtable_to_data(x) \ + container_of((x), struct amd_io_pgtable, iop) + +#define io_pgtable_ops_to_data(x) \ + io_pgtable_to_data(io_pgtable_ops_to_pgtable(x)) + +#define io_pgtable_ops_to_domain(x) \ + container_of(io_pgtable_ops_to_data(x), \ +struct protection_domain, iop) + +struct amd_io_pgtable { + struct io_pgtable_cfg pgtbl_cfg; + struct io_pgtable iop; + int mode; + u64 *root; +}; + /* * This structure contains generic data for IOMMU protection domains * independent of their use. @@ -469,6 +500,7 @@ struct protection_domain { struct list_head dev_list; /* List of all devices in this domain */ struct iommu_domain domain; /* generic domain handle used by iommu core code */ + struct amd_io_pgtable iop; spinlock_t lock;/* mostly used to lock the page table*/ u16 id; /* the domain id written to the device table */ atomic64_t pt_root; /* pgtable root and pgtable mode */ diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c new file mode 100644 index ..f123ab6e8a51 --- /dev/null +++ b/drivers/iommu/amd/io_pgtable.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * CPU-agnostic AMD IO page table allocator. + * + * Copyright (C) 2020 Advanced Micro Devices, Inc. + * Author: Suravee Suthikulpanit + */ + +#define pr_fmt(fmt) "AMD-Vi: " fmt +#define dev_fmt(fmt)pr_fmt(fmt) + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "amd_iommu_types.h" +#include "amd_iommu.h" + +/* + * + */ +static void v1_free_pgtable(struct io_pgtable *iop) +{ +} + +static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) +{ + struct protection_domain *pdom = (struct protection_domain *)cookie; + + return &pdom->iop.iop; +} + +struct io_pgtable_init_fns io_pgtable_amd_iommu_v1_init_fns = { + .alloc = v1_alloc_pgtable, + .free = v1_free_pgtable, +}; diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index e92b3f744292..2b7eb51dcbb8 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -59,16 +59,6 @@ #define
xen-swiotlb vs phys_to_dma
Hi Stefano, I've looked over xen-swiotlb in linux-next, that is with your recent changes to take dma offsets into account. One thing that puzzles me is that xen_swiotlb_map_page passes virt_to_phys(xen_io_tlb_start) as the tbl_dma_addr argument to swiotlb_tbl_map_single, despite the fact that the argument is a dma_addr_t and both other callers translate from a physical to the dma address. Was this an oversight? ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 12/13] iommu/amd: Introduce iommu_v1_map_page and iommu_v1_unmap_page
These implement map and unmap for AMD IOMMU v1 pagetable, which will be used by the IO pagetable framework. Also clean up unused extern function declarations. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/amd_iommu.h | 13 - drivers/iommu/amd/io_pgtable.c | 25 - drivers/iommu/amd/iommu.c | 7 --- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index 69996e57fae2..2e8dc2a1ec0f 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -124,19 +124,6 @@ void amd_iommu_apply_ivrs_quirks(void); static inline void amd_iommu_apply_ivrs_quirks(void) { } #endif -/* TODO: These are temporary and will be removed once fully transition */ -extern int iommu_map_page(struct protection_domain *dom, - unsigned long bus_addr, - unsigned long phys_addr, - unsigned long page_size, - int prot, - gfp_t gfp); -extern unsigned long iommu_unmap_page(struct protection_domain *dom, - unsigned long bus_addr, - unsigned long page_size); -extern u64 *fetch_pte(struct amd_io_pgtable *pgtable, - unsigned long address, - unsigned long *page_size); extern void amd_iommu_domain_set_pgtable(struct protection_domain *domain, u64 *root, int mode); extern void amd_iommu_free_pgtable(struct amd_io_pgtable *pgtable); diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c index bbbf18d2514a..a5f8d80a9d35 100644 --- a/drivers/iommu/amd/io_pgtable.c +++ b/drivers/iommu/amd/io_pgtable.c @@ -317,9 +317,9 @@ static u64 *alloc_pte(struct protection_domain *domain, * This function checks if there is a PTE for a given dma address. If * there is one, it returns the pointer to it. */ -u64 *fetch_pte(struct amd_io_pgtable *pgtable, - unsigned long address, - unsigned long *page_size) +static u64 *fetch_pte(struct amd_io_pgtable *pgtable, + unsigned long address, + unsigned long *page_size) { int level; u64 *pte; @@ -392,13 +392,10 @@ static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist) * supporting all features of AMD IOMMU page tables like level skipping * and full 64 bit address spaces. */ -int iommu_map_page(struct protection_domain *dom, - unsigned long iova, - unsigned long paddr, - unsigned long size, - int prot, - gfp_t gfp) +static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova, + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { + struct protection_domain *dom = io_pgtable_ops_to_domain(ops); struct page *freelist = NULL; bool updated = false; u64 __pte, *pte; @@ -461,11 +458,11 @@ int iommu_map_page(struct protection_domain *dom, return ret; } -unsigned long iommu_unmap_page(struct protection_domain *dom, - unsigned long iova, - unsigned long size) +static unsigned long iommu_v1_unmap_page(struct io_pgtable_ops *ops, + unsigned long iova, + size_t size, + struct iommu_iotlb_gather *gather) { - struct io_pgtable_ops *ops = &dom->iop.iop.ops; struct amd_io_pgtable *pgtable = io_pgtable_ops_to_data(ops); unsigned long long unmapped; unsigned long unmap_size; @@ -525,6 +522,8 @@ static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *coo { struct protection_domain *pdom = (struct protection_domain *)cookie; + pdom->iop.iop.ops.map = iommu_v1_map_page; + pdom->iop.iop.ops.unmap= iommu_v1_unmap_page; pdom->iop.iop.ops.iova_to_phys = iommu_v1_iova_to_phys; return &pdom->iop.iop; } diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 9a1a16031e00..77f44b927ae7 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -2044,6 +2044,7 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, gfp_t gfp) { struct protection_domain *domain = to_pdomain(dom); + struct io_pgtable_ops *ops = &domain->iop.iop.ops; int prot = 0; int ret; @@ -2055,8 +2056,7 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, if (iommu_prot & IOMMU_WRITE) prot |= IOMMU_PROT_IW; - ret = iommu_map_page(domain, iova, paddr, page_size, prot, gfp); - + ret = ops->map(ops, iova, paddr, page_size,
[PATCH v2 13/13] iommu/amd: Adopt IO page table framework
Switch to using IO page table framework for AMD IOMMU v1 page table. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/iommu.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 77f44b927ae7..c28949be3442 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1573,6 +1574,20 @@ static int pdev_iommuv2_enable(struct pci_dev *pdev) return ret; } +struct io_pgtable_ops * +amd_iommu_setup_io_pgtable_ops(struct iommu_dev_data *dev_data, + struct protection_domain *domain) +{ + domain->iop.pgtbl_cfg = (struct io_pgtable_cfg) { + .pgsize_bitmap = AMD_IOMMU_PGSIZES, + .ias= IOMMU_IN_ADDR_BIT_SIZE, + .oas= IOMMU_OUT_ADDR_BIT_SIZE, + .iommu_dev = &dev_data->pdev->dev, + }; + + return alloc_io_pgtable_ops(AMD_IOMMU_V1, &domain->iop.pgtbl_cfg, domain); +} + /* * If a device is not yet associated with a domain, this function makes the * device visible in the domain @@ -1580,6 +1595,7 @@ static int pdev_iommuv2_enable(struct pci_dev *pdev) static int attach_device(struct device *dev, struct protection_domain *domain) { + struct io_pgtable_ops *pgtbl_ops; struct iommu_dev_data *dev_data; struct pci_dev *pdev; unsigned long flags; @@ -1623,6 +1639,12 @@ static int attach_device(struct device *dev, skip_ats_check: ret = 0; + pgtbl_ops = amd_iommu_setup_io_pgtable_ops(dev_data, domain); + if (!pgtbl_ops) { + ret = -ENOMEM; + goto out; + } + do_attach(dev_data, domain); /* @@ -1958,6 +1980,8 @@ static void amd_iommu_domain_free(struct iommu_domain *dom) if (domain->dev_cnt > 0) cleanup_domain(domain); + free_io_pgtable_ops(&domain->iop.iop.ops); + BUG_ON(domain->dev_cnt != 0); if (!dom) -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 10/13] iommu/amd: Refactor fetch_pte to use struct amd_io_pgtable
To simplify the fetch_pte function. There is no functional change. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/amd_iommu.h | 2 +- drivers/iommu/amd/io_pgtable.c | 13 +++-- drivers/iommu/amd/iommu.c | 4 +++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index 2059e64fdc53..69996e57fae2 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -134,7 +134,7 @@ extern int iommu_map_page(struct protection_domain *dom, extern unsigned long iommu_unmap_page(struct protection_domain *dom, unsigned long bus_addr, unsigned long page_size); -extern u64 *fetch_pte(struct protection_domain *domain, +extern u64 *fetch_pte(struct amd_io_pgtable *pgtable, unsigned long address, unsigned long *page_size); extern void amd_iommu_domain_set_pgtable(struct protection_domain *domain, diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c index ff1294e8729d..1729c303bae5 100644 --- a/drivers/iommu/amd/io_pgtable.c +++ b/drivers/iommu/amd/io_pgtable.c @@ -317,7 +317,7 @@ static u64 *alloc_pte(struct protection_domain *domain, * This function checks if there is a PTE for a given dma address. If * there is one, it returns the pointer to it. */ -u64 *fetch_pte(struct protection_domain *domain, +u64 *fetch_pte(struct amd_io_pgtable *pgtable, unsigned long address, unsigned long *page_size) { @@ -326,11 +326,11 @@ u64 *fetch_pte(struct protection_domain *domain, *page_size = 0; - if (address > PM_LEVEL_SIZE(domain->iop.mode)) + if (address > PM_LEVEL_SIZE(pgtable->mode)) return NULL; - level = domain->iop.mode - 1; - pte= &domain->iop.root[PM_LEVEL_INDEX(level, address)]; + level = pgtable->mode - 1; + pte= &pgtable->root[PM_LEVEL_INDEX(level, address)]; *page_size = PTE_LEVEL_PAGE_SIZE(level); while (level > 0) { @@ -465,6 +465,8 @@ unsigned long iommu_unmap_page(struct protection_domain *dom, unsigned long iova, unsigned long size) { + struct io_pgtable_ops *ops = &dom->iop.iop.ops; + struct amd_io_pgtable *pgtable = io_pgtable_ops_to_data(ops); unsigned long long unmapped; unsigned long unmap_size; u64 *pte; @@ -474,8 +476,7 @@ unsigned long iommu_unmap_page(struct protection_domain *dom, unmapped = 0; while (unmapped < size) { - pte = fetch_pte(dom, iova, &unmap_size); - + pte = fetch_pte(pgtable, iova, &unmap_size); if (pte) { int i, count; diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 3f6ede1e572c..87cea1cde414 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -2078,13 +2078,15 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, dma_addr_t iova) { struct protection_domain *domain = to_pdomain(dom); + struct io_pgtable_ops *ops = &domain->iop.iop.ops; + struct amd_io_pgtable *pgtable = io_pgtable_ops_to_data(ops); unsigned long offset_mask, pte_pgsize; u64 *pte, __pte; if (domain->iop.mode == PAGE_MODE_NONE) return iova; - pte = fetch_pte(domain, iova, &pte_pgsize); + pte = fetch_pte(pgtable, iova, &pte_pgsize); if (!pte || !IOMMU_PTE_PRESENT(*pte)) return 0; -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 09/13] iommu/amd: Rename variables to be consistent with struct io_pgtable_ops
There is no functional change. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/io_pgtable.c | 31 +++ 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c index a2acd7e85ec3..ff1294e8729d 100644 --- a/drivers/iommu/amd/io_pgtable.c +++ b/drivers/iommu/amd/io_pgtable.c @@ -393,9 +393,9 @@ static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist) * and full 64 bit address spaces. */ int iommu_map_page(struct protection_domain *dom, - unsigned long bus_addr, - unsigned long phys_addr, - unsigned long page_size, + unsigned long iova, + unsigned long paddr, + unsigned long size, int prot, gfp_t gfp) { @@ -404,15 +404,15 @@ int iommu_map_page(struct protection_domain *dom, u64 __pte, *pte; int ret, i, count; - BUG_ON(!IS_ALIGNED(bus_addr, page_size)); - BUG_ON(!IS_ALIGNED(phys_addr, page_size)); + BUG_ON(!IS_ALIGNED(iova, size)); + BUG_ON(!IS_ALIGNED(paddr, size)); ret = -EINVAL; if (!(prot & IOMMU_PROT_MASK)) goto out; - count = PAGE_SIZE_PTE_COUNT(page_size); - pte = alloc_pte(dom, bus_addr, page_size, NULL, gfp, &updated); + count = PAGE_SIZE_PTE_COUNT(size); + pte = alloc_pte(dom, iova, size, NULL, gfp, &updated); ret = -ENOMEM; if (!pte) @@ -425,10 +425,10 @@ int iommu_map_page(struct protection_domain *dom, updated = true; if (count > 1) { - __pte = PAGE_SIZE_PTE(__sme_set(phys_addr), page_size); + __pte = PAGE_SIZE_PTE(__sme_set(paddr), size); __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_PR | IOMMU_PTE_FC; } else - __pte = __sme_set(phys_addr) | IOMMU_PTE_PR | IOMMU_PTE_FC; + __pte = __sme_set(paddr) | IOMMU_PTE_PR | IOMMU_PTE_FC; if (prot & IOMMU_PROT_IR) __pte |= IOMMU_PTE_IR; @@ -462,20 +462,19 @@ int iommu_map_page(struct protection_domain *dom, } unsigned long iommu_unmap_page(struct protection_domain *dom, - unsigned long bus_addr, - unsigned long page_size) + unsigned long iova, + unsigned long size) { unsigned long long unmapped; unsigned long unmap_size; u64 *pte; - BUG_ON(!is_power_of_2(page_size)); + BUG_ON(!is_power_of_2(size)); unmapped = 0; - while (unmapped < page_size) { - - pte = fetch_pte(dom, bus_addr, &unmap_size); + while (unmapped < size) { + pte = fetch_pte(dom, iova, &unmap_size); if (pte) { int i, count; @@ -485,7 +484,7 @@ unsigned long iommu_unmap_page(struct protection_domain *dom, pte[i] = 0ULL; } - bus_addr = (bus_addr & ~(unmap_size - 1)) + unmap_size; + iova = (iova & ~(unmap_size - 1)) + unmap_size; unmapped += unmap_size; } -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 06/13] iommu/amd: Move IO page table related functions
Preparing to migrate to use IO page table framework. There is no functional change. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/amd_iommu.h | 18 ++ drivers/iommu/amd/io_pgtable.c | 473 drivers/iommu/amd/iommu.c | 476 + 3 files changed, 493 insertions(+), 474 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index 8b7be9171030..ee7ff4d827e1 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -122,4 +122,22 @@ void amd_iommu_apply_ivrs_quirks(void); static inline void amd_iommu_apply_ivrs_quirks(void) { } #endif +/* TODO: These are temporary and will be removed once fully transition */ +extern void free_pagetable(struct domain_pgtable *pgtable); +extern int iommu_map_page(struct protection_domain *dom, + unsigned long bus_addr, + unsigned long phys_addr, + unsigned long page_size, + int prot, + gfp_t gfp); +extern unsigned long iommu_unmap_page(struct protection_domain *dom, + unsigned long bus_addr, + unsigned long page_size); +extern u64 *fetch_pte(struct protection_domain *domain, + unsigned long address, + unsigned long *page_size); +extern void amd_iommu_domain_get_pgtable(struct protection_domain *domain, +struct domain_pgtable *pgtable); +extern void amd_iommu_domain_set_pgtable(struct protection_domain *domain, +u64 *root, int mode); #endif diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c index f123ab6e8a51..7fd3dd9db197 100644 --- a/drivers/iommu/amd/io_pgtable.c +++ b/drivers/iommu/amd/io_pgtable.c @@ -23,6 +23,479 @@ #include "amd_iommu_types.h" #include "amd_iommu.h" +/* + * Helper function to get the first pte of a large mapping + */ +static u64 *first_pte_l7(u64 *pte, unsigned long *page_size, +unsigned long *count) +{ + unsigned long pte_mask, pg_size, cnt; + u64 *fpte; + + pg_size = PTE_PAGE_SIZE(*pte); + cnt = PAGE_SIZE_PTE_COUNT(pg_size); + pte_mask = ~((cnt << 3) - 1); + fpte = (u64 *)(((unsigned long)pte) & pte_mask); + + if (page_size) + *page_size = pg_size; + + if (count) + *count = cnt; + + return fpte; +} + +/ + * + * The functions below are used the create the page table mappings for + * unity mapped regions. + * + / + +static void free_page_list(struct page *freelist) +{ + while (freelist != NULL) { + unsigned long p = (unsigned long)page_address(freelist); + + freelist = freelist->freelist; + free_page(p); + } +} + +static struct page *free_pt_page(unsigned long pt, struct page *freelist) +{ + struct page *p = virt_to_page((void *)pt); + + p->freelist = freelist; + + return p; +} + +#define DEFINE_FREE_PT_FN(LVL, FN) \ +static struct page *free_pt_##LVL (unsigned long __pt, struct page *freelist) \ +{ \ + unsigned long p; \ + u64 *pt; \ + int i; \ + \ + pt = (u64 *)__pt; \ + \ + for (i = 0; i < 512; ++i) { \ + /* PTE present? */ \ + if (!IOMMU_PTE_PRESENT(pt[i])) \ + continue; \ + \ + /* Large PTE? */ \ + if (PM_PTE_LEVEL(pt[i]) == 0 || \ + PM_PTE_LEVEL(pt[i]) == 7) \ + continue; \ + \ + p = (unsigned long)IOMMU_PTE_PAGE(pt[i]); \ + freelist = FN(p, free
[PATCH v2 08/13] iommu/amd: Remove amd_iommu_domain_get_pgtable
Since the IO page table root and mode parameters have been moved into the struct amd_io_pg, the function is no longer needed. Therefore, remove it along with the struct domain_pgtable. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/amd_iommu.h | 4 ++-- drivers/iommu/amd/amd_iommu_types.h | 6 - drivers/iommu/amd/io_pgtable.c | 36 ++--- drivers/iommu/amd/iommu.c | 34 --- 4 files changed, 19 insertions(+), 61 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index 8dff7d85be79..2059e64fdc53 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -101,6 +101,8 @@ static inline void amd_iommu_domain_set_pt_root(struct protection_domain *domain, u64 root) { atomic64_set(&domain->iop.pt_root, root); + domain->iop.root = (u64 *)(root & PAGE_MASK); + domain->iop.mode = root & 7; /* lowest 3 bits encode pgtable mode */ } static inline @@ -135,8 +137,6 @@ extern unsigned long iommu_unmap_page(struct protection_domain *dom, extern u64 *fetch_pte(struct protection_domain *domain, unsigned long address, unsigned long *page_size); -extern void amd_iommu_domain_get_pgtable(struct protection_domain *domain, -struct domain_pgtable *pgtable); extern void amd_iommu_domain_set_pgtable(struct protection_domain *domain, u64 *root, int mode); extern void amd_iommu_free_pgtable(struct amd_io_pgtable *pgtable); diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h index 5d53b7bec256..a07af389eae1 100644 --- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -511,12 +511,6 @@ struct protection_domain { unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */ }; -/* For decocded pt_root */ -struct domain_pgtable { - int mode; - u64 *root; -}; - /* * Structure where we save information about one hardware AMD IOMMU in the * system. diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c index 0c886419166b..a2acd7e85ec3 100644 --- a/drivers/iommu/amd/io_pgtable.c +++ b/drivers/iommu/amd/io_pgtable.c @@ -184,30 +184,27 @@ static bool increase_address_space(struct protection_domain *domain, unsigned long address, gfp_t gfp) { - struct domain_pgtable pgtable; unsigned long flags; bool ret = true; u64 *pte; spin_lock_irqsave(&domain->lock, flags); - amd_iommu_domain_get_pgtable(domain, &pgtable); - - if (address <= PM_LEVEL_SIZE(pgtable.mode)) + if (address <= PM_LEVEL_SIZE(domain->iop.mode)) goto out; ret = false; - if (WARN_ON_ONCE(pgtable.mode == PAGE_MODE_6_LEVEL)) + if (WARN_ON_ONCE(domain->iop.mode == PAGE_MODE_6_LEVEL)) goto out; pte = (void *)get_zeroed_page(gfp); if (!pte) goto out; - *pte = PM_LEVEL_PDE(pgtable.mode, iommu_virt_to_phys(pgtable.root)); + *pte = PM_LEVEL_PDE(domain->iop.mode, iommu_virt_to_phys(domain->iop.root)); - pgtable.root = pte; - pgtable.mode += 1; + domain->iop.root = pte; + domain->iop.mode += 1; amd_iommu_update_and_flush_device_table(domain); amd_iommu_domain_flush_complete(domain); @@ -215,7 +212,7 @@ static bool increase_address_space(struct protection_domain *domain, * Device Table needs to be updated and flushed before the new root can * be published. */ - amd_iommu_domain_set_pgtable(domain, pte, pgtable.mode); + amd_iommu_domain_set_pgtable(domain, pte, domain->iop.mode); ret = true; @@ -232,29 +229,23 @@ static u64 *alloc_pte(struct protection_domain *domain, gfp_t gfp, bool *updated) { - struct domain_pgtable pgtable; int level, end_lvl; u64 *pte, *page; BUG_ON(!is_power_of_2(page_size)); - amd_iommu_domain_get_pgtable(domain, &pgtable); - - while (address > PM_LEVEL_SIZE(pgtable.mode)) { + while (address > PM_LEVEL_SIZE(domain->iop.mode)) { /* * Return an error if there is no memory to update the * page-table. */ if (!increase_address_space(domain, address, gfp)) return NULL; - - /* Read new values to check if update was successful */ - amd_iommu_domain_get_pgtable(domain, &pgtable); } - level = pgtable.mode - 1; - pte = &pgtable.root[PM_LEVEL_INDEX(level, address)]; + level = domain->iop.mode - 1; + pte = &domain->iop.root[PM_LEVEL_INDEX(level, address)]; ad
[PATCH v2 11/13] iommu/amd: Introduce iommu_v1_iova_to_phys
This implements iova_to_phys for AMD IOMMU v1 pagetable, which will be used by the IO page table framework. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/io_pgtable.c | 21 + drivers/iommu/amd/iommu.c | 16 +--- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c index 1729c303bae5..bbbf18d2514a 100644 --- a/drivers/iommu/amd/io_pgtable.c +++ b/drivers/iommu/amd/io_pgtable.c @@ -494,6 +494,26 @@ unsigned long iommu_unmap_page(struct protection_domain *dom, return unmapped; } +static phys_addr_t iommu_v1_iova_to_phys(struct io_pgtable_ops *ops, unsigned long iova) +{ + struct amd_io_pgtable *pgtable = io_pgtable_ops_to_data(ops); + unsigned long offset_mask, pte_pgsize; + u64 *pte, __pte; + + if (pgtable->mode == PAGE_MODE_NONE) + return iova; + + pte = fetch_pte(pgtable, iova, &pte_pgsize); + + if (!pte || !IOMMU_PTE_PRESENT(*pte)) + return 0; + + offset_mask = pte_pgsize - 1; + __pte = __sme_clr(*pte & PM_ADDR_MASK); + + return (__pte & ~offset_mask) | (iova & offset_mask); +} + /* * */ @@ -505,6 +525,7 @@ static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *coo { struct protection_domain *pdom = (struct protection_domain *)cookie; + pdom->iop.iop.ops.iova_to_phys = iommu_v1_iova_to_phys; return &pdom->iop.iop; } diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 87cea1cde414..9a1a16031e00 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -2079,22 +2079,8 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, { struct protection_domain *domain = to_pdomain(dom); struct io_pgtable_ops *ops = &domain->iop.iop.ops; - struct amd_io_pgtable *pgtable = io_pgtable_ops_to_data(ops); - unsigned long offset_mask, pte_pgsize; - u64 *pte, __pte; - if (domain->iop.mode == PAGE_MODE_NONE) - return iova; - - pte = fetch_pte(pgtable, iova, &pte_pgsize); - - if (!pte || !IOMMU_PTE_PRESENT(*pte)) - return 0; - - offset_mask = pte_pgsize - 1; - __pte = __sme_clr(*pte & PM_ADDR_MASK); - - return (__pte & ~offset_mask) | (iova & offset_mask); + return ops->iova_to_phys(ops, iova); } static bool amd_iommu_capable(enum iommu_cap cap) -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2 07/13] iommu/amd: Restructure code for freeing page table
Introduce amd_iommu_free_pgtable helper function, which consolidates logic for freeing page table. Signed-off-by: Suravee Suthikulpanit --- drivers/iommu/amd/amd_iommu.h | 2 +- drivers/iommu/amd/io_pgtable.c | 12 +++- drivers/iommu/amd/iommu.c | 19 ++- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h index ee7ff4d827e1..8dff7d85be79 100644 --- a/drivers/iommu/amd/amd_iommu.h +++ b/drivers/iommu/amd/amd_iommu.h @@ -123,7 +123,6 @@ static inline void amd_iommu_apply_ivrs_quirks(void) { } #endif /* TODO: These are temporary and will be removed once fully transition */ -extern void free_pagetable(struct domain_pgtable *pgtable); extern int iommu_map_page(struct protection_domain *dom, unsigned long bus_addr, unsigned long phys_addr, @@ -140,4 +139,5 @@ extern void amd_iommu_domain_get_pgtable(struct protection_domain *domain, struct domain_pgtable *pgtable); extern void amd_iommu_domain_set_pgtable(struct protection_domain *domain, u64 *root, int mode); +extern void amd_iommu_free_pgtable(struct amd_io_pgtable *pgtable); #endif diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c index 7fd3dd9db197..0c886419166b 100644 --- a/drivers/iommu/amd/io_pgtable.c +++ b/drivers/iommu/amd/io_pgtable.c @@ -136,14 +136,24 @@ static struct page *free_sub_pt(unsigned long root, int mode, return freelist; } -void free_pagetable(struct domain_pgtable *pgtable) +void amd_iommu_free_pgtable(struct amd_io_pgtable *pgtable) { + struct protection_domain *dom; struct page *freelist = NULL; unsigned long root; if (pgtable->mode == PAGE_MODE_NONE) return; + dom = container_of(pgtable, struct protection_domain, iop); + + /* Update data structure */ + amd_iommu_domain_clr_pt_root(dom); + + /* Make changes visible to IOMMUs */ + amd_iommu_domain_update(dom); + + /* Page-table is not visible to IOMMU anymore, so free it */ BUG_ON(pgtable->mode < PAGE_MODE_NONE || pgtable->mode > PAGE_MODE_6_LEVEL); diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 4d65f64236b6..cbbea7b952fb 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -1882,17 +1882,13 @@ static void cleanup_domain(struct protection_domain *domain) static void protection_domain_free(struct protection_domain *domain) { - struct domain_pgtable pgtable; - if (!domain) return; if (domain->id) domain_id_free(domain->id); - amd_iommu_domain_get_pgtable(domain, &pgtable); - amd_iommu_domain_clr_pt_root(domain); - free_pagetable(&pgtable); + amd_iommu_free_pgtable(&domain->iop); kfree(domain); } @@ -2281,22 +2277,11 @@ EXPORT_SYMBOL(amd_iommu_unregister_ppr_notifier); void amd_iommu_domain_direct_map(struct iommu_domain *dom) { struct protection_domain *domain = to_pdomain(dom); - struct domain_pgtable pgtable; unsigned long flags; spin_lock_irqsave(&domain->lock, flags); - /* First save pgtable configuration*/ - amd_iommu_domain_get_pgtable(domain, &pgtable); - - /* Remove page-table from domain */ - amd_iommu_domain_clr_pt_root(domain); - - /* Make changes visible to IOMMUs */ - amd_iommu_domain_update(domain); - - /* Page-table is not visible to IOMMU anymore, so free it */ - free_pagetable(&pgtable); + amd_iommu_free_pgtable(&domain->iop); spin_unlock_irqrestore(&domain->lock, flags); } -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 0/7] Convert the intel iommu driver to the dma-iommu api
Hi Joerg, On 2020/10/1 20:17, Joerg Roedel wrote: Hi Baolu, On Tue, Sep 29, 2020 at 08:11:35AM +0800, Lu Baolu wrote: I have no preference. It depends on which patch goes first. Let the maintainers help here. No preference on my side, except that it is too late for this now to make it into v5.10. Besides that I let the decission up to you when this is ready. Just send me a pull-request when it should get into the iommu-tree. Sure. Best regards, baolu Regards, Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 1/4] of/fdt: Update zone_dma_bits when running in bcm2711
On Thu, Oct 01, 2020 at 07:31:19PM +0200, Nicolas Saenz Julienne wrote: > On Thu, 2020-10-01 at 18:23 +0100, Catalin Marinas wrote: > > On Thu, Oct 01, 2020 at 06:15:01PM +0100, Catalin Marinas wrote: > > > On Thu, Oct 01, 2020 at 06:17:37PM +0200, Nicolas Saenz Julienne wrote: > > > > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c > > > > index 4602e467ca8b..cd0d115ef329 100644 > > > > --- a/drivers/of/fdt.c > > > > +++ b/drivers/of/fdt.c > > > > @@ -25,6 +25,7 @@ > > > > #include > > > > #include > > > > #include > > > > +#include /* for zone_dma_bits */ > > > > > > > > #include /* for COMMAND_LINE_SIZE */ > > > > #include > > > > @@ -1198,6 +1199,14 @@ void __init early_init_dt_scan_nodes(void) > > > > of_scan_flat_dt(early_init_dt_scan_memory, NULL); > > > > } > > > > > > > > +void __init early_init_dt_update_zone_dma_bits(void) > > > > +{ > > > > + unsigned long dt_root = of_get_flat_dt_root(); > > > > + > > > > + if (of_flat_dt_is_compatible(dt_root, "brcm,bcm2711")) > > > > + zone_dma_bits = 30; > > > > +} > > > > > > I think we could keep this entirely in the arm64 setup_machine_fdt() and > > > not pollute the core code with RPi4-specific code. > > > > Actually, even better, could we not move the check to > > arm64_memblock_init() when we initialise zone_dma_bits? > > I did it this way as I vaguely remembered Rob saying he wanted to centralise > all early boot fdt code in one place. But I'll be happy to move it there. I can see Rob replied and I'm fine if that's his preference. However, what I don't particularly like is that in the arm64 code, if zone_dma_bits == 24, we set it to 32 assuming that it wasn't touched by the early_init_dt_update_zone_dma_bits(). What if at some point we'll get a platform that actually needs 24 here (I truly hope not, but just the principle of relying on magic values)? So rather than guessing, I'd prefer if the arch code can override ZONE_DMA_BITS_DEFAULT. Then, in arm64, we'll just set it to 32 and no need to explicitly touch the zone_dma_bits variable. -- Catalin ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 24/24] memory: mtk-smi: Add mt8192 support
On Wed, Sep 30, 2020 at 03:06:47PM +0800, Yong Wu wrote: > Add mt8192 smi support. > > Signed-off-by: Yong Wu > --- > drivers/memory/mtk-smi.c | 19 +++ > 1 file changed, 19 insertions(+) Does it depend on any of the previous patches (so can it be applied independently)? Best regards, Krzysztof ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 06/24] dt-bindings: mediatek: Add binding for mt8192 IOMMU
On Wed, Sep 30, 2020 at 03:06:29PM +0800, Yong Wu wrote: > This patch adds decriptions for mt8192 IOMMU and SMI. > > mt8192 also is MTK IOMMU gen2 which uses ARM Short-Descriptor translation > table format. The M4U-SMI HW diagram is as below: > > EMI >| > M4U >| > >SMI Common > >| > +---+--+--+--+---+ > | | | | .. | | > | | | | | | > larb0 larb1 larb2 larb4 .. larb19 larb20 > disp0 disp1 mdpvdec IPE IPE > > All the connections are HW fixed, SW can NOT adjust it. > > mt8192 M4U support 0~16GB iova range. we preassign different engines > into different iova ranges: > > domain-id module iova-range larbs >0 disp0 ~ 4G larb0/1 >1 vcodec 4G ~ 8G larb4/5/7 >2 cam/mdp 8G ~ 12G larb2/9/11/13/14/16/17/18/19/20 >3 CCU00x4000_ ~ 0x43ff_ larb13: port 9/10 >4 CCU10x4400_ ~ 0x47ff_ larb14: port 4/5 > > The iova range for CCU0/1(camera control unit) is HW requirement. > > Signed-off-by: Yong Wu > Reviewed-by: Rob Herring > --- > .../bindings/iommu/mediatek,iommu.yaml| 9 +- > .../mediatek,smi-common.yaml | 5 +- > .../memory-controllers/mediatek,smi-larb.yaml | 3 +- > include/dt-bindings/memory/mt8192-larb-port.h | 239 ++ > 4 files changed, 251 insertions(+), 5 deletions(-) > create mode 100644 include/dt-bindings/memory/mt8192-larb-port.h I see it depends on previous patches but does it have to be within one commit? Is it not bisectable? The memory changes/bindings could go via memory tree if this is split. Best regards, Krzysztof ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 02/24] dt-bindings: memory: mediatek: Convert SMI to DT schema
On Wed, Sep 30, 2020 at 03:06:25PM +0800, Yong Wu wrote: > Convert MediaTek SMI to DT schema. > > Signed-off-by: Yong Wu > --- > .../mediatek,smi-common.txt | 49 - > .../mediatek,smi-common.yaml | 100 ++ > .../memory-controllers/mediatek,smi-larb.txt | 49 - > .../memory-controllers/mediatek,smi-larb.yaml | 91 > 4 files changed, 191 insertions(+), 98 deletions(-) > delete mode 100644 > Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt > create mode 100644 > Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml > delete mode 100644 > Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt > create mode 100644 > Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml > > diff --git > a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt > > b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt > deleted file mode 100644 > index b64573680b42.. > --- > a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt > +++ /dev/null > @@ -1,49 +0,0 @@ > -SMI (Smart Multimedia Interface) Common > - > -The hardware block diagram please check bindings/iommu/mediatek,iommu.txt > - > -Mediatek SMI have two generations of HW architecture, here is the list > -which generation the SoCs use: > -generation 1: mt2701 and mt7623. > -generation 2: mt2712, mt6779, mt8173 and mt8183. > - > -There's slight differences between the two SMI, for generation 2, the > -register which control the iommu port is at each larb's register base. But > -for generation 1, the register is at smi ao base(smi always on register > -base). Besides that, the smi async clock should be prepared and enabled for > -SMI generation 1 to transform the smi clock into emi clock domain, but that > is > -not needed for SMI generation 2. > - > -Required properties: > -- compatible : must be one of : > - "mediatek,mt2701-smi-common" > - "mediatek,mt2712-smi-common" > - "mediatek,mt6779-smi-common" > - "mediatek,mt7623-smi-common", "mediatek,mt2701-smi-common" > - "mediatek,mt8173-smi-common" > - "mediatek,mt8183-smi-common" > -- reg : the register and size of the SMI block. > -- power-domains : a phandle to the power domain of this local arbiter. > -- clocks : Must contain an entry for each entry in clock-names. > -- clock-names : must contain 3 entries for generation 1 smi HW and 2 entries > - for generation 2 smi HW as follows: > - - "apb" : Advanced Peripheral Bus clock, It's the clock for setting > - the register. > - - "smi" : It's the clock for transfer data and command. > - They may be the same if both source clocks are the same. > - - "async" : asynchronous clock, it help transform the smi clock into the > emi > - clock domain, this clock is only needed by generation 1 smi HW. > - and these 2 option clocks for generation 2 smi HW: > - - "gals0": the path0 clock of GALS(Global Async Local Sync). > - - "gals1": the path1 clock of GALS(Global Async Local Sync). > - Here is the list which has this GALS: mt6779 and mt8183. > - > -Example: > - smi_common: smi@14022000 { > - compatible = "mediatek,mt8173-smi-common"; > - reg = <0 0x14022000 0 0x1000>; > - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; > - clocks = <&mmsys CLK_MM_SMI_COMMON>, > - <&mmsys CLK_MM_SMI_COMMON>; > - clock-names = "apb", "smi"; > - }; > diff --git > a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml > > b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml > new file mode 100644 > index ..76ecc7205438 > --- /dev/null > +++ > b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml > @@ -0,0 +1,100 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: > http://devicetree.org/schemas/memory-controllers/mediatek,smi-common.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: SMI (Smart Multimedia Interface) Common > + > +maintainers: > + - Yong Wu > + > +description: |+ > + The hardware block diagram please check bindings/iommu/mediatek,iommu.yaml > + > + MediaTek SMI have two generations of HW architecture, here is the list > + which generation the SoCs use: > + generation 1: mt2701 and mt7623. > + generation 2: mt2712, mt6779, mt8173 and mt8183. > + > + There's slight differences between the two SMI, for generation 2, the > + register which control the iommu port is at each larb's register base. But > + for generation 1, the register is at smi ao base(smi always on register > + base). Besides that, the smi async clock should be prepared and enabled for > + SMI generation 1 to transform the smi clock
Re: [PATCH v3 01/24] dt-bindings: iommu: mediatek: Convert IOMMU to DT schema
On Wed, Sep 30, 2020 at 03:06:24PM +0800, Yong Wu wrote: > Convert MediaTek IOMMU to DT schema. > > Signed-off-by: Yong Wu > --- > .../bindings/iommu/mediatek,iommu.txt | 103 > .../bindings/iommu/mediatek,iommu.yaml| 154 ++ > 2 files changed, 154 insertions(+), 103 deletions(-) > delete mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > create mode 100644 > Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml > > diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > deleted file mode 100644 > index c1ccd8582eb2.. > --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > +++ /dev/null > @@ -1,103 +0,0 @@ > -* Mediatek IOMMU Architecture Implementation > - > - Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U), and > -this M4U have two generations of HW architecture. Generation one uses flat > -pagetable, and only supports 4K size page mapping. Generation two uses the > -ARM Short-Descriptor translation table format for address translation. > - > - About the M4U Hardware Block Diagram, please check below: > - > - EMI (External Memory Interface) > - | > - m4u (Multimedia Memory Management Unit) > - | > - ++ > - || > - gals0-rx gals1-rx(Global Async Local Sync rx) > - || > - || > - gals0-tx gals1-tx(Global Async Local Sync tx) > - || Some SoCs may have GALS. > - ++ > - | > - SMI Common(Smart Multimedia Interface Common) > - | > - ++--- > - || > - | gals-rxThere may be GALS in some larbs. > - || > - || > - | gals-tx > - || > - SMI larb0SMI larb1 ... SoCs have several SMI local > arbiter(larb). > - (display) (vdec) > - || > - || > - +-+-+ +++ > - | | | ||| > - | | |... ||| ... There are different ports in each larb. > - | | | ||| > -OVL0 RDMA0 WDMA0 MC PP VLD > - > - As above, The Multimedia HW will go through SMI and M4U while it > -access EMI. SMI is a bridge between m4u and the Multimedia HW. It contain > -smi local arbiter and smi common. It will control whether the Multimedia > -HW should go though the m4u for translation or bypass it and talk > -directly with EMI. And also SMI help control the power domain and clocks for > -each local arbiter. > - Normally we specify a local arbiter(larb) for each multimedia HW > -like display, video decode, and camera. And there are different ports > -in each larb. Take a example, There are many ports like MC, PP, VLD in the > -video decode local arbiter, all these ports are according to the video HW. > - In some SoCs, there may be a GALS(Global Async Local Sync) module between > -smi-common and m4u, and additional GALS module between smi-larb and > -smi-common. GALS can been seen as a "asynchronous fifo" which could help > -synchronize for the modules in different clock frequency. > - > -Required properties: > -- compatible : must be one of the following string: > - "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW. > - "mediatek,mt2712-m4u" for mt2712 which uses generation two m4u HW. > - "mediatek,mt6779-m4u" for mt6779 which uses generation two m4u HW. > - "mediatek,mt7623-m4u", "mediatek,mt2701-m4u" for mt7623 which uses > - generation one m4u HW. > - "mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW. > - "mediatek,mt8183-m4u" for mt8183 which uses generation two m4u HW. > -- reg : m4u register base and size. > -- interrupts : the interrupt of m4u. > -- clocks : must contain one entry for each clock-names. > -- clock-names : Only 1 optional clock: > - - "bclk": the block clock of m4u. > - Here is the list which require this "bclk": > - - mt2701, mt2712, mt7623 and mt8173. > - Note that m4u use the EMI clock which always has been enabled before kernel > - if there is no this "bclk". > -- mediatek,larbs : List of phandle to the local arbiters in the current Socs. > - Refer to bindings/memory-controllers/mediatek,smi-larb.txt. It must sort > - according to the local arbiter index, like larb0, larb1, larb2... > -- iommu-cells : must be 1. This is the mtk_m4u_id according to the HW. > - Specifies the mtk_m4u_id as defined in > - dt-binding/memory/mt2701-larb-port.h for mt2701, mt7623 > - dt-binding/memory/mt2712-larb-port.h for mt2712, > - dt-binding/memory/mt6779-larb-port.h for mt6779, > - dt-binding/me
Re: [PATCH v3 02/24] dt-bindings: memory: mediatek: Convert SMI to DT schema
On Wed, Sep 30, 2020 at 03:06:25PM +0800, Yong Wu wrote: > Convert MediaTek SMI to DT schema. > > Signed-off-by: Yong Wu > --- > .../mediatek,smi-common.txt | 49 - > .../mediatek,smi-common.yaml | 100 ++ > .../memory-controllers/mediatek,smi-larb.txt | 49 - > .../memory-controllers/mediatek,smi-larb.yaml | 91 > 4 files changed, 191 insertions(+), 98 deletions(-) > delete mode 100644 > Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt > create mode 100644 > Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml > delete mode 100644 > Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt > create mode 100644 > Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml > > diff --git > a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt > > b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt > deleted file mode 100644 > index b64573680b42.. > --- > a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt > +++ /dev/null > @@ -1,49 +0,0 @@ > -SMI (Smart Multimedia Interface) Common > - > -The hardware block diagram please check bindings/iommu/mediatek,iommu.txt > - > -Mediatek SMI have two generations of HW architecture, here is the list > -which generation the SoCs use: > -generation 1: mt2701 and mt7623. > -generation 2: mt2712, mt6779, mt8173 and mt8183. > - > -There's slight differences between the two SMI, for generation 2, the > -register which control the iommu port is at each larb's register base. But > -for generation 1, the register is at smi ao base(smi always on register > -base). Besides that, the smi async clock should be prepared and enabled for > -SMI generation 1 to transform the smi clock into emi clock domain, but that > is > -not needed for SMI generation 2. > - > -Required properties: > -- compatible : must be one of : > - "mediatek,mt2701-smi-common" > - "mediatek,mt2712-smi-common" > - "mediatek,mt6779-smi-common" > - "mediatek,mt7623-smi-common", "mediatek,mt2701-smi-common" > - "mediatek,mt8173-smi-common" > - "mediatek,mt8183-smi-common" > -- reg : the register and size of the SMI block. > -- power-domains : a phandle to the power domain of this local arbiter. > -- clocks : Must contain an entry for each entry in clock-names. > -- clock-names : must contain 3 entries for generation 1 smi HW and 2 entries > - for generation 2 smi HW as follows: > - - "apb" : Advanced Peripheral Bus clock, It's the clock for setting > - the register. > - - "smi" : It's the clock for transfer data and command. > - They may be the same if both source clocks are the same. > - - "async" : asynchronous clock, it help transform the smi clock into the > emi > - clock domain, this clock is only needed by generation 1 smi HW. > - and these 2 option clocks for generation 2 smi HW: > - - "gals0": the path0 clock of GALS(Global Async Local Sync). > - - "gals1": the path1 clock of GALS(Global Async Local Sync). > - Here is the list which has this GALS: mt6779 and mt8183. > - > -Example: > - smi_common: smi@14022000 { > - compatible = "mediatek,mt8173-smi-common"; > - reg = <0 0x14022000 0 0x1000>; > - power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; > - clocks = <&mmsys CLK_MM_SMI_COMMON>, > - <&mmsys CLK_MM_SMI_COMMON>; > - clock-names = "apb", "smi"; > - }; > diff --git > a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml > > b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml > new file mode 100644 > index ..76ecc7205438 > --- /dev/null > +++ > b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml > @@ -0,0 +1,100 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) You relicense existing GPLv2 work. Please CC all contributors and collect their acks/SoB. > +%YAML 1.2 > +--- > +$id: > http://devicetree.org/schemas/memory-controllers/mediatek,smi-common.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: SMI (Smart Multimedia Interface) Common > + > +maintainers: > + - Yong Wu > + > +description: |+ > + The hardware block diagram please check bindings/iommu/mediatek,iommu.yaml > + > + MediaTek SMI have two generations of HW architecture, here is the list > + which generation the SoCs use: > + generation 1: mt2701 and mt7623. > + generation 2: mt2712, mt6779, mt8173 and mt8183. > + > + There's slight differences between the two SMI, for generation 2, the > + register which control the iommu port is at each larb's register base. But > + for generation 1, the register is at smi ao base(smi always on register > + base). Besides that, the smi asyn
Re: [PATCH v3 01/24] dt-bindings: iommu: mediatek: Convert IOMMU to DT schema
On Wed, Sep 30, 2020 at 03:06:24PM +0800, Yong Wu wrote: > Convert MediaTek IOMMU to DT schema. > > Signed-off-by: Yong Wu > --- > .../bindings/iommu/mediatek,iommu.txt | 103 > .../bindings/iommu/mediatek,iommu.yaml| 154 ++ > 2 files changed, 154 insertions(+), 103 deletions(-) > delete mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > create mode 100644 > Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml > > diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > deleted file mode 100644 > index c1ccd8582eb2.. > --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt > +++ /dev/null > @@ -1,103 +0,0 @@ > -* Mediatek IOMMU Architecture Implementation > - > - Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U), and > -this M4U have two generations of HW architecture. Generation one uses flat > -pagetable, and only supports 4K size page mapping. Generation two uses the > -ARM Short-Descriptor translation table format for address translation. > - > - About the M4U Hardware Block Diagram, please check below: > - > - EMI (External Memory Interface) > - | > - m4u (Multimedia Memory Management Unit) > - | > - ++ > - || > - gals0-rx gals1-rx(Global Async Local Sync rx) > - || > - || > - gals0-tx gals1-tx(Global Async Local Sync tx) > - || Some SoCs may have GALS. > - ++ > - | > - SMI Common(Smart Multimedia Interface Common) > - | > - ++--- > - || > - | gals-rxThere may be GALS in some larbs. > - || > - || > - | gals-tx > - || > - SMI larb0SMI larb1 ... SoCs have several SMI local > arbiter(larb). > - (display) (vdec) > - || > - || > - +-+-+ +++ > - | | | ||| > - | | |... ||| ... There are different ports in each larb. > - | | | ||| > -OVL0 RDMA0 WDMA0 MC PP VLD > - > - As above, The Multimedia HW will go through SMI and M4U while it > -access EMI. SMI is a bridge between m4u and the Multimedia HW. It contain > -smi local arbiter and smi common. It will control whether the Multimedia > -HW should go though the m4u for translation or bypass it and talk > -directly with EMI. And also SMI help control the power domain and clocks for > -each local arbiter. > - Normally we specify a local arbiter(larb) for each multimedia HW > -like display, video decode, and camera. And there are different ports > -in each larb. Take a example, There are many ports like MC, PP, VLD in the > -video decode local arbiter, all these ports are according to the video HW. > - In some SoCs, there may be a GALS(Global Async Local Sync) module between > -smi-common and m4u, and additional GALS module between smi-larb and > -smi-common. GALS can been seen as a "asynchronous fifo" which could help > -synchronize for the modules in different clock frequency. > - > -Required properties: > -- compatible : must be one of the following string: > - "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW. > - "mediatek,mt2712-m4u" for mt2712 which uses generation two m4u HW. > - "mediatek,mt6779-m4u" for mt6779 which uses generation two m4u HW. > - "mediatek,mt7623-m4u", "mediatek,mt2701-m4u" for mt7623 which uses > - generation one m4u HW. > - "mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW. > - "mediatek,mt8183-m4u" for mt8183 which uses generation two m4u HW. > -- reg : m4u register base and size. > -- interrupts : the interrupt of m4u. > -- clocks : must contain one entry for each clock-names. > -- clock-names : Only 1 optional clock: > - - "bclk": the block clock of m4u. > - Here is the list which require this "bclk": > - - mt2701, mt2712, mt7623 and mt8173. > - Note that m4u use the EMI clock which always has been enabled before kernel > - if there is no this "bclk". > -- mediatek,larbs : List of phandle to the local arbiters in the current Socs. > - Refer to bindings/memory-controllers/mediatek,smi-larb.txt. It must sort > - according to the local arbiter index, like larb0, larb1, larb2... > -- iommu-cells : must be 1. This is the mtk_m4u_id according to the HW. > - Specifies the mtk_m4u_id as defined in > - dt-binding/memory/mt2701-larb-port.h for mt2701, mt7623 > - dt-binding/memory/mt2712-larb-port.h for mt2712, > - dt-binding/memory/mt6779-larb-port.h for mt6779, > - dt-binding/me
Re: [PATCH 1/4] of/fdt: Update zone_dma_bits when running in bcm2711
Hi Nicolas, I love your patch! Perhaps something to improve: [auto build test WARNING on next-20201001] [also build test WARNING on v5.9-rc7] [cannot apply to robh/for-next arm64/for-next/core hnaz-linux-mm/master linus/master v5.9-rc7 v5.9-rc6 v5.9-rc5] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Nicolas-Saenz-Julienne/arm64-Default-to-32-bit-wide-ZONE_DMA/20201002-002007 base:d39294091fee6b89d9c4a683bb19441b25098330 config: arm64-randconfig-r005-20200930 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project bcd05599d0e53977a963799d6ee4f6e0bc21331b) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/0day-ci/linux/commit/7d073ab6c280772b1bcf9e337528be2138d0bc85 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Nicolas-Saenz-Julienne/arm64-Default-to-32-bit-wide-ZONE_DMA/20201002-002007 git checkout 7d073ab6c280772b1bcf9e337528be2138d0bc85 # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/of/fdt.c:1202:13: warning: no previous prototype for function >> 'early_init_dt_update_zone_dma_bits' [-Wmissing-prototypes] void __init early_init_dt_update_zone_dma_bits(void) ^ drivers/of/fdt.c:1202:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void __init early_init_dt_update_zone_dma_bits(void) ^ static 1 warning generated. vim +/early_init_dt_update_zone_dma_bits +1202 drivers/of/fdt.c 1201 > 1202 void __init early_init_dt_update_zone_dma_bits(void) 1203 { 1204 unsigned long dt_root = of_get_flat_dt_root(); 1205 1206 if (of_flat_dt_is_compatible(dt_root, "brcm,bcm2711")) 1207 zone_dma_bits = 30; 1208 } 1209 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu