···44- compatible : Should be one of,55 "ti,omap2-iommu" for OMAP2/OMAP3 IOMMU instances66 "ti,omap4-iommu" for OMAP4/OMAP5 IOMMU instances77+ "ti,dra7-dsp-iommu" for DRA7xx DSP IOMMU instances78 "ti,dra7-iommu" for DRA7xx IOMMU instances89- ti,hwmods : Name of the hwmod associated with the IOMMU instance910- reg : Address space for the configuration registers···2019 Should be either 8 or 32 (default: 32)2120- ti,iommu-bus-err-back : Indicates the IOMMU instance supports throwing2221 back a bus error response on MMU faults.2222+- ti,syscon-mmuconfig : Should be a pair of the phandle to the DSP_SYSTEM2323+ syscon node that contains the additional control2424+ register for enabling the MMU, and the MMU instance2525+ number (0-indexed) within the sub-system. This property2626+ is required for DSP IOMMU instances on DRA7xx SoCs. The2727+ instance number should be 0 for DSP MDMA MMUs and 1 for2828+ DSP EDMA MMUs.23292430Example:2531 /* OMAP3 ISP MMU */···3729 interrupts = <24>;3830 ti,hwmods = "mmu_isp";3931 ti,#tlb-entries = <8>;3232+ };3333+3434+ /* DRA74x DSP2 MMUs */3535+ mmu0_dsp2: mmu@41501000 {3636+ compatible = "ti,dra7-dsp-iommu";3737+ reg = <0x41501000 0x100>;3838+ interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;3939+ ti,hwmods = "mmu0_dsp2";4040+ #iommu-cells = <0>;4141+ ti,syscon-mmuconfig = <&dsp2_system 0x0>;4242+ };4343+4444+ mmu1_dsp2: mmu@41502000 {4545+ compatible = "ti,dra7-dsp-iommu";4646+ reg = <0x41502000 0x100>;4747+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;4848+ ti,hwmods = "mmu1_dsp2";4949+ #iommu-cells = <0>;5050+ ti,syscon-mmuconfig = <&dsp2_system 0x1>;4051 };
···6262 u8 size; /* order 2 exponent */6363};64646565+struct s390_domain;6666+6567/* Private data per function */6668struct zpci_dev {6769 struct pci_dev *pdev;···120118121119 struct dentry *debugfs_dev;122120 struct dentry *debugfs_perf;121121+122122+ struct s390_domain *s390_domain; /* s390 IOMMU domain data */123123};124124125125static inline bool zdev_enabled(struct zpci_dev *zdev)
+4-1
arch/s390/include/asm/pci_dma.h
···192192/* Prototypes */193193int zpci_dma_init_device(struct zpci_dev *);194194void zpci_dma_exit_device(struct zpci_dev *);195195-195195+void dma_free_seg_table(unsigned long);196196+unsigned long *dma_alloc_cpu_table(void);197197+void dma_cleanup_tables(unsigned long *);198198+void dma_update_cpu_trans(unsigned long *, void *, dma_addr_t, int);196199#endif
+25-12
arch/s390/pci/pci_dma.c
···2424 zdev->iommu_pages * PAGE_SIZE);2525}26262727-static unsigned long *dma_alloc_cpu_table(void)2727+unsigned long *dma_alloc_cpu_table(void)2828{2929 unsigned long *table, *entry;3030···114114 return &pto[px];115115}116116117117-static void dma_update_cpu_trans(struct zpci_dev *zdev, void *page_addr,118118- dma_addr_t dma_addr, int flags)117117+void dma_update_cpu_trans(unsigned long *dma_table, void *page_addr,118118+ dma_addr_t dma_addr, int flags)119119{120120 unsigned long *entry;121121122122- entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr);122122+ entry = dma_walk_cpu_trans(dma_table, dma_addr);123123 if (!entry) {124124 WARN_ON_ONCE(1);125125 return;···156156 goto no_refresh;157157158158 for (i = 0; i < nr_pages; i++) {159159- dma_update_cpu_trans(zdev, page_addr, dma_addr, flags);159159+ dma_update_cpu_trans(zdev->dma_table, page_addr, dma_addr,160160+ flags);160161 page_addr += PAGE_SIZE;161162 dma_addr += PAGE_SIZE;162163 }···182181 return rc;183182}184183185185-static void dma_free_seg_table(unsigned long entry)184184+void dma_free_seg_table(unsigned long entry)186185{187186 unsigned long *sto = get_rt_sto(entry);188187 int sx;···194193 dma_free_cpu_table(sto);195194}196195197197-static void dma_cleanup_tables(struct zpci_dev *zdev)196196+void dma_cleanup_tables(unsigned long *table)198197{199199- unsigned long *table;200198 int rtx;201199202202- if (!zdev || !zdev->dma_table)200200+ if (!table)203201 return;204202205205- table = zdev->dma_table;206203 for (rtx = 0; rtx < ZPCI_TABLE_ENTRIES; rtx++)207204 if (reg_entry_isvalid(table[rtx]))208205 dma_free_seg_table(table[rtx]);209206210207 dma_free_cpu_table(table);211211- zdev->dma_table = NULL;212208}213209214210static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev,···414416{415417 int rc;416418419419+ /*420420+ * At this point, if the device is part of an IOMMU domain, this would421421+ * be a strong hint towards a bug in the IOMMU API (common) code and/or422422+ * simultaneous access via IOMMU and DMA API. So let's issue a warning.423423+ */424424+ WARN_ON(zdev->s390_domain);425425+417426 spin_lock_init(&zdev->iommu_bitmap_lock);418427 spin_lock_init(&zdev->dma_table_lock);419428···455450456451void zpci_dma_exit_device(struct zpci_dev *zdev)457452{453453+ /*454454+ * At this point, if the device is part of an IOMMU domain, this would455455+ * be a strong hint towards a bug in the IOMMU API (common) code and/or456456+ * simultaneous access via IOMMU and DMA API. So let's issue a warning.457457+ */458458+ WARN_ON(zdev->s390_domain);459459+458460 zpci_unregister_ioat(zdev, 0);459459- dma_cleanup_tables(zdev);461461+ dma_cleanup_tables(zdev->dma_table);462462+ zdev->dma_table = NULL;460463 vfree(zdev->iommu_bitmap);461464 zdev->iommu_bitmap = NULL;462465 zdev->next_bit = 0;
+15
drivers/iommu/Kconfig
···4848 def_bool y4949 depends on OF && IOMMU_API50505151+# IOMMU-agnostic DMA-mapping layer5252+config IOMMU_DMA5353+ bool5454+ depends on NEED_SG_DMA_LENGTH5555+ select IOMMU_API5656+ select IOMMU_IOVA5757+5158config FSL_PAMU5259 bool "Freescale IOMMU support"5360 depends on PPC32···368361 depends on ARM64 && PCI369362 select IOMMU_API370363 select IOMMU_IO_PGTABLE_LPAE364364+ select GENERIC_MSI_IRQ_DOMAIN371365 help372366 Support for implementations of the ARM System MMU architecture373367 version 3 providing translation support to a PCIe root complex.374368375369 Say Y here if your system includes an IOMMU device implementing376370 the ARM SMMUv3 architecture.371371+372372+config S390_IOMMU373373+ def_bool y if S390 && PCI374374+ depends on S390 && PCI375375+ select IOMMU_API376376+ help377377+ Support for the IOMMU API for s390 PCI devices.377378378379endif # IOMMU_SUPPORT
···8989struct iommu_dev_data {9090 struct list_head list; /* For domain->dev_list */9191 struct list_head dev_data_list; /* For global dev_data_list */9292- struct list_head alias_list; /* Link alias-groups together */9393- struct iommu_dev_data *alias_data;/* The alias dev_data */9492 struct protection_domain *domain; /* Domain the device is bound to */9593 u16 devid; /* PCI Device ID */9694 bool iommu_v2; /* Device can make use of IOMMUv2 */···134136 if (!dev_data)135137 return NULL;136138137137- INIT_LIST_HEAD(&dev_data->alias_list);138138-139139 dev_data->devid = devid;140140141141 spin_lock_irqsave(&dev_data_list_lock, flags);···141145 spin_unlock_irqrestore(&dev_data_list_lock, flags);142146143147 return dev_data;144144-}145145-146146-static void free_dev_data(struct iommu_dev_data *dev_data)147147-{148148- unsigned long flags;149149-150150- spin_lock_irqsave(&dev_data_list_lock, flags);151151- list_del(&dev_data->dev_data_list);152152- spin_unlock_irqrestore(&dev_data_list_lock, flags);153153-154154- kfree(dev_data);155148}156149157150static struct iommu_dev_data *search_dev_data(u16 devid)···296311 iommu_group_put(group);297312}298313299299-static int __last_alias(struct pci_dev *pdev, u16 alias, void *data)300300-{301301- *(u16 *)data = alias;302302- return 0;303303-}304304-305305-static u16 get_alias(struct device *dev)306306-{307307- struct pci_dev *pdev = to_pci_dev(dev);308308- u16 devid, ivrs_alias, pci_alias;309309-310310- devid = get_device_id(dev);311311- ivrs_alias = amd_iommu_alias_table[devid];312312- pci_for_each_dma_alias(pdev, __last_alias, &pci_alias);313313-314314- if (ivrs_alias == pci_alias)315315- return ivrs_alias;316316-317317- /*318318- * DMA alias showdown319319- *320320- * The IVRS is fairly reliable in telling us about aliases, but it321321- * can't know about every screwy device. If we don't have an IVRS322322- * reported alias, use the PCI reported alias. In that case we may323323- * still need to initialize the rlookup and dev_table entries if the324324- * alias is to a non-existent device.325325- */326326- if (ivrs_alias == devid) {327327- if (!amd_iommu_rlookup_table[pci_alias]) {328328- amd_iommu_rlookup_table[pci_alias] =329329- amd_iommu_rlookup_table[devid];330330- memcpy(amd_iommu_dev_table[pci_alias].data,331331- amd_iommu_dev_table[devid].data,332332- sizeof(amd_iommu_dev_table[pci_alias].data));333333- }334334-335335- return pci_alias;336336- }337337-338338- pr_info("AMD-Vi: Using IVRS reported alias %02x:%02x.%d "339339- "for device %s[%04x:%04x], kernel reported alias "340340- "%02x:%02x.%d\n", PCI_BUS_NUM(ivrs_alias), PCI_SLOT(ivrs_alias),341341- PCI_FUNC(ivrs_alias), dev_name(dev), pdev->vendor, pdev->device,342342- PCI_BUS_NUM(pci_alias), PCI_SLOT(pci_alias),343343- PCI_FUNC(pci_alias));344344-345345- /*346346- * If we don't have a PCI DMA alias and the IVRS alias is on the same347347- * bus, then the IVRS table may know about a quirk that we don't.348348- */349349- if (pci_alias == devid &&350350- PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) {351351- pdev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN;352352- pdev->dma_alias_devfn = ivrs_alias & 0xff;353353- pr_info("AMD-Vi: Added PCI DMA alias %02x.%d for %s\n",354354- PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias),355355- dev_name(dev));356356- }357357-358358- return ivrs_alias;359359-}360360-361314static int iommu_init_device(struct device *dev)362315{363316 struct pci_dev *pdev = to_pci_dev(dev);364317 struct iommu_dev_data *dev_data;365365- u16 alias;366318367319 if (dev->archdata.iommu)368320 return 0;···307385 dev_data = find_dev_data(get_device_id(dev));308386 if (!dev_data)309387 return -ENOMEM;310310-311311- alias = get_alias(dev);312312-313313- if (alias != dev_data->devid) {314314- struct iommu_dev_data *alias_data;315315-316316- alias_data = find_dev_data(alias);317317- if (alias_data == NULL) {318318- pr_err("AMD-Vi: Warning: Unhandled device %s\n",319319- dev_name(dev));320320- free_dev_data(dev_data);321321- return -ENOTSUPP;322322- }323323- dev_data->alias_data = alias_data;324324-325325- /* Add device to the alias_list */326326- list_add(&dev_data->alias_list, &alias_data->alias_list);327327- }328388329389 if (pci_iommuv2_capable(pdev)) {330390 struct amd_iommu *iommu;···348444 dev);349445350446 iommu_group_remove_device(dev);351351-352352- /* Unlink from alias, it may change if another device is re-plugged */353353- dev_data->alias_data = NULL;354447355448 /* Remove dma-ops */356449 dev->archdata.dma_ops = NULL;···534633535634 while (head != tail) {536635 iommu_print_event(iommu, iommu->evt_buf + head);537537- head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size;636636+ head = (head + EVENT_ENTRY_SIZE) % EVT_BUFFER_SIZE;538637 }539638540639 writel(head, iommu->mmio_base + MMIO_EVT_HEAD_OFFSET);···684783 u8 *target;685784686785 target = iommu->cmd_buf + tail;687687- tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;786786+ tail = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE;688787689788 /* Copy command to buffer */690789 memcpy(target, cmd, sizeof(*cmd));···851950 u32 left, tail, head, next_tail;852951 unsigned long flags;853952854854- WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED);855855-856953again:857954 spin_lock_irqsave(&iommu->lock, flags);858955859956 head = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);860957 tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);861861- next_tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;862862- left = (head - next_tail) % iommu->cmd_buf_size;958958+ next_tail = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE;959959+ left = (head - next_tail) % CMD_BUFFER_SIZE;863960864961 if (left <= 2) {865962 struct iommu_cmd sync_cmd;···10131114static int device_flush_dte(struct iommu_dev_data *dev_data)10141115{10151116 struct amd_iommu *iommu;11171117+ u16 alias;10161118 int ret;1017111910181120 iommu = amd_iommu_rlookup_table[dev_data->devid];11211121+ alias = amd_iommu_alias_table[dev_data->devid];1019112210201123 ret = iommu_flush_dte(iommu, dev_data->devid);11241124+ if (!ret && alias != dev_data->devid)11251125+ ret = iommu_flush_dte(iommu, alias);10211126 if (ret)10221127 return ret;10231128···18871984 struct protection_domain *domain)18881985{18891986 struct amd_iommu *iommu;19871987+ u16 alias;18901988 bool ats;1891198918921990 iommu = amd_iommu_rlookup_table[dev_data->devid];19911991+ alias = amd_iommu_alias_table[dev_data->devid];18931992 ats = dev_data->ats.enabled;1894199318951994 /* Update data structures */18961995 dev_data->domain = domain;18971996 list_add(&dev_data->list, &domain->dev_list);18981898- set_dte_entry(dev_data->devid, domain, ats);1899199719001998 /* Do reference counting */19011999 domain->dev_iommu[iommu->index] += 1;19022000 domain->dev_cnt += 1;1903200119041904- /* Flush the DTE entry */20022002+ /* Update device table */20032003+ set_dte_entry(dev_data->devid, domain, ats);20042004+ if (alias != dev_data->devid)20052005+ set_dte_entry(dev_data->devid, domain, ats);20062006+19052007 device_flush_dte(dev_data);19062008}1907200919082010static void do_detach(struct iommu_dev_data *dev_data)19092011{19102012 struct amd_iommu *iommu;20132013+ u16 alias;1911201419122015 /*19132016 * First check if the device is still attached. It might already···19252016 return;1926201719272018 iommu = amd_iommu_rlookup_table[dev_data->devid];20192019+ alias = amd_iommu_alias_table[dev_data->devid];1928202019292021 /* decrease reference counters */19302022 dev_data->domain->dev_iommu[iommu->index] -= 1;···19352025 dev_data->domain = NULL;19362026 list_del(&dev_data->list);19372027 clear_dte_entry(dev_data->devid);20282028+ if (alias != dev_data->devid)20292029+ clear_dte_entry(alias);1938203019392031 /* Flush the DTE entry */19402032 device_flush_dte(dev_data);···19492037static int __attach_device(struct iommu_dev_data *dev_data,19502038 struct protection_domain *domain)19512039{19521952- struct iommu_dev_data *head, *entry;19532040 int ret;20412041+20422042+ /*20432043+ * Must be called with IRQs disabled. Warn here to detect early20442044+ * when its not.20452045+ */20462046+ WARN_ON(!irqs_disabled());1954204719552048 /* lock domain */19562049 spin_lock(&domain->lock);1957205019581958- head = dev_data;19591959-19601960- if (head->alias_data != NULL)19611961- head = head->alias_data;19621962-19631963- /* Now we have the root of the alias group, if any */19641964-19652051 ret = -EBUSY;19661966- if (head->domain != NULL)20522052+ if (dev_data->domain != NULL)19672053 goto out_unlock;1968205419692055 /* Attach alias group root */19701970- do_attach(head, domain);19711971-19721972- /* Attach other devices in the alias group */19731973- list_for_each_entry(entry, &head->alias_list, alias_list)19741974- do_attach(entry, domain);20562056+ do_attach(dev_data, domain);1975205719762058 ret = 0;19772059···21152209 */21162210static void __detach_device(struct iommu_dev_data *dev_data)21172211{21182118- struct iommu_dev_data *head, *entry;21192212 struct protection_domain *domain;21202120- unsigned long flags;2121221321222122- BUG_ON(!dev_data->domain);22142214+ /*22152215+ * Must be called with IRQs disabled. Warn here to detect early22162216+ * when its not.22172217+ */22182218+ WARN_ON(!irqs_disabled());22192219+22202220+ if (WARN_ON(!dev_data->domain))22212221+ return;2123222221242223 domain = dev_data->domain;2125222421262126- spin_lock_irqsave(&domain->lock, flags);22252225+ spin_lock(&domain->lock);2127222621282128- head = dev_data;21292129- if (head->alias_data != NULL)21302130- head = head->alias_data;22272227+ do_detach(dev_data);2131222821322132- list_for_each_entry(entry, &head->alias_list, alias_list)21332133- do_detach(entry);21342134-21352135- do_detach(head);21362136-21372137- spin_unlock_irqrestore(&domain->lock, flags);22292229+ spin_unlock(&domain->lock);21382230}2139223121402232/*···31023198 .iova_to_phys = amd_iommu_iova_to_phys,31033199 .add_device = amd_iommu_add_device,31043200 .remove_device = amd_iommu_remove_device,32013201+ .device_group = pci_device_group,31053202 .get_dm_regions = amd_iommu_get_dm_regions,31063203 .put_dm_regions = amd_iommu_put_dm_regions,31073204 .pgsize_bitmap = AMD_IOMMU_PGSIZES,
+27-93
drivers/iommu/amd_iommu_init.c
···408408}409409410410/*411411- * This function reads the last device id the IOMMU has to handle from the PCI412412- * capability header for this IOMMU413413- */414414-static int __init find_last_devid_on_pci(int bus, int dev, int fn, int cap_ptr)415415-{416416- u32 cap;417417-418418- cap = read_pci_config(bus, dev, fn, cap_ptr+MMIO_RANGE_OFFSET);419419- update_last_devid(PCI_DEVID(MMIO_GET_BUS(cap), MMIO_GET_LD(cap)));420420-421421- return 0;422422-}423423-424424-/*425411 * After reading the highest device id from the IOMMU PCI capability header426412 * this function looks if there is a higher device id defined in the ACPI table427413 */···419433 p += sizeof(*h);420434 end += h->length;421435422422- find_last_devid_on_pci(PCI_BUS_NUM(h->devid),423423- PCI_SLOT(h->devid),424424- PCI_FUNC(h->devid),425425- h->cap_ptr);426426-427436 while (p < end) {428437 dev = (struct ivhd_entry *)p;429438 switch (dev->type) {439439+ case IVHD_DEV_ALL:440440+ /* Use maximum BDF value for DEV_ALL */441441+ update_last_devid(0xffff);442442+ break;430443 case IVHD_DEV_SELECT:431444 case IVHD_DEV_RANGE_END:432445 case IVHD_DEV_ALIAS:···498513 * write commands to that buffer later and the IOMMU will execute them499514 * asynchronously500515 */501501-static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)516516+static int __init alloc_command_buffer(struct amd_iommu *iommu)502517{503503- u8 *cmd_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,504504- get_order(CMD_BUFFER_SIZE));518518+ iommu->cmd_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,519519+ get_order(CMD_BUFFER_SIZE));505520506506- if (cmd_buf == NULL)507507- return NULL;508508-509509- iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED;510510-511511- return cmd_buf;521521+ return iommu->cmd_buf ? 0 : -ENOMEM;512522}513523514524/*···537557 &entry, sizeof(entry));538558539559 amd_iommu_reset_cmd_buffer(iommu);540540- iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED);541560}542561543562static void __init free_command_buffer(struct amd_iommu *iommu)544563{545545- free_pages((unsigned long)iommu->cmd_buf,546546- get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED)));564564+ free_pages((unsigned long)iommu->cmd_buf, get_order(CMD_BUFFER_SIZE));547565}548566549567/* allocates the memory where the IOMMU will log its events to */550550-static u8 * __init alloc_event_buffer(struct amd_iommu *iommu)568568+static int __init alloc_event_buffer(struct amd_iommu *iommu)551569{552552- iommu->evt_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,553553- get_order(EVT_BUFFER_SIZE));570570+ iommu->evt_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,571571+ get_order(EVT_BUFFER_SIZE));554572555555- if (iommu->evt_buf == NULL)556556- return NULL;557557-558558- iommu->evt_buf_size = EVT_BUFFER_SIZE;559559-560560- return iommu->evt_buf;573573+ return iommu->evt_buf ? 0 : -ENOMEM;561574}562575563576static void iommu_enable_event_buffer(struct amd_iommu *iommu)···577604}578605579606/* allocates the memory where the IOMMU will log its events to */580580-static u8 * __init alloc_ppr_log(struct amd_iommu *iommu)607607+static int __init alloc_ppr_log(struct amd_iommu *iommu)581608{582582- iommu->ppr_log = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,583583- get_order(PPR_LOG_SIZE));609609+ iommu->ppr_log = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,610610+ get_order(PPR_LOG_SIZE));584611585585- if (iommu->ppr_log == NULL)586586- return NULL;587587-588588- return iommu->ppr_log;612612+ return iommu->ppr_log ? 0 : -ENOMEM;589613}590614591615static void iommu_enable_ppr_log(struct amd_iommu *iommu)···805835 switch (e->type) {806836 case IVHD_DEV_ALL:807837808808- DUMP_printk(" DEV_ALL\t\t\t first devid: %02x:%02x.%x"809809- " last device %02x:%02x.%x flags: %02x\n",810810- PCI_BUS_NUM(iommu->first_device),811811- PCI_SLOT(iommu->first_device),812812- PCI_FUNC(iommu->first_device),813813- PCI_BUS_NUM(iommu->last_device),814814- PCI_SLOT(iommu->last_device),815815- PCI_FUNC(iommu->last_device),816816- e->flags);838838+ DUMP_printk(" DEV_ALL\t\t\tflags: %02x\n", e->flags);817839818818- for (dev_i = iommu->first_device;819819- dev_i <= iommu->last_device; ++dev_i)820820- set_dev_entry_from_acpi(iommu, dev_i,821821- e->flags, 0);840840+ for (dev_i = 0; dev_i <= amd_iommu_last_bdf; ++dev_i)841841+ set_dev_entry_from_acpi(iommu, dev_i, e->flags, 0);822842 break;823843 case IVHD_DEV_SELECT:824844···9641004 return 0;9651005}9661006967967-/* Initializes the device->iommu mapping for the driver */968968-static int __init init_iommu_devices(struct amd_iommu *iommu)969969-{970970- u32 i;971971-972972- for (i = iommu->first_device; i <= iommu->last_device; ++i)973973- set_iommu_for_device(iommu, i);974974-975975- return 0;976976-}977977-9781007static void __init free_iommu_one(struct amd_iommu *iommu)9791008{9801009 free_command_buffer(iommu);···10601111 if (!iommu->mmio_base)10611112 return -ENOMEM;1062111310631063- iommu->cmd_buf = alloc_command_buffer(iommu);10641064- if (!iommu->cmd_buf)11141114+ if (alloc_command_buffer(iommu))10651115 return -ENOMEM;1066111610671067- iommu->evt_buf = alloc_event_buffer(iommu);10681068- if (!iommu->evt_buf)11171117+ if (alloc_event_buffer(iommu))10691118 return -ENOMEM;1070111910711120 iommu->int_enabled = false;···10811134 * table tells us so, but this is a lie!10821135 */10831136 amd_iommu_rlookup_table[iommu->devid] = NULL;10841084-10851085- init_iommu_devices(iommu);1086113710871138 return 0;10881139}···12111266 pci_read_config_dword(iommu->dev, cap_ptr + MMIO_MISC_OFFSET,12121267 &misc);1213126812141214- iommu->first_device = PCI_DEVID(MMIO_GET_BUS(range),12151215- MMIO_GET_FD(range));12161216- iommu->last_device = PCI_DEVID(MMIO_GET_BUS(range),12171217- MMIO_GET_LD(range));12181218-12191269 if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB)))12201270 amd_iommu_iotlb_sup = false;12211271···12481308 amd_iommu_v2_present = true;12491309 }1250131012511251- if (iommu_feature(iommu, FEATURE_PPR)) {12521252- iommu->ppr_log = alloc_ppr_log(iommu);12531253- if (!iommu->ppr_log)12541254- return -ENOMEM;12551255- }13111311+ if (iommu_feature(iommu, FEATURE_PPR) && alloc_ppr_log(iommu))13121312+ return -ENOMEM;1256131312571314 if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))12581315 amd_iommu_np_cache = true;···16951758 free_pages((unsigned long)irq_lookup_table,16961759 get_order(rlookup_table_size));1697176016981698- if (amd_iommu_irq_cache) {16991699- kmem_cache_destroy(amd_iommu_irq_cache);17001700- amd_iommu_irq_cache = NULL;17011701-17021702- }17611761+ kmem_cache_destroy(amd_iommu_irq_cache);17621762+ amd_iommu_irq_cache = NULL;1703176317041764 free_pages((unsigned long)amd_iommu_rlookup_table,17051765 get_order(rlookup_table_size));···21352201 iommu_detected = 1;21362202 x86_init.iommu.iommu_init = amd_iommu_init;2137220321382138- return 0;22042204+ return 1;21392205}2140220621412207/****************************************************************************
+2-11
drivers/iommu/amd_iommu_types.h
···295295#define IOMMU_PTE_IR (1ULL << 61)296296#define IOMMU_PTE_IW (1ULL << 62)297297298298+#define DTE_FLAG_IOTLB (1ULL << 32)299299+#define DTE_FLAG_GV (1ULL << 55)298300#define DTE_FLAG_MASK (0x3ffULL << 32)299299-#define DTE_FLAG_IOTLB (0x01UL << 32)300300-#define DTE_FLAG_GV (0x01ULL << 55)301301#define DTE_GLX_SHIFT (56)302302#define DTE_GLX_MASK (3)303303···517517 /* pci domain of this IOMMU */518518 u16 pci_seg;519519520520- /* first device this IOMMU handles. read from PCI */521521- u16 first_device;522522- /* last device this IOMMU handles. read from PCI */523523- u16 last_device;524524-525520 /* start of exclusion range of that IOMMU */526521 u64 exclusion_start;527522 /* length of exclusion range of that IOMMU */···524529525530 /* command buffer virtual address */526531 u8 *cmd_buf;527527- /* size of command buffer */528528- u32 cmd_buf_size;529532530530- /* size of event buffer */531531- u32 evt_buf_size;532533 /* event buffer virtual address */533534 u8 *evt_buf;534535
+111-44
drivers/iommu/arm-smmu-v3.c
···2626#include <linux/iommu.h>2727#include <linux/iopoll.h>2828#include <linux/module.h>2929+#include <linux/msi.h>2930#include <linux/of.h>3031#include <linux/of_address.h>3232+#include <linux/of_platform.h>3133#include <linux/pci.h>3234#include <linux/platform_device.h>3335···405403 PRI_RESP_SUCC,406404};407405406406+enum arm_smmu_msi_index {407407+ EVTQ_MSI_INDEX,408408+ GERROR_MSI_INDEX,409409+ PRIQ_MSI_INDEX,410410+ ARM_SMMU_MAX_MSIS,411411+};412412+413413+static phys_addr_t arm_smmu_msi_cfg[ARM_SMMU_MAX_MSIS][3] = {414414+ [EVTQ_MSI_INDEX] = {415415+ ARM_SMMU_EVTQ_IRQ_CFG0,416416+ ARM_SMMU_EVTQ_IRQ_CFG1,417417+ ARM_SMMU_EVTQ_IRQ_CFG2,418418+ },419419+ [GERROR_MSI_INDEX] = {420420+ ARM_SMMU_GERROR_IRQ_CFG0,421421+ ARM_SMMU_GERROR_IRQ_CFG1,422422+ ARM_SMMU_GERROR_IRQ_CFG2,423423+ },424424+ [PRIQ_MSI_INDEX] = {425425+ ARM_SMMU_PRIQ_IRQ_CFG0,426426+ ARM_SMMU_PRIQ_IRQ_CFG1,427427+ ARM_SMMU_PRIQ_IRQ_CFG2,428428+ },429429+};430430+408431struct arm_smmu_cmdq_ent {409432 /* Common fields */410433 u8 opcode;···597570 unsigned int sid_bits;598571599572 struct arm_smmu_strtab_cfg strtab_cfg;600600- struct list_head list;601573};602574603575/* SMMU private data for an IOMMU group */···630604631605 struct iommu_domain domain;632606};633633-634634-/* Our list of SMMU instances */635635-static DEFINE_SPINLOCK(arm_smmu_devices_lock);636636-static LIST_HEAD(arm_smmu_devices);637607638608struct arm_smmu_option_prop {639609 u32 opt;···14491427 struct io_pgtable_cfg *pgtbl_cfg)14501428{14511429 int ret;14521452- u16 asid;14301430+ int asid;14531431 struct arm_smmu_device *smmu = smmu_domain->smmu;14541432 struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;14551433···14611439 &cfg->cdptr_dma, GFP_KERNEL);14621440 if (!cfg->cdptr) {14631441 dev_warn(smmu->dev, "failed to allocate context descriptor\n");14421442+ ret = -ENOMEM;14641443 goto out_free_asid;14651444 }1466144514671467- cfg->cd.asid = asid;14461446+ cfg->cd.asid = (u16)asid;14681447 cfg->cd.ttbr = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];14691448 cfg->cd.tcr = pgtbl_cfg->arm_lpae_s1_cfg.tcr;14701449 cfg->cd.mair = pgtbl_cfg->arm_lpae_s1_cfg.mair[0];···14791456static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,14801457 struct io_pgtable_cfg *pgtbl_cfg)14811458{14821482- u16 vmid;14591459+ int vmid;14831460 struct arm_smmu_device *smmu = smmu_domain->smmu;14841461 struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;14851462···14871464 if (IS_ERR_VALUE(vmid))14881465 return vmid;1489146614901490- cfg->vmid = vmid;14671467+ cfg->vmid = (u16)vmid;14911468 cfg->vttbr = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;14921469 cfg->vtcr = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;14931470 return 0;···17491726static struct arm_smmu_device *arm_smmu_get_for_pci_dev(struct pci_dev *pdev)17501727{17511728 struct device_node *of_node;17521752- struct arm_smmu_device *curr, *smmu = NULL;17291729+ struct platform_device *smmu_pdev;17301730+ struct arm_smmu_device *smmu = NULL;17531731 struct pci_bus *bus = pdev->bus;1754173217551733 /* Walk up to the root bus */···17631739 return NULL;1764174017651741 /* See if we can find an SMMU corresponding to the phandle */17661766- spin_lock(&arm_smmu_devices_lock);17671767- list_for_each_entry(curr, &arm_smmu_devices, list) {17681768- if (curr->dev->of_node == of_node) {17691769- smmu = curr;17701770- break;17711771- }17721772- }17731773- spin_unlock(&arm_smmu_devices_lock);17421742+ smmu_pdev = of_find_device_by_node(of_node);17431743+ if (smmu_pdev)17441744+ smmu = platform_get_drvdata(smmu_pdev);17451745+17741746 of_node_put(of_node);17751747 return smmu;17761748}···19221902 .iova_to_phys = arm_smmu_iova_to_phys,19231903 .add_device = arm_smmu_add_device,19241904 .remove_device = arm_smmu_remove_device,19051905+ .device_group = pci_device_group,19251906 .domain_get_attr = arm_smmu_domain_get_attr,19261907 .domain_set_attr = arm_smmu_domain_set_attr,19271908 .pgsize_bitmap = -1UL, /* Restricted during device attach */···22072186 1, ARM_SMMU_POLL_TIMEOUT_US);22082187}2209218821892189+static void arm_smmu_free_msis(void *data)21902190+{21912191+ struct device *dev = data;21922192+ platform_msi_domain_free_irqs(dev);21932193+}21942194+21952195+static void arm_smmu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg)21962196+{21972197+ phys_addr_t doorbell;21982198+ struct device *dev = msi_desc_to_dev(desc);21992199+ struct arm_smmu_device *smmu = dev_get_drvdata(dev);22002200+ phys_addr_t *cfg = arm_smmu_msi_cfg[desc->platform.msi_index];22012201+22022202+ doorbell = (((u64)msg->address_hi) << 32) | msg->address_lo;22032203+ doorbell &= MSI_CFG0_ADDR_MASK << MSI_CFG0_ADDR_SHIFT;22042204+22052205+ writeq_relaxed(doorbell, smmu->base + cfg[0]);22062206+ writel_relaxed(msg->data, smmu->base + cfg[1]);22072207+ writel_relaxed(MSI_CFG2_MEMATTR_DEVICE_nGnRE, smmu->base + cfg[2]);22082208+}22092209+22102210+static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)22112211+{22122212+ struct msi_desc *desc;22132213+ int ret, nvec = ARM_SMMU_MAX_MSIS;22142214+ struct device *dev = smmu->dev;22152215+22162216+ /* Clear the MSI address regs */22172217+ writeq_relaxed(0, smmu->base + ARM_SMMU_GERROR_IRQ_CFG0);22182218+ writeq_relaxed(0, smmu->base + ARM_SMMU_EVTQ_IRQ_CFG0);22192219+22202220+ if (smmu->features & ARM_SMMU_FEAT_PRI)22212221+ writeq_relaxed(0, smmu->base + ARM_SMMU_PRIQ_IRQ_CFG0);22222222+ else22232223+ nvec--;22242224+22252225+ if (!(smmu->features & ARM_SMMU_FEAT_MSI))22262226+ return;22272227+22282228+ /* Allocate MSIs for evtq, gerror and priq. Ignore cmdq */22292229+ ret = platform_msi_domain_alloc_irqs(dev, nvec, arm_smmu_write_msi_msg);22302230+ if (ret) {22312231+ dev_warn(dev, "failed to allocate MSIs\n");22322232+ return;22332233+ }22342234+22352235+ for_each_msi_entry(desc, dev) {22362236+ switch (desc->platform.msi_index) {22372237+ case EVTQ_MSI_INDEX:22382238+ smmu->evtq.q.irq = desc->irq;22392239+ break;22402240+ case GERROR_MSI_INDEX:22412241+ smmu->gerr_irq = desc->irq;22422242+ break;22432243+ case PRIQ_MSI_INDEX:22442244+ smmu->priq.q.irq = desc->irq;22452245+ break;22462246+ default: /* Unknown */22472247+ continue;22482248+ }22492249+ }22502250+22512251+ /* Add callback to free MSIs on teardown */22522252+ devm_add_action(dev, arm_smmu_free_msis, dev);22532253+}22542254+22102255static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)22112256{22122257 int ret, irq;···22862199 return ret;22872200 }2288220122892289- /* Clear the MSI address regs */22902290- writeq_relaxed(0, smmu->base + ARM_SMMU_GERROR_IRQ_CFG0);22912291- writeq_relaxed(0, smmu->base + ARM_SMMU_EVTQ_IRQ_CFG0);22022202+ arm_smmu_setup_msis(smmu);2292220322932293- /* Request wired interrupt lines */22042204+ /* Request interrupt lines */22942205 irq = smmu->evtq.q.irq;22952206 if (irq) {22962207 ret = devm_request_threaded_irq(smmu->dev, irq,···23172232 }2318223323192234 if (smmu->features & ARM_SMMU_FEAT_PRI) {23202320- writeq_relaxed(0, smmu->base + ARM_SMMU_PRIQ_IRQ_CFG0);23212321-23222235 irq = smmu->priq.q.irq;23232236 if (irq) {23242237 ret = devm_request_threaded_irq(smmu->dev, irq,···26952612 if (ret)26962613 return ret;2697261426152615+ /* Record our private device structure */26162616+ platform_set_drvdata(pdev, smmu);26172617+26982618 /* Reset the device */26992619 ret = arm_smmu_device_reset(smmu);27002620 if (ret)27012621 goto out_free_structures;2702262227032703- /* Record our private device structure */27042704- INIT_LIST_HEAD(&smmu->list);27052705- spin_lock(&arm_smmu_devices_lock);27062706- list_add(&smmu->list, &arm_smmu_devices);27072707- spin_unlock(&arm_smmu_devices_lock);27082623 return 0;2709262427102625out_free_structures:···2712263127132632static int arm_smmu_device_remove(struct platform_device *pdev)27142633{27152715- struct arm_smmu_device *curr, *smmu = NULL;27162716- struct device *dev = &pdev->dev;27172717-27182718- spin_lock(&arm_smmu_devices_lock);27192719- list_for_each_entry(curr, &arm_smmu_devices, list) {27202720- if (curr->dev == dev) {27212721- smmu = curr;27222722- list_del(&smmu->list);27232723- break;27242724- }27252725- }27262726- spin_unlock(&arm_smmu_devices_lock);27272727-27282728- if (!smmu)27292729- return -ENODEV;26342634+ struct arm_smmu_device *smmu = platform_get_drvdata(pdev);2730263527312636 arm_smmu_device_disable(smmu);27322637 arm_smmu_free_structures(smmu);
+74-56
drivers/iommu/arm-smmu.c
···7070 ((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS) \7171 ? 0x400 : 0))72727373+#ifdef CONFIG_64BIT7474+#define smmu_writeq writeq_relaxed7575+#else7676+#define smmu_writeq(reg64, addr) \7777+ do { \7878+ u64 __val = (reg64); \7979+ void __iomem *__addr = (addr); \8080+ writel_relaxed(__val >> 32, __addr + 4); \8181+ writel_relaxed(__val, __addr); \8282+ } while (0)8383+#endif8484+7385/* Configuration registers */7486#define ARM_SMMU_GR0_sCR0 0x07587#define sCR0_CLIENTPD (1 << 0)···197185#define ARM_SMMU_CB_SCTLR 0x0198186#define ARM_SMMU_CB_RESUME 0x8199187#define ARM_SMMU_CB_TTBCR2 0x10200200-#define ARM_SMMU_CB_TTBR0_LO 0x20201201-#define ARM_SMMU_CB_TTBR0_HI 0x24202202-#define ARM_SMMU_CB_TTBR1_LO 0x28203203-#define ARM_SMMU_CB_TTBR1_HI 0x2c188188+#define ARM_SMMU_CB_TTBR0 0x20189189+#define ARM_SMMU_CB_TTBR1 0x28204190#define ARM_SMMU_CB_TTBCR 0x30205191#define ARM_SMMU_CB_S1_MAIR0 0x38206192#define ARM_SMMU_CB_S1_MAIR1 0x3c···236226#define TTBCR2_SEP_SHIFT 15237227#define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT)238228239239-#define TTBRn_HI_ASID_SHIFT 16229229+#define TTBRn_ASID_SHIFT 48240230241231#define FSR_MULTI (1 << 31)242232#define FSR_SS (1 << 30)···705695 struct io_pgtable_cfg *pgtbl_cfg)706696{707697 u32 reg;698698+ u64 reg64;708699 bool stage1;709700 struct arm_smmu_cfg *cfg = &smmu_domain->cfg;710701 struct arm_smmu_device *smmu = smmu_domain->smmu;711711- void __iomem *cb_base, *gr0_base, *gr1_base;702702+ void __iomem *cb_base, *gr1_base;712703713713- gr0_base = ARM_SMMU_GR0(smmu);714704 gr1_base = ARM_SMMU_GR1(smmu);715705 stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;716706 cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx);···748738749739 /* TTBRs */750740 if (stage1) {751751- reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];752752- writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);753753- reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0] >> 32;754754- reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;755755- writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);741741+ reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];756742757757- reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];758758- writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO);759759- reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1] >> 32;760760- reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;761761- writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI);743743+ reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;744744+ smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);745745+746746+ reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];747747+ reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;748748+ smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR1);762749 } else {763763- reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;764764- writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);765765- reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr >> 32;766766- writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);750750+ reg64 = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;751751+ smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);767752 }768753769754 /* TTBCR */···1217121212181213 /* ATS1 registers can only be written atomically */12191214 va = iova & ~0xfffUL;12201220-#ifdef CONFIG_64BIT12211215 if (smmu->version == ARM_SMMU_V2)12221222- writeq_relaxed(va, cb_base + ARM_SMMU_CB_ATS1PR);12161216+ smmu_writeq(va, cb_base + ARM_SMMU_CB_ATS1PR);12231217 else12241224-#endif12251218 writel_relaxed(va, cb_base + ARM_SMMU_CB_ATS1PR);1226121912271220 if (readl_poll_timeout_atomic(cb_base + ARM_SMMU_CB_ATSR, tmp,12281221 !(tmp & ATSR_ACTIVE), 5, 50)) {12291222 dev_err(dev,12301230- "iova to phys timed out on 0x%pad. Falling back to software table walk.\n",12231223+ "iova to phys timed out on %pad. Falling back to software table walk.\n",12311224 &iova);12321225 return ops->iova_to_phys(ops, iova);12331226 }···12951292 kfree(data);12961293}1297129412981298-static int arm_smmu_add_pci_device(struct pci_dev *pdev)12951295+static int arm_smmu_init_pci_device(struct pci_dev *pdev,12961296+ struct iommu_group *group)12991297{13001300- int i, ret;13011301- u16 sid;13021302- struct iommu_group *group;13031298 struct arm_smmu_master_cfg *cfg;13041304-13051305- group = iommu_group_get_for_dev(&pdev->dev);13061306- if (IS_ERR(group))13071307- return PTR_ERR(group);12991299+ u16 sid;13001300+ int i;1308130113091302 cfg = iommu_group_get_iommudata(group);13101303 if (!cfg) {13111304 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);13121312- if (!cfg) {13131313- ret = -ENOMEM;13141314- goto out_put_group;13151315- }13051305+ if (!cfg)13061306+ return -ENOMEM;1316130713171308 iommu_group_set_iommudata(group, cfg,13181309 __arm_smmu_release_pci_iommudata);13191310 }1320131113211321- if (cfg->num_streamids >= MAX_MASTER_STREAMIDS) {13221322- ret = -ENOSPC;13231323- goto out_put_group;13241324- }13121312+ if (cfg->num_streamids >= MAX_MASTER_STREAMIDS)13131313+ return -ENOSPC;1325131413261315 /*13271316 * Assume Stream ID == Requester ID for now.···13291334 cfg->streamids[cfg->num_streamids++] = sid;1330133513311336 return 0;13321332-out_put_group:13331333- iommu_group_put(group);13341334- return ret;13351337}1336133813371337-static int arm_smmu_add_platform_device(struct device *dev)13391339+static int arm_smmu_init_platform_device(struct device *dev,13401340+ struct iommu_group *group)13381341{13391339- struct iommu_group *group;13401340- struct arm_smmu_master *master;13411342 struct arm_smmu_device *smmu = find_smmu_for_device(dev);13431343+ struct arm_smmu_master *master;1342134413431345 if (!smmu)13441346 return -ENODEV;···13441352 if (!master)13451353 return -ENODEV;1346135413471347- /* No automatic group creation for platform devices */13481348- group = iommu_group_alloc();13491349- if (IS_ERR(group))13501350- return PTR_ERR(group);13511351-13521355 iommu_group_set_iommudata(group, &master->cfg, NULL);13531353- return iommu_group_add_device(group, dev);13561356+13571357+ return 0;13541358}1355135913561360static int arm_smmu_add_device(struct device *dev)13571361{13581358- if (dev_is_pci(dev))13591359- return arm_smmu_add_pci_device(to_pci_dev(dev));13621362+ struct iommu_group *group;1360136313611361- return arm_smmu_add_platform_device(dev);13641364+ group = iommu_group_get_for_dev(dev);13651365+ if (IS_ERR(group))13661366+ return PTR_ERR(group);13671367+13681368+ return 0;13621369}1363137013641371static void arm_smmu_remove_device(struct device *dev)13651372{13661373 iommu_group_remove_device(dev);13741374+}13751375+13761376+static struct iommu_group *arm_smmu_device_group(struct device *dev)13771377+{13781378+ struct iommu_group *group;13791379+ int ret;13801380+13811381+ if (dev_is_pci(dev))13821382+ group = pci_device_group(dev);13831383+ else13841384+ group = generic_device_group(dev);13851385+13861386+ if (IS_ERR(group))13871387+ return group;13881388+13891389+ if (dev_is_pci(dev))13901390+ ret = arm_smmu_init_pci_device(to_pci_dev(dev), group);13911391+ else13921392+ ret = arm_smmu_init_platform_device(dev, group);13931393+13941394+ if (ret) {13951395+ iommu_group_put(group);13961396+ group = ERR_PTR(ret);13971397+ }13981398+13991399+ return group;13671400}1368140113691402static int arm_smmu_domain_get_attr(struct iommu_domain *domain,···14471430 .iova_to_phys = arm_smmu_iova_to_phys,14481431 .add_device = arm_smmu_add_device,14491432 .remove_device = arm_smmu_remove_device,14331433+ .device_group = arm_smmu_device_group,14501434 .domain_get_attr = arm_smmu_domain_get_attr,14511435 .domain_set_attr = arm_smmu_domain_set_attr,14521436 .pgsize_bitmap = -1UL, /* Restricted during device attach */
+524
drivers/iommu/dma-iommu.c
···11+/*22+ * A fairly generic DMA-API to IOMMU-API glue layer.33+ *44+ * Copyright (C) 2014-2015 ARM Ltd.55+ *66+ * based in part on arch/arm/mm/dma-mapping.c:77+ * Copyright (C) 2000-2004 Russell King88+ *99+ * This program is free software; you can redistribute it and/or modify1010+ * it under the terms of the GNU General Public License version 2 as1111+ * published by the Free Software Foundation.1212+ *1313+ * This program is distributed in the hope that it will be useful,1414+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1515+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1616+ * GNU General Public License for more details.1717+ *1818+ * You should have received a copy of the GNU General Public License1919+ * along with this program. If not, see <http://www.gnu.org/licenses/>.2020+ */2121+2222+#include <linux/device.h>2323+#include <linux/dma-iommu.h>2424+#include <linux/huge_mm.h>2525+#include <linux/iommu.h>2626+#include <linux/iova.h>2727+#include <linux/mm.h>2828+2929+int iommu_dma_init(void)3030+{3131+ return iova_cache_get();3232+}3333+3434+/**3535+ * iommu_get_dma_cookie - Acquire DMA-API resources for a domain3636+ * @domain: IOMMU domain to prepare for DMA-API usage3737+ *3838+ * IOMMU drivers should normally call this from their domain_alloc3939+ * callback when domain->type == IOMMU_DOMAIN_DMA.4040+ */4141+int iommu_get_dma_cookie(struct iommu_domain *domain)4242+{4343+ struct iova_domain *iovad;4444+4545+ if (domain->iova_cookie)4646+ return -EEXIST;4747+4848+ iovad = kzalloc(sizeof(*iovad), GFP_KERNEL);4949+ domain->iova_cookie = iovad;5050+5151+ return iovad ? 0 : -ENOMEM;5252+}5353+EXPORT_SYMBOL(iommu_get_dma_cookie);5454+5555+/**5656+ * iommu_put_dma_cookie - Release a domain's DMA mapping resources5757+ * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie()5858+ *5959+ * IOMMU drivers should normally call this from their domain_free callback.6060+ */6161+void iommu_put_dma_cookie(struct iommu_domain *domain)6262+{6363+ struct iova_domain *iovad = domain->iova_cookie;6464+6565+ if (!iovad)6666+ return;6767+6868+ put_iova_domain(iovad);6969+ kfree(iovad);7070+ domain->iova_cookie = NULL;7171+}7272+EXPORT_SYMBOL(iommu_put_dma_cookie);7373+7474+/**7575+ * iommu_dma_init_domain - Initialise a DMA mapping domain7676+ * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie()7777+ * @base: IOVA at which the mappable address space starts7878+ * @size: Size of IOVA space7979+ *8080+ * @base and @size should be exact multiples of IOMMU page granularity to8181+ * avoid rounding surprises. If necessary, we reserve the page at address 08282+ * to ensure it is an invalid IOVA. It is safe to reinitialise a domain, but8383+ * any change which could make prior IOVAs invalid will fail.8484+ */8585+int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, u64 size)8686+{8787+ struct iova_domain *iovad = domain->iova_cookie;8888+ unsigned long order, base_pfn, end_pfn;8989+9090+ if (!iovad)9191+ return -ENODEV;9292+9393+ /* Use the smallest supported page size for IOVA granularity */9494+ order = __ffs(domain->ops->pgsize_bitmap);9595+ base_pfn = max_t(unsigned long, 1, base >> order);9696+ end_pfn = (base + size - 1) >> order;9797+9898+ /* Check the domain allows at least some access to the device... */9999+ if (domain->geometry.force_aperture) {100100+ if (base > domain->geometry.aperture_end ||101101+ base + size <= domain->geometry.aperture_start) {102102+ pr_warn("specified DMA range outside IOMMU capability\n");103103+ return -EFAULT;104104+ }105105+ /* ...then finally give it a kicking to make sure it fits */106106+ base_pfn = max_t(unsigned long, base_pfn,107107+ domain->geometry.aperture_start >> order);108108+ end_pfn = min_t(unsigned long, end_pfn,109109+ domain->geometry.aperture_end >> order);110110+ }111111+112112+ /* All we can safely do with an existing domain is enlarge it */113113+ if (iovad->start_pfn) {114114+ if (1UL << order != iovad->granule ||115115+ base_pfn != iovad->start_pfn ||116116+ end_pfn < iovad->dma_32bit_pfn) {117117+ pr_warn("Incompatible range for DMA domain\n");118118+ return -EFAULT;119119+ }120120+ iovad->dma_32bit_pfn = end_pfn;121121+ } else {122122+ init_iova_domain(iovad, 1UL << order, base_pfn, end_pfn);123123+ }124124+ return 0;125125+}126126+EXPORT_SYMBOL(iommu_dma_init_domain);127127+128128+/**129129+ * dma_direction_to_prot - Translate DMA API directions to IOMMU API page flags130130+ * @dir: Direction of DMA transfer131131+ * @coherent: Is the DMA master cache-coherent?132132+ *133133+ * Return: corresponding IOMMU API page protection flags134134+ */135135+int dma_direction_to_prot(enum dma_data_direction dir, bool coherent)136136+{137137+ int prot = coherent ? IOMMU_CACHE : 0;138138+139139+ switch (dir) {140140+ case DMA_BIDIRECTIONAL:141141+ return prot | IOMMU_READ | IOMMU_WRITE;142142+ case DMA_TO_DEVICE:143143+ return prot | IOMMU_READ;144144+ case DMA_FROM_DEVICE:145145+ return prot | IOMMU_WRITE;146146+ default:147147+ return 0;148148+ }149149+}150150+151151+static struct iova *__alloc_iova(struct iova_domain *iovad, size_t size,152152+ dma_addr_t dma_limit)153153+{154154+ unsigned long shift = iova_shift(iovad);155155+ unsigned long length = iova_align(iovad, size) >> shift;156156+157157+ /*158158+ * Enforce size-alignment to be safe - there could perhaps be an159159+ * attribute to control this per-device, or at least per-domain...160160+ */161161+ return alloc_iova(iovad, length, dma_limit >> shift, true);162162+}163163+164164+/* The IOVA allocator knows what we mapped, so just unmap whatever that was */165165+static void __iommu_dma_unmap(struct iommu_domain *domain, dma_addr_t dma_addr)166166+{167167+ struct iova_domain *iovad = domain->iova_cookie;168168+ unsigned long shift = iova_shift(iovad);169169+ unsigned long pfn = dma_addr >> shift;170170+ struct iova *iova = find_iova(iovad, pfn);171171+ size_t size;172172+173173+ if (WARN_ON(!iova))174174+ return;175175+176176+ size = iova_size(iova) << shift;177177+ size -= iommu_unmap(domain, pfn << shift, size);178178+ /* ...and if we can't, then something is horribly, horribly wrong */179179+ WARN_ON(size > 0);180180+ __free_iova(iovad, iova);181181+}182182+183183+static void __iommu_dma_free_pages(struct page **pages, int count)184184+{185185+ while (count--)186186+ __free_page(pages[count]);187187+ kvfree(pages);188188+}189189+190190+static struct page **__iommu_dma_alloc_pages(unsigned int count, gfp_t gfp)191191+{192192+ struct page **pages;193193+ unsigned int i = 0, array_size = count * sizeof(*pages);194194+195195+ if (array_size <= PAGE_SIZE)196196+ pages = kzalloc(array_size, GFP_KERNEL);197197+ else198198+ pages = vzalloc(array_size);199199+ if (!pages)200200+ return NULL;201201+202202+ /* IOMMU can map any pages, so himem can also be used here */203203+ gfp |= __GFP_NOWARN | __GFP_HIGHMEM;204204+205205+ while (count) {206206+ struct page *page = NULL;207207+ int j, order = __fls(count);208208+209209+ /*210210+ * Higher-order allocations are a convenience rather211211+ * than a necessity, hence using __GFP_NORETRY until212212+ * falling back to single-page allocations.213213+ */214214+ for (order = min(order, MAX_ORDER); order > 0; order--) {215215+ page = alloc_pages(gfp | __GFP_NORETRY, order);216216+ if (!page)217217+ continue;218218+ if (PageCompound(page)) {219219+ if (!split_huge_page(page))220220+ break;221221+ __free_pages(page, order);222222+ } else {223223+ split_page(page, order);224224+ break;225225+ }226226+ }227227+ if (!page)228228+ page = alloc_page(gfp);229229+ if (!page) {230230+ __iommu_dma_free_pages(pages, i);231231+ return NULL;232232+ }233233+ j = 1 << order;234234+ count -= j;235235+ while (j--)236236+ pages[i++] = page++;237237+ }238238+ return pages;239239+}240240+241241+/**242242+ * iommu_dma_free - Free a buffer allocated by iommu_dma_alloc()243243+ * @dev: Device which owns this buffer244244+ * @pages: Array of buffer pages as returned by iommu_dma_alloc()245245+ * @size: Size of buffer in bytes246246+ * @handle: DMA address of buffer247247+ *248248+ * Frees both the pages associated with the buffer, and the array249249+ * describing them250250+ */251251+void iommu_dma_free(struct device *dev, struct page **pages, size_t size,252252+ dma_addr_t *handle)253253+{254254+ __iommu_dma_unmap(iommu_get_domain_for_dev(dev), *handle);255255+ __iommu_dma_free_pages(pages, PAGE_ALIGN(size) >> PAGE_SHIFT);256256+ *handle = DMA_ERROR_CODE;257257+}258258+259259+/**260260+ * iommu_dma_alloc - Allocate and map a buffer contiguous in IOVA space261261+ * @dev: Device to allocate memory for. Must be a real device262262+ * attached to an iommu_dma_domain263263+ * @size: Size of buffer in bytes264264+ * @gfp: Allocation flags265265+ * @prot: IOMMU mapping flags266266+ * @handle: Out argument for allocated DMA handle267267+ * @flush_page: Arch callback which must ensure PAGE_SIZE bytes from the268268+ * given VA/PA are visible to the given non-coherent device.269269+ *270270+ * If @size is less than PAGE_SIZE, then a full CPU page will be allocated,271271+ * but an IOMMU which supports smaller pages might not map the whole thing.272272+ *273273+ * Return: Array of struct page pointers describing the buffer,274274+ * or NULL on failure.275275+ */276276+struct page **iommu_dma_alloc(struct device *dev, size_t size,277277+ gfp_t gfp, int prot, dma_addr_t *handle,278278+ void (*flush_page)(struct device *, const void *, phys_addr_t))279279+{280280+ struct iommu_domain *domain = iommu_get_domain_for_dev(dev);281281+ struct iova_domain *iovad = domain->iova_cookie;282282+ struct iova *iova;283283+ struct page **pages;284284+ struct sg_table sgt;285285+ dma_addr_t dma_addr;286286+ unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;287287+288288+ *handle = DMA_ERROR_CODE;289289+290290+ pages = __iommu_dma_alloc_pages(count, gfp);291291+ if (!pages)292292+ return NULL;293293+294294+ iova = __alloc_iova(iovad, size, dev->coherent_dma_mask);295295+ if (!iova)296296+ goto out_free_pages;297297+298298+ size = iova_align(iovad, size);299299+ if (sg_alloc_table_from_pages(&sgt, pages, count, 0, size, GFP_KERNEL))300300+ goto out_free_iova;301301+302302+ if (!(prot & IOMMU_CACHE)) {303303+ struct sg_mapping_iter miter;304304+ /*305305+ * The CPU-centric flushing implied by SG_MITER_TO_SG isn't306306+ * sufficient here, so skip it by using the "wrong" direction.307307+ */308308+ sg_miter_start(&miter, sgt.sgl, sgt.orig_nents, SG_MITER_FROM_SG);309309+ while (sg_miter_next(&miter))310310+ flush_page(dev, miter.addr, page_to_phys(miter.page));311311+ sg_miter_stop(&miter);312312+ }313313+314314+ dma_addr = iova_dma_addr(iovad, iova);315315+ if (iommu_map_sg(domain, dma_addr, sgt.sgl, sgt.orig_nents, prot)316316+ < size)317317+ goto out_free_sg;318318+319319+ *handle = dma_addr;320320+ sg_free_table(&sgt);321321+ return pages;322322+323323+out_free_sg:324324+ sg_free_table(&sgt);325325+out_free_iova:326326+ __free_iova(iovad, iova);327327+out_free_pages:328328+ __iommu_dma_free_pages(pages, count);329329+ return NULL;330330+}331331+332332+/**333333+ * iommu_dma_mmap - Map a buffer into provided user VMA334334+ * @pages: Array representing buffer from iommu_dma_alloc()335335+ * @size: Size of buffer in bytes336336+ * @vma: VMA describing requested userspace mapping337337+ *338338+ * Maps the pages of the buffer in @pages into @vma. The caller is responsible339339+ * for verifying the correct size and protection of @vma beforehand.340340+ */341341+342342+int iommu_dma_mmap(struct page **pages, size_t size, struct vm_area_struct *vma)343343+{344344+ unsigned long uaddr = vma->vm_start;345345+ unsigned int i, count = PAGE_ALIGN(size) >> PAGE_SHIFT;346346+ int ret = -ENXIO;347347+348348+ for (i = vma->vm_pgoff; i < count && uaddr < vma->vm_end; i++) {349349+ ret = vm_insert_page(vma, uaddr, pages[i]);350350+ if (ret)351351+ break;352352+ uaddr += PAGE_SIZE;353353+ }354354+ return ret;355355+}356356+357357+dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,358358+ unsigned long offset, size_t size, int prot)359359+{360360+ dma_addr_t dma_addr;361361+ struct iommu_domain *domain = iommu_get_domain_for_dev(dev);362362+ struct iova_domain *iovad = domain->iova_cookie;363363+ phys_addr_t phys = page_to_phys(page) + offset;364364+ size_t iova_off = iova_offset(iovad, phys);365365+ size_t len = iova_align(iovad, size + iova_off);366366+ struct iova *iova = __alloc_iova(iovad, len, dma_get_mask(dev));367367+368368+ if (!iova)369369+ return DMA_ERROR_CODE;370370+371371+ dma_addr = iova_dma_addr(iovad, iova);372372+ if (iommu_map(domain, dma_addr, phys - iova_off, len, prot)) {373373+ __free_iova(iovad, iova);374374+ return DMA_ERROR_CODE;375375+ }376376+ return dma_addr + iova_off;377377+}378378+379379+void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,380380+ enum dma_data_direction dir, struct dma_attrs *attrs)381381+{382382+ __iommu_dma_unmap(iommu_get_domain_for_dev(dev), handle);383383+}384384+385385+/*386386+ * Prepare a successfully-mapped scatterlist to give back to the caller.387387+ * Handling IOVA concatenation can come later, if needed388388+ */389389+static int __finalise_sg(struct device *dev, struct scatterlist *sg, int nents,390390+ dma_addr_t dma_addr)391391+{392392+ struct scatterlist *s;393393+ int i;394394+395395+ for_each_sg(sg, s, nents, i) {396396+ /* Un-swizzling the fields here, hence the naming mismatch */397397+ unsigned int s_offset = sg_dma_address(s);398398+ unsigned int s_length = sg_dma_len(s);399399+ unsigned int s_dma_len = s->length;400400+401401+ s->offset = s_offset;402402+ s->length = s_length;403403+ sg_dma_address(s) = dma_addr + s_offset;404404+ dma_addr += s_dma_len;405405+ }406406+ return i;407407+}408408+409409+/*410410+ * If mapping failed, then just restore the original list,411411+ * but making sure the DMA fields are invalidated.412412+ */413413+static void __invalidate_sg(struct scatterlist *sg, int nents)414414+{415415+ struct scatterlist *s;416416+ int i;417417+418418+ for_each_sg(sg, s, nents, i) {419419+ if (sg_dma_address(s) != DMA_ERROR_CODE)420420+ s->offset = sg_dma_address(s);421421+ if (sg_dma_len(s))422422+ s->length = sg_dma_len(s);423423+ sg_dma_address(s) = DMA_ERROR_CODE;424424+ sg_dma_len(s) = 0;425425+ }426426+}427427+428428+/*429429+ * The DMA API client is passing in a scatterlist which could describe430430+ * any old buffer layout, but the IOMMU API requires everything to be431431+ * aligned to IOMMU pages. Hence the need for this complicated bit of432432+ * impedance-matching, to be able to hand off a suitably-aligned list,433433+ * but still preserve the original offsets and sizes for the caller.434434+ */435435+int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,436436+ int nents, int prot)437437+{438438+ struct iommu_domain *domain = iommu_get_domain_for_dev(dev);439439+ struct iova_domain *iovad = domain->iova_cookie;440440+ struct iova *iova;441441+ struct scatterlist *s, *prev = NULL;442442+ dma_addr_t dma_addr;443443+ size_t iova_len = 0;444444+ int i;445445+446446+ /*447447+ * Work out how much IOVA space we need, and align the segments to448448+ * IOVA granules for the IOMMU driver to handle. With some clever449449+ * trickery we can modify the list in-place, but reversibly, by450450+ * hiding the original data in the as-yet-unused DMA fields.451451+ */452452+ for_each_sg(sg, s, nents, i) {453453+ size_t s_offset = iova_offset(iovad, s->offset);454454+ size_t s_length = s->length;455455+456456+ sg_dma_address(s) = s->offset;457457+ sg_dma_len(s) = s_length;458458+ s->offset -= s_offset;459459+ s_length = iova_align(iovad, s_length + s_offset);460460+ s->length = s_length;461461+462462+ /*463463+ * The simple way to avoid the rare case of a segment464464+ * crossing the boundary mask is to pad the previous one465465+ * to end at a naturally-aligned IOVA for this one's size,466466+ * at the cost of potentially over-allocating a little.467467+ */468468+ if (prev) {469469+ size_t pad_len = roundup_pow_of_two(s_length);470470+471471+ pad_len = (pad_len - iova_len) & (pad_len - 1);472472+ prev->length += pad_len;473473+ iova_len += pad_len;474474+ }475475+476476+ iova_len += s_length;477477+ prev = s;478478+ }479479+480480+ iova = __alloc_iova(iovad, iova_len, dma_get_mask(dev));481481+ if (!iova)482482+ goto out_restore_sg;483483+484484+ /*485485+ * We'll leave any physical concatenation to the IOMMU driver's486486+ * implementation - it knows better than we do.487487+ */488488+ dma_addr = iova_dma_addr(iovad, iova);489489+ if (iommu_map_sg(domain, dma_addr, sg, nents, prot) < iova_len)490490+ goto out_free_iova;491491+492492+ return __finalise_sg(dev, sg, nents, dma_addr);493493+494494+out_free_iova:495495+ __free_iova(iovad, iova);496496+out_restore_sg:497497+ __invalidate_sg(sg, nents);498498+ return 0;499499+}500500+501501+void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,502502+ enum dma_data_direction dir, struct dma_attrs *attrs)503503+{504504+ /*505505+ * The scatterlist segments are mapped into a single506506+ * contiguous IOVA allocation, so this is incredibly easy.507507+ */508508+ __iommu_dma_unmap(iommu_get_domain_for_dev(dev), sg_dma_address(sg));509509+}510510+511511+int iommu_dma_supported(struct device *dev, u64 mask)512512+{513513+ /*514514+ * 'Special' IOMMUs which don't have the same addressing capability515515+ * as the CPU will have to wait until we have some way to query that516516+ * before they'll be able to use this framework.517517+ */518518+ return 1;519519+}520520+521521+int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)522522+{523523+ return dma_addr == DMA_ERROR_CODE;524524+}
+16-25
drivers/iommu/fsl_pamu_domain.c
···923923 pci_endpt_partioning = check_pci_ctl_endpt_part(pci_ctl);924924 /* We can partition PCIe devices so assign device group to the device */925925 if (pci_endpt_partioning) {926926- group = iommu_group_get_for_dev(&pdev->dev);926926+ group = pci_device_group(&pdev->dev);927927928928 /*929929 * PCIe controller is not a paritionable entity···956956 return group;957957}958958959959-static int fsl_pamu_add_device(struct device *dev)959959+static struct iommu_group *fsl_pamu_device_group(struct device *dev)960960{961961 struct iommu_group *group = ERR_PTR(-ENODEV);962962- struct pci_dev *pdev;963963- const u32 *prop;964964- int ret = 0, len;962962+ int len;965963966964 /*967965 * For platform devices we allocate a separate group for968966 * each of the devices.969967 */970970- if (dev_is_pci(dev)) {971971- pdev = to_pci_dev(dev);972972- /* Don't create device groups for virtual PCI bridges */973973- if (pdev->subordinate)974974- return 0;968968+ if (dev_is_pci(dev))969969+ group = get_pci_device_group(to_pci_dev(dev));970970+ else if (of_get_property(dev->of_node, "fsl,liodn", &len))971971+ group = get_device_iommu_group(dev);975972976976- group = get_pci_device_group(pdev);973973+ return group;974974+}977975978978- } else {979979- prop = of_get_property(dev->of_node, "fsl,liodn", &len);980980- if (prop)981981- group = get_device_iommu_group(dev);982982- }976976+static int fsl_pamu_add_device(struct device *dev)977977+{978978+ struct iommu_group *group;983979980980+ group = iommu_group_get_for_dev(dev);984981 if (IS_ERR(group))985982 return PTR_ERR(group);986983987987- /*988988- * Check if device has already been added to an iommu group.989989- * Group could have already been created for a PCI device in990990- * the iommu_group_get_for_dev path.991991- */992992- if (!dev->iommu_group)993993- ret = iommu_group_add_device(group, dev);994994-995984 iommu_group_put(group);996996- return ret;985985+986986+ return 0;997987}998988999989static void fsl_pamu_remove_device(struct device *dev)···10621072 .domain_get_attr = fsl_pamu_get_domain_attr,10631073 .add_device = fsl_pamu_add_device,10641074 .remove_device = fsl_pamu_remove_device,10751075+ .device_group = fsl_pamu_device_group,10651076};1066107710671078int __init pamu_domain_init(void)
+54-29
drivers/iommu/intel-iommu.c
···3434#include <linux/mempool.h>3535#include <linux/memory.h>3636#include <linux/timer.h>3737+#include <linux/io.h>3738#include <linux/iova.h>3839#include <linux/iommu.h>3940#include <linux/intel-iommu.h>···24352434 DMA_PTE_READ|DMA_PTE_WRITE);24362435}2437243624382438-static int iommu_prepare_identity_map(struct device *dev,24392439- unsigned long long start,24402440- unsigned long long end)24372437+static int domain_prepare_identity_map(struct device *dev,24382438+ struct dmar_domain *domain,24392439+ unsigned long long start,24402440+ unsigned long long end)24412441{24422442- struct dmar_domain *domain;24432443- int ret;24442444-24452445- domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);24462446- if (!domain)24472447- return -ENOMEM;24482448-24492442 /* For _hardware_ passthrough, don't bother. But for software24502443 passthrough, we do it anyway -- it may indicate a memory24512444 range which is reserved in E820, so which didn't get set···24592464 dmi_get_system_info(DMI_BIOS_VENDOR),24602465 dmi_get_system_info(DMI_BIOS_VERSION),24612466 dmi_get_system_info(DMI_PRODUCT_VERSION));24622462- ret = -EIO;24632463- goto error;24672467+ return -EIO;24642468 }2465246924662470 if (end >> agaw_to_width(domain->agaw)) {···24692475 dmi_get_system_info(DMI_BIOS_VENDOR),24702476 dmi_get_system_info(DMI_BIOS_VERSION),24712477 dmi_get_system_info(DMI_PRODUCT_VERSION));24722472- ret = -EIO;24732473- goto error;24782478+ return -EIO;24742479 }2475248024762476- ret = iommu_domain_identity_map(domain, start, end);24812481+ return iommu_domain_identity_map(domain, start, end);24822482+}24832483+24842484+static int iommu_prepare_identity_map(struct device *dev,24852485+ unsigned long long start,24862486+ unsigned long long end)24872487+{24882488+ struct dmar_domain *domain;24892489+ int ret;24902490+24912491+ domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);24922492+ if (!domain)24932493+ return -ENOMEM;24942494+24952495+ ret = domain_prepare_identity_map(dev, domain, start, end);24772496 if (ret)24782478- goto error;24972497+ domain_exit(domain);2479249824802480- return 0;24812481-24822482- error:24832483- domain_exit(domain);24842499 return ret;24852500}24862501···28152812}2816281328172814static int copy_context_table(struct intel_iommu *iommu,28182818- struct root_entry __iomem *old_re,28152815+ struct root_entry *old_re,28192816 struct context_entry **tbl,28202817 int bus, bool ext)28212818{28222819 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;28232823- struct context_entry __iomem *old_ce = NULL;28242820 struct context_entry *new_ce = NULL, ce;28212821+ struct context_entry *old_ce = NULL;28252822 struct root_entry re;28262823 phys_addr_t old_ce_phys;2827282428282825 tbl_idx = ext ? bus * 2 : bus;28292829- memcpy_fromio(&re, old_re, sizeof(re));28262826+ memcpy(&re, old_re, sizeof(re));2830282728312828 for (devfn = 0; devfn < 256; devfn++) {28322829 /* First calculate the correct index */···28612858 }2862285928632860 ret = -ENOMEM;28642864- old_ce = ioremap_cache(old_ce_phys, PAGE_SIZE);28612861+ old_ce = memremap(old_ce_phys, PAGE_SIZE,28622862+ MEMREMAP_WB);28652863 if (!old_ce)28662864 goto out;28672865···28742870 }2875287128762872 /* Now copy the context entry */28772877- memcpy_fromio(&ce, old_ce + idx, sizeof(ce));28732873+ memcpy(&ce, old_ce + idx, sizeof(ce));2878287428792875 if (!__context_present(&ce))28802876 continue;···29102906 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);2911290729122908out_unmap:29132913- iounmap(old_ce);29092909+ memunmap(old_ce);2914291029152911out:29162912 return ret;···2918291429192915static int copy_translation_tables(struct intel_iommu *iommu)29202916{29212921- struct root_entry __iomem *old_rt;29222917 struct context_entry **ctxt_tbls;29182918+ struct root_entry *old_rt;29232919 phys_addr_t old_rt_phys;29242920 int ctxt_table_entries;29252921 unsigned long flags;···29442940 if (!old_rt_phys)29452941 return -EINVAL;2946294229472947- old_rt = ioremap_cache(old_rt_phys, PAGE_SIZE);29432943+ old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);29482944 if (!old_rt)29492945 return -ENOMEM;29502946···29932989 ret = 0;2994299029952991out_unmap:29962996- iounmap(old_rt);29922992+ memunmap(old_rt);2997299329982994 return ret;29992995}···3250324632513247static struct dmar_domain *__get_valid_domain_for_dev(struct device *dev)32523248{32493249+ struct dmar_rmrr_unit *rmrr;32533250 struct dmar_domain *domain;32513251+ struct device *i_dev;32523252+ int i, ret;3254325332553254 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);32563255 if (!domain) {···32613254 dev_name(dev));32623255 return NULL;32633256 }32573257+32583258+ /* We have a new domain - setup possible RMRRs for the device */32593259+ rcu_read_lock();32603260+ for_each_rmrr_units(rmrr) {32613261+ for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,32623262+ i, i_dev) {32633263+ if (i_dev != dev)32643264+ continue;32653265+32663266+ ret = domain_prepare_identity_map(dev, domain,32673267+ rmrr->base_address,32683268+ rmrr->end_address);32693269+ if (ret)32703270+ dev_err(dev, "Mapping reserved region failed\n");32713271+ }32723272+ }32733273+ rcu_read_unlock();3264327432653275 return domain;32663276}···49014877 .iova_to_phys = intel_iommu_iova_to_phys,49024878 .add_device = intel_iommu_add_device,49034879 .remove_device = intel_iommu_remove_device,48804880+ .device_group = pci_device_group,49044881 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,49054882};49064883
+48-16
drivers/iommu/intel_irq_remapping.c
···169169 index = irq_iommu->irte_index + irq_iommu->sub_handle;170170 irte = &iommu->ir_table->base[index];171171172172- set_64bit(&irte->low, irte_modified->low);173173- set_64bit(&irte->high, irte_modified->high);172172+#if defined(CONFIG_HAVE_CMPXCHG_DOUBLE)173173+ if ((irte->pst == 1) || (irte_modified->pst == 1)) {174174+ bool ret;175175+176176+ ret = cmpxchg_double(&irte->low, &irte->high,177177+ irte->low, irte->high,178178+ irte_modified->low, irte_modified->high);179179+ /*180180+ * We use cmpxchg16 to atomically update the 128-bit IRTE,181181+ * and it cannot be updated by the hardware or other processors182182+ * behind us, so the return value of cmpxchg16 should be the183183+ * same as the old value.184184+ */185185+ WARN_ON(!ret);186186+ } else187187+#endif188188+ {189189+ set_64bit(&irte->low, irte_modified->low);190190+ set_64bit(&irte->high, irte_modified->high);191191+ }174192 __iommu_flush_cache(iommu, irte, sizeof(*irte));175193176194 rc = qi_flush_iec(iommu, index, 0);···402384403385static int iommu_load_old_irte(struct intel_iommu *iommu)404386{405405- struct irte __iomem *old_ir_table;387387+ struct irte *old_ir_table;406388 phys_addr_t irt_phys;407389 unsigned int i;408390 size_t size;···426408 size = INTR_REMAP_TABLE_ENTRIES*sizeof(struct irte);427409428410 /* Map the old IR table */429429- old_ir_table = ioremap_cache(irt_phys, size);411411+ old_ir_table = memremap(irt_phys, size, MEMREMAP_WB);430412 if (!old_ir_table)431413 return -ENOMEM;432414433415 /* Copy data over */434434- memcpy_fromio(iommu->ir_table->base, old_ir_table, size);416416+ memcpy(iommu->ir_table->base, old_ir_table, size);435417436418 __iommu_flush_cache(iommu, iommu->ir_table->base, size);437419···444426 bitmap_set(iommu->ir_table->bitmap, i, 1);445427 }446428447447- iounmap(old_ir_table);429429+ memunmap(old_ir_table);448430449431 return 0;450432}···690672 if (!dmar_ir_support())691673 return -ENODEV;692674693693- if (parse_ioapics_under_ir() != 1) {675675+ if (parse_ioapics_under_ir()) {694676 pr_info("Not enabling interrupt remapping\n");695677 goto error;696678 }···745727 struct intel_iommu *iommu;746728747729 if (!disable_irq_post) {748748- intel_irq_remap_ops.capability |= 1 << IRQ_POSTING_CAP;730730+ /*731731+ * If IRTE is in posted format, the 'pda' field goes across the732732+ * 64-bit boundary, we need use cmpxchg16b to atomically update733733+ * it. We only expose posted-interrupt when X86_FEATURE_CX16734734+ * is supported. Actually, hardware platforms supporting PI735735+ * should have X86_FEATURE_CX16 support, this has been confirmed736736+ * with Intel hardware guys.737737+ */738738+ if ( cpu_has_cx16 )739739+ intel_irq_remap_ops.capability |= 1 << IRQ_POSTING_CAP;749740750741 for_each_iommu(iommu, drhd)751742 if (!cap_pi_support(iommu->cap)) {···934907 bool ir_supported = false;935908 int ioapic_idx;936909937937- for_each_iommu(iommu, drhd)938938- if (ecap_ir_support(iommu->ecap)) {939939- if (ir_parse_ioapic_hpet_scope(drhd->hdr, iommu))940940- return -1;910910+ for_each_iommu(iommu, drhd) {911911+ int ret;941912942942- ir_supported = true;943943- }913913+ if (!ecap_ir_support(iommu->ecap))914914+ continue;915915+916916+ ret = ir_parse_ioapic_hpet_scope(drhd->hdr, iommu);917917+ if (ret)918918+ return ret;919919+920920+ ir_supported = true;921921+ }944922945923 if (!ir_supported)946946- return 0;924924+ return -ENODEV;947925948926 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) {949927 int ioapic_id = mpc_ioapic_id(ioapic_idx);···960928 }961929 }962930963963- return 1;931931+ return 0;964932}965933966934static int __init ir_dev_scope_init(void)
+34-12
drivers/iommu/iommu.c
···728728}729729730730/*731731+ * Generic device_group call-back function. It just allocates one732732+ * iommu-group per device.733733+ */734734+struct iommu_group *generic_device_group(struct device *dev)735735+{736736+ struct iommu_group *group;737737+738738+ group = iommu_group_alloc();739739+ if (IS_ERR(group))740740+ return NULL;741741+742742+ return group;743743+}744744+745745+/*731746 * Use standard PCI bus topology, isolation features, and DMA alias quirks732747 * to find or create an IOMMU group for a device.733748 */734734-static struct iommu_group *iommu_group_get_for_pci_dev(struct pci_dev *pdev)749749+struct iommu_group *pci_device_group(struct device *dev)735750{751751+ struct pci_dev *pdev = to_pci_dev(dev);736752 struct group_for_pci_data data;737753 struct pci_bus *bus;738754 struct iommu_group *group = NULL;739755 u64 devfns[4] = { 0 };756756+757757+ if (WARN_ON(!dev_is_pci(dev)))758758+ return ERR_PTR(-EINVAL);740759741760 /*742761 * Find the upstream DMA alias for the device. A device must not···810791 if (IS_ERR(group))811792 return NULL;812793813813- /*814814- * Try to allocate a default domain - needs support from the815815- * IOMMU driver.816816- */817817- group->default_domain = __iommu_domain_alloc(pdev->dev.bus,818818- IOMMU_DOMAIN_DMA);819819- group->domain = group->default_domain;820820-821794 return group;822795}823796···825814 */826815struct iommu_group *iommu_group_get_for_dev(struct device *dev)827816{817817+ const struct iommu_ops *ops = dev->bus->iommu_ops;828818 struct iommu_group *group;829819 int ret;830820···833821 if (group)834822 return group;835823836836- if (!dev_is_pci(dev))837837- return ERR_PTR(-EINVAL);824824+ group = ERR_PTR(-EINVAL);838825839839- group = iommu_group_get_for_pci_dev(to_pci_dev(dev));826826+ if (ops && ops->device_group)827827+ group = ops->device_group(dev);840828841829 if (IS_ERR(group))842830 return group;831831+832832+ /*833833+ * Try to allocate a default domain - needs support from the834834+ * IOMMU driver.835835+ */836836+ if (!group->default_domain) {837837+ group->default_domain = __iommu_domain_alloc(dev->bus,838838+ IOMMU_DOMAIN_DMA);839839+ group->domain = group->default_domain;840840+ }843841844842 ret = iommu_group_add_device(group, dev);845843 if (ret) {
+58
drivers/iommu/omap-iommu.c
···2626#include <linux/of_iommu.h>2727#include <linux/of_irq.h>2828#include <linux/of_platform.h>2929+#include <linux/regmap.h>3030+#include <linux/mfd/syscon.h>29313032#include <asm/cacheflush.h>3133···114112}115113EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx);116114115115+static void dra7_cfg_dspsys_mmu(struct omap_iommu *obj, bool enable)116116+{117117+ u32 val, mask;118118+119119+ if (!obj->syscfg)120120+ return;121121+122122+ mask = (1 << (obj->id * DSP_SYS_MMU_CONFIG_EN_SHIFT));123123+ val = enable ? mask : 0;124124+ regmap_update_bits(obj->syscfg, DSP_SYS_MMU_CONFIG, mask, val);125125+}126126+117127static void __iommu_set_twl(struct omap_iommu *obj, bool on)118128{119129 u32 l = iommu_read_reg(obj, MMU_CNTL);···161147162148 iommu_write_reg(obj, pa, MMU_TTB);163149150150+ dra7_cfg_dspsys_mmu(obj, true);151151+164152 if (obj->has_bus_err_back)165153 iommu_write_reg(obj, MMU_GP_REG_BUS_ERR_BACK_EN, MMU_GP_REG);166154···177161178162 l &= ~MMU_CNTL_MASK;179163 iommu_write_reg(obj, l, MMU_CNTL);164164+ dra7_cfg_dspsys_mmu(obj, false);180165181166 dev_dbg(obj->dev, "%s is shutting down\n", obj->name);182167}···881864 dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);882865}883866867867+static int omap_iommu_dra7_get_dsp_system_cfg(struct platform_device *pdev,868868+ struct omap_iommu *obj)869869+{870870+ struct device_node *np = pdev->dev.of_node;871871+ int ret;872872+873873+ if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))874874+ return 0;875875+876876+ if (!of_property_read_bool(np, "ti,syscon-mmuconfig")) {877877+ dev_err(&pdev->dev, "ti,syscon-mmuconfig property is missing\n");878878+ return -EINVAL;879879+ }880880+881881+ obj->syscfg =882882+ syscon_regmap_lookup_by_phandle(np, "ti,syscon-mmuconfig");883883+ if (IS_ERR(obj->syscfg)) {884884+ /* can fail with -EPROBE_DEFER */885885+ ret = PTR_ERR(obj->syscfg);886886+ return ret;887887+ }888888+889889+ if (of_property_read_u32_index(np, "ti,syscon-mmuconfig", 1,890890+ &obj->id)) {891891+ dev_err(&pdev->dev, "couldn't get the IOMMU instance id within subsystem\n");892892+ return -EINVAL;893893+ }894894+895895+ if (obj->id != 0 && obj->id != 1) {896896+ dev_err(&pdev->dev, "invalid IOMMU instance id\n");897897+ return -EINVAL;898898+ }899899+900900+ return 0;901901+}902902+884903/*885904 * OMAP Device MMU(IOMMU) detection886905 */···960907 if (IS_ERR(obj->regbase))961908 return PTR_ERR(obj->regbase);962909910910+ err = omap_iommu_dra7_get_dsp_system_cfg(pdev, obj);911911+ if (err)912912+ return err;913913+963914 irq = platform_get_irq(pdev, 0);964915 if (irq < 0)965916 return -ENODEV;···1000943 { .compatible = "ti,omap2-iommu" },1001944 { .compatible = "ti,omap4-iommu" },1002945 { .compatible = "ti,dra7-iommu" },946946+ { .compatible = "ti,dra7-dsp-iommu" },1003947 {},1004948};1005949
+9
drivers/iommu/omap-iommu.h
···3030struct omap_iommu {3131 const char *name;3232 void __iomem *regbase;3333+ struct regmap *syscfg;3334 struct device *dev;3435 struct iommu_domain *domain;3536 struct dentry *debug_dir;···4948 void *ctx; /* iommu context: registres saved area */50495150 int has_bus_err_back;5151+ u32 id;5252};53535454struct cr_regs {···159157 ((pgsz) == MMU_CAM_PGSZ_1M) ? 0xfff00000 : \160158 ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \161159 ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0)160160+161161+/*162162+ * DSP_SYSTEM registers and bit definitions (applicable only for DRA7xx DSP)163163+ */164164+#define DSP_SYS_REVISION 0x00165165+#define DSP_SYS_MMU_CONFIG 0x18166166+#define DSP_SYS_MMU_CONFIG_EN_SHIFT 4162167163168/*164169 * utilities for super page(16MB, 1MB, 64KB and 4KB)
+337
drivers/iommu/s390-iommu.c
···11+/*22+ * IOMMU API for s390 PCI devices33+ *44+ * Copyright IBM Corp. 201555+ * Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com>66+ */77+88+#include <linux/pci.h>99+#include <linux/iommu.h>1010+#include <linux/iommu-helper.h>1111+#include <linux/pci.h>1212+#include <linux/sizes.h>1313+#include <asm/pci_dma.h>1414+1515+/*1616+ * Physically contiguous memory regions can be mapped with 4 KiB alignment,1717+ * we allow all page sizes that are an order of 4KiB (no special large page1818+ * support so far).1919+ */2020+#define S390_IOMMU_PGSIZES (~0xFFFUL)2121+2222+struct s390_domain {2323+ struct iommu_domain domain;2424+ struct list_head devices;2525+ unsigned long *dma_table;2626+ spinlock_t dma_table_lock;2727+ spinlock_t list_lock;2828+};2929+3030+struct s390_domain_device {3131+ struct list_head list;3232+ struct zpci_dev *zdev;3333+};3434+3535+static struct s390_domain *to_s390_domain(struct iommu_domain *dom)3636+{3737+ return container_of(dom, struct s390_domain, domain);3838+}3939+4040+static bool s390_iommu_capable(enum iommu_cap cap)4141+{4242+ switch (cap) {4343+ case IOMMU_CAP_CACHE_COHERENCY:4444+ return true;4545+ case IOMMU_CAP_INTR_REMAP:4646+ return true;4747+ default:4848+ return false;4949+ }5050+}5151+5252+struct iommu_domain *s390_domain_alloc(unsigned domain_type)5353+{5454+ struct s390_domain *s390_domain;5555+5656+ if (domain_type != IOMMU_DOMAIN_UNMANAGED)5757+ return NULL;5858+5959+ s390_domain = kzalloc(sizeof(*s390_domain), GFP_KERNEL);6060+ if (!s390_domain)6161+ return NULL;6262+6363+ s390_domain->dma_table = dma_alloc_cpu_table();6464+ if (!s390_domain->dma_table) {6565+ kfree(s390_domain);6666+ return NULL;6767+ }6868+6969+ spin_lock_init(&s390_domain->dma_table_lock);7070+ spin_lock_init(&s390_domain->list_lock);7171+ INIT_LIST_HEAD(&s390_domain->devices);7272+7373+ return &s390_domain->domain;7474+}7575+7676+void s390_domain_free(struct iommu_domain *domain)7777+{7878+ struct s390_domain *s390_domain = to_s390_domain(domain);7979+8080+ dma_cleanup_tables(s390_domain->dma_table);8181+ kfree(s390_domain);8282+}8383+8484+static int s390_iommu_attach_device(struct iommu_domain *domain,8585+ struct device *dev)8686+{8787+ struct s390_domain *s390_domain = to_s390_domain(domain);8888+ struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;8989+ struct s390_domain_device *domain_device;9090+ unsigned long flags;9191+ int rc;9292+9393+ if (!zdev)9494+ return -ENODEV;9595+9696+ domain_device = kzalloc(sizeof(*domain_device), GFP_KERNEL);9797+ if (!domain_device)9898+ return -ENOMEM;9999+100100+ if (zdev->dma_table)101101+ zpci_dma_exit_device(zdev);102102+103103+ zdev->dma_table = s390_domain->dma_table;104104+ rc = zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET,105105+ zdev->start_dma + zdev->iommu_size - 1,106106+ (u64) zdev->dma_table);107107+ if (rc)108108+ goto out_restore;109109+110110+ spin_lock_irqsave(&s390_domain->list_lock, flags);111111+ /* First device defines the DMA range limits */112112+ if (list_empty(&s390_domain->devices)) {113113+ domain->geometry.aperture_start = zdev->start_dma;114114+ domain->geometry.aperture_end = zdev->end_dma;115115+ domain->geometry.force_aperture = true;116116+ /* Allow only devices with identical DMA range limits */117117+ } else if (domain->geometry.aperture_start != zdev->start_dma ||118118+ domain->geometry.aperture_end != zdev->end_dma) {119119+ rc = -EINVAL;120120+ spin_unlock_irqrestore(&s390_domain->list_lock, flags);121121+ goto out_restore;122122+ }123123+ domain_device->zdev = zdev;124124+ zdev->s390_domain = s390_domain;125125+ list_add(&domain_device->list, &s390_domain->devices);126126+ spin_unlock_irqrestore(&s390_domain->list_lock, flags);127127+128128+ return 0;129129+130130+out_restore:131131+ zpci_dma_init_device(zdev);132132+ kfree(domain_device);133133+134134+ return rc;135135+}136136+137137+static void s390_iommu_detach_device(struct iommu_domain *domain,138138+ struct device *dev)139139+{140140+ struct s390_domain *s390_domain = to_s390_domain(domain);141141+ struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;142142+ struct s390_domain_device *domain_device, *tmp;143143+ unsigned long flags;144144+ int found = 0;145145+146146+ if (!zdev)147147+ return;148148+149149+ spin_lock_irqsave(&s390_domain->list_lock, flags);150150+ list_for_each_entry_safe(domain_device, tmp, &s390_domain->devices,151151+ list) {152152+ if (domain_device->zdev == zdev) {153153+ list_del(&domain_device->list);154154+ kfree(domain_device);155155+ found = 1;156156+ break;157157+ }158158+ }159159+ spin_unlock_irqrestore(&s390_domain->list_lock, flags);160160+161161+ if (found) {162162+ zdev->s390_domain = NULL;163163+ zpci_unregister_ioat(zdev, 0);164164+ zpci_dma_init_device(zdev);165165+ }166166+}167167+168168+static int s390_iommu_add_device(struct device *dev)169169+{170170+ struct iommu_group *group;171171+ int rc;172172+173173+ group = iommu_group_get(dev);174174+ if (!group) {175175+ group = iommu_group_alloc();176176+ if (IS_ERR(group))177177+ return PTR_ERR(group);178178+ }179179+180180+ rc = iommu_group_add_device(group, dev);181181+ iommu_group_put(group);182182+183183+ return rc;184184+}185185+186186+static void s390_iommu_remove_device(struct device *dev)187187+{188188+ struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;189189+ struct iommu_domain *domain;190190+191191+ /*192192+ * This is a workaround for a scenario where the IOMMU API common code193193+ * "forgets" to call the detach_dev callback: After binding a device194194+ * to vfio-pci and completing the VFIO_SET_IOMMU ioctl (which triggers195195+ * the attach_dev), removing the device via196196+ * "echo 1 > /sys/bus/pci/devices/.../remove" won't trigger detach_dev,197197+ * only remove_device will be called via the BUS_NOTIFY_REMOVED_DEVICE198198+ * notifier.199199+ *200200+ * So let's call detach_dev from here if it hasn't been called before.201201+ */202202+ if (zdev && zdev->s390_domain) {203203+ domain = iommu_get_domain_for_dev(dev);204204+ if (domain)205205+ s390_iommu_detach_device(domain, dev);206206+ }207207+208208+ iommu_group_remove_device(dev);209209+}210210+211211+static int s390_iommu_update_trans(struct s390_domain *s390_domain,212212+ unsigned long pa, dma_addr_t dma_addr,213213+ size_t size, int flags)214214+{215215+ struct s390_domain_device *domain_device;216216+ u8 *page_addr = (u8 *) (pa & PAGE_MASK);217217+ dma_addr_t start_dma_addr = dma_addr;218218+ unsigned long irq_flags, nr_pages, i;219219+ int rc = 0;220220+221221+ if (dma_addr < s390_domain->domain.geometry.aperture_start ||222222+ dma_addr + size > s390_domain->domain.geometry.aperture_end)223223+ return -EINVAL;224224+225225+ nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;226226+ if (!nr_pages)227227+ return 0;228228+229229+ spin_lock_irqsave(&s390_domain->dma_table_lock, irq_flags);230230+ for (i = 0; i < nr_pages; i++) {231231+ dma_update_cpu_trans(s390_domain->dma_table, page_addr,232232+ dma_addr, flags);233233+ page_addr += PAGE_SIZE;234234+ dma_addr += PAGE_SIZE;235235+ }236236+237237+ spin_lock(&s390_domain->list_lock);238238+ list_for_each_entry(domain_device, &s390_domain->devices, list) {239239+ rc = zpci_refresh_trans((u64) domain_device->zdev->fh << 32,240240+ start_dma_addr, nr_pages * PAGE_SIZE);241241+ if (rc)242242+ break;243243+ }244244+ spin_unlock(&s390_domain->list_lock);245245+ spin_unlock_irqrestore(&s390_domain->dma_table_lock, irq_flags);246246+247247+ return rc;248248+}249249+250250+static int s390_iommu_map(struct iommu_domain *domain, unsigned long iova,251251+ phys_addr_t paddr, size_t size, int prot)252252+{253253+ struct s390_domain *s390_domain = to_s390_domain(domain);254254+ int flags = ZPCI_PTE_VALID, rc = 0;255255+256256+ if (!(prot & IOMMU_READ))257257+ return -EINVAL;258258+259259+ if (!(prot & IOMMU_WRITE))260260+ flags |= ZPCI_TABLE_PROTECTED;261261+262262+ rc = s390_iommu_update_trans(s390_domain, (unsigned long) paddr, iova,263263+ size, flags);264264+265265+ return rc;266266+}267267+268268+static phys_addr_t s390_iommu_iova_to_phys(struct iommu_domain *domain,269269+ dma_addr_t iova)270270+{271271+ struct s390_domain *s390_domain = to_s390_domain(domain);272272+ unsigned long *sto, *pto, *rto, flags;273273+ unsigned int rtx, sx, px;274274+ phys_addr_t phys = 0;275275+276276+ if (iova < domain->geometry.aperture_start ||277277+ iova > domain->geometry.aperture_end)278278+ return 0;279279+280280+ rtx = calc_rtx(iova);281281+ sx = calc_sx(iova);282282+ px = calc_px(iova);283283+ rto = s390_domain->dma_table;284284+285285+ spin_lock_irqsave(&s390_domain->dma_table_lock, flags);286286+ if (rto && reg_entry_isvalid(rto[rtx])) {287287+ sto = get_rt_sto(rto[rtx]);288288+ if (sto && reg_entry_isvalid(sto[sx])) {289289+ pto = get_st_pto(sto[sx]);290290+ if (pto && pt_entry_isvalid(pto[px]))291291+ phys = pto[px] & ZPCI_PTE_ADDR_MASK;292292+ }293293+ }294294+ spin_unlock_irqrestore(&s390_domain->dma_table_lock, flags);295295+296296+ return phys;297297+}298298+299299+static size_t s390_iommu_unmap(struct iommu_domain *domain,300300+ unsigned long iova, size_t size)301301+{302302+ struct s390_domain *s390_domain = to_s390_domain(domain);303303+ int flags = ZPCI_PTE_INVALID;304304+ phys_addr_t paddr;305305+ int rc;306306+307307+ paddr = s390_iommu_iova_to_phys(domain, iova);308308+ if (!paddr)309309+ return 0;310310+311311+ rc = s390_iommu_update_trans(s390_domain, (unsigned long) paddr, iova,312312+ size, flags);313313+ if (rc)314314+ return 0;315315+316316+ return size;317317+}318318+319319+static struct iommu_ops s390_iommu_ops = {320320+ .capable = s390_iommu_capable,321321+ .domain_alloc = s390_domain_alloc,322322+ .domain_free = s390_domain_free,323323+ .attach_dev = s390_iommu_attach_device,324324+ .detach_dev = s390_iommu_detach_device,325325+ .map = s390_iommu_map,326326+ .unmap = s390_iommu_unmap,327327+ .iova_to_phys = s390_iommu_iova_to_phys,328328+ .add_device = s390_iommu_add_device,329329+ .remove_device = s390_iommu_remove_device,330330+ .pgsize_bitmap = S390_IOMMU_PGSIZES,331331+};332332+333333+static int __init s390_iommu_init(void)334334+{335335+ return bus_set_iommu(&pci_bus_type, &s390_iommu_ops);336336+}337337+subsys_initcall(s390_iommu_init);
+85
include/linux/dma-iommu.h
···11+/*22+ * Copyright (C) 2014-2015 ARM Ltd.33+ *44+ * This program is free software; you can redistribute it and/or modify55+ * it under the terms of the GNU General Public License version 2 as66+ * published by the Free Software Foundation.77+ *88+ * This program is distributed in the hope that it will be useful,99+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1010+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1111+ * GNU General Public License for more details.1212+ *1313+ * You should have received a copy of the GNU General Public License1414+ * along with this program. If not, see <http://www.gnu.org/licenses/>.1515+ */1616+#ifndef __DMA_IOMMU_H1717+#define __DMA_IOMMU_H1818+1919+#ifdef __KERNEL__2020+#include <asm/errno.h>2121+2222+#ifdef CONFIG_IOMMU_DMA2323+#include <linux/iommu.h>2424+2525+int iommu_dma_init(void);2626+2727+/* Domain management interface for IOMMU drivers */2828+int iommu_get_dma_cookie(struct iommu_domain *domain);2929+void iommu_put_dma_cookie(struct iommu_domain *domain);3030+3131+/* Setup call for arch DMA mapping code */3232+int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, u64 size);3333+3434+/* General helpers for DMA-API <-> IOMMU-API interaction */3535+int dma_direction_to_prot(enum dma_data_direction dir, bool coherent);3636+3737+/*3838+ * These implement the bulk of the relevant DMA mapping callbacks, but require3939+ * the arch code to take care of attributes and cache maintenance4040+ */4141+struct page **iommu_dma_alloc(struct device *dev, size_t size,4242+ gfp_t gfp, int prot, dma_addr_t *handle,4343+ void (*flush_page)(struct device *, const void *, phys_addr_t));4444+void iommu_dma_free(struct device *dev, struct page **pages, size_t size,4545+ dma_addr_t *handle);4646+4747+int iommu_dma_mmap(struct page **pages, size_t size, struct vm_area_struct *vma);4848+4949+dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,5050+ unsigned long offset, size_t size, int prot);5151+int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,5252+ int nents, int prot);5353+5454+/*5555+ * Arch code with no special attribute handling may use these5656+ * directly as DMA mapping callbacks for simplicity5757+ */5858+void iommu_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,5959+ enum dma_data_direction dir, struct dma_attrs *attrs);6060+void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,6161+ enum dma_data_direction dir, struct dma_attrs *attrs);6262+int iommu_dma_supported(struct device *dev, u64 mask);6363+int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);6464+6565+#else6666+6767+struct iommu_domain;6868+6969+static inline int iommu_dma_init(void)7070+{7171+ return 0;7272+}7373+7474+static inline int iommu_get_dma_cookie(struct iommu_domain *domain)7575+{7676+ return -ENODEV;7777+}7878+7979+static inline void iommu_put_dma_cookie(struct iommu_domain *domain)8080+{8181+}8282+8383+#endif /* CONFIG_IOMMU_DMA */8484+#endif /* __KERNEL__ */8585+#endif /* __DMA_IOMMU_H */