···18691869 bypassed by not enabling DMAR with this option. In18701870 this case, gfx device will use physical address for18711871 DMA.18721872- forcedac [X86-64]18731873- With this option iommu will not optimize to look18741874- for io virtual address below 32-bit forcing dual18751875- address cycle on pci bus for cards supporting greater18761876- than 32-bit addressing. The default is to look18771877- for translation below 32-bit and if not available18781878- then look in the higher range.18791872 strict [Default Off]18801873 With this option on every unmap_single operation will18811874 result in a hardware IOTLB flush operation as opposed···19561963 nopt [X86]19571964 nobypass [PPC/POWERNV]19581965 Disable IOMMU bypass, using IOMMU for PCI devices.19661966+19671967+ iommu.forcedac= [ARM64, X86] Control IOVA allocation for PCI devices.19681968+ Format: { "0" | "1" }19691969+ 0 - Try to allocate a 32-bit DMA address first, before19701970+ falling back to the full range if needed.19711971+ 1 - Allocate directly from the full usable range,19721972+ forcing Dual Address Cycle for PCI cards supporting19731973+ greater than 32-bit addressing.1959197419601975 iommu.strict= [ARM64] Configure TLB invalidation behaviour19611976 Format: { "0" | "1" }
···349349 is not implemented as it is not necessary for VFIO.350350351351config MTK_IOMMU352352- bool "MTK IOMMU Support"352352+ tristate "MediaTek IOMMU Support"353353 depends on ARCH_MEDIATEK || COMPILE_TEST354354 select ARM_DMA_USE_IOMMU355355 select IOMMU_API···364364 If unsure, say N here.365365366366config MTK_IOMMU_V1367367- bool "MTK IOMMU Version 1 (M4U gen1) Support"367367+ tristate "MediaTek IOMMU Version 1 (M4U gen1) Support"368368 depends on ARM369369 depends on ARCH_MEDIATEK || COMPILE_TEST370370 select ARM_DMA_USE_IOMMU···407407 Para-virtualised IOMMU driver with virtio.408408409409 Say Y here if you intend to run this kernel as a guest.410410+411411+config SPRD_IOMMU412412+ tristate "Unisoc IOMMU Support"413413+ depends on ARCH_SPRD || COMPILE_TEST414414+ select IOMMU_API415415+ help416416+ Support for IOMMU on Unisoc's SoCs, this IOMMU can be used by417417+ Unisoc's multimedia devices, such as display, Image codec(jpeg)418418+ and a few signal processors, including VSP(video), GSP(graphic),419419+ ISP(image), and CPP(camera pixel processor), etc.420420+421421+ Say Y here if you want to use the multimedia devices listed above.410422411423endif # IOMMU_SUPPORT
···5252};53535454static DEFINE_STATIC_KEY_FALSE(iommu_deferred_attach_enabled);5555+bool iommu_dma_forcedac __read_mostly;55565656-void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,5757- struct iommu_domain *domain)5757+static int __init iommu_dma_forcedac_setup(char *str)5858{5959- struct iommu_dma_cookie *cookie = domain->iova_cookie;6060- struct iova_domain *iovad = &cookie->iovad;5959+ int ret = kstrtobool(str, &iommu_dma_forcedac);61606262- free_cpu_cached_iovas(cpu, iovad);6161+ if (!ret && iommu_dma_forcedac)6262+ pr_info("Forcing DAC for PCI devices\n");6363+ return ret;6364}6565+early_param("iommu.forcedac", iommu_dma_forcedac_setup);64666567static void iommu_dma_entry_dtor(unsigned long data)6668{···306304307305 cookie = container_of(iovad, struct iommu_dma_cookie, iovad);308306 domain = cookie->fq_domain;309309- /*310310- * The IOMMU driver supporting DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE311311- * implies that ops->flush_iotlb_all must be non-NULL.312312- */307307+313308 domain->ops->flush_iotlb_all(domain);314309}315310···333334 struct iommu_dma_cookie *cookie = domain->iova_cookie;334335 unsigned long order, base_pfn;335336 struct iova_domain *iovad;336336- int attr;337337338338 if (!cookie || cookie->type != IOMMU_DMA_IOVA_COOKIE)339339 return -EINVAL;···369371 init_iova_domain(iovad, 1UL << order, base_pfn);370372371373 if (!cookie->fq_domain && (!dev || !dev_is_untrusted(dev)) &&372372- !iommu_domain_get_attr(domain, DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE, &attr) &&373373- attr) {374374+ domain->ops->flush_iotlb_all && !iommu_get_dma_strict(domain)) {374375 if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,375376 iommu_dma_entry_dtor))376377 pr_warn("iova flush queue initialization failed\n");···441444 dma_limit = min(dma_limit, (u64)domain->geometry.aperture_end);442445443446 /* Try to get PCI devices a SAC address */444444- if (dma_limit > DMA_BIT_MASK(32) && dev_is_pci(dev))447447+ if (dma_limit > DMA_BIT_MASK(32) && !iommu_dma_forcedac && dev_is_pci(dev))445448 iova = alloc_iova_fast(iovad, iova_len,446449 DMA_BIT_MASK(32) >> shift, false);447450
+1-1
drivers/iommu/exynos-iommu.c
···407407 struct sysmmu_drvdata *data = dev_id;408408 const struct sysmmu_fault_info *finfo;409409 unsigned int i, n, itype;410410- sysmmu_iova_t fault_addr = -1;410410+ sysmmu_iova_t fault_addr;411411 unsigned short reg_status, reg_clear;412412 int ret = -ENOSYS;413413
+11-282
drivers/iommu/fsl_pamu.c
···6363/* maximum subwindows permitted per liodn */6464static u32 max_subwindow_count;65656666-/* Pool for fspi allocation */6767-static struct gen_pool *spaace_pool;6868-6969-/**7070- * pamu_get_max_subwin_cnt() - Return the maximum supported7171- * subwindow count per liodn.7272- *7373- */7474-u32 pamu_get_max_subwin_cnt(void)7575-{7676- return max_subwindow_count;7777-}7878-7966/**8067 * pamu_get_ppaace() - Return the primary PACCE8168 * @liodn: liodn PAACT index for desired PAACE···142155 return fls64(addrspace_size) - 2;143156}144157145145-/* Derive the PAACE window count encoding for the subwindow count */146146-static unsigned int map_subwindow_cnt_to_wce(u32 subwindow_cnt)147147-{148148- /* window count is 2^(WCE+1) bytes */149149- return __ffs(subwindow_cnt) - 1;150150-}151151-152158/*153159 * Set the PAACE type as primary and set the coherency required domain154160 * attribute···155175}156176157177/*158158- * Set the PAACE type as secondary and set the coherency required domain159159- * attribute.160160- */161161-static void pamu_init_spaace(struct paace *spaace)162162-{163163- set_bf(spaace->addr_bitfields, PAACE_AF_PT, PAACE_PT_SECONDARY);164164- set_bf(spaace->domain_attr.to_host.coherency_required, PAACE_DA_HOST_CR,165165- PAACE_M_COHERENCE_REQ);166166-}167167-168168-/*169169- * Return the spaace (corresponding to the secondary window index)170170- * for a particular ppaace.171171- */172172-static struct paace *pamu_get_spaace(struct paace *paace, u32 wnum)173173-{174174- u32 subwin_cnt;175175- struct paace *spaace = NULL;176176-177177- subwin_cnt = 1UL << (get_bf(paace->impl_attr, PAACE_IA_WCE) + 1);178178-179179- if (wnum < subwin_cnt)180180- spaace = &spaact[paace->fspi + wnum];181181- else182182- pr_debug("secondary paace out of bounds\n");183183-184184- return spaace;185185-}186186-187187-/**188188- * pamu_get_fspi_and_allocate() - Allocates fspi index and reserves subwindows189189- * required for primary PAACE in the secondary190190- * PAACE table.191191- * @subwin_cnt: Number of subwindows to be reserved.192192- *193193- * A PPAACE entry may have a number of associated subwindows. A subwindow194194- * corresponds to a SPAACE entry in the SPAACT table. Each PAACE entry stores195195- * the index (fspi) of the first SPAACE entry in the SPAACT table. This196196- * function returns the index of the first SPAACE entry. The remaining197197- * SPAACE entries are reserved contiguously from that index.198198- *199199- * Returns a valid fspi index in the range of 0 - SPAACE_NUMBER_ENTRIES on success.200200- * If no SPAACE entry is available or the allocator can not reserve the required201201- * number of contiguous entries function returns ULONG_MAX indicating a failure.202202- *203203- */204204-static unsigned long pamu_get_fspi_and_allocate(u32 subwin_cnt)205205-{206206- unsigned long spaace_addr;207207-208208- spaace_addr = gen_pool_alloc(spaace_pool, subwin_cnt * sizeof(struct paace));209209- if (!spaace_addr)210210- return ULONG_MAX;211211-212212- return (spaace_addr - (unsigned long)spaact) / (sizeof(struct paace));213213-}214214-215215-/* Release the subwindows reserved for a particular LIODN */216216-void pamu_free_subwins(int liodn)217217-{218218- struct paace *ppaace;219219- u32 subwin_cnt, size;220220-221221- ppaace = pamu_get_ppaace(liodn);222222- if (!ppaace) {223223- pr_debug("Invalid liodn entry\n");224224- return;225225- }226226-227227- if (get_bf(ppaace->addr_bitfields, PPAACE_AF_MW)) {228228- subwin_cnt = 1UL << (get_bf(ppaace->impl_attr, PAACE_IA_WCE) + 1);229229- size = (subwin_cnt - 1) * sizeof(struct paace);230230- gen_pool_free(spaace_pool, (unsigned long)&spaact[ppaace->fspi], size);231231- set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0);232232- }233233-}234234-235235-/*236178 * Function used for updating stash destination for the coressponding237179 * LIODN.238180 */239239-int pamu_update_paace_stash(int liodn, u32 subwin, u32 value)181181+int pamu_update_paace_stash(int liodn, u32 value)240182{241183 struct paace *paace;242184···166264 if (!paace) {167265 pr_debug("Invalid liodn entry\n");168266 return -ENOENT;169169- }170170- if (subwin) {171171- paace = pamu_get_spaace(paace, subwin - 1);172172- if (!paace)173173- return -ENOENT;174267 }175268 set_bf(paace->impl_attr, PAACE_IA_CID, value);176176-177177- mb();178178-179179- return 0;180180-}181181-182182-/* Disable a subwindow corresponding to the LIODN */183183-int pamu_disable_spaace(int liodn, u32 subwin)184184-{185185- struct paace *paace;186186-187187- paace = pamu_get_ppaace(liodn);188188- if (!paace) {189189- pr_debug("Invalid liodn entry\n");190190- return -ENOENT;191191- }192192- if (subwin) {193193- paace = pamu_get_spaace(paace, subwin - 1);194194- if (!paace)195195- return -ENOENT;196196- set_bf(paace->addr_bitfields, PAACE_AF_V, PAACE_V_INVALID);197197- } else {198198- set_bf(paace->addr_bitfields, PAACE_AF_AP,199199- PAACE_AP_PERMS_DENIED);200200- }201269202270 mb();203271···178306 * pamu_config_paace() - Sets up PPAACE entry for specified liodn179307 *180308 * @liodn: Logical IO device number181181- * @win_addr: starting address of DSA window182182- * @win-size: size of DSA window183309 * @omi: Operation mapping index -- if ~omi == 0 then omi not defined184184- * @rpn: real (true physical) page number185310 * @stashid: cache stash id for associated cpu -- if ~stashid == 0 then186311 * stashid not defined187187- * @snoopid: snoop id for hardware coherency -- if ~snoopid == 0 then188188- * snoopid not defined189189- * @subwin_cnt: number of sub-windows190312 * @prot: window permissions191313 *192314 * Returns 0 upon success else error code < 0 returned193315 */194194-int pamu_config_ppaace(int liodn, phys_addr_t win_addr, phys_addr_t win_size,195195- u32 omi, unsigned long rpn, u32 snoopid, u32 stashid,196196- u32 subwin_cnt, int prot)316316+int pamu_config_ppaace(int liodn, u32 omi, u32 stashid, int prot)197317{198318 struct paace *ppaace;199199- unsigned long fspi;200200-201201- if ((win_size & (win_size - 1)) || win_size < PAMU_PAGE_SIZE) {202202- pr_debug("window size too small or not a power of two %pa\n",203203- &win_size);204204- return -EINVAL;205205- }206206-207207- if (win_addr & (win_size - 1)) {208208- pr_debug("window address is not aligned with window size\n");209209- return -EINVAL;210210- }211319212320 ppaace = pamu_get_ppaace(liodn);213321 if (!ppaace)···195343196344 /* window size is 2^(WSE+1) bytes */197345 set_bf(ppaace->addr_bitfields, PPAACE_AF_WSE,198198- map_addrspace_size_to_wse(win_size));346346+ map_addrspace_size_to_wse(1ULL << 36));199347200348 pamu_init_ppaace(ppaace);201349202202- ppaace->wbah = win_addr >> (PAMU_PAGE_SHIFT + 20);203203- set_bf(ppaace->addr_bitfields, PPAACE_AF_WBAL,204204- (win_addr >> PAMU_PAGE_SHIFT));350350+ ppaace->wbah = 0;351351+ set_bf(ppaace->addr_bitfields, PPAACE_AF_WBAL, 0);205352206353 /* set up operation mapping if it's configured */207354 if (omi < OME_NUMBER_ENTRIES) {···215364 if (~stashid != 0)216365 set_bf(ppaace->impl_attr, PAACE_IA_CID, stashid);217366218218- /* configure snoop id */219219- if (~snoopid != 0)220220- ppaace->domain_attr.to_host.snpid = snoopid;221221-222222- if (subwin_cnt) {223223- /* The first entry is in the primary PAACE instead */224224- fspi = pamu_get_fspi_and_allocate(subwin_cnt - 1);225225- if (fspi == ULONG_MAX) {226226- pr_debug("spaace indexes exhausted\n");227227- return -EINVAL;228228- }229229-230230- /* window count is 2^(WCE+1) bytes */231231- set_bf(ppaace->impl_attr, PAACE_IA_WCE,232232- map_subwindow_cnt_to_wce(subwin_cnt));233233- set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0x1);234234- ppaace->fspi = fspi;235235- } else {236236- set_bf(ppaace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE);237237- ppaace->twbah = rpn >> 20;238238- set_bf(ppaace->win_bitfields, PAACE_WIN_TWBAL, rpn);239239- set_bf(ppaace->addr_bitfields, PAACE_AF_AP, prot);240240- set_bf(ppaace->impl_attr, PAACE_IA_WCE, 0);241241- set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0);242242- }243243- mb();244244-245245- return 0;246246-}247247-248248-/**249249- * pamu_config_spaace() - Sets up SPAACE entry for specified subwindow250250- *251251- * @liodn: Logical IO device number252252- * @subwin_cnt: number of sub-windows associated with dma-window253253- * @subwin: subwindow index254254- * @subwin_size: size of subwindow255255- * @omi: Operation mapping index256256- * @rpn: real (true physical) page number257257- * @snoopid: snoop id for hardware coherency -- if ~snoopid == 0 then258258- * snoopid not defined259259- * @stashid: cache stash id for associated cpu260260- * @enable: enable/disable subwindow after reconfiguration261261- * @prot: sub window permissions262262- *263263- * Returns 0 upon success else error code < 0 returned264264- */265265-int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin,266266- phys_addr_t subwin_size, u32 omi, unsigned long rpn,267267- u32 snoopid, u32 stashid, int enable, int prot)268268-{269269- struct paace *paace;270270-271271- /* setup sub-windows */272272- if (!subwin_cnt) {273273- pr_debug("Invalid subwindow count\n");274274- return -EINVAL;275275- }276276-277277- paace = pamu_get_ppaace(liodn);278278- if (subwin > 0 && subwin < subwin_cnt && paace) {279279- paace = pamu_get_spaace(paace, subwin - 1);280280-281281- if (paace && !(paace->addr_bitfields & PAACE_V_VALID)) {282282- pamu_init_spaace(paace);283283- set_bf(paace->addr_bitfields, SPAACE_AF_LIODN, liodn);284284- }285285- }286286-287287- if (!paace) {288288- pr_debug("Invalid liodn entry\n");289289- return -ENOENT;290290- }291291-292292- if ((subwin_size & (subwin_size - 1)) || subwin_size < PAMU_PAGE_SIZE) {293293- pr_debug("subwindow size out of range, or not a power of 2\n");294294- return -EINVAL;295295- }296296-297297- if (rpn == ULONG_MAX) {298298- pr_debug("real page number out of range\n");299299- return -EINVAL;300300- }301301-302302- /* window size is 2^(WSE+1) bytes */303303- set_bf(paace->win_bitfields, PAACE_WIN_SWSE,304304- map_addrspace_size_to_wse(subwin_size));305305-306306- set_bf(paace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE);307307- paace->twbah = rpn >> 20;308308- set_bf(paace->win_bitfields, PAACE_WIN_TWBAL, rpn);309309- set_bf(paace->addr_bitfields, PAACE_AF_AP, prot);310310-311311- /* configure snoop id */312312- if (~snoopid != 0)313313- paace->domain_attr.to_host.snpid = snoopid;314314-315315- /* set up operation mapping if it's configured */316316- if (omi < OME_NUMBER_ENTRIES) {317317- set_bf(paace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);318318- paace->op_encode.index_ot.omi = omi;319319- } else if (~omi != 0) {320320- pr_debug("bad operation mapping index: %d\n", omi);321321- return -EINVAL;322322- }323323-324324- if (~stashid != 0)325325- set_bf(paace->impl_attr, PAACE_IA_CID, stashid);326326-327327- smp_wmb();328328-329329- if (enable)330330- set_bf(paace->addr_bitfields, PAACE_AF_V, PAACE_V_VALID);331331-367367+ set_bf(ppaace->impl_attr, PAACE_IA_ATM, PAACE_ATM_WINDOW_XLATE);368368+ ppaace->twbah = 0;369369+ set_bf(ppaace->win_bitfields, PAACE_WIN_TWBAL, 0);370370+ set_bf(ppaace->addr_bitfields, PAACE_AF_AP, prot);371371+ set_bf(ppaace->impl_attr, PAACE_IA_WCE, 0);372372+ set_bf(ppaace->addr_bitfields, PPAACE_AF_MW, 0);332373 mb();333374334375 return 0;···8721129 spaact_phys = virt_to_phys(spaact);8731130 omt_phys = virt_to_phys(omt);8741131875875- spaace_pool = gen_pool_create(ilog2(sizeof(struct paace)), -1);876876- if (!spaace_pool) {877877- ret = -ENOMEM;878878- dev_err(dev, "Failed to allocate spaace gen pool\n");879879- goto error;880880- }881881-882882- ret = gen_pool_add(spaace_pool, (unsigned long)spaact, SPAACT_SIZE, -1);883883- if (ret)884884- goto error_genpool;885885-8861132 pamubypenr = in_be32(&guts_regs->pamubypenr);88711338881134 for (pamu_reg_off = 0, pamu_counter = 0x80000000; pamu_reg_off < size;···8981166 probed = true;89911679001168 return 0;901901-902902-error_genpool:903903- gen_pool_destroy(spaace_pool);90411699051170error:9061171 if (irq != NO_IRQ)
···5454 return 0;5555}56565757-static phys_addr_t get_phys_addr(struct fsl_dma_domain *dma_domain, dma_addr_t iova)5858-{5959- u32 win_cnt = dma_domain->win_cnt;6060- struct dma_window *win_ptr = &dma_domain->win_arr[0];6161- struct iommu_domain_geometry *geom;6262-6363- geom = &dma_domain->iommu_domain.geometry;6464-6565- if (!win_cnt || !dma_domain->geom_size) {6666- pr_debug("Number of windows/geometry not configured for the domain\n");6767- return 0;6868- }6969-7070- if (win_cnt > 1) {7171- u64 subwin_size;7272- dma_addr_t subwin_iova;7373- u32 wnd;7474-7575- subwin_size = dma_domain->geom_size >> ilog2(win_cnt);7676- subwin_iova = iova & ~(subwin_size - 1);7777- wnd = (subwin_iova - geom->aperture_start) >> ilog2(subwin_size);7878- win_ptr = &dma_domain->win_arr[wnd];7979- }8080-8181- if (win_ptr->valid)8282- return win_ptr->paddr + (iova & (win_ptr->size - 1));8383-8484- return 0;8585-}8686-8787-static int map_subwins(int liodn, struct fsl_dma_domain *dma_domain)8888-{8989- struct dma_window *sub_win_ptr = &dma_domain->win_arr[0];9090- int i, ret;9191- unsigned long rpn, flags;9292-9393- for (i = 0; i < dma_domain->win_cnt; i++) {9494- if (sub_win_ptr[i].valid) {9595- rpn = sub_win_ptr[i].paddr >> PAMU_PAGE_SHIFT;9696- spin_lock_irqsave(&iommu_lock, flags);9797- ret = pamu_config_spaace(liodn, dma_domain->win_cnt, i,9898- sub_win_ptr[i].size,9999- ~(u32)0,100100- rpn,101101- dma_domain->snoop_id,102102- dma_domain->stash_id,103103- (i > 0) ? 1 : 0,104104- sub_win_ptr[i].prot);105105- spin_unlock_irqrestore(&iommu_lock, flags);106106- if (ret) {107107- pr_debug("SPAACE configuration failed for liodn %d\n",108108- liodn);109109- return ret;110110- }111111- }112112- }113113-114114- return ret;115115-}116116-117117-static int map_win(int liodn, struct fsl_dma_domain *dma_domain)118118-{119119- int ret;120120- struct dma_window *wnd = &dma_domain->win_arr[0];121121- phys_addr_t wnd_addr = dma_domain->iommu_domain.geometry.aperture_start;122122- unsigned long flags;123123-124124- spin_lock_irqsave(&iommu_lock, flags);125125- ret = pamu_config_ppaace(liodn, wnd_addr,126126- wnd->size,127127- ~(u32)0,128128- wnd->paddr >> PAMU_PAGE_SHIFT,129129- dma_domain->snoop_id, dma_domain->stash_id,130130- 0, wnd->prot);131131- spin_unlock_irqrestore(&iommu_lock, flags);132132- if (ret)133133- pr_debug("PAACE configuration failed for liodn %d\n", liodn);134134-135135- return ret;136136-}137137-138138-/* Map the DMA window corresponding to the LIODN */139139-static int map_liodn(int liodn, struct fsl_dma_domain *dma_domain)140140-{141141- if (dma_domain->win_cnt > 1)142142- return map_subwins(liodn, dma_domain);143143- else144144- return map_win(liodn, dma_domain);145145-}146146-147147-/* Update window/subwindow mapping for the LIODN */148148-static int update_liodn(int liodn, struct fsl_dma_domain *dma_domain, u32 wnd_nr)149149-{150150- int ret;151151- struct dma_window *wnd = &dma_domain->win_arr[wnd_nr];152152- unsigned long flags;153153-154154- spin_lock_irqsave(&iommu_lock, flags);155155- if (dma_domain->win_cnt > 1) {156156- ret = pamu_config_spaace(liodn, dma_domain->win_cnt, wnd_nr,157157- wnd->size,158158- ~(u32)0,159159- wnd->paddr >> PAMU_PAGE_SHIFT,160160- dma_domain->snoop_id,161161- dma_domain->stash_id,162162- (wnd_nr > 0) ? 1 : 0,163163- wnd->prot);164164- if (ret)165165- pr_debug("Subwindow reconfiguration failed for liodn %d\n",166166- liodn);167167- } else {168168- phys_addr_t wnd_addr;169169-170170- wnd_addr = dma_domain->iommu_domain.geometry.aperture_start;171171-172172- ret = pamu_config_ppaace(liodn, wnd_addr,173173- wnd->size,174174- ~(u32)0,175175- wnd->paddr >> PAMU_PAGE_SHIFT,176176- dma_domain->snoop_id, dma_domain->stash_id,177177- 0, wnd->prot);178178- if (ret)179179- pr_debug("Window reconfiguration failed for liodn %d\n",180180- liodn);181181- }182182-183183- spin_unlock_irqrestore(&iommu_lock, flags);184184-185185- return ret;186186-}187187-18857static int update_liodn_stash(int liodn, struct fsl_dma_domain *dma_domain,18958 u32 val)19059{191191- int ret = 0, i;6060+ int ret = 0;19261 unsigned long flags;1936219463 spin_lock_irqsave(&iommu_lock, flags);195195- if (!dma_domain->win_arr) {196196- pr_debug("Windows not configured, stash destination update failed for liodn %d\n",197197- liodn);6464+ ret = pamu_update_paace_stash(liodn, val);6565+ if (ret) {6666+ pr_debug("Failed to update SPAACE for liodn %d\n ", liodn);19867 spin_unlock_irqrestore(&iommu_lock, flags);199199- return -EINVAL;200200- }201201-202202- for (i = 0; i < dma_domain->win_cnt; i++) {203203- ret = pamu_update_paace_stash(liodn, i, val);204204- if (ret) {205205- pr_debug("Failed to update SPAACE %d field for liodn %d\n ",206206- i, liodn);207207- spin_unlock_irqrestore(&iommu_lock, flags);208208- return ret;209209- }6868+ return ret;21069 }2117021271 spin_unlock_irqrestore(&iommu_lock, flags);···74215}7521676217/* Set the geometry parameters for a LIODN */7777-static int pamu_set_liodn(int liodn, struct device *dev,7878- struct fsl_dma_domain *dma_domain,7979- struct iommu_domain_geometry *geom_attr,8080- u32 win_cnt)218218+static int pamu_set_liodn(struct fsl_dma_domain *dma_domain, struct device *dev,219219+ int liodn)81220{8282- phys_addr_t window_addr, window_size;8383- phys_addr_t subwin_size;8484- int ret = 0, i;85221 u32 omi_index = ~(u32)0;86222 unsigned long flags;223223+ int ret;8722488225 /*89226 * Configure the omi_index at the geometry setup time.···88233 */89234 get_ome_index(&omi_index, dev);902359191- window_addr = geom_attr->aperture_start;9292- window_size = dma_domain->geom_size;9393-94236 spin_lock_irqsave(&iommu_lock, flags);95237 ret = pamu_disable_liodn(liodn);9696- if (!ret)9797- ret = pamu_config_ppaace(liodn, window_addr, window_size, omi_index,9898- 0, dma_domain->snoop_id,9999- dma_domain->stash_id, win_cnt, 0);238238+ if (ret)239239+ goto out_unlock;240240+ ret = pamu_config_ppaace(liodn, omi_index, dma_domain->stash_id, 0);241241+ if (ret)242242+ goto out_unlock;243243+ ret = pamu_config_ppaace(liodn, ~(u32)0, dma_domain->stash_id,244244+ PAACE_AP_PERMS_QUERY | PAACE_AP_PERMS_UPDATE);245245+out_unlock:100246 spin_unlock_irqrestore(&iommu_lock, flags);101247 if (ret) {102102- pr_debug("PAACE configuration failed for liodn %d, win_cnt =%d\n",103103- liodn, win_cnt);104104- return ret;248248+ pr_debug("PAACE configuration failed for liodn %d\n",249249+ liodn);105250 }106106-107107- if (win_cnt > 1) {108108- subwin_size = window_size >> ilog2(win_cnt);109109- for (i = 0; i < win_cnt; i++) {110110- spin_lock_irqsave(&iommu_lock, flags);111111- ret = pamu_disable_spaace(liodn, i);112112- if (!ret)113113- ret = pamu_config_spaace(liodn, win_cnt, i,114114- subwin_size, omi_index,115115- 0, dma_domain->snoop_id,116116- dma_domain->stash_id,117117- 0, 0);118118- spin_unlock_irqrestore(&iommu_lock, flags);119119- if (ret) {120120- pr_debug("SPAACE configuration failed for liodn %d\n",121121- liodn);122122- return ret;123123- }124124- }125125- }126126-127251 return ret;128252}129253130130-static int check_size(u64 size, dma_addr_t iova)131131-{132132- /*133133- * Size must be a power of two and at least be equal134134- * to PAMU page size.135135- */136136- if ((size & (size - 1)) || size < PAMU_PAGE_SIZE) {137137- pr_debug("Size too small or not a power of two\n");138138- return -EINVAL;139139- }140140-141141- /* iova must be page size aligned */142142- if (iova & (size - 1)) {143143- pr_debug("Address is not aligned with window size\n");144144- return -EINVAL;145145- }146146-147147- return 0;148148-}149149-150150-static struct fsl_dma_domain *iommu_alloc_dma_domain(void)151151-{152152- struct fsl_dma_domain *domain;153153-154154- domain = kmem_cache_zalloc(fsl_pamu_domain_cache, GFP_KERNEL);155155- if (!domain)156156- return NULL;157157-158158- domain->stash_id = ~(u32)0;159159- domain->snoop_id = ~(u32)0;160160- domain->win_cnt = pamu_get_max_subwin_cnt();161161- domain->geom_size = 0;162162-163163- INIT_LIST_HEAD(&domain->devices);164164-165165- spin_lock_init(&domain->domain_lock);166166-167167- return domain;168168-}169169-170170-static void remove_device_ref(struct device_domain_info *info, u32 win_cnt)254254+static void remove_device_ref(struct device_domain_info *info)171255{172256 unsigned long flags;173257174258 list_del(&info->link);175259 spin_lock_irqsave(&iommu_lock, flags);176176- if (win_cnt > 1)177177- pamu_free_subwins(info->liodn);178260 pamu_disable_liodn(info->liodn);179261 spin_unlock_irqrestore(&iommu_lock, flags);180262 spin_lock_irqsave(&device_domain_lock, flags);···129337 /* Remove the device from the domain device list */130338 list_for_each_entry_safe(info, tmp, &dma_domain->devices, link) {131339 if (!dev || (info->dev == dev))132132- remove_device_ref(info, dma_domain->win_cnt);340340+ remove_device_ref(info);133341 }134342 spin_unlock_irqrestore(&dma_domain->domain_lock, flags);135343}···171379static phys_addr_t fsl_pamu_iova_to_phys(struct iommu_domain *domain,172380 dma_addr_t iova)173381{174174- struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);175175-176382 if (iova < domain->geometry.aperture_start ||177383 iova > domain->geometry.aperture_end)178384 return 0;179179-180180- return get_phys_addr(dma_domain, iova);385385+ return iova;181386}182387183388static bool fsl_pamu_capable(enum iommu_cap cap)···188399189400 /* remove all the devices from the device list */190401 detach_device(NULL, dma_domain);191191-192192- dma_domain->enabled = 0;193193- dma_domain->mapped = 0;194194-195402 kmem_cache_free(fsl_pamu_domain_cache, dma_domain);196403}197404···198413 if (type != IOMMU_DOMAIN_UNMANAGED)199414 return NULL;200415201201- dma_domain = iommu_alloc_dma_domain();202202- if (!dma_domain) {203203- pr_debug("dma_domain allocation failed\n");416416+ dma_domain = kmem_cache_zalloc(fsl_pamu_domain_cache, GFP_KERNEL);417417+ if (!dma_domain)204418 return NULL;205205- }206206- /* defaul geometry 64 GB i.e. maximum system address */419419+420420+ dma_domain->stash_id = ~(u32)0;421421+ INIT_LIST_HEAD(&dma_domain->devices);422422+ spin_lock_init(&dma_domain->domain_lock);423423+424424+ /* default geometry 64 GB i.e. maximum system address */207425 dma_domain->iommu_domain. geometry.aperture_start = 0;208426 dma_domain->iommu_domain.geometry.aperture_end = (1ULL << 36) - 1;209427 dma_domain->iommu_domain.geometry.force_aperture = true;210428211429 return &dma_domain->iommu_domain;212212-}213213-214214-/* Configure geometry settings for all LIODNs associated with domain */215215-static int pamu_set_domain_geometry(struct fsl_dma_domain *dma_domain,216216- struct iommu_domain_geometry *geom_attr,217217- u32 win_cnt)218218-{219219- struct device_domain_info *info;220220- int ret = 0;221221-222222- list_for_each_entry(info, &dma_domain->devices, link) {223223- ret = pamu_set_liodn(info->liodn, info->dev, dma_domain,224224- geom_attr, win_cnt);225225- if (ret)226226- break;227227- }228228-229229- return ret;230430}231431232432/* Update stash destination for all LIODNs associated with the domain */···229459 return ret;230460}231461232232-/* Update domain mappings for all LIODNs associated with the domain */233233-static int update_domain_mapping(struct fsl_dma_domain *dma_domain, u32 wnd_nr)234234-{235235- struct device_domain_info *info;236236- int ret = 0;237237-238238- list_for_each_entry(info, &dma_domain->devices, link) {239239- ret = update_liodn(info->liodn, dma_domain, wnd_nr);240240- if (ret)241241- break;242242- }243243- return ret;244244-}245245-246246-static int disable_domain_win(struct fsl_dma_domain *dma_domain, u32 wnd_nr)247247-{248248- struct device_domain_info *info;249249- int ret = 0;250250-251251- list_for_each_entry(info, &dma_domain->devices, link) {252252- if (dma_domain->win_cnt == 1 && dma_domain->enabled) {253253- ret = pamu_disable_liodn(info->liodn);254254- if (!ret)255255- dma_domain->enabled = 0;256256- } else {257257- ret = pamu_disable_spaace(info->liodn, wnd_nr);258258- }259259- }260260-261261- return ret;262262-}263263-264264-static void fsl_pamu_window_disable(struct iommu_domain *domain, u32 wnd_nr)265265-{266266- struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);267267- unsigned long flags;268268- int ret;269269-270270- spin_lock_irqsave(&dma_domain->domain_lock, flags);271271- if (!dma_domain->win_arr) {272272- pr_debug("Number of windows not configured\n");273273- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);274274- return;275275- }276276-277277- if (wnd_nr >= dma_domain->win_cnt) {278278- pr_debug("Invalid window index\n");279279- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);280280- return;281281- }282282-283283- if (dma_domain->win_arr[wnd_nr].valid) {284284- ret = disable_domain_win(dma_domain, wnd_nr);285285- if (!ret) {286286- dma_domain->win_arr[wnd_nr].valid = 0;287287- dma_domain->mapped--;288288- }289289- }290290-291291- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);292292-}293293-294294-static int fsl_pamu_window_enable(struct iommu_domain *domain, u32 wnd_nr,295295- phys_addr_t paddr, u64 size, int prot)296296-{297297- struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);298298- struct dma_window *wnd;299299- int pamu_prot = 0;300300- int ret;301301- unsigned long flags;302302- u64 win_size;303303-304304- if (prot & IOMMU_READ)305305- pamu_prot |= PAACE_AP_PERMS_QUERY;306306- if (prot & IOMMU_WRITE)307307- pamu_prot |= PAACE_AP_PERMS_UPDATE;308308-309309- spin_lock_irqsave(&dma_domain->domain_lock, flags);310310- if (!dma_domain->win_arr) {311311- pr_debug("Number of windows not configured\n");312312- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);313313- return -ENODEV;314314- }315315-316316- if (wnd_nr >= dma_domain->win_cnt) {317317- pr_debug("Invalid window index\n");318318- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);319319- return -EINVAL;320320- }321321-322322- win_size = dma_domain->geom_size >> ilog2(dma_domain->win_cnt);323323- if (size > win_size) {324324- pr_debug("Invalid window size\n");325325- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);326326- return -EINVAL;327327- }328328-329329- if (dma_domain->win_cnt == 1) {330330- if (dma_domain->enabled) {331331- pr_debug("Disable the window before updating the mapping\n");332332- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);333333- return -EBUSY;334334- }335335-336336- ret = check_size(size, domain->geometry.aperture_start);337337- if (ret) {338338- pr_debug("Aperture start not aligned to the size\n");339339- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);340340- return -EINVAL;341341- }342342- }343343-344344- wnd = &dma_domain->win_arr[wnd_nr];345345- if (!wnd->valid) {346346- wnd->paddr = paddr;347347- wnd->size = size;348348- wnd->prot = pamu_prot;349349-350350- ret = update_domain_mapping(dma_domain, wnd_nr);351351- if (!ret) {352352- wnd->valid = 1;353353- dma_domain->mapped++;354354- }355355- } else {356356- pr_debug("Disable the window before updating the mapping\n");357357- ret = -EBUSY;358358- }359359-360360- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);361361-362362- return ret;363363-}364364-365365-/*366366- * Attach the LIODN to the DMA domain and configure the geometry367367- * and window mappings.368368- */369369-static int handle_attach_device(struct fsl_dma_domain *dma_domain,370370- struct device *dev, const u32 *liodn,371371- int num)372372-{373373- unsigned long flags;374374- struct iommu_domain *domain = &dma_domain->iommu_domain;375375- int ret = 0;376376- int i;377377-378378- spin_lock_irqsave(&dma_domain->domain_lock, flags);379379- for (i = 0; i < num; i++) {380380- /* Ensure that LIODN value is valid */381381- if (liodn[i] >= PAACE_NUMBER_ENTRIES) {382382- pr_debug("Invalid liodn %d, attach device failed for %pOF\n",383383- liodn[i], dev->of_node);384384- ret = -EINVAL;385385- break;386386- }387387-388388- attach_device(dma_domain, liodn[i], dev);389389- /*390390- * Check if geometry has already been configured391391- * for the domain. If yes, set the geometry for392392- * the LIODN.393393- */394394- if (dma_domain->win_arr) {395395- u32 win_cnt = dma_domain->win_cnt > 1 ? dma_domain->win_cnt : 0;396396-397397- ret = pamu_set_liodn(liodn[i], dev, dma_domain,398398- &domain->geometry, win_cnt);399399- if (ret)400400- break;401401- if (dma_domain->mapped) {402402- /*403403- * Create window/subwindow mapping for404404- * the LIODN.405405- */406406- ret = map_liodn(liodn[i], dma_domain);407407- if (ret)408408- break;409409- }410410- }411411- }412412- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);413413-414414- return ret;415415-}416416-417462static int fsl_pamu_attach_device(struct iommu_domain *domain,418463 struct device *dev)419464{420465 struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);466466+ unsigned long flags;467467+ int len, ret = 0, i;421468 const u32 *liodn;422422- u32 liodn_cnt;423423- int len, ret = 0;424469 struct pci_dev *pdev = NULL;425470 struct pci_controller *pci_ctl;426471···255670 }256671257672 liodn = of_get_property(dev->of_node, "fsl,liodn", &len);258258- if (liodn) {259259- liodn_cnt = len / sizeof(u32);260260- ret = handle_attach_device(dma_domain, dev, liodn, liodn_cnt);261261- } else {673673+ if (!liodn) {262674 pr_debug("missing fsl,liodn property at %pOF\n", dev->of_node);263263- ret = -EINVAL;675675+ return -EINVAL;264676 }265677678678+ spin_lock_irqsave(&dma_domain->domain_lock, flags);679679+ for (i = 0; i < len / sizeof(u32); i++) {680680+ /* Ensure that LIODN value is valid */681681+ if (liodn[i] >= PAACE_NUMBER_ENTRIES) {682682+ pr_debug("Invalid liodn %d, attach device failed for %pOF\n",683683+ liodn[i], dev->of_node);684684+ ret = -EINVAL;685685+ break;686686+ }687687+688688+ attach_device(dma_domain, liodn[i], dev);689689+ ret = pamu_set_liodn(dma_domain, dev, liodn[i]);690690+ if (ret)691691+ break;692692+ ret = pamu_enable_liodn(liodn[i]);693693+ if (ret)694694+ break;695695+ }696696+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);266697 return ret;267698}268699···313712 pr_debug("missing fsl,liodn property at %pOF\n", dev->of_node);314713}315714316316-static int configure_domain_geometry(struct iommu_domain *domain, void *data)317317-{318318- struct iommu_domain_geometry *geom_attr = data;319319- struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);320320- dma_addr_t geom_size;321321- unsigned long flags;322322-323323- geom_size = geom_attr->aperture_end - geom_attr->aperture_start + 1;324324- /*325325- * Sanity check the geometry size. Also, we do not support326326- * DMA outside of the geometry.327327- */328328- if (check_size(geom_size, geom_attr->aperture_start) ||329329- !geom_attr->force_aperture) {330330- pr_debug("Invalid PAMU geometry attributes\n");331331- return -EINVAL;332332- }333333-334334- spin_lock_irqsave(&dma_domain->domain_lock, flags);335335- if (dma_domain->enabled) {336336- pr_debug("Can't set geometry attributes as domain is active\n");337337- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);338338- return -EBUSY;339339- }340340-341341- /* Copy the domain geometry information */342342- memcpy(&domain->geometry, geom_attr,343343- sizeof(struct iommu_domain_geometry));344344- dma_domain->geom_size = geom_size;345345-346346- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);347347-348348- return 0;349349-}350350-351715/* Set the domain stash attribute */352352-static int configure_domain_stash(struct fsl_dma_domain *dma_domain, void *data)716716+int fsl_pamu_configure_l1_stash(struct iommu_domain *domain, u32 cpu)353717{354354- struct pamu_stash_attribute *stash_attr = data;718718+ struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);355719 unsigned long flags;356720 int ret;357721358722 spin_lock_irqsave(&dma_domain->domain_lock, flags);359359-360360- memcpy(&dma_domain->dma_stash, stash_attr,361361- sizeof(struct pamu_stash_attribute));362362-363363- dma_domain->stash_id = get_stash_id(stash_attr->cache,364364- stash_attr->cpu);723723+ dma_domain->stash_id = get_stash_id(PAMU_ATTR_CACHE_L1, cpu);365724 if (dma_domain->stash_id == ~(u32)0) {366725 pr_debug("Invalid stash attributes\n");367726 spin_unlock_irqrestore(&dma_domain->domain_lock, flags);368727 return -EINVAL;369728 }370370-371729 ret = update_domain_stash(dma_domain, dma_domain->stash_id);372372-373730 spin_unlock_irqrestore(&dma_domain->domain_lock, flags);374374-375375- return ret;376376-}377377-378378-/* Configure domain dma state i.e. enable/disable DMA */379379-static int configure_domain_dma_state(struct fsl_dma_domain *dma_domain, bool enable)380380-{381381- struct device_domain_info *info;382382- unsigned long flags;383383- int ret;384384-385385- spin_lock_irqsave(&dma_domain->domain_lock, flags);386386-387387- if (enable && !dma_domain->mapped) {388388- pr_debug("Can't enable DMA domain without valid mapping\n");389389- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);390390- return -ENODEV;391391- }392392-393393- dma_domain->enabled = enable;394394- list_for_each_entry(info, &dma_domain->devices, link) {395395- ret = (enable) ? pamu_enable_liodn(info->liodn) :396396- pamu_disable_liodn(info->liodn);397397- if (ret)398398- pr_debug("Unable to set dma state for liodn %d",399399- info->liodn);400400- }401401- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);402402-403403- return 0;404404-}405405-406406-static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count)407407-{408408- struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);409409- unsigned long flags;410410- int ret;411411-412412- spin_lock_irqsave(&dma_domain->domain_lock, flags);413413- /* Ensure domain is inactive i.e. DMA should be disabled for the domain */414414- if (dma_domain->enabled) {415415- pr_debug("Can't set geometry attributes as domain is active\n");416416- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);417417- return -EBUSY;418418- }419419-420420- /* Ensure that the geometry has been set for the domain */421421- if (!dma_domain->geom_size) {422422- pr_debug("Please configure geometry before setting the number of windows\n");423423- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);424424- return -EINVAL;425425- }426426-427427- /*428428- * Ensure we have valid window count i.e. it should be less than429429- * maximum permissible limit and should be a power of two.430430- */431431- if (w_count > pamu_get_max_subwin_cnt() || !is_power_of_2(w_count)) {432432- pr_debug("Invalid window count\n");433433- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);434434- return -EINVAL;435435- }436436-437437- ret = pamu_set_domain_geometry(dma_domain, &domain->geometry,438438- w_count > 1 ? w_count : 0);439439- if (!ret) {440440- kfree(dma_domain->win_arr);441441- dma_domain->win_arr = kcalloc(w_count,442442- sizeof(*dma_domain->win_arr),443443- GFP_ATOMIC);444444- if (!dma_domain->win_arr) {445445- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);446446- return -ENOMEM;447447- }448448- dma_domain->win_cnt = w_count;449449- }450450- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);451451-452452- return ret;453453-}454454-455455-static int fsl_pamu_set_domain_attr(struct iommu_domain *domain,456456- enum iommu_attr attr_type, void *data)457457-{458458- struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);459459- int ret = 0;460460-461461- switch (attr_type) {462462- case DOMAIN_ATTR_GEOMETRY:463463- ret = configure_domain_geometry(domain, data);464464- break;465465- case DOMAIN_ATTR_FSL_PAMU_STASH:466466- ret = configure_domain_stash(dma_domain, data);467467- break;468468- case DOMAIN_ATTR_FSL_PAMU_ENABLE:469469- ret = configure_domain_dma_state(dma_domain, *(int *)data);470470- break;471471- case DOMAIN_ATTR_WINDOWS:472472- ret = fsl_pamu_set_windows(domain, *(u32 *)data);473473- break;474474- default:475475- pr_debug("Unsupported attribute type\n");476476- ret = -EINVAL;477477- break;478478- }479479-480480- return ret;481481-}482482-483483-static int fsl_pamu_get_domain_attr(struct iommu_domain *domain,484484- enum iommu_attr attr_type, void *data)485485-{486486- struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);487487- int ret = 0;488488-489489- switch (attr_type) {490490- case DOMAIN_ATTR_FSL_PAMU_STASH:491491- memcpy(data, &dma_domain->dma_stash,492492- sizeof(struct pamu_stash_attribute));493493- break;494494- case DOMAIN_ATTR_FSL_PAMU_ENABLE:495495- *(int *)data = dma_domain->enabled;496496- break;497497- case DOMAIN_ATTR_FSL_PAMUV1:498498- *(int *)data = DOMAIN_ATTR_FSL_PAMUV1;499499- break;500500- case DOMAIN_ATTR_WINDOWS:501501- *(u32 *)data = dma_domain->win_cnt;502502- break;503503- default:504504- pr_debug("Unsupported attribute type\n");505505- ret = -EINVAL;506506- break;507507- }508731509732 return ret;510733}···4561031 .domain_free = fsl_pamu_domain_free,4571032 .attach_dev = fsl_pamu_attach_device,4581033 .detach_dev = fsl_pamu_detach_device,459459- .domain_window_enable = fsl_pamu_window_enable,460460- .domain_window_disable = fsl_pamu_window_disable,4611034 .iova_to_phys = fsl_pamu_iova_to_phys,462462- .domain_set_attr = fsl_pamu_set_domain_attr,463463- .domain_get_attr = fsl_pamu_get_domain_attr,4641035 .probe_device = fsl_pamu_probe_device,4651036 .release_device = fsl_pamu_release_device,4661037 .device_group = fsl_pamu_device_group,
-46
drivers/iommu/fsl_pamu_domain.h
···991010#include "fsl_pamu.h"11111212-struct dma_window {1313- phys_addr_t paddr;1414- u64 size;1515- int valid;1616- int prot;1717-};1818-1912struct fsl_dma_domain {2020- /*2121- * Indicates the geometry size for the domain.2222- * This would be set when the geometry is2323- * configured for the domain.2424- */2525- dma_addr_t geom_size;2626- /*2727- * Number of windows assocaited with this domain.2828- * During domain initialization, it is set to the2929- * the maximum number of subwindows allowed for a LIODN.3030- * Minimum value for this is 1 indicating a single PAMU3131- * window, without any sub windows. Value can be set/3232- * queried by set_attr/get_attr API for DOMAIN_ATTR_WINDOWS.3333- * Value can only be set once the geometry has been configured.3434- */3535- u32 win_cnt;3636- /*3737- * win_arr contains information of the configured3838- * windows for a domain. This is allocated only3939- * when the number of windows for the domain are4040- * set.4141- */4242- struct dma_window *win_arr;4313 /* list of devices associated with the domain */4414 struct list_head devices;4545- /* dma_domain states:4646- * mapped - A particular mapping has been created4747- * within the configured geometry.4848- * enabled - DMA has been enabled for the given4949- * domain. This translates to setting of the5050- * valid bit for the primary PAACE in the PAMU5151- * PAACT table. Domain geometry should be set and5252- * it must have a valid mapping before DMA can be5353- * enabled for it.5454- *5555- */5656- int mapped;5757- int enabled;5858- /* stash_id obtained from the stash attribute details */5915 u32 stash_id;6060- struct pamu_stash_attribute dma_stash;6161- u32 snoop_id;6216 struct iommu_domain iommu_domain;6317 spinlock_t domain_lock;6418};
+64-4
drivers/iommu/intel/dmar.c
···12051205 }12061206}1207120712081208+static const char *qi_type_string(u8 type)12091209+{12101210+ switch (type) {12111211+ case QI_CC_TYPE:12121212+ return "Context-cache Invalidation";12131213+ case QI_IOTLB_TYPE:12141214+ return "IOTLB Invalidation";12151215+ case QI_DIOTLB_TYPE:12161216+ return "Device-TLB Invalidation";12171217+ case QI_IEC_TYPE:12181218+ return "Interrupt Entry Cache Invalidation";12191219+ case QI_IWD_TYPE:12201220+ return "Invalidation Wait";12211221+ case QI_EIOTLB_TYPE:12221222+ return "PASID-based IOTLB Invalidation";12231223+ case QI_PC_TYPE:12241224+ return "PASID-cache Invalidation";12251225+ case QI_DEIOTLB_TYPE:12261226+ return "PASID-based Device-TLB Invalidation";12271227+ case QI_PGRP_RESP_TYPE:12281228+ return "Page Group Response";12291229+ default:12301230+ return "UNKNOWN";12311231+ }12321232+}12331233+12341234+static void qi_dump_fault(struct intel_iommu *iommu, u32 fault)12351235+{12361236+ unsigned int head = dmar_readl(iommu->reg + DMAR_IQH_REG);12371237+ u64 iqe_err = dmar_readq(iommu->reg + DMAR_IQER_REG);12381238+ struct qi_desc *desc = iommu->qi->desc + head;12391239+12401240+ if (fault & DMA_FSTS_IQE)12411241+ pr_err("VT-d detected Invalidation Queue Error: Reason %llx",12421242+ DMAR_IQER_REG_IQEI(iqe_err));12431243+ if (fault & DMA_FSTS_ITE)12441244+ pr_err("VT-d detected Invalidation Time-out Error: SID %llx",12451245+ DMAR_IQER_REG_ITESID(iqe_err));12461246+ if (fault & DMA_FSTS_ICE)12471247+ pr_err("VT-d detected Invalidation Completion Error: SID %llx",12481248+ DMAR_IQER_REG_ICESID(iqe_err));12491249+12501250+ pr_err("QI HEAD: %s qw0 = 0x%llx, qw1 = 0x%llx\n",12511251+ qi_type_string(desc->qw0 & 0xf),12521252+ (unsigned long long)desc->qw0,12531253+ (unsigned long long)desc->qw1);12541254+12551255+ head = ((head >> qi_shift(iommu)) + QI_LENGTH - 1) % QI_LENGTH;12561256+ head <<= qi_shift(iommu);12571257+ desc = iommu->qi->desc + head;12581258+12591259+ pr_err("QI PRIOR: %s qw0 = 0x%llx, qw1 = 0x%llx\n",12601260+ qi_type_string(desc->qw0 & 0xf),12611261+ (unsigned long long)desc->qw0,12621262+ (unsigned long long)desc->qw1);12631263+}12641264+12081265static int qi_check_fault(struct intel_iommu *iommu, int index, int wait_index)12091266{12101267 u32 fault;···12731216 return -EAGAIN;1274121712751218 fault = readl(iommu->reg + DMAR_FSTS_REG);12191219+ if (fault & (DMA_FSTS_IQE | DMA_FSTS_ITE | DMA_FSTS_ICE))12201220+ qi_dump_fault(iommu, fault);1276122112771222 /*12781223 * If IQE happens, the head points to the descriptor associated···12911232 * used by software as private data. We won't print12921233 * out these two qw's for security consideration.12931234 */12941294- pr_err("VT-d detected invalid descriptor: qw0 = %llx, qw1 = %llx\n",12951295- (unsigned long long)desc->qw0,12961296- (unsigned long long)desc->qw1);12971235 memcpy(desc, qi->desc + (wait_index << shift),12981236 1 << shift);12991237 writel(DMA_FSTS_IQE, iommu->reg + DMAR_FSTS_REG);12381238+ pr_info("Invalidation Queue Error (IQE) cleared\n");13001239 return -EINVAL;13011240 }13021241 }···13111254 tail = ((tail >> shift) - 1 + QI_LENGTH) % QI_LENGTH;1312125513131256 writel(DMA_FSTS_ITE, iommu->reg + DMAR_FSTS_REG);12571257+ pr_info("Invalidation Time-out Error (ITE) cleared\n");1314125813151259 do {13161260 if (qi->desc_status[head] == QI_IN_USE)···13231265 return -EAGAIN;13241266 }1325126713261326- if (fault & DMA_FSTS_ICE)12681268+ if (fault & DMA_FSTS_ICE) {13271269 writel(DMA_FSTS_ICE, iommu->reg + DMAR_FSTS_REG);12701270+ pr_info("Invalidation Completion Error (ICE) cleared\n");12711271+ }1328127213291273 return 0;13301274}
+94-136
drivers/iommu/intel/iommu.c
···360360EXPORT_SYMBOL_GPL(intel_iommu_enabled);361361362362static int dmar_map_gfx = 1;363363-static int dmar_forcedac;364363static int intel_iommu_strict;365364static int intel_iommu_superpage = 1;366365static int iommu_identity_mapping;···450451 dmar_map_gfx = 0;451452 pr_info("Disable GFX device mapping\n");452453 } else if (!strncmp(str, "forcedac", 8)) {453453- pr_info("Forcing DAC for PCI devices\n");454454- dmar_forcedac = 1;454454+ pr_warn("intel_iommu=forcedac deprecated; use iommu.forcedac instead\n");455455+ iommu_dma_forcedac = true;455456 } else if (!strncmp(str, "strict", 6)) {456457 pr_info("Disable batched IOTLB flush\n");457458 intel_iommu_strict = 1;···657658 rcu_read_lock();658659 for_each_active_iommu(iommu, drhd) {659660 if (iommu != skip) {660660- if (!ecap_sc_support(iommu->ecap)) {661661+ /*662662+ * If the hardware is operating in the scalable mode,663663+ * the snooping control is always supported since we664664+ * always set PASID-table-entry.PGSNP bit if the domain665665+ * is managed outside (UNMANAGED).666666+ */667667+ if (!sm_supported(iommu) &&668668+ !ecap_sc_support(iommu->ecap)) {661669 ret = 0;662670 break;663671 }···13461340 readl, (sts & DMA_GSTS_RTPS), sts);1347134113481342 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);13431343+13441344+ iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);13451345+ if (sm_supported(iommu))13461346+ qi_flush_pasid_cache(iommu, 0, QI_PC_GLOBAL, 0);13471347+ iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);13491348}1350134913511350void iommu_flush_write_buffer(struct intel_iommu *iommu)···23002289 return level;23012290}2302229122922292+/*22932293+ * Ensure that old small page tables are removed to make room for superpage(s).22942294+ * We're going to add new large pages, so make sure we don't remove their parent22952295+ * tables. The IOTLB/devTLBs should be flushed if any PDE/PTEs are cleared.22962296+ */22972297+static void switch_to_super_page(struct dmar_domain *domain,22982298+ unsigned long start_pfn,22992299+ unsigned long end_pfn, int level)23002300+{23012301+ unsigned long lvl_pages = lvl_to_nr_pages(level);23022302+ struct dma_pte *pte = NULL;23032303+ int i;23042304+23052305+ while (start_pfn <= end_pfn) {23062306+ if (!pte)23072307+ pte = pfn_to_dma_pte(domain, start_pfn, &level);23082308+23092309+ if (dma_pte_present(pte)) {23102310+ dma_pte_free_pagetable(domain, start_pfn,23112311+ start_pfn + lvl_pages - 1,23122312+ level + 1);23132313+23142314+ for_each_domain_iommu(i, domain)23152315+ iommu_flush_iotlb_psi(g_iommus[i], domain,23162316+ start_pfn, lvl_pages,23172317+ 0, 0);23182318+ }23192319+23202320+ pte++;23212321+ start_pfn += lvl_pages;23222322+ if (first_pte_in_page(pte))23232323+ pte = NULL;23242324+ }23252325+}23262326+23032327static int23042328__domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,23052329 unsigned long phys_pfn, unsigned long nr_pages, int prot)···23512305 return -EINVAL;2352230623532307 attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP);23082308+ attr |= DMA_FL_PTE_PRESENT;23542309 if (domain_use_first_level(domain)) {23552355- attr |= DMA_FL_PTE_PRESENT | DMA_FL_PTE_XD | DMA_FL_PTE_US;23102310+ attr |= DMA_FL_PTE_XD | DMA_FL_PTE_US;2356231123572312 if (domain->domain.type == IOMMU_DOMAIN_DMA) {23582313 attr |= DMA_FL_PTE_ACCESS;···23762329 return -ENOMEM;23772330 /* It is large page*/23782331 if (largepage_lvl > 1) {23792379- unsigned long nr_superpages, end_pfn;23322332+ unsigned long end_pfn;2380233323812334 pteval |= DMA_PTE_LARGE_PAGE;23822382- lvl_pages = lvl_to_nr_pages(largepage_lvl);23832383-23842384- nr_superpages = nr_pages / lvl_pages;23852385- end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;23862386-23872387- /*23882388- * Ensure that old small page tables are23892389- * removed to make room for superpage(s).23902390- * We're adding new large pages, so make sure23912391- * we don't remove their parent tables.23922392- */23932393- dma_pte_free_pagetable(domain, iov_pfn, end_pfn,23942394- largepage_lvl + 1);23352335+ end_pfn = ((iov_pfn + nr_pages) & level_mask(largepage_lvl)) - 1;23362336+ switch_to_super_page(domain, iov_pfn, end_pfn, largepage_lvl);23952337 } else {23962338 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;23972339 }···24582422 (((u16)bus) << 8) | devfn,24592423 DMA_CCMD_MASK_NOBIT,24602424 DMA_CCMD_DEVICE_INVL);24252425+24262426+ if (sm_supported(iommu))24272427+ qi_flush_pasid_cache(iommu, did_old, QI_PC_ALL_PASIDS, 0);24282428+24612429 iommu->flush.flush_iotlb(iommu,24622430 did_old,24632431 0,···25442504 return -EINVAL;2545250525462506 flags |= (level == 5) ? PASID_FLAG_FL5LP : 0;25072507+25082508+ if (domain->domain.type == IOMMU_DOMAIN_UNMANAGED)25092509+ flags |= PASID_FLAG_PAGE_SNOOP;2547251025482511 return intel_pasid_setup_first_level(iommu, dev, (pgd_t *)pgd, pasid,25492512 domain->iommu_did[iommu->seq_id],···33103267 register_pasid_allocator(iommu);33113268#endif33123269 iommu_set_root_entry(iommu);33133313- iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);33143314- iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);33153270 }3316327133173272#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA···34993458 }3500345935013460 iommu_flush_write_buffer(iommu);35023502-35033461 iommu_set_root_entry(iommu);35043504-35053505- iommu->flush.flush_context(iommu, 0, 0, 0,35063506- DMA_CCMD_GLOBAL_INVL);35073507- iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);35083462 iommu_enable_translation(iommu);35093463 iommu_disable_protect_mem_regions(iommu);35103464 }···38823846 goto disable_iommu;3883384738843848 iommu_set_root_entry(iommu);38853885- iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);38863886- iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);38873849 iommu_enable_translation(iommu);3888385038893851 iommu_disable_protect_mem_regions(iommu);···40984064 .notifier_call = intel_iommu_memory_notifier,40994065 .priority = 041004066};41014101-41024102-static void free_all_cpu_cached_iovas(unsigned int cpu)41034103-{41044104- int i;41054105-41064106- for (i = 0; i < g_num_of_iommus; i++) {41074107- struct intel_iommu *iommu = g_iommus[i];41084108- struct dmar_domain *domain;41094109- int did;41104110-41114111- if (!iommu)41124112- continue;41134113-41144114- for (did = 0; did < cap_ndoms(iommu->cap); did++) {41154115- domain = get_iommu_domain(iommu, (u16)did);41164116-41174117- if (!domain || domain->domain.type != IOMMU_DOMAIN_DMA)41184118- continue;41194119-41204120- iommu_dma_free_cpu_cached_iovas(cpu, &domain->domain);41214121- }41224122- }41234123-}41244124-41254125-static int intel_iommu_cpu_dead(unsigned int cpu)41264126-{41274127- free_all_cpu_cached_iovas(cpu);41284128- return 0;41294129-}4130406741314068static void intel_disable_iommus(void)41324069{···4382437743834378 down_read(&dmar_global_lock);43844379 for_each_active_iommu(iommu, drhd) {43804380+ /*43814381+ * The flush queue implementation does not perform43824382+ * page-selective invalidations that are required for efficient43834383+ * TLB flushes in virtual environments. The benefit of batching43844384+ * is likely to be much lower than the overhead of synchronizing43854385+ * the virtual and physical IOMMU page-tables.43864386+ */43874387+ if (!intel_iommu_strict && cap_caching_mode(iommu->cap)) {43884388+ pr_warn("IOMMU batching is disabled due to virtualization");43894389+ intel_iommu_strict = 1;43904390+ }43854391 iommu_device_sysfs_add(&iommu->iommu, NULL,43864392 intel_iommu_groups,43874393 "%s", iommu->name);···44014385 }44024386 up_read(&dmar_global_lock);4403438743884388+ iommu_set_dma_strict(intel_iommu_strict);44044389 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);44054390 if (si_domain && !hw_pass_through)44064391 register_memory_notifier(&intel_iommu_memory_nb);44074407- cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,44084408- intel_iommu_cpu_dead);4409439244104393 down_read(&dmar_global_lock);44114394 if (probe_acpi_namespace_devices())···53585343static bool53595344intel_iommu_dev_has_feat(struct device *dev, enum iommu_dev_features feat)53605345{53465346+ struct device_domain_info *info = get_domain_info(dev);53475347+53615348 if (feat == IOMMU_DEV_FEAT_AUX) {53625349 int ret;53635350···53745357 return !!siov_find_pci_dvsec(to_pci_dev(dev));53755358 }5376535953775377- if (feat == IOMMU_DEV_FEAT_SVA) {53785378- struct device_domain_info *info = get_domain_info(dev);53605360+ if (feat == IOMMU_DEV_FEAT_IOPF)53615361+ return info && info->pri_supported;5379536253635363+ if (feat == IOMMU_DEV_FEAT_SVA)53805364 return info && (info->iommu->flags & VTD_FLAG_SVM_CAPABLE) &&53815365 info->pasid_supported && info->pri_supported &&53825366 info->ats_supported;53835383- }5384536753855368 return false;53865369}···53915374 if (feat == IOMMU_DEV_FEAT_AUX)53925375 return intel_iommu_enable_auxd(dev);5393537653775377+ if (feat == IOMMU_DEV_FEAT_IOPF)53785378+ return intel_iommu_dev_has_feat(dev, feat) ? 0 : -ENODEV;53795379+53945380 if (feat == IOMMU_DEV_FEAT_SVA) {53955381 struct device_domain_info *info = get_domain_info(dev);5396538253975383 if (!info)53845384+ return -EINVAL;53855385+53865386+ if (!info->pasid_enabled || !info->pri_enabled || !info->ats_enabled)53985387 return -EINVAL;5399538854005389 if (info->iommu->flags & VTD_FLAG_SVM_CAPABLE)···54465423}5447542454485425static int54495449-intel_iommu_domain_set_attr(struct iommu_domain *domain,54505450- enum iommu_attr attr, void *data)54265426+intel_iommu_enable_nesting(struct iommu_domain *domain)54515427{54525428 struct dmar_domain *dmar_domain = to_dmar_domain(domain);54535429 unsigned long flags;54545454- int ret = 0;54305430+ int ret = -ENODEV;5455543154565456- if (domain->type != IOMMU_DOMAIN_UNMANAGED)54575457- return -EINVAL;54585458-54595459- switch (attr) {54605460- case DOMAIN_ATTR_NESTING:54615461- spin_lock_irqsave(&device_domain_lock, flags);54625462- if (nested_mode_support() &&54635463- list_empty(&dmar_domain->devices)) {54645464- dmar_domain->flags |= DOMAIN_FLAG_NESTING_MODE;54655465- dmar_domain->flags &= ~DOMAIN_FLAG_USE_FIRST_LEVEL;54665466- } else {54675467- ret = -ENODEV;54685468- }54695469- spin_unlock_irqrestore(&device_domain_lock, flags);54705470- break;54715471- default:54725472- ret = -EINVAL;54735473- break;54325432+ spin_lock_irqsave(&device_domain_lock, flags);54335433+ if (nested_mode_support() && list_empty(&dmar_domain->devices)) {54345434+ dmar_domain->flags |= DOMAIN_FLAG_NESTING_MODE;54355435+ dmar_domain->flags &= ~DOMAIN_FLAG_USE_FIRST_LEVEL;54365436+ ret = 0;54745437 }54385438+ spin_unlock_irqrestore(&device_domain_lock, flags);5475543954765440 return ret;54775477-}54785478-54795479-static bool domain_use_flush_queue(void)54805480-{54815481- struct dmar_drhd_unit *drhd;54825482- struct intel_iommu *iommu;54835483- bool r = true;54845484-54855485- if (intel_iommu_strict)54865486- return false;54875487-54885488- /*54895489- * The flush queue implementation does not perform page-selective54905490- * invalidations that are required for efficient TLB flushes in virtual54915491- * environments. The benefit of batching is likely to be much lower than54925492- * the overhead of synchronizing the virtual and physical IOMMU54935493- * page-tables.54945494- */54955495- rcu_read_lock();54965496- for_each_active_iommu(iommu, drhd) {54975497- if (!cap_caching_mode(iommu->cap))54985498- continue;54995499-55005500- pr_warn_once("IOMMU batching is disabled due to virtualization");55015501- r = false;55025502- break;55035503- }55045504- rcu_read_unlock();55055505-55065506- return r;55075507-}55085508-55095509-static int55105510-intel_iommu_domain_get_attr(struct iommu_domain *domain,55115511- enum iommu_attr attr, void *data)55125512-{55135513- switch (domain->type) {55145514- case IOMMU_DOMAIN_UNMANAGED:55155515- return -ENODEV;55165516- case IOMMU_DOMAIN_DMA:55175517- switch (attr) {55185518- case DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE:55195519- *(int *)data = domain_use_flush_queue();55205520- return 0;55215521- default:55225522- return -ENODEV;55235523- }55245524- break;55255525- default:55265526- return -EINVAL;55275527- }55285441}5529544255305443/*···55355576 .capable = intel_iommu_capable,55365577 .domain_alloc = intel_iommu_domain_alloc,55375578 .domain_free = intel_iommu_domain_free,55385538- .domain_get_attr = intel_iommu_domain_get_attr,55395539- .domain_set_attr = intel_iommu_domain_set_attr,55795579+ .enable_nesting = intel_iommu_enable_nesting,55405580 .attach_dev = intel_iommu_attach_device,55415581 .detach_dev = intel_iommu_detach_device,55425582 .aux_attach_dev = intel_iommu_aux_attach_device,
+1-1
drivers/iommu/intel/irq_remapping.c
···736736 return -ENODEV;737737738738 if (intel_cap_audit(CAP_AUDIT_STATIC_IRQR, NULL))739739- goto error;739739+ return -ENODEV;740740741741 if (!dmar_ir_support())742742 return -ENODEV;
+65-10
drivers/iommu/intel/pasid.c
···2424/*2525 * Intel IOMMU system wide PASID name space:2626 */2727-static DEFINE_SPINLOCK(pasid_lock);2827u32 intel_pasid_max_id = PASID_MAX;29283029int vcmd_alloc_pasid(struct intel_iommu *iommu, u32 *pasid)···230231 return info->pasid_table;231232}232233233233-int intel_pasid_get_dev_max_id(struct device *dev)234234+static int intel_pasid_get_dev_max_id(struct device *dev)234235{235236 struct device_domain_info *info;236237···241242 return info->pasid_table->max_pasid;242243}243244244244-struct pasid_entry *intel_pasid_get_entry(struct device *dev, u32 pasid)245245+static struct pasid_entry *intel_pasid_get_entry(struct device *dev, u32 pasid)245246{246247 struct device_domain_info *info;247248 struct pasid_table *pasid_table;···258259 dir_index = pasid >> PASID_PDE_SHIFT;259260 index = pasid & PASID_PTE_MASK;260261261261- spin_lock(&pasid_lock);262262+retry:262263 entries = get_pasid_table_from_pde(&dir[dir_index]);263264 if (!entries) {264265 entries = alloc_pgtable_page(info->iommu->node);265265- if (!entries) {266266- spin_unlock(&pasid_lock);266266+ if (!entries)267267 return NULL;268268- }269268270270- WRITE_ONCE(dir[dir_index].val,271271- (u64)virt_to_phys(entries) | PASID_PTE_PRESENT);269269+ /*270270+ * The pasid directory table entry won't be freed after271271+ * allocation. No worry about the race with free and272272+ * clear. However, this entry might be populated by others273273+ * while we are preparing it. Use theirs with a retry.274274+ */275275+ if (cmpxchg64(&dir[dir_index].val, 0ULL,276276+ (u64)virt_to_phys(entries) | PASID_PTE_PRESENT)) {277277+ free_pgtable_page(entries);278278+ goto retry;279279+ }272280 }273273- spin_unlock(&pasid_lock);274281275282 return &entries[index];276283}···399394}400395401396/*397397+ * Setup the WPE(Write Protect Enable) field (Bit 132) of a398398+ * scalable mode PASID entry.399399+ */400400+static inline void pasid_set_wpe(struct pasid_entry *pe)401401+{402402+ pasid_set_bits(&pe->val[2], 1 << 4, 1 << 4);403403+}404404+405405+/*402406 * Setup the P(Present) field (Bit 0) of a scalable mode PASID403407 * entry.404408 */···423409static inline void pasid_set_page_snoop(struct pasid_entry *pe, bool value)424410{425411 pasid_set_bits(&pe->val[1], 1 << 23, value << 23);412412+}413413+414414+/*415415+ * Setup the Page Snoop (PGSNP) field (Bit 88) of a scalable mode416416+ * PASID entry.417417+ */418418+static inline void419419+pasid_set_pgsnp(struct pasid_entry *pe)420420+{421421+ pasid_set_bits(&pe->val[1], 1ULL << 24, 1ULL << 24);426422}427423428424/*···517493 if (WARN_ON(!pte))518494 return;519495496496+ if (!(pte->val[0] & PASID_PTE_PRESENT))497497+ return;498498+520499 did = pasid_get_domain_id(pte);521500 intel_pasid_clear_entry(dev, pasid, fault_ignore);522501···548521 iommu_flush_write_buffer(iommu);549522 }550523}524524+525525+static inline int pasid_enable_wpe(struct pasid_entry *pte)526526+{527527+#ifdef CONFIG_X86528528+ unsigned long cr0 = read_cr0();529529+530530+ /* CR0.WP is normally set but just to be sure */531531+ if (unlikely(!(cr0 & X86_CR0_WP))) {532532+ pr_err_ratelimited("No CPU write protect!\n");533533+ return -EINVAL;534534+ }535535+#endif536536+ pasid_set_wpe(pte);537537+538538+ return 0;539539+};551540552541/*553542 * Set up the scalable mode pasid table entry for first only···596553 return -EINVAL;597554 }598555 pasid_set_sre(pte);556556+ if (pasid_enable_wpe(pte))557557+ return -EINVAL;558558+599559 }600560601561 if (flags & PASID_FLAG_FL5LP) {···610564 return -EINVAL;611565 }612566 }567567+568568+ if (flags & PASID_FLAG_PAGE_SNOOP)569569+ pasid_set_pgsnp(pte);613570614571 pasid_set_domain_id(pte, did);615572 pasid_set_address_width(pte, iommu->agaw);···692643 pasid_set_fault_enable(pte);693644 pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap));694645646646+ if (domain->domain.type == IOMMU_DOMAIN_UNMANAGED)647647+ pasid_set_pgsnp(pte);648648+695649 /*696650 * Since it is a second level only translation setup, we should697651 * set SRE bit as well (addresses are expected to be GPAs).···758706 return -EINVAL;759707 }760708 pasid_set_sre(pte);709709+ /* Enable write protect WP if guest requested */710710+ if (pasid_data->flags & IOMMU_SVA_VTD_GPASID_WPE)711711+ pasid_set_wpe(pte);761712 }762713763714 if (pasid_data->flags & IOMMU_SVA_VTD_GPASID_EAFE) {
+1-5
drivers/iommu/intel/pasid.h
···4848 */4949#define PASID_FLAG_SUPERVISOR_MODE BIT(0)5050#define PASID_FLAG_NESTED BIT(1)5151+#define PASID_FLAG_PAGE_SNOOP BIT(2)51525253/*5354 * The PASID_FLAG_FL5LP flag Indicates using 5-level paging for first-···10099}101100102101extern unsigned int intel_pasid_max_id;103103-int intel_pasid_alloc_id(void *ptr, int start, int end, gfp_t gfp);104104-void intel_pasid_free_id(u32 pasid);105105-void *intel_pasid_lookup_id(u32 pasid);106102int intel_pasid_alloc_table(struct device *dev);107103void intel_pasid_free_table(struct device *dev);108104struct pasid_table *intel_pasid_get_table(struct device *dev);109109-int intel_pasid_get_dev_max_id(struct device *dev);110110-struct pasid_entry *intel_pasid_get_entry(struct device *dev, u32 pasid);111105int intel_pasid_setup_first_level(struct intel_iommu *iommu,112106 struct device *dev, pgd_t *pgd,113107 u32 pasid, u16 did, int flags);
+40-44
drivers/iommu/intel/svm.c
···462462/* Caller must hold pasid_mutex, mm reference */463463static int464464intel_svm_bind_mm(struct device *dev, unsigned int flags,465465- struct svm_dev_ops *ops,466465 struct mm_struct *mm, struct intel_svm_dev **sd)467466{468467 struct intel_iommu *iommu = device_to_iommu(dev, NULL, NULL);468468+ struct intel_svm *svm = NULL, *t;469469 struct device_domain_info *info;470470 struct intel_svm_dev *sdev;471471- struct intel_svm *svm = NULL;472471 unsigned long iflags;473472 int pasid_max;474473 int ret;···493494 }494495 }495496496496- if (!(flags & SVM_FLAG_PRIVATE_PASID)) {497497- struct intel_svm *t;497497+ list_for_each_entry(t, &global_svm_list, list) {498498+ if (t->mm != mm)499499+ continue;498500499499- list_for_each_entry(t, &global_svm_list, list) {500500- if (t->mm != mm || (t->flags & SVM_FLAG_PRIVATE_PASID))501501- continue;502502-503503- svm = t;504504- if (svm->pasid >= pasid_max) {505505- dev_warn(dev,506506- "Limited PASID width. Cannot use existing PASID %d\n",507507- svm->pasid);508508- ret = -ENOSPC;509509- goto out;510510- }511511-512512- /* Find the matching device in svm list */513513- for_each_svm_dev(sdev, svm, dev) {514514- if (sdev->ops != ops) {515515- ret = -EBUSY;516516- goto out;517517- }518518- sdev->users++;519519- goto success;520520- }521521-522522- break;501501+ svm = t;502502+ if (svm->pasid >= pasid_max) {503503+ dev_warn(dev,504504+ "Limited PASID width. Cannot use existing PASID %d\n",505505+ svm->pasid);506506+ ret = -ENOSPC;507507+ goto out;523508 }509509+510510+ /* Find the matching device in svm list */511511+ for_each_svm_dev(sdev, svm, dev) {512512+ sdev->users++;513513+ goto success;514514+ }515515+516516+ break;524517 }525518526519 sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);···541550542551 /* Finish the setup now we know we're keeping it */543552 sdev->users = 1;544544- sdev->ops = ops;545553 init_rcu_head(&sdev->rcu);546554547555 if (!svm) {···852862 /* Fill in event data for device specific processing */853863 memset(&event, 0, sizeof(struct iommu_fault_event));854864 event.fault.type = IOMMU_FAULT_PAGE_REQ;855855- event.fault.prm.addr = desc->addr;865865+ event.fault.prm.addr = (u64)desc->addr << VTD_PAGE_SHIFT;856866 event.fault.prm.pasid = desc->pasid;857867 event.fault.prm.grpid = desc->prg_index;858868 event.fault.prm.perm = prq_to_iommu_prot(desc);···885895 struct intel_iommu *iommu = d;886896 struct intel_svm *svm = NULL;887897 int head, tail, handled = 0;898898+ unsigned int flags = 0;888899889900 /* Clear PPR bit before reading head/tail registers, to890901 * ensure that we get a new interrupt if needed. */···911920 ((unsigned long long *)req)[1]);912921 goto no_pasid;913922 }914914-923923+ /* We shall not receive page request for supervisor SVM */924924+ if (req->pm_req && (req->rd_req | req->wr_req)) {925925+ pr_err("Unexpected page request in Privilege Mode");926926+ /* No need to find the matching sdev as for bad_req */927927+ goto no_pasid;928928+ }929929+ /* DMA read with exec requeset is not supported. */930930+ if (req->exe_req && req->rd_req) {931931+ pr_err("Execution request not supported\n");932932+ goto no_pasid;933933+ }915934 if (!svm || svm->pasid != req->pasid) {916935 rcu_read_lock();917936 svm = ioasid_find(NULL, req->pasid, NULL);···983982 if (access_error(vma, req))984983 goto invalid;985984986986- ret = handle_mm_fault(vma, address,987987- req->wr_req ? FAULT_FLAG_WRITE : 0,988988- NULL);985985+ flags = FAULT_FLAG_USER | FAULT_FLAG_REMOTE;986986+ if (req->wr_req)987987+ flags |= FAULT_FLAG_WRITE;988988+989989+ ret = handle_mm_fault(vma, address, flags, NULL);989990 if (ret & VM_FAULT_ERROR)990991 goto invalid;991992···996993 mmap_read_unlock(svm->mm);997994 mmput(svm->mm);998995bad_req:999999- WARN_ON(!sdev);10001000- if (sdev && sdev->ops && sdev->ops->fault_cb) {10011001- int rwxp = (req->rd_req << 3) | (req->wr_req << 2) |10021002- (req->exe_req << 1) | (req->pm_req);10031003- sdev->ops->fault_cb(sdev->dev, req->pasid, req->addr,10041004- req->priv_data, rwxp, result);10051005- }1006996 /* We get here in the error case where the PASID lookup failed,1007997 and these can be NULL. Do not use them below this point! */1008998 sdev = NULL;···10171021 QI_PGRP_RESP_TYPE;10181022 resp.qw1 = QI_PGRP_IDX(req->prg_index) |10191023 QI_PGRP_LPIG(req->lpig);10241024+ resp.qw2 = 0;10251025+ resp.qw3 = 0;1020102610211027 if (req->priv_data_present)10221028 memcpy(&resp.qw2, req->priv_data,10231029 sizeof(req->priv_data));10241024- resp.qw2 = 0;10251025- resp.qw3 = 0;10261030 qi_submit_sync(iommu, &resp, 1, 0);10271031 }10281032prq_advance:···10701074 if (drvdata)10711075 flags = *(unsigned int *)drvdata;10721076 mutex_lock(&pasid_mutex);10731073- ret = intel_svm_bind_mm(dev, flags, NULL, mm, &sdev);10771077+ ret = intel_svm_bind_mm(dev, flags, mm, &sdev);10741078 if (ret)10751079 sva = ERR_PTR(ret);10761080 else if (sdev)
+461
drivers/iommu/io-pgfault.c
···11+// SPDX-License-Identifier: GPL-2.022+/*33+ * Handle device page faults44+ *55+ * Copyright (C) 2020 ARM Ltd.66+ */77+88+#include <linux/iommu.h>99+#include <linux/list.h>1010+#include <linux/sched/mm.h>1111+#include <linux/slab.h>1212+#include <linux/workqueue.h>1313+1414+#include "iommu-sva-lib.h"1515+1616+/**1717+ * struct iopf_queue - IO Page Fault queue1818+ * @wq: the fault workqueue1919+ * @devices: devices attached to this queue2020+ * @lock: protects the device list2121+ */2222+struct iopf_queue {2323+ struct workqueue_struct *wq;2424+ struct list_head devices;2525+ struct mutex lock;2626+};2727+2828+/**2929+ * struct iopf_device_param - IO Page Fault data attached to a device3030+ * @dev: the device that owns this param3131+ * @queue: IOPF queue3232+ * @queue_list: index into queue->devices3333+ * @partial: faults that are part of a Page Request Group for which the last3434+ * request hasn't been submitted yet.3535+ */3636+struct iopf_device_param {3737+ struct device *dev;3838+ struct iopf_queue *queue;3939+ struct list_head queue_list;4040+ struct list_head partial;4141+};4242+4343+struct iopf_fault {4444+ struct iommu_fault fault;4545+ struct list_head list;4646+};4747+4848+struct iopf_group {4949+ struct iopf_fault last_fault;5050+ struct list_head faults;5151+ struct work_struct work;5252+ struct device *dev;5353+};5454+5555+static int iopf_complete_group(struct device *dev, struct iopf_fault *iopf,5656+ enum iommu_page_response_code status)5757+{5858+ struct iommu_page_response resp = {5959+ .version = IOMMU_PAGE_RESP_VERSION_1,6060+ .pasid = iopf->fault.prm.pasid,6161+ .grpid = iopf->fault.prm.grpid,6262+ .code = status,6363+ };6464+6565+ if ((iopf->fault.prm.flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID) &&6666+ (iopf->fault.prm.flags & IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID))6767+ resp.flags = IOMMU_PAGE_RESP_PASID_VALID;6868+6969+ return iommu_page_response(dev, &resp);7070+}7171+7272+static enum iommu_page_response_code7373+iopf_handle_single(struct iopf_fault *iopf)7474+{7575+ vm_fault_t ret;7676+ struct mm_struct *mm;7777+ struct vm_area_struct *vma;7878+ unsigned int access_flags = 0;7979+ unsigned int fault_flags = FAULT_FLAG_REMOTE;8080+ struct iommu_fault_page_request *prm = &iopf->fault.prm;8181+ enum iommu_page_response_code status = IOMMU_PAGE_RESP_INVALID;8282+8383+ if (!(prm->flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID))8484+ return status;8585+8686+ mm = iommu_sva_find(prm->pasid);8787+ if (IS_ERR_OR_NULL(mm))8888+ return status;8989+9090+ mmap_read_lock(mm);9191+9292+ vma = find_extend_vma(mm, prm->addr);9393+ if (!vma)9494+ /* Unmapped area */9595+ goto out_put_mm;9696+9797+ if (prm->perm & IOMMU_FAULT_PERM_READ)9898+ access_flags |= VM_READ;9999+100100+ if (prm->perm & IOMMU_FAULT_PERM_WRITE) {101101+ access_flags |= VM_WRITE;102102+ fault_flags |= FAULT_FLAG_WRITE;103103+ }104104+105105+ if (prm->perm & IOMMU_FAULT_PERM_EXEC) {106106+ access_flags |= VM_EXEC;107107+ fault_flags |= FAULT_FLAG_INSTRUCTION;108108+ }109109+110110+ if (!(prm->perm & IOMMU_FAULT_PERM_PRIV))111111+ fault_flags |= FAULT_FLAG_USER;112112+113113+ if (access_flags & ~vma->vm_flags)114114+ /* Access fault */115115+ goto out_put_mm;116116+117117+ ret = handle_mm_fault(vma, prm->addr, fault_flags, NULL);118118+ status = ret & VM_FAULT_ERROR ? IOMMU_PAGE_RESP_INVALID :119119+ IOMMU_PAGE_RESP_SUCCESS;120120+121121+out_put_mm:122122+ mmap_read_unlock(mm);123123+ mmput(mm);124124+125125+ return status;126126+}127127+128128+static void iopf_handle_group(struct work_struct *work)129129+{130130+ struct iopf_group *group;131131+ struct iopf_fault *iopf, *next;132132+ enum iommu_page_response_code status = IOMMU_PAGE_RESP_SUCCESS;133133+134134+ group = container_of(work, struct iopf_group, work);135135+136136+ list_for_each_entry_safe(iopf, next, &group->faults, list) {137137+ /*138138+ * For the moment, errors are sticky: don't handle subsequent139139+ * faults in the group if there is an error.140140+ */141141+ if (status == IOMMU_PAGE_RESP_SUCCESS)142142+ status = iopf_handle_single(iopf);143143+144144+ if (!(iopf->fault.prm.flags &145145+ IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE))146146+ kfree(iopf);147147+ }148148+149149+ iopf_complete_group(group->dev, &group->last_fault, status);150150+ kfree(group);151151+}152152+153153+/**154154+ * iommu_queue_iopf - IO Page Fault handler155155+ * @fault: fault event156156+ * @cookie: struct device, passed to iommu_register_device_fault_handler.157157+ *158158+ * Add a fault to the device workqueue, to be handled by mm.159159+ *160160+ * This module doesn't handle PCI PASID Stop Marker; IOMMU drivers must discard161161+ * them before reporting faults. A PASID Stop Marker (LRW = 0b100) doesn't162162+ * expect a response. It may be generated when disabling a PASID (issuing a163163+ * PASID stop request) by some PCI devices.164164+ *165165+ * The PASID stop request is issued by the device driver before unbind(). Once166166+ * it completes, no page request is generated for this PASID anymore and167167+ * outstanding ones have been pushed to the IOMMU (as per PCIe 4.0r1.0 - 6.20.1168168+ * and 10.4.1.2 - Managing PASID TLP Prefix Usage). Some PCI devices will wait169169+ * for all outstanding page requests to come back with a response before170170+ * completing the PASID stop request. Others do not wait for page responses, and171171+ * instead issue this Stop Marker that tells us when the PASID can be172172+ * reallocated.173173+ *174174+ * It is safe to discard the Stop Marker because it is an optimization.175175+ * a. Page requests, which are posted requests, have been flushed to the IOMMU176176+ * when the stop request completes.177177+ * b. The IOMMU driver flushes all fault queues on unbind() before freeing the178178+ * PASID.179179+ *180180+ * So even though the Stop Marker might be issued by the device *after* the stop181181+ * request completes, outstanding faults will have been dealt with by the time182182+ * the PASID is freed.183183+ *184184+ * Return: 0 on success and <0 on error.185185+ */186186+int iommu_queue_iopf(struct iommu_fault *fault, void *cookie)187187+{188188+ int ret;189189+ struct iopf_group *group;190190+ struct iopf_fault *iopf, *next;191191+ struct iopf_device_param *iopf_param;192192+193193+ struct device *dev = cookie;194194+ struct dev_iommu *param = dev->iommu;195195+196196+ lockdep_assert_held(¶m->lock);197197+198198+ if (fault->type != IOMMU_FAULT_PAGE_REQ)199199+ /* Not a recoverable page fault */200200+ return -EOPNOTSUPP;201201+202202+ /*203203+ * As long as we're holding param->lock, the queue can't be unlinked204204+ * from the device and therefore cannot disappear.205205+ */206206+ iopf_param = param->iopf_param;207207+ if (!iopf_param)208208+ return -ENODEV;209209+210210+ if (!(fault->prm.flags & IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE)) {211211+ iopf = kzalloc(sizeof(*iopf), GFP_KERNEL);212212+ if (!iopf)213213+ return -ENOMEM;214214+215215+ iopf->fault = *fault;216216+217217+ /* Non-last request of a group. Postpone until the last one */218218+ list_add(&iopf->list, &iopf_param->partial);219219+220220+ return 0;221221+ }222222+223223+ group = kzalloc(sizeof(*group), GFP_KERNEL);224224+ if (!group) {225225+ /*226226+ * The caller will send a response to the hardware. But we do227227+ * need to clean up before leaving, otherwise partial faults228228+ * will be stuck.229229+ */230230+ ret = -ENOMEM;231231+ goto cleanup_partial;232232+ }233233+234234+ group->dev = dev;235235+ group->last_fault.fault = *fault;236236+ INIT_LIST_HEAD(&group->faults);237237+ list_add(&group->last_fault.list, &group->faults);238238+ INIT_WORK(&group->work, iopf_handle_group);239239+240240+ /* See if we have partial faults for this group */241241+ list_for_each_entry_safe(iopf, next, &iopf_param->partial, list) {242242+ if (iopf->fault.prm.grpid == fault->prm.grpid)243243+ /* Insert *before* the last fault */244244+ list_move(&iopf->list, &group->faults);245245+ }246246+247247+ queue_work(iopf_param->queue->wq, &group->work);248248+ return 0;249249+250250+cleanup_partial:251251+ list_for_each_entry_safe(iopf, next, &iopf_param->partial, list) {252252+ if (iopf->fault.prm.grpid == fault->prm.grpid) {253253+ list_del(&iopf->list);254254+ kfree(iopf);255255+ }256256+ }257257+ return ret;258258+}259259+EXPORT_SYMBOL_GPL(iommu_queue_iopf);260260+261261+/**262262+ * iopf_queue_flush_dev - Ensure that all queued faults have been processed263263+ * @dev: the endpoint whose faults need to be flushed.264264+ *265265+ * The IOMMU driver calls this before releasing a PASID, to ensure that all266266+ * pending faults for this PASID have been handled, and won't hit the address267267+ * space of the next process that uses this PASID. The driver must make sure268268+ * that no new fault is added to the queue. In particular it must flush its269269+ * low-level queue before calling this function.270270+ *271271+ * Return: 0 on success and <0 on error.272272+ */273273+int iopf_queue_flush_dev(struct device *dev)274274+{275275+ int ret = 0;276276+ struct iopf_device_param *iopf_param;277277+ struct dev_iommu *param = dev->iommu;278278+279279+ if (!param)280280+ return -ENODEV;281281+282282+ mutex_lock(¶m->lock);283283+ iopf_param = param->iopf_param;284284+ if (iopf_param)285285+ flush_workqueue(iopf_param->queue->wq);286286+ else287287+ ret = -ENODEV;288288+ mutex_unlock(¶m->lock);289289+290290+ return ret;291291+}292292+EXPORT_SYMBOL_GPL(iopf_queue_flush_dev);293293+294294+/**295295+ * iopf_queue_discard_partial - Remove all pending partial fault296296+ * @queue: the queue whose partial faults need to be discarded297297+ *298298+ * When the hardware queue overflows, last page faults in a group may have been299299+ * lost and the IOMMU driver calls this to discard all partial faults. The300300+ * driver shouldn't be adding new faults to this queue concurrently.301301+ *302302+ * Return: 0 on success and <0 on error.303303+ */304304+int iopf_queue_discard_partial(struct iopf_queue *queue)305305+{306306+ struct iopf_fault *iopf, *next;307307+ struct iopf_device_param *iopf_param;308308+309309+ if (!queue)310310+ return -EINVAL;311311+312312+ mutex_lock(&queue->lock);313313+ list_for_each_entry(iopf_param, &queue->devices, queue_list) {314314+ list_for_each_entry_safe(iopf, next, &iopf_param->partial,315315+ list) {316316+ list_del(&iopf->list);317317+ kfree(iopf);318318+ }319319+ }320320+ mutex_unlock(&queue->lock);321321+ return 0;322322+}323323+EXPORT_SYMBOL_GPL(iopf_queue_discard_partial);324324+325325+/**326326+ * iopf_queue_add_device - Add producer to the fault queue327327+ * @queue: IOPF queue328328+ * @dev: device to add329329+ *330330+ * Return: 0 on success and <0 on error.331331+ */332332+int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev)333333+{334334+ int ret = -EBUSY;335335+ struct iopf_device_param *iopf_param;336336+ struct dev_iommu *param = dev->iommu;337337+338338+ if (!param)339339+ return -ENODEV;340340+341341+ iopf_param = kzalloc(sizeof(*iopf_param), GFP_KERNEL);342342+ if (!iopf_param)343343+ return -ENOMEM;344344+345345+ INIT_LIST_HEAD(&iopf_param->partial);346346+ iopf_param->queue = queue;347347+ iopf_param->dev = dev;348348+349349+ mutex_lock(&queue->lock);350350+ mutex_lock(¶m->lock);351351+ if (!param->iopf_param) {352352+ list_add(&iopf_param->queue_list, &queue->devices);353353+ param->iopf_param = iopf_param;354354+ ret = 0;355355+ }356356+ mutex_unlock(¶m->lock);357357+ mutex_unlock(&queue->lock);358358+359359+ if (ret)360360+ kfree(iopf_param);361361+362362+ return ret;363363+}364364+EXPORT_SYMBOL_GPL(iopf_queue_add_device);365365+366366+/**367367+ * iopf_queue_remove_device - Remove producer from fault queue368368+ * @queue: IOPF queue369369+ * @dev: device to remove370370+ *371371+ * Caller makes sure that no more faults are reported for this device.372372+ *373373+ * Return: 0 on success and <0 on error.374374+ */375375+int iopf_queue_remove_device(struct iopf_queue *queue, struct device *dev)376376+{377377+ int ret = -EINVAL;378378+ struct iopf_fault *iopf, *next;379379+ struct iopf_device_param *iopf_param;380380+ struct dev_iommu *param = dev->iommu;381381+382382+ if (!param || !queue)383383+ return -EINVAL;384384+385385+ mutex_lock(&queue->lock);386386+ mutex_lock(¶m->lock);387387+ iopf_param = param->iopf_param;388388+ if (iopf_param && iopf_param->queue == queue) {389389+ list_del(&iopf_param->queue_list);390390+ param->iopf_param = NULL;391391+ ret = 0;392392+ }393393+ mutex_unlock(¶m->lock);394394+ mutex_unlock(&queue->lock);395395+ if (ret)396396+ return ret;397397+398398+ /* Just in case some faults are still stuck */399399+ list_for_each_entry_safe(iopf, next, &iopf_param->partial, list)400400+ kfree(iopf);401401+402402+ kfree(iopf_param);403403+404404+ return 0;405405+}406406+EXPORT_SYMBOL_GPL(iopf_queue_remove_device);407407+408408+/**409409+ * iopf_queue_alloc - Allocate and initialize a fault queue410410+ * @name: a unique string identifying the queue (for workqueue)411411+ *412412+ * Return: the queue on success and NULL on error.413413+ */414414+struct iopf_queue *iopf_queue_alloc(const char *name)415415+{416416+ struct iopf_queue *queue;417417+418418+ queue = kzalloc(sizeof(*queue), GFP_KERNEL);419419+ if (!queue)420420+ return NULL;421421+422422+ /*423423+ * The WQ is unordered because the low-level handler enqueues faults by424424+ * group. PRI requests within a group have to be ordered, but once425425+ * that's dealt with, the high-level function can handle groups out of426426+ * order.427427+ */428428+ queue->wq = alloc_workqueue("iopf_queue/%s", WQ_UNBOUND, 0, name);429429+ if (!queue->wq) {430430+ kfree(queue);431431+ return NULL;432432+ }433433+434434+ INIT_LIST_HEAD(&queue->devices);435435+ mutex_init(&queue->lock);436436+437437+ return queue;438438+}439439+EXPORT_SYMBOL_GPL(iopf_queue_alloc);440440+441441+/**442442+ * iopf_queue_free - Free IOPF queue443443+ * @queue: queue to free444444+ *445445+ * Counterpart to iopf_queue_alloc(). The driver must not be queuing faults or446446+ * adding/removing devices on this queue anymore.447447+ */448448+void iopf_queue_free(struct iopf_queue *queue)449449+{450450+ struct iopf_device_param *iopf_param, *next;451451+452452+ if (!queue)453453+ return;454454+455455+ list_for_each_entry_safe(iopf_param, next, &queue->devices, queue_list)456456+ iopf_queue_remove_device(queue, iopf_param->dev);457457+458458+ destroy_workqueue(queue->wq);459459+ kfree(queue);460460+}461461+EXPORT_SYMBOL_GPL(iopf_queue_free);
···10101111#include <linux/types.h>12121313+struct amd_iommu;1414+1315/*1416 * This is mainly used to communicate information back-and-forth1517 * between SVM and IOMMU for setting up and tearing down posted···33313432extern int amd_iommu_detect(void);3533extern int amd_iommu_init_hardware(void);3636-3737-/**3838- * amd_iommu_enable_device_erratum() - Enable erratum workaround for device3939- * in the IOMMUv2 driver4040- * @pdev: The PCI device the workaround is necessary for4141- * @erratum: The erratum workaround to enable4242- *4343- * The function needs to be called before amd_iommu_init_device().4444- * Possible values for the erratum number are for now:4545- * - AMD_PRI_DEV_ERRATUM_ENABLE_RESET - Reset PRI capability when PRI4646- * is enabled4747- * - AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE - Limit number of outstanding PRI4848- * requests to one4949- */5050-#define AMD_PRI_DEV_ERRATUM_ENABLE_RESET 05151-#define AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE 15252-5353-extern void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum);54345535/**5636 * amd_iommu_init_device() - Init device for use with IOMMUv2 driver···195211 return 0;196212}197213#endif /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */214214+215215+int amd_iommu_get_num_iommus(void);216216+bool amd_iommu_pc_supported(void);217217+u8 amd_iommu_pc_get_max_banks(unsigned int idx);218218+u8 amd_iommu_pc_get_max_counters(unsigned int idx);219219+int amd_iommu_pc_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, u8 fxn,220220+ u64 *value);221221+int amd_iommu_pc_get_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, u8 fxn,222222+ u64 *value);223223+struct amd_iommu *get_amd_iommu(unsigned int idx);198224199225#endif /* _ASM_X86_AMD_IOMMU_H */
···88#ifndef __INTEL_SVM_H__99#define __INTEL_SVM_H__10101111-struct device;1212-1313-struct svm_dev_ops {1414- void (*fault_cb)(struct device *dev, u32 pasid, u64 address,1515- void *private, int rwxp, int response);1616-};1717-1811/* Values for rxwp in fault_cb callback */1912#define SVM_REQ_READ (1<<3)2013#define SVM_REQ_WRITE (1<<2)2114#define SVM_REQ_EXEC (1<<1)2215#define SVM_REQ_PRIV (1<<0)2323-2424-/*2525- * The SVM_FLAG_PRIVATE_PASID flag requests a PASID which is *not* the "main"2626- * PASID for the current process. Even if a PASID already exists, a new one2727- * will be allocated. And the PASID allocated with SVM_FLAG_PRIVATE_PASID2828- * will not be given to subsequent callers. This facility allows a driver to2929- * disambiguate between multiple device contexts which access the same MM,3030- * if there is no other way to do so. It should be used sparingly, if at all.3131- */3232-#define SVM_FLAG_PRIVATE_PASID (1<<0)33163417/*3518 * The SVM_FLAG_SUPERVISOR_MODE flag requests a PASID which can be used only···2542 * It is unlikely that we will ever hook into flush_tlb_kernel_range() to2643 * do such IOTLB flushes automatically.2744 */2828-#define SVM_FLAG_SUPERVISOR_MODE (1<<1)4545+#define SVM_FLAG_SUPERVISOR_MODE BIT(0)2946/*3047 * The SVM_FLAG_GUEST_MODE flag is used when a PASID bind is for guest3148 * processes. Compared to the host bind, the primary differences are:3249 * 1. mm life cycle management3350 * 2. fault reporting3451 */3535-#define SVM_FLAG_GUEST_MODE (1<<2)5252+#define SVM_FLAG_GUEST_MODE BIT(1)3653/*3754 * The SVM_FLAG_GUEST_PASID flag is used when a guest has its own PASID space,3855 * which requires guest and host PASID translation at both directions.3956 */4040-#define SVM_FLAG_GUEST_PASID (1<<3)5757+#define SVM_FLAG_GUEST_PASID BIT(2)41584259#endif /* __INTEL_SVM_H__ */
-4
include/linux/io-pgtable.h
···204204205205#define io_pgtable_ops_to_pgtable(x) container_of((x), struct io_pgtable, ops)206206207207-struct io_pgtable_domain_attr {208208- unsigned long quirks;209209-};210210-211207static inline void io_pgtable_tlb_flush_all(struct io_pgtable *iop)212208{213209 if (iop->cfg.tlb && iop->cfg.tlb->tlb_flush_all)
+34-70
include/linux/iommu.h
···9696 IOMMU_CAP_NOEXEC, /* IOMMU_NOEXEC flag */9797};98989999-/*100100- * Following constraints are specifc to FSL_PAMUV1:101101- * -aperture must be power of 2, and naturally aligned102102- * -number of windows must be power of 2, and address space size103103- * of each window is determined by aperture size / # of windows104104- * -the actual size of the mapped region of a window must be power105105- * of 2 starting with 4KB and physical address must be naturally106106- * aligned.107107- * DOMAIN_ATTR_FSL_PAMUV1 corresponds to the above mentioned contraints.108108- * The caller can invoke iommu_domain_get_attr to check if the underlying109109- * iommu implementation supports these constraints.110110- */111111-112112-enum iommu_attr {113113- DOMAIN_ATTR_GEOMETRY,114114- DOMAIN_ATTR_PAGING,115115- DOMAIN_ATTR_WINDOWS,116116- DOMAIN_ATTR_FSL_PAMU_STASH,117117- DOMAIN_ATTR_FSL_PAMU_ENABLE,118118- DOMAIN_ATTR_FSL_PAMUV1,119119- DOMAIN_ATTR_NESTING, /* two stages of translation */120120- DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,121121- DOMAIN_ATTR_IO_PGTABLE_CFG,122122- DOMAIN_ATTR_MAX,123123-};124124-12599/* These are the possible reserved region types */126100enum iommu_resv_type {127101 /* Memory regions which must be mapped 1:1 at all times */···130156 enum iommu_resv_type type;131157};132158133133-/* Per device IOMMU features */159159+/**160160+ * enum iommu_dev_features - Per device IOMMU features161161+ * @IOMMU_DEV_FEAT_AUX: Auxiliary domain feature162162+ * @IOMMU_DEV_FEAT_SVA: Shared Virtual Addresses163163+ * @IOMMU_DEV_FEAT_IOPF: I/O Page Faults such as PRI or Stall. Generally164164+ * enabling %IOMMU_DEV_FEAT_SVA requires165165+ * %IOMMU_DEV_FEAT_IOPF, but some devices manage I/O Page166166+ * Faults themselves instead of relying on the IOMMU. When167167+ * supported, this feature must be enabled before and168168+ * disabled after %IOMMU_DEV_FEAT_SVA.169169+ *170170+ * Device drivers query whether a feature is supported using171171+ * iommu_dev_has_feature(), and enable it using iommu_dev_enable_feature().172172+ */134173enum iommu_dev_features {135135- IOMMU_DEV_FEAT_AUX, /* Aux-domain feature */136136- IOMMU_DEV_FEAT_SVA, /* Shared Virtual Addresses */174174+ IOMMU_DEV_FEAT_AUX,175175+ IOMMU_DEV_FEAT_SVA,176176+ IOMMU_DEV_FEAT_IOPF,137177};138178139179#define IOMMU_PASID_INVALID (-1U)···191203 * @probe_finalize: Do final setup work after the device is added to an IOMMU192204 * group and attached to the groups domain193205 * @device_group: find iommu group for a particular device194194- * @domain_get_attr: Query domain attributes195195- * @domain_set_attr: Change domain attributes206206+ * @enable_nesting: Enable nesting207207+ * @set_pgtable_quirks: Set io page table quirks (IO_PGTABLE_QUIRK_*)196208 * @get_resv_regions: Request list of reserved regions for a device197209 * @put_resv_regions: Free list of reserved regions for a device198210 * @apply_resv_region: Temporary helper call-back for iova reserved ranges199199- * @domain_window_enable: Configure and enable a particular window for a domain200200- * @domain_window_disable: Disable a particular window for a domain201211 * @of_xlate: add OF master IDs to iommu grouping202212 * @is_attach_deferred: Check if domain attach should be deferred from iommu203213 * driver init to device driver init (default no)···241255 void (*release_device)(struct device *dev);242256 void (*probe_finalize)(struct device *dev);243257 struct iommu_group *(*device_group)(struct device *dev);244244- int (*domain_get_attr)(struct iommu_domain *domain,245245- enum iommu_attr attr, void *data);246246- int (*domain_set_attr)(struct iommu_domain *domain,247247- enum iommu_attr attr, void *data);258258+ int (*enable_nesting)(struct iommu_domain *domain);259259+ int (*set_pgtable_quirks)(struct iommu_domain *domain,260260+ unsigned long quirks);248261249262 /* Request/Free a list of reserved regions for a device */250263 void (*get_resv_regions)(struct device *dev, struct list_head *list);···251266 void (*apply_resv_region)(struct device *dev,252267 struct iommu_domain *domain,253268 struct iommu_resv_region *region);254254-255255- /* Window handling functions */256256- int (*domain_window_enable)(struct iommu_domain *domain, u32 wnd_nr,257257- phys_addr_t paddr, u64 size, int prot);258258- void (*domain_window_disable)(struct iommu_domain *domain, u32 wnd_nr);259269260270 int (*of_xlate)(struct device *dev, struct of_phandle_args *args);261271 bool (*is_attach_deferred)(struct iommu_domain *domain, struct device *dev);···333353 * struct dev_iommu - Collection of per-device IOMMU data334354 *335355 * @fault_param: IOMMU detected device fault reporting data356356+ * @iopf_param: I/O Page Fault queue and data336357 * @fwspec: IOMMU fwspec data337358 * @iommu_dev: IOMMU device this device is linked to338359 * @priv: IOMMU Driver private data···344363struct dev_iommu {345364 struct mutex lock;346365 struct iommu_fault_param *fault_param;366366+ struct iopf_device_param *iopf_param;347367 struct iommu_fwspec *fwspec;348368 struct iommu_device *iommu_dev;349369 void *priv;···489507extern int iommu_group_id(struct iommu_group *group);490508extern struct iommu_domain *iommu_group_default_domain(struct iommu_group *);491509492492-extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr,493493- void *data);494494-extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr,495495- void *data);510510+int iommu_enable_nesting(struct iommu_domain *domain);511511+int iommu_set_pgtable_quirks(struct iommu_domain *domain,512512+ unsigned long quirks);496513497497-/* Window handling function prototypes */498498-extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,499499- phys_addr_t offset, u64 size,500500- int prot);514514+void iommu_set_dma_strict(bool val);515515+bool iommu_get_dma_strict(struct iommu_domain *domain);501516502517extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev,503518 unsigned long iova, int flags);···526547 * structure can be rewritten.527548 */528549 if (gather->pgsize != size ||529529- end < gather->start || start > gather->end) {550550+ end + 1 < gather->start || start > gather->end + 1) {530551 if (gather->pgsize)531552 iommu_iotlb_sync(domain, gather);532553 gather->pgsize = size;···550571 * struct iommu_fwspec - per-device IOMMU instance data551572 * @ops: ops for this device's IOMMU552573 * @iommu_fwnode: firmware handle for this device's IOMMU553553- * @iommu_priv: IOMMU driver private data for this device554554- * @num_pasid_bits: number of PASID bits supported by this device574574+ * @flags: IOMMU_FWSPEC_* flags555575 * @num_ids: number of associated device IDs556576 * @ids: IDs which this device may present to the IOMMU557577 */···558580 const struct iommu_ops *ops;559581 struct fwnode_handle *iommu_fwnode;560582 u32 flags;561561- u32 num_pasid_bits;562583 unsigned int num_ids;563584 u32 ids[];564585};···719742{720743}721744722722-static inline int iommu_domain_window_enable(struct iommu_domain *domain,723723- u32 wnd_nr, phys_addr_t paddr,724724- u64 size, int prot)725725-{726726- return -ENODEV;727727-}728728-729745static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)730746{731747 return 0;···859889 return -ENODEV;860890}861891862862-static inline int iommu_domain_get_attr(struct iommu_domain *domain,863863- enum iommu_attr attr, void *data)892892+static inline int iommu_set_pgtable_quirks(struct iommu_domain *domain,893893+ unsigned long quirks)864894{865865- return -EINVAL;866866-}867867-868868-static inline int iommu_domain_set_attr(struct iommu_domain *domain,869869- enum iommu_attr attr, void *data)870870-{871871- return -EINVAL;895895+ return 0;872896}873897874898static inline int iommu_device_register(struct iommu_device *iommu)
+1-5
include/linux/iova.h
···9595 flush-queues */9696 atomic_t fq_timer_on; /* 1 when timer is active, 09797 when not */9898+ struct hlist_node cpuhp_dead;9899};99100100101static inline unsigned long iova_size(struct iova *iova)···157156 iova_flush_cb flush_cb, iova_entry_dtor entry_dtor);158157struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);159158void put_iova_domain(struct iova_domain *iovad);160160-void free_cpu_cached_iovas(unsigned int cpu, struct iova_domain *iovad);161159#else162160static inline int iova_cache_get(void)163161{···233233{234234}235235236236-static inline void free_cpu_cached_iovas(unsigned int cpu,237237- struct iova_domain *iovad)238238-{239239-}240236#endif241237242238#endif