···586586 your BIOS for an option to enable it or if you have an IVRS ACPI587587 table.588588589589+config AMD_IOMMU_STATS590590+ bool "Export AMD IOMMU statistics to debugfs"591591+ depends on AMD_IOMMU592592+ select DEBUG_FS593593+ help594594+ This option enables code in the AMD IOMMU driver to collect various595595+ statistics about whats happening in the driver and exports that596596+ information to userspace via debugfs.597597+ If unsure, say N.598598+589599# need this always selected by IOMMU for the VIA workaround590600config SWIOTLB591601 def_bool y if X86_64
+42-19
arch/x86/include/asm/amd_iommu_types.h
···190190/* FIXME: move this macro to <linux/pci.h> */191191#define PCI_BUS(x) (((x) >> 8) & 0xff)192192193193+/* Protection domain flags */194194+#define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */195195+#define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops196196+ domain for an IOMMU */197197+193198/*194199 * This structure contains generic data for IOMMU protection domains195200 * independent of their use.196201 */197202struct protection_domain {198198- spinlock_t lock; /* mostly used to lock the page table*/199199- u16 id; /* the domain id written to the device table */200200- int mode; /* paging mode (0-6 levels) */201201- u64 *pt_root; /* page table root pointer */202202- void *priv; /* private data */203203+ spinlock_t lock; /* mostly used to lock the page table*/204204+ u16 id; /* the domain id written to the device table */205205+ int mode; /* paging mode (0-6 levels) */206206+ u64 *pt_root; /* page table root pointer */207207+ unsigned long flags; /* flags to find out type of domain */208208+ unsigned dev_cnt; /* devices assigned to this domain */209209+ void *priv; /* private data */203210};204211205212/*···302295 bool int_enabled;303296304297 /* if one, we need to send a completion wait command */305305- int need_sync;298298+ bool need_sync;306299307300 /* default dma_ops domain for that IOMMU */308301 struct dma_ops_domain *default_dom;···381374extern unsigned long *amd_iommu_pd_alloc_bitmap;382375383376/* will be 1 if device isolation is enabled */384384-extern int amd_iommu_isolate;377377+extern bool amd_iommu_isolate;385378386379/*387380 * If true, the addresses will be flushed on unmap time, not when···389382 */390383extern bool amd_iommu_unmap_flush;391384392392-/* takes a PCI device id and prints it out in a readable form */393393-static inline void print_devid(u16 devid, int nl)394394-{395395- int bus = devid >> 8;396396- int dev = devid >> 3 & 0x1f;397397- int fn = devid & 0x07;398398-399399- printk("%02x:%02x.%x", bus, dev, fn);400400- if (nl)401401- printk("\n");402402-}403403-404385/* takes bus and device/function and returns the device id405386 * FIXME: should that be in generic PCI code? */406387static inline u16 calc_devid(u8 bus, u8 devfn)407388{408389 return (((u16)bus) << 8) | devfn;409390}391391+392392+#ifdef CONFIG_AMD_IOMMU_STATS393393+394394+struct __iommu_counter {395395+ char *name;396396+ struct dentry *dent;397397+ u64 value;398398+};399399+400400+#define DECLARE_STATS_COUNTER(nm) \401401+ static struct __iommu_counter nm = { \402402+ .name = #nm, \403403+ }404404+405405+#define INC_STATS_COUNTER(name) name.value += 1406406+#define ADD_STATS_COUNTER(name, x) name.value += (x)407407+#define SUB_STATS_COUNTER(name, x) name.value -= (x)408408+409409+#else /* CONFIG_AMD_IOMMU_STATS */410410+411411+#define DECLARE_STATS_COUNTER(name)412412+#define INC_STATS_COUNTER(name)413413+#define ADD_STATS_COUNTER(name, x)414414+#define SUB_STATS_COUNTER(name, x)415415+416416+static inline void amd_iommu_stats_init(void) { }417417+418418+#endif /* CONFIG_AMD_IOMMU_STATS */410419411420#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
+619-60
arch/x86/kernel/amd_iommu.c
···2020#include <linux/pci.h>2121#include <linux/gfp.h>2222#include <linux/bitops.h>2323+#include <linux/debugfs.h>2324#include <linux/scatterlist.h>2425#include <linux/iommu-helper.h>2626+#ifdef CONFIG_IOMMU_API2727+#include <linux/iommu.h>2828+#endif2529#include <asm/proto.h>2630#include <asm/iommu.h>2731#include <asm/gart.h>···4238static LIST_HEAD(iommu_pd_list);4339static DEFINE_SPINLOCK(iommu_pd_list_lock);44404141+#ifdef CONFIG_IOMMU_API4242+static struct iommu_ops amd_iommu_ops;4343+#endif4444+4545/*4646 * general struct to manage commands send to an IOMMU4747 */···55475648static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,5749 struct unity_map_entry *e);5050+static struct dma_ops_domain *find_protection_domain(u16 devid);5151+5252+5353+#ifdef CONFIG_AMD_IOMMU_STATS5454+5555+/*5656+ * Initialization code for statistics collection5757+ */5858+5959+DECLARE_STATS_COUNTER(compl_wait);6060+DECLARE_STATS_COUNTER(cnt_map_single);6161+DECLARE_STATS_COUNTER(cnt_unmap_single);6262+DECLARE_STATS_COUNTER(cnt_map_sg);6363+DECLARE_STATS_COUNTER(cnt_unmap_sg);6464+DECLARE_STATS_COUNTER(cnt_alloc_coherent);6565+DECLARE_STATS_COUNTER(cnt_free_coherent);6666+DECLARE_STATS_COUNTER(cross_page);6767+DECLARE_STATS_COUNTER(domain_flush_single);6868+DECLARE_STATS_COUNTER(domain_flush_all);6969+DECLARE_STATS_COUNTER(alloced_io_mem);7070+DECLARE_STATS_COUNTER(total_map_requests);7171+7272+static struct dentry *stats_dir;7373+static struct dentry *de_isolate;7474+static struct dentry *de_fflush;7575+7676+static void amd_iommu_stats_add(struct __iommu_counter *cnt)7777+{7878+ if (stats_dir == NULL)7979+ return;8080+8181+ cnt->dent = debugfs_create_u64(cnt->name, 0444, stats_dir,8282+ &cnt->value);8383+}8484+8585+static void amd_iommu_stats_init(void)8686+{8787+ stats_dir = debugfs_create_dir("amd-iommu", NULL);8888+ if (stats_dir == NULL)8989+ return;9090+9191+ de_isolate = debugfs_create_bool("isolation", 0444, stats_dir,9292+ (u32 *)&amd_iommu_isolate);9393+9494+ de_fflush = debugfs_create_bool("fullflush", 0444, stats_dir,9595+ (u32 *)&amd_iommu_unmap_flush);9696+9797+ amd_iommu_stats_add(&compl_wait);9898+ amd_iommu_stats_add(&cnt_map_single);9999+ amd_iommu_stats_add(&cnt_unmap_single);100100+ amd_iommu_stats_add(&cnt_map_sg);101101+ amd_iommu_stats_add(&cnt_unmap_sg);102102+ amd_iommu_stats_add(&cnt_alloc_coherent);103103+ amd_iommu_stats_add(&cnt_free_coherent);104104+ amd_iommu_stats_add(&cross_page);105105+ amd_iommu_stats_add(&domain_flush_single);106106+ amd_iommu_stats_add(&domain_flush_all);107107+ amd_iommu_stats_add(&alloced_io_mem);108108+ amd_iommu_stats_add(&total_map_requests);109109+}110110+111111+#endif5811259113/* returns !0 if the IOMMU is caching non-present entries in its TLB */60114static int iommu_has_npcache(struct amd_iommu *iommu)···259189 spin_lock_irqsave(&iommu->lock, flags);260190 ret = __iommu_queue_command(iommu, cmd);261191 if (!ret)262262- iommu->need_sync = 1;192192+ iommu->need_sync = true;263193 spin_unlock_irqrestore(&iommu->lock, flags);264194265195 return ret;266196}267197268198/*269269- * This function is called whenever we need to ensure that the IOMMU has270270- * completed execution of all commands we sent. It sends a271271- * COMPLETION_WAIT command and waits for it to finish. The IOMMU informs272272- * us about that by writing a value to a physical address we pass with273273- * the command.199199+ * This function waits until an IOMMU has completed a completion200200+ * wait command274201 */275275-static int iommu_completion_wait(struct amd_iommu *iommu)202202+static void __iommu_wait_for_completion(struct amd_iommu *iommu)276203{277277- int ret = 0, ready = 0;204204+ int ready = 0;278205 unsigned status = 0;279279- struct iommu_cmd cmd;280280- unsigned long flags, i = 0;206206+ unsigned long i = 0;281207282282- memset(&cmd, 0, sizeof(cmd));283283- cmd.data[0] = CMD_COMPL_WAIT_INT_MASK;284284- CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT);285285-286286- spin_lock_irqsave(&iommu->lock, flags);287287-288288- if (!iommu->need_sync)289289- goto out;290290-291291- iommu->need_sync = 0;292292-293293- ret = __iommu_queue_command(iommu, &cmd);294294-295295- if (ret)296296- goto out;208208+ INC_STATS_COUNTER(compl_wait);297209298210 while (!ready && (i < EXIT_LOOP_COUNT)) {299211 ++i;···290238291239 if (unlikely(i == EXIT_LOOP_COUNT))292240 panic("AMD IOMMU: Completion wait loop failed\n");241241+}242242+243243+/*244244+ * This function queues a completion wait command into the command245245+ * buffer of an IOMMU246246+ */247247+static int __iommu_completion_wait(struct amd_iommu *iommu)248248+{249249+ struct iommu_cmd cmd;250250+251251+ memset(&cmd, 0, sizeof(cmd));252252+ cmd.data[0] = CMD_COMPL_WAIT_INT_MASK;253253+ CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT);254254+255255+ return __iommu_queue_command(iommu, &cmd);256256+}257257+258258+/*259259+ * This function is called whenever we need to ensure that the IOMMU has260260+ * completed execution of all commands we sent. It sends a261261+ * COMPLETION_WAIT command and waits for it to finish. The IOMMU informs262262+ * us about that by writing a value to a physical address we pass with263263+ * the command.264264+ */265265+static int iommu_completion_wait(struct amd_iommu *iommu)266266+{267267+ int ret = 0;268268+ unsigned long flags;269269+270270+ spin_lock_irqsave(&iommu->lock, flags);271271+272272+ if (!iommu->need_sync)273273+ goto out;274274+275275+ ret = __iommu_completion_wait(iommu);276276+277277+ iommu->need_sync = false;278278+279279+ if (ret)280280+ goto out;281281+282282+ __iommu_wait_for_completion(iommu);293283294284out:295285 spin_unlock_irqrestore(&iommu->lock, flags);···358264 return ret;359265}360266267267+static void __iommu_build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address,268268+ u16 domid, int pde, int s)269269+{270270+ memset(cmd, 0, sizeof(*cmd));271271+ address &= PAGE_MASK;272272+ CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);273273+ cmd->data[1] |= domid;274274+ cmd->data[2] = lower_32_bits(address);275275+ cmd->data[3] = upper_32_bits(address);276276+ if (s) /* size bit - we flush more than one 4kb page */277277+ cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;278278+ if (pde) /* PDE bit - we wan't flush everything not only the PTEs */279279+ cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;280280+}281281+361282/*362283 * Generic command send function for invalidaing TLB entries363284 */···382273 struct iommu_cmd cmd;383274 int ret;384275385385- memset(&cmd, 0, sizeof(cmd));386386- address &= PAGE_MASK;387387- CMD_SET_TYPE(&cmd, CMD_INV_IOMMU_PAGES);388388- cmd.data[1] |= domid;389389- cmd.data[2] = lower_32_bits(address);390390- cmd.data[3] = upper_32_bits(address);391391- if (s) /* size bit - we flush more than one 4kb page */392392- cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;393393- if (pde) /* PDE bit - we wan't flush everything not only the PTEs */394394- cmd.data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;276276+ __iommu_build_inv_iommu_pages(&cmd, address, domid, pde, s);395277396278 ret = iommu_queue_command(iommu, &cmd);397279···421321{422322 u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;423323324324+ INC_STATS_COUNTER(domain_flush_single);325325+424326 iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1);425327}328328+329329+#ifdef CONFIG_IOMMU_API330330+/*331331+ * This function is used to flush the IO/TLB for a given protection domain332332+ * on every IOMMU in the system333333+ */334334+static void iommu_flush_domain(u16 domid)335335+{336336+ unsigned long flags;337337+ struct amd_iommu *iommu;338338+ struct iommu_cmd cmd;339339+340340+ INC_STATS_COUNTER(domain_flush_all);341341+342342+ __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,343343+ domid, 1, 1);344344+345345+ list_for_each_entry(iommu, &amd_iommu_list, list) {346346+ spin_lock_irqsave(&iommu->lock, flags);347347+ __iommu_queue_command(iommu, &cmd);348348+ __iommu_completion_wait(iommu);349349+ __iommu_wait_for_completion(iommu);350350+ spin_unlock_irqrestore(&iommu->lock, flags);351351+ }352352+}353353+#endif426354427355/****************************************************************************428356 *···466338 * supporting all features of AMD IOMMU page tables like level skipping467339 * and full 64 bit address spaces.468340 */469469-static int iommu_map(struct protection_domain *dom,470470- unsigned long bus_addr,471471- unsigned long phys_addr,472472- int prot)341341+static int iommu_map_page(struct protection_domain *dom,342342+ unsigned long bus_addr,343343+ unsigned long phys_addr,344344+ int prot)473345{474346 u64 __pte, *pte, *page;475347···515387516388 return 0;517389}390390+391391+#ifdef CONFIG_IOMMU_API392392+static void iommu_unmap_page(struct protection_domain *dom,393393+ unsigned long bus_addr)394394+{395395+ u64 *pte;396396+397397+ pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(bus_addr)];398398+399399+ if (!IOMMU_PTE_PRESENT(*pte))400400+ return;401401+402402+ pte = IOMMU_PTE_PAGE(*pte);403403+ pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)];404404+405405+ if (!IOMMU_PTE_PRESENT(*pte))406406+ return;407407+408408+ pte = IOMMU_PTE_PAGE(*pte);409409+ pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)];410410+411411+ *pte = 0;412412+}413413+#endif518414519415/*520416 * This function checks if a specific unity mapping entry is needed for···592440593441 for (addr = e->address_start; addr < e->address_end;594442 addr += PAGE_SIZE) {595595- ret = iommu_map(&dma_dom->domain, addr, addr, e->prot);443443+ ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot);596444 if (ret)597445 return ret;598446 /*···723571 return id;724572}725573574574+#ifdef CONFIG_IOMMU_API575575+static void domain_id_free(int id)576576+{577577+ unsigned long flags;578578+579579+ write_lock_irqsave(&amd_iommu_devtable_lock, flags);580580+ if (id > 0 && id < MAX_DOMAIN_ID)581581+ __clear_bit(id, amd_iommu_pd_alloc_bitmap);582582+ write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);583583+}584584+#endif585585+726586/*727587 * Used to reserve address ranges in the aperture (e.g. for exclusion728588 * ranges.···751587 iommu_area_reserve(dom->bitmap, start_page, pages);752588}753589754754-static void dma_ops_free_pagetable(struct dma_ops_domain *dma_dom)590590+static void free_pagetable(struct protection_domain *domain)755591{756592 int i, j;757593 u64 *p1, *p2, *p3;758594759759- p1 = dma_dom->domain.pt_root;595595+ p1 = domain->pt_root;760596761597 if (!p1)762598 return;···777613 }778614779615 free_page((unsigned long)p1);616616+617617+ domain->pt_root = NULL;780618}781619782620/*···790624 if (!dom)791625 return;792626793793- dma_ops_free_pagetable(dom);627627+ free_pagetable(&dom->domain);794628795629 kfree(dom->pte_pages);796630···829663 goto free_dma_dom;830664 dma_dom->domain.mode = PAGE_MODE_3_LEVEL;831665 dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL);666666+ dma_dom->domain.flags = PD_DMA_OPS_MASK;832667 dma_dom->domain.priv = dma_dom;833668 if (!dma_dom->domain.pt_root)834669 goto free_dma_dom;···892725}893726894727/*728728+ * little helper function to check whether a given protection domain is a729729+ * dma_ops domain730730+ */731731+static bool dma_ops_domain(struct protection_domain *domain)732732+{733733+ return domain->flags & PD_DMA_OPS_MASK;734734+}735735+736736+/*895737 * Find out the protection domain structure for a given PCI device. This896738 * will give us the pointer to the page table root for example.897739 */···920744 * If a device is not yet associated with a domain, this function does921745 * assigns it visible for the hardware922746 */923923-static void set_device_domain(struct amd_iommu *iommu,924924- struct protection_domain *domain,925925- u16 devid)747747+static void attach_device(struct amd_iommu *iommu,748748+ struct protection_domain *domain,749749+ u16 devid)926750{927751 unsigned long flags;928928-929752 u64 pte_root = virt_to_phys(domain->pt_root);753753+754754+ domain->dev_cnt += 1;930755931756 pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK)932757 << DEV_ENTRY_MODE_SHIFT;···943766944767 iommu_queue_inv_dev_entry(iommu, devid);945768}769769+770770+/*771771+ * Removes a device from a protection domain (unlocked)772772+ */773773+static void __detach_device(struct protection_domain *domain, u16 devid)774774+{775775+776776+ /* lock domain */777777+ spin_lock(&domain->lock);778778+779779+ /* remove domain from the lookup table */780780+ amd_iommu_pd_table[devid] = NULL;781781+782782+ /* remove entry from the device table seen by the hardware */783783+ amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;784784+ amd_iommu_dev_table[devid].data[1] = 0;785785+ amd_iommu_dev_table[devid].data[2] = 0;786786+787787+ /* decrease reference counter */788788+ domain->dev_cnt -= 1;789789+790790+ /* ready */791791+ spin_unlock(&domain->lock);792792+}793793+794794+/*795795+ * Removes a device from a protection domain (with devtable_lock held)796796+ */797797+static void detach_device(struct protection_domain *domain, u16 devid)798798+{799799+ unsigned long flags;800800+801801+ /* lock device table */802802+ write_lock_irqsave(&amd_iommu_devtable_lock, flags);803803+ __detach_device(domain, devid);804804+ write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);805805+}806806+807807+static int device_change_notifier(struct notifier_block *nb,808808+ unsigned long action, void *data)809809+{810810+ struct device *dev = data;811811+ struct pci_dev *pdev = to_pci_dev(dev);812812+ u16 devid = calc_devid(pdev->bus->number, pdev->devfn);813813+ struct protection_domain *domain;814814+ struct dma_ops_domain *dma_domain;815815+ struct amd_iommu *iommu;816816+ int order = amd_iommu_aperture_order;817817+ unsigned long flags;818818+819819+ if (devid > amd_iommu_last_bdf)820820+ goto out;821821+822822+ devid = amd_iommu_alias_table[devid];823823+824824+ iommu = amd_iommu_rlookup_table[devid];825825+ if (iommu == NULL)826826+ goto out;827827+828828+ domain = domain_for_device(devid);829829+830830+ if (domain && !dma_ops_domain(domain))831831+ WARN_ONCE(1, "AMD IOMMU WARNING: device %s already bound "832832+ "to a non-dma-ops domain\n", dev_name(dev));833833+834834+ switch (action) {835835+ case BUS_NOTIFY_BOUND_DRIVER:836836+ if (domain)837837+ goto out;838838+ dma_domain = find_protection_domain(devid);839839+ if (!dma_domain)840840+ dma_domain = iommu->default_dom;841841+ attach_device(iommu, &dma_domain->domain, devid);842842+ printk(KERN_INFO "AMD IOMMU: Using protection domain %d for "843843+ "device %s\n", dma_domain->domain.id, dev_name(dev));844844+ break;845845+ case BUS_NOTIFY_UNBIND_DRIVER:846846+ if (!domain)847847+ goto out;848848+ detach_device(domain, devid);849849+ break;850850+ case BUS_NOTIFY_ADD_DEVICE:851851+ /* allocate a protection domain if a device is added */852852+ dma_domain = find_protection_domain(devid);853853+ if (dma_domain)854854+ goto out;855855+ dma_domain = dma_ops_domain_alloc(iommu, order);856856+ if (!dma_domain)857857+ goto out;858858+ dma_domain->target_dev = devid;859859+860860+ spin_lock_irqsave(&iommu_pd_list_lock, flags);861861+ list_add_tail(&dma_domain->list, &iommu_pd_list);862862+ spin_unlock_irqrestore(&iommu_pd_list_lock, flags);863863+864864+ break;865865+ default:866866+ goto out;867867+ }868868+869869+ iommu_queue_inv_dev_entry(iommu, devid);870870+ iommu_completion_wait(iommu);871871+872872+out:873873+ return 0;874874+}875875+876876+struct notifier_block device_nb = {877877+ .notifier_call = device_change_notifier,878878+};946879947880/*****************************************************************************948881 *···1089802 list_for_each_entry(entry, &iommu_pd_list, list) {1090803 if (entry->target_dev == devid) {1091804 ret = entry;10921092- list_del(&ret->list);1093805 break;1094806 }1095807 }···1139853 if (!dma_dom)1140854 dma_dom = (*iommu)->default_dom;1141855 *domain = &dma_dom->domain;11421142- set_device_domain(*iommu, *domain, *bdf);856856+ attach_device(*iommu, *domain, *bdf);1143857 printk(KERN_INFO "AMD IOMMU: Using protection domain %d for "11441144- "device ", (*domain)->id);11451145- print_devid(_bdf, 1);858858+ "device %s\n", (*domain)->id, dev_name(dev));1146859 }11478601148861 if (domain_for_device(_bdf) == NULL)11491149- set_device_domain(*iommu, *domain, _bdf);862862+ attach_device(*iommu, *domain, _bdf);11508631151864 return 1;1152865}···1231946 pages = iommu_num_pages(paddr, size, PAGE_SIZE);1232947 paddr &= PAGE_MASK;1233948949949+ INC_STATS_COUNTER(total_map_requests);950950+951951+ if (pages > 1)952952+ INC_STATS_COUNTER(cross_page);953953+1234954 if (align)1235955 align_mask = (1UL << get_order(size)) - 1;1236956···1251961 start += PAGE_SIZE;1252962 }1253963 address += offset;964964+965965+ ADD_STATS_COUNTER(alloced_io_mem, size);12549661255967 if (unlikely(dma_dom->need_flush && !amd_iommu_unmap_flush)) {1256968 iommu_flush_tlb(iommu, dma_dom->domain.id);···1290998 start += PAGE_SIZE;1291999 }1292100010011001+ SUB_STATS_COUNTER(alloced_io_mem, size);10021002+12931003 dma_ops_free_addresses(dma_dom, dma_addr, pages);1294100412951005 if (amd_iommu_unmap_flush || dma_dom->need_flush) {···13131019 dma_addr_t addr;13141020 u64 dma_mask;1315102110221022+ INC_STATS_COUNTER(cnt_map_single);10231023+13161024 if (!check_device(dev))13171025 return bad_dma_address;13181026···13251029 if (iommu == NULL || domain == NULL)13261030 /* device not handled by any AMD IOMMU */13271031 return (dma_addr_t)paddr;10321032+10331033+ if (!dma_ops_domain(domain))10341034+ return bad_dma_address;1328103513291036 spin_lock_irqsave(&domain->lock, flags);13301037 addr = __map_single(dev, iommu, domain->priv, paddr, size, dir, false,···13541055 struct protection_domain *domain;13551056 u16 devid;1356105710581058+ INC_STATS_COUNTER(cnt_unmap_single);10591059+13571060 if (!check_device(dev) ||13581061 !get_device_resources(dev, &iommu, &domain, &devid))13591062 /* device not handled by any AMD IOMMU */10631063+ return;10641064+10651065+ if (!dma_ops_domain(domain))13601066 return;1361106713621068 spin_lock_irqsave(&domain->lock, flags);···14081104 int mapped_elems = 0;14091105 u64 dma_mask;1410110611071107+ INC_STATS_COUNTER(cnt_map_sg);11081108+14111109 if (!check_device(dev))14121110 return 0;14131111···1419111314201114 if (!iommu || !domain)14211115 return map_sg_no_iommu(dev, sglist, nelems, dir);11161116+11171117+ if (!dma_ops_domain(domain))11181118+ return 0;1422111914231120 spin_lock_irqsave(&domain->lock, flags);14241121···14721163 u16 devid;14731164 int i;1474116511661166+ INC_STATS_COUNTER(cnt_unmap_sg);11671167+14751168 if (!check_device(dev) ||14761169 !get_device_resources(dev, &iommu, &domain, &devid))11701170+ return;11711171+11721172+ if (!dma_ops_domain(domain))14771173 return;1478117414791175 spin_lock_irqsave(&domain->lock, flags);···15081194 phys_addr_t paddr;15091195 u64 dma_mask = dev->coherent_dma_mask;1510119611971197+ INC_STATS_COUNTER(cnt_alloc_coherent);11981198+15111199 if (!check_device(dev))15121200 return NULL;15131201···15281212 return virt_addr;15291213 }1530121412151215+ if (!dma_ops_domain(domain))12161216+ goto out_free;12171217+15311218 if (!dma_mask)15321219 dma_mask = *dev->dma_mask;15331220···15391220 *dma_addr = __map_single(dev, iommu, domain->priv, paddr,15401221 size, DMA_BIDIRECTIONAL, true, dma_mask);1541122215421542- if (*dma_addr == bad_dma_address) {15431543- free_pages((unsigned long)virt_addr, get_order(size));15441544- virt_addr = NULL;15451545- goto out;15461546- }12231223+ if (*dma_addr == bad_dma_address)12241224+ goto out_free;1547122515481226 iommu_completion_wait(iommu);1549122715501550-out:15511228 spin_unlock_irqrestore(&domain->lock, flags);1552122915531230 return virt_addr;12311231+12321232+out_free:12331233+12341234+ free_pages((unsigned long)virt_addr, get_order(size));12351235+12361236+ return NULL;15541237}1555123815561239/*···15661245 struct protection_domain *domain;15671246 u16 devid;1568124712481248+ INC_STATS_COUNTER(cnt_free_coherent);12491249+15691250 if (!check_device(dev))15701251 return;1571125215721253 get_device_resources(dev, &iommu, &domain, &devid);1573125415741255 if (!iommu || !domain)12561256+ goto free_mem;12571257+12581258+ if (!dma_ops_domain(domain))15751259 goto free_mem;1576126015771261 spin_lock_irqsave(&domain->lock, flags);···16221296 * we don't need to preallocate the protection domains anymore.16231297 * For now we have to.16241298 */16251625-void prealloc_protection_domains(void)12991299+static void prealloc_protection_domains(void)16261300{16271301 struct pci_dev *dev = NULL;16281302 struct dma_ops_domain *dma_dom;···16311305 u16 devid;1632130616331307 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {16341634- devid = (dev->bus->number << 8) | dev->devfn;13081308+ devid = calc_devid(dev->bus->number, dev->devfn);16351309 if (devid > amd_iommu_last_bdf)16361310 continue;16371311 devid = amd_iommu_alias_table[devid];···16781352 iommu->default_dom = dma_ops_domain_alloc(iommu, order);16791353 if (iommu->default_dom == NULL)16801354 return -ENOMEM;13551355+ iommu->default_dom->domain.flags |= PD_DEFAULT_MASK;16811356 ret = iommu_init_unity_mappings(iommu);16821357 if (ret)16831358 goto free_domains;···17021375 /* Make the driver finally visible to the drivers */17031376 dma_ops = &amd_iommu_dma_ops;1704137713781378+#ifdef CONFIG_IOMMU_API13791379+ register_iommu(&amd_iommu_ops);13801380+#endif13811381+13821382+ bus_register_notifier(&pci_bus_type, &device_nb);13831383+13841384+ amd_iommu_stats_init();13851385+17051386 return 0;1706138717071388free_domains:···1721138617221387 return ret;17231388}13891389+13901390+/*****************************************************************************13911391+ *13921392+ * The following functions belong to the exported interface of AMD IOMMU13931393+ *13941394+ * This interface allows access to lower level functions of the IOMMU13951395+ * like protection domain handling and assignement of devices to domains13961396+ * which is not possible with the dma_ops interface.13971397+ *13981398+ *****************************************************************************/13991399+14001400+#ifdef CONFIG_IOMMU_API14011401+14021402+static void cleanup_domain(struct protection_domain *domain)14031403+{14041404+ unsigned long flags;14051405+ u16 devid;14061406+14071407+ write_lock_irqsave(&amd_iommu_devtable_lock, flags);14081408+14091409+ for (devid = 0; devid <= amd_iommu_last_bdf; ++devid)14101410+ if (amd_iommu_pd_table[devid] == domain)14111411+ __detach_device(domain, devid);14121412+14131413+ write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);14141414+}14151415+14161416+static int amd_iommu_domain_init(struct iommu_domain *dom)14171417+{14181418+ struct protection_domain *domain;14191419+14201420+ domain = kzalloc(sizeof(*domain), GFP_KERNEL);14211421+ if (!domain)14221422+ return -ENOMEM;14231423+14241424+ spin_lock_init(&domain->lock);14251425+ domain->mode = PAGE_MODE_3_LEVEL;14261426+ domain->id = domain_id_alloc();14271427+ if (!domain->id)14281428+ goto out_free;14291429+ domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL);14301430+ if (!domain->pt_root)14311431+ goto out_free;14321432+14331433+ dom->priv = domain;14341434+14351435+ return 0;14361436+14371437+out_free:14381438+ kfree(domain);14391439+14401440+ return -ENOMEM;14411441+}14421442+14431443+static void amd_iommu_domain_destroy(struct iommu_domain *dom)14441444+{14451445+ struct protection_domain *domain = dom->priv;14461446+14471447+ if (!domain)14481448+ return;14491449+14501450+ if (domain->dev_cnt > 0)14511451+ cleanup_domain(domain);14521452+14531453+ BUG_ON(domain->dev_cnt != 0);14541454+14551455+ free_pagetable(domain);14561456+14571457+ domain_id_free(domain->id);14581458+14591459+ kfree(domain);14601460+14611461+ dom->priv = NULL;14621462+}14631463+14641464+static void amd_iommu_detach_device(struct iommu_domain *dom,14651465+ struct device *dev)14661466+{14671467+ struct protection_domain *domain = dom->priv;14681468+ struct amd_iommu *iommu;14691469+ struct pci_dev *pdev;14701470+ u16 devid;14711471+14721472+ if (dev->bus != &pci_bus_type)14731473+ return;14741474+14751475+ pdev = to_pci_dev(dev);14761476+14771477+ devid = calc_devid(pdev->bus->number, pdev->devfn);14781478+14791479+ if (devid > 0)14801480+ detach_device(domain, devid);14811481+14821482+ iommu = amd_iommu_rlookup_table[devid];14831483+ if (!iommu)14841484+ return;14851485+14861486+ iommu_queue_inv_dev_entry(iommu, devid);14871487+ iommu_completion_wait(iommu);14881488+}14891489+14901490+static int amd_iommu_attach_device(struct iommu_domain *dom,14911491+ struct device *dev)14921492+{14931493+ struct protection_domain *domain = dom->priv;14941494+ struct protection_domain *old_domain;14951495+ struct amd_iommu *iommu;14961496+ struct pci_dev *pdev;14971497+ u16 devid;14981498+14991499+ if (dev->bus != &pci_bus_type)15001500+ return -EINVAL;15011501+15021502+ pdev = to_pci_dev(dev);15031503+15041504+ devid = calc_devid(pdev->bus->number, pdev->devfn);15051505+15061506+ if (devid >= amd_iommu_last_bdf ||15071507+ devid != amd_iommu_alias_table[devid])15081508+ return -EINVAL;15091509+15101510+ iommu = amd_iommu_rlookup_table[devid];15111511+ if (!iommu)15121512+ return -EINVAL;15131513+15141514+ old_domain = domain_for_device(devid);15151515+ if (old_domain)15161516+ return -EBUSY;15171517+15181518+ attach_device(iommu, domain, devid);15191519+15201520+ iommu_completion_wait(iommu);15211521+15221522+ return 0;15231523+}15241524+15251525+static int amd_iommu_map_range(struct iommu_domain *dom,15261526+ unsigned long iova, phys_addr_t paddr,15271527+ size_t size, int iommu_prot)15281528+{15291529+ struct protection_domain *domain = dom->priv;15301530+ unsigned long i, npages = iommu_num_pages(paddr, size, PAGE_SIZE);15311531+ int prot = 0;15321532+ int ret;15331533+15341534+ if (iommu_prot & IOMMU_READ)15351535+ prot |= IOMMU_PROT_IR;15361536+ if (iommu_prot & IOMMU_WRITE)15371537+ prot |= IOMMU_PROT_IW;15381538+15391539+ iova &= PAGE_MASK;15401540+ paddr &= PAGE_MASK;15411541+15421542+ for (i = 0; i < npages; ++i) {15431543+ ret = iommu_map_page(domain, iova, paddr, prot);15441544+ if (ret)15451545+ return ret;15461546+15471547+ iova += PAGE_SIZE;15481548+ paddr += PAGE_SIZE;15491549+ }15501550+15511551+ return 0;15521552+}15531553+15541554+static void amd_iommu_unmap_range(struct iommu_domain *dom,15551555+ unsigned long iova, size_t size)15561556+{15571557+15581558+ struct protection_domain *domain = dom->priv;15591559+ unsigned long i, npages = iommu_num_pages(iova, size, PAGE_SIZE);15601560+15611561+ iova &= PAGE_MASK;15621562+15631563+ for (i = 0; i < npages; ++i) {15641564+ iommu_unmap_page(domain, iova);15651565+ iova += PAGE_SIZE;15661566+ }15671567+15681568+ iommu_flush_domain(domain->id);15691569+}15701570+15711571+static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,15721572+ unsigned long iova)15731573+{15741574+ struct protection_domain *domain = dom->priv;15751575+ unsigned long offset = iova & ~PAGE_MASK;15761576+ phys_addr_t paddr;15771577+ u64 *pte;15781578+15791579+ pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(iova)];15801580+15811581+ if (!IOMMU_PTE_PRESENT(*pte))15821582+ return 0;15831583+15841584+ pte = IOMMU_PTE_PAGE(*pte);15851585+ pte = &pte[IOMMU_PTE_L1_INDEX(iova)];15861586+15871587+ if (!IOMMU_PTE_PRESENT(*pte))15881588+ return 0;15891589+15901590+ pte = IOMMU_PTE_PAGE(*pte);15911591+ pte = &pte[IOMMU_PTE_L0_INDEX(iova)];15921592+15931593+ if (!IOMMU_PTE_PRESENT(*pte))15941594+ return 0;15951595+15961596+ paddr = *pte & IOMMU_PAGE_MASK;15971597+ paddr |= offset;15981598+15991599+ return paddr;16001600+}16011601+16021602+static struct iommu_ops amd_iommu_ops = {16031603+ .domain_init = amd_iommu_domain_init,16041604+ .domain_destroy = amd_iommu_domain_destroy,16051605+ .attach_dev = amd_iommu_attach_device,16061606+ .detach_dev = amd_iommu_detach_device,16071607+ .map = amd_iommu_map_range,16081608+ .unmap = amd_iommu_unmap_range,16091609+ .iova_to_phys = amd_iommu_iova_to_phys,16101610+};16111611+16121612+#endif
+6-9
arch/x86/kernel/amd_iommu_init.c
···122122LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings123123 we find in ACPI */124124unsigned amd_iommu_aperture_order = 26; /* size of aperture in power of 2 */125125-int amd_iommu_isolate = 1; /* if 1, device isolation is enabled */125125+bool amd_iommu_isolate = true; /* if true, device isolation is126126+ enabled */126127bool amd_iommu_unmap_flush; /* if true, flush on every unmap */127128128129LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the···246245/* Function to enable the hardware */247246void __init iommu_enable(struct amd_iommu *iommu)248247{249249- printk(KERN_INFO "AMD IOMMU: Enabling IOMMU "250250- "at %02x:%02x.%x cap 0x%hx\n",251251- iommu->dev->bus->number,252252- PCI_SLOT(iommu->dev->devfn),253253- PCI_FUNC(iommu->dev->devfn),254254- iommu->cap_ptr);248248+ printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at %s cap 0x%hx\n",249249+ dev_name(&iommu->dev->dev), iommu->cap_ptr);255250256251 iommu_feature_enable(iommu, CONTROL_IOMMU_EN);257252}···12151218{12161219 for (; *str; ++str) {12171220 if (strncmp(str, "isolate", 7) == 0)12181218- amd_iommu_isolate = 1;12211221+ amd_iommu_isolate = true;12191222 if (strncmp(str, "share", 5) == 0)12201220- amd_iommu_isolate = 0;12231223+ amd_iommu_isolate = false;12211224 if (strncmp(str, "fullflush", 9) == 0)12221225 amd_iommu_unmap_flush = true;12231226 }