···6666 re-discover previously removed devices.6767 Depends on CONFIG_HOTPLUG.68686969+What: /sys/bus/pci/devices/.../msi_irqs/7070+Date: September, 20117171+Contact: Neil Horman <nhorman@tuxdriver.com>7272+Description:7373+ The /sys/devices/.../msi_irqs directory contains a variable set7474+ of sub-directories, with each sub-directory being named after a7575+ corresponding msi irq vector allocated to that device. Each7676+ numbered sub-directory N contains attributes of that irq.7777+ Note that this directory is not created for device drivers which7878+ do not support msi irqs7979+8080+What: /sys/bus/pci/devices/.../msi_irqs/<N>/mode8181+Date: September 20118282+Contact: Neil Horman <nhorman@tuxdriver.com>8383+Description:8484+ This attribute indicates the mode that the irq vector named by8585+ the parent directory is in (msi vs. msix)8686+6987What: /sys/bus/pci/devices/.../remove7088Date: January 20097189Contact: Linux PCI developers <linux-pci@vger.kernel.org>
+5
Documentation/kernel-parameters.txt
···329329 is a lot of faster330330 off - do not initialize any AMD IOMMU found in331331 the system332332+ force_isolation - Force device isolation for all333333+ devices. The IOMMU driver is not334334+ allowed anymore to lift isolation335335+ requirements as needed. This option336336+ does not override iommu=pt332337333338 amijoy.map= [HW,JOY] Amiga joystick support334339 Map of devices attached to JOY0DAT and JOY1DAT
···596596 if (ACPI_SUCCESS(status)) {597597 dev_info(root->bus->bridge,598598 "ACPI _OSC control (0x%02x) granted\n", flags);599599+ if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {600600+ /*601601+ * We have ASPM control, but the FADT indicates602602+ * that it's unsupported. Clear it.603603+ */604604+ pcie_clear_aspm(root->bus);605605+ }599606 } else {600607 dev_info(root->bus->bridge,601608 "ACPI _OSC request failed (%s), "
+12-1
drivers/iommu/Kconfig
···3434 bool "AMD IOMMU support"3535 select SWIOTLB3636 select PCI_MSI3737- select PCI_IOV3737+ select PCI_ATS3838+ select PCI_PRI3939+ select PCI_PASID3840 select IOMMU_API3941 depends on X86_64 && PCI && ACPI4042 ---help---···5957 statistics about whats happening in the driver and exports that6058 information to userspace via debugfs.6159 If unsure, say N.6060+6161+config AMD_IOMMU_V26262+ tristate "AMD IOMMU Version 2 driver (EXPERIMENTAL)"6363+ depends on AMD_IOMMU && PROFILING && EXPERIMENTAL6464+ select MMU_NOTIFIER6565+ ---help---6666+ This option enables support for the AMD IOMMUv2 features of the IOMMU6767+ hardware. Select this option if you want to use devices that support6868+ the the PCI PRI and PASID interface.62696370# Intel IOMMU support6471config DMAR_TABLE
···1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA1818 */19192020+#include <linux/ratelimit.h>2021#include <linux/pci.h>2122#include <linux/pci-ats.h>2223#include <linux/bitmap.h>···2928#include <linux/iommu.h>3029#include <linux/delay.h>3130#include <linux/amd-iommu.h>3131+#include <linux/notifier.h>3232+#include <linux/export.h>3233#include <asm/msidef.h>3334#include <asm/proto.h>3435#include <asm/iommu.h>···4340#define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))44414542#define LOOP_TIMEOUT 1000004343+4444+/*4545+ * This bitmap is used to advertise the page sizes our hardware support4646+ * to the IOMMU core, which will then use this information to split4747+ * physically contiguous memory regions it is mapping into page sizes4848+ * that we support.4949+ *5050+ * Traditionally the IOMMU core just handed us the mappings directly,5151+ * after making sure the size is an order of a 4KiB page and that the5252+ * mapping has natural alignment.5353+ *5454+ * To retain this behavior, we currently advertise that we support5555+ * all page sizes that are an order of 4KiB.5656+ *5757+ * If at some point we'd like to utilize the IOMMU core's new behavior,5858+ * we could change this to advertise the real page sizes we support.5959+ */6060+#define AMD_IOMMU_PGSIZES (~0xFFFUL)46614762static DEFINE_RWLOCK(amd_iommu_devtable_lock);4863···80598160static struct iommu_ops amd_iommu_ops;82616262+static ATOMIC_NOTIFIER_HEAD(ppr_notifier);6363+int amd_iommu_max_glx_val = -1;6464+8365/*8466 * general struct to manage commands send to an IOMMU8567 */···9167};92689369static void update_domain(struct protection_domain *domain);7070+static int __init alloc_passthrough_domain(void);94719572/****************************************************************************9673 *···172147 return dev->archdata.iommu;173148}174149150150+static bool pci_iommuv2_capable(struct pci_dev *pdev)151151+{152152+ static const int caps[] = {153153+ PCI_EXT_CAP_ID_ATS,154154+ PCI_EXT_CAP_ID_PRI,155155+ PCI_EXT_CAP_ID_PASID,156156+ };157157+ int i, pos;158158+159159+ for (i = 0; i < 3; ++i) {160160+ pos = pci_find_ext_capability(pdev, caps[i]);161161+ if (pos == 0)162162+ return false;163163+ }164164+165165+ return true;166166+}167167+168168+static bool pdev_pri_erratum(struct pci_dev *pdev, u32 erratum)169169+{170170+ struct iommu_dev_data *dev_data;171171+172172+ dev_data = get_dev_data(&pdev->dev);173173+174174+ return dev_data->errata & (1 << erratum) ? true : false;175175+}176176+175177/*176178 * In this function the list of preallocated protection domains is traversed to177179 * find the domain for a specific device···256204257205static int iommu_init_device(struct device *dev)258206{207207+ struct pci_dev *pdev = to_pci_dev(dev);259208 struct iommu_dev_data *dev_data;260209 u16 alias;261210···279226 return -ENOTSUPP;280227 }281228 dev_data->alias_data = alias_data;229229+ }230230+231231+ if (pci_iommuv2_capable(pdev)) {232232+ struct amd_iommu *iommu;233233+234234+ iommu = amd_iommu_rlookup_table[dev_data->devid];235235+ dev_data->iommu_v2 = iommu->is_iommu_v2;282236 }283237284238 dev->archdata.iommu = dev_data;···377317DECLARE_STATS_COUNTER(domain_flush_all);378318DECLARE_STATS_COUNTER(alloced_io_mem);379319DECLARE_STATS_COUNTER(total_map_requests);320320+DECLARE_STATS_COUNTER(complete_ppr);321321+DECLARE_STATS_COUNTER(invalidate_iotlb);322322+DECLARE_STATS_COUNTER(invalidate_iotlb_all);323323+DECLARE_STATS_COUNTER(pri_requests);324324+380325381326static struct dentry *stats_dir;382327static struct dentry *de_fflush;···416351 amd_iommu_stats_add(&domain_flush_all);417352 amd_iommu_stats_add(&alloced_io_mem);418353 amd_iommu_stats_add(&total_map_requests);354354+ amd_iommu_stats_add(&complete_ppr);355355+ amd_iommu_stats_add(&invalidate_iotlb);356356+ amd_iommu_stats_add(&invalidate_iotlb_all);357357+ amd_iommu_stats_add(&pri_requests);419358}420359421360#endif···434365{435366 int i;436367437437- for (i = 0; i < 8; ++i)438438- pr_err("AMD-Vi: DTE[%d]: %08x\n", i,368368+ for (i = 0; i < 4; ++i)369369+ pr_err("AMD-Vi: DTE[%d]: %016llx\n", i,439370 amd_iommu_dev_table[devid].data[i]);440371}441372···530461 spin_unlock_irqrestore(&iommu->lock, flags);531462}532463464464+static void iommu_handle_ppr_entry(struct amd_iommu *iommu, u32 head)465465+{466466+ struct amd_iommu_fault fault;467467+ volatile u64 *raw;468468+ int i;469469+470470+ INC_STATS_COUNTER(pri_requests);471471+472472+ raw = (u64 *)(iommu->ppr_log + head);473473+474474+ /*475475+ * Hardware bug: Interrupt may arrive before the entry is written to476476+ * memory. If this happens we need to wait for the entry to arrive.477477+ */478478+ for (i = 0; i < LOOP_TIMEOUT; ++i) {479479+ if (PPR_REQ_TYPE(raw[0]) != 0)480480+ break;481481+ udelay(1);482482+ }483483+484484+ if (PPR_REQ_TYPE(raw[0]) != PPR_REQ_FAULT) {485485+ pr_err_ratelimited("AMD-Vi: Unknown PPR request received\n");486486+ return;487487+ }488488+489489+ fault.address = raw[1];490490+ fault.pasid = PPR_PASID(raw[0]);491491+ fault.device_id = PPR_DEVID(raw[0]);492492+ fault.tag = PPR_TAG(raw[0]);493493+ fault.flags = PPR_FLAGS(raw[0]);494494+495495+ /*496496+ * To detect the hardware bug we need to clear the entry497497+ * to back to zero.498498+ */499499+ raw[0] = raw[1] = 0;500500+501501+ atomic_notifier_call_chain(&ppr_notifier, 0, &fault);502502+}503503+504504+static void iommu_poll_ppr_log(struct amd_iommu *iommu)505505+{506506+ unsigned long flags;507507+ u32 head, tail;508508+509509+ if (iommu->ppr_log == NULL)510510+ return;511511+512512+ spin_lock_irqsave(&iommu->lock, flags);513513+514514+ head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);515515+ tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);516516+517517+ while (head != tail) {518518+519519+ /* Handle PPR entry */520520+ iommu_handle_ppr_entry(iommu, head);521521+522522+ /* Update and refresh ring-buffer state*/523523+ head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE;524524+ writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);525525+ tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);526526+ }527527+528528+ /* enable ppr interrupts again */529529+ writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET);530530+531531+ spin_unlock_irqrestore(&iommu->lock, flags);532532+}533533+533534irqreturn_t amd_iommu_int_thread(int irq, void *data)534535{535536 struct amd_iommu *iommu;536537537537- for_each_iommu(iommu)538538+ for_each_iommu(iommu) {538539 iommu_poll_events(iommu);540540+ iommu_poll_ppr_log(iommu);541541+ }539542540543 return IRQ_HANDLED;541544}···734593 CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES);735594 if (s)736595 cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;596596+}597597+598598+static void build_inv_iommu_pasid(struct iommu_cmd *cmd, u16 domid, int pasid,599599+ u64 address, bool size)600600+{601601+ memset(cmd, 0, sizeof(*cmd));602602+603603+ address &= ~(0xfffULL);604604+605605+ cmd->data[0] = pasid & PASID_MASK;606606+ cmd->data[1] = domid;607607+ cmd->data[2] = lower_32_bits(address);608608+ cmd->data[3] = upper_32_bits(address);609609+ cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;610610+ cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK;611611+ if (size)612612+ cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;613613+ CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);614614+}615615+616616+static void build_inv_iotlb_pasid(struct iommu_cmd *cmd, u16 devid, int pasid,617617+ int qdep, u64 address, bool size)618618+{619619+ memset(cmd, 0, sizeof(*cmd));620620+621621+ address &= ~(0xfffULL);622622+623623+ cmd->data[0] = devid;624624+ cmd->data[0] |= (pasid & 0xff) << 16;625625+ cmd->data[0] |= (qdep & 0xff) << 24;626626+ cmd->data[1] = devid;627627+ cmd->data[1] |= ((pasid >> 8) & 0xfff) << 16;628628+ cmd->data[2] = lower_32_bits(address);629629+ cmd->data[2] |= CMD_INV_IOMMU_PAGES_GN_MASK;630630+ cmd->data[3] = upper_32_bits(address);631631+ if (size)632632+ cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;633633+ CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES);634634+}635635+636636+static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid,637637+ int status, int tag, bool gn)638638+{639639+ memset(cmd, 0, sizeof(*cmd));640640+641641+ cmd->data[0] = devid;642642+ if (gn) {643643+ cmd->data[1] = pasid & PASID_MASK;644644+ cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK;645645+ }646646+ cmd->data[3] = tag & 0x1ff;647647+ cmd->data[3] |= (status & PPR_STATUS_MASK) << PPR_STATUS_SHIFT;648648+649649+ CMD_SET_TYPE(cmd, CMD_COMPLETE_PPR);737650}738651739652static void build_inv_all(struct iommu_cmd *cmd)···16911496 domain->pt_root = NULL;16921497}1693149814991499+static void free_gcr3_tbl_level1(u64 *tbl)15001500+{15011501+ u64 *ptr;15021502+ int i;15031503+15041504+ for (i = 0; i < 512; ++i) {15051505+ if (!(tbl[i] & GCR3_VALID))15061506+ continue;15071507+15081508+ ptr = __va(tbl[i] & PAGE_MASK);15091509+15101510+ free_page((unsigned long)ptr);15111511+ }15121512+}15131513+15141514+static void free_gcr3_tbl_level2(u64 *tbl)15151515+{15161516+ u64 *ptr;15171517+ int i;15181518+15191519+ for (i = 0; i < 512; ++i) {15201520+ if (!(tbl[i] & GCR3_VALID))15211521+ continue;15221522+15231523+ ptr = __va(tbl[i] & PAGE_MASK);15241524+15251525+ free_gcr3_tbl_level1(ptr);15261526+ }15271527+}15281528+15291529+static void free_gcr3_table(struct protection_domain *domain)15301530+{15311531+ if (domain->glx == 2)15321532+ free_gcr3_tbl_level2(domain->gcr3_tbl);15331533+ else if (domain->glx == 1)15341534+ free_gcr3_tbl_level1(domain->gcr3_tbl);15351535+ else if (domain->glx != 0)15361536+ BUG();15371537+15381538+ free_page((unsigned long)domain->gcr3_tbl);15391539+}15401540+16941541/*16951542 * Free a domain, only used if something went wrong in the16961543 * allocation path and we need to free an already allocated page table···1819158218201583static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)18211584{18221822- u64 pte_root = virt_to_phys(domain->pt_root);18231823- u32 flags = 0;15851585+ u64 pte_root = 0;15861586+ u64 flags = 0;15871587+15881588+ if (domain->mode != PAGE_MODE_NONE)15891589+ pte_root = virt_to_phys(domain->pt_root);1824159018251591 pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK)18261592 << DEV_ENTRY_MODE_SHIFT;18271593 pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV;1828159415951595+ flags = amd_iommu_dev_table[devid].data[1];15961596+18291597 if (ats)18301598 flags |= DTE_FLAG_IOTLB;1831159918321832- amd_iommu_dev_table[devid].data[3] |= flags;18331833- amd_iommu_dev_table[devid].data[2] = domain->id;18341834- amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root);18351835- amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root);16001600+ if (domain->flags & PD_IOMMUV2_MASK) {16011601+ u64 gcr3 = __pa(domain->gcr3_tbl);16021602+ u64 glx = domain->glx;16031603+ u64 tmp;16041604+16051605+ pte_root |= DTE_FLAG_GV;16061606+ pte_root |= (glx & DTE_GLX_MASK) << DTE_GLX_SHIFT;16071607+16081608+ /* First mask out possible old values for GCR3 table */16091609+ tmp = DTE_GCR3_VAL_B(~0ULL) << DTE_GCR3_SHIFT_B;16101610+ flags &= ~tmp;16111611+16121612+ tmp = DTE_GCR3_VAL_C(~0ULL) << DTE_GCR3_SHIFT_C;16131613+ flags &= ~tmp;16141614+16151615+ /* Encode GCR3 table into DTE */16161616+ tmp = DTE_GCR3_VAL_A(gcr3) << DTE_GCR3_SHIFT_A;16171617+ pte_root |= tmp;16181618+16191619+ tmp = DTE_GCR3_VAL_B(gcr3) << DTE_GCR3_SHIFT_B;16201620+ flags |= tmp;16211621+16221622+ tmp = DTE_GCR3_VAL_C(gcr3) << DTE_GCR3_SHIFT_C;16231623+ flags |= tmp;16241624+ }16251625+16261626+ flags &= ~(0xffffUL);16271627+ flags |= domain->id;16281628+16291629+ amd_iommu_dev_table[devid].data[1] = flags;16301630+ amd_iommu_dev_table[devid].data[0] = pte_root;18361631}1837163218381633static void clear_dte_entry(u16 devid)···18721603 /* remove entry from the device table seen by the hardware */18731604 amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;18741605 amd_iommu_dev_table[devid].data[1] = 0;18751875- amd_iommu_dev_table[devid].data[2] = 0;1876160618771607 amd_iommu_apply_erratum_63(devid);18781608}···19641696 return ret;19651697}1966169816991699+17001700+static void pdev_iommuv2_disable(struct pci_dev *pdev)17011701+{17021702+ pci_disable_ats(pdev);17031703+ pci_disable_pri(pdev);17041704+ pci_disable_pasid(pdev);17051705+}17061706+17071707+/* FIXME: Change generic reset-function to do the same */17081708+static int pri_reset_while_enabled(struct pci_dev *pdev)17091709+{17101710+ u16 control;17111711+ int pos;17121712+17131713+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);17141714+ if (!pos)17151715+ return -EINVAL;17161716+17171717+ pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);17181718+ control |= PCI_PRI_CTRL_RESET;17191719+ pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);17201720+17211721+ return 0;17221722+}17231723+17241724+static int pdev_iommuv2_enable(struct pci_dev *pdev)17251725+{17261726+ bool reset_enable;17271727+ int reqs, ret;17281728+17291729+ /* FIXME: Hardcode number of outstanding requests for now */17301730+ reqs = 32;17311731+ if (pdev_pri_erratum(pdev, AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE))17321732+ reqs = 1;17331733+ reset_enable = pdev_pri_erratum(pdev, AMD_PRI_DEV_ERRATUM_ENABLE_RESET);17341734+17351735+ /* Only allow access to user-accessible pages */17361736+ ret = pci_enable_pasid(pdev, 0);17371737+ if (ret)17381738+ goto out_err;17391739+17401740+ /* First reset the PRI state of the device */17411741+ ret = pci_reset_pri(pdev);17421742+ if (ret)17431743+ goto out_err;17441744+17451745+ /* Enable PRI */17461746+ ret = pci_enable_pri(pdev, reqs);17471747+ if (ret)17481748+ goto out_err;17491749+17501750+ if (reset_enable) {17511751+ ret = pri_reset_while_enabled(pdev);17521752+ if (ret)17531753+ goto out_err;17541754+ }17551755+17561756+ ret = pci_enable_ats(pdev, PAGE_SHIFT);17571757+ if (ret)17581758+ goto out_err;17591759+17601760+ return 0;17611761+17621762+out_err:17631763+ pci_disable_pri(pdev);17641764+ pci_disable_pasid(pdev);17651765+17661766+ return ret;17671767+}17681768+17691769+/* FIXME: Move this to PCI code */17701770+#define PCI_PRI_TLP_OFF (1 << 2)17711771+17721772+bool pci_pri_tlp_required(struct pci_dev *pdev)17731773+{17741774+ u16 control;17751775+ int pos;17761776+17771777+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);17781778+ if (!pos)17791779+ return false;17801780+17811781+ pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);17821782+17831783+ return (control & PCI_PRI_TLP_OFF) ? true : false;17841784+}17851785+19671786/*19681787 * If a device is not yet associated with a domain, this function does19691788 * assigns it visible for the hardware···2065171020661711 dev_data = get_dev_data(dev);2067171220682068- if (amd_iommu_iotlb_sup && pci_enable_ats(pdev, PAGE_SHIFT) == 0) {17131713+ if (domain->flags & PD_IOMMUV2_MASK) {17141714+ if (!dev_data->iommu_v2 || !dev_data->passthrough)17151715+ return -EINVAL;17161716+17171717+ if (pdev_iommuv2_enable(pdev) != 0)17181718+ return -EINVAL;17191719+17201720+ dev_data->ats.enabled = true;17211721+ dev_data->ats.qdep = pci_ats_queue_depth(pdev);17221722+ dev_data->pri_tlp = pci_pri_tlp_required(pdev);17231723+ } else if (amd_iommu_iotlb_sup &&17241724+ pci_enable_ats(pdev, PAGE_SHIFT) == 0) {20691725 dev_data->ats.enabled = true;20701726 dev_data->ats.qdep = pci_ats_queue_depth(pdev);20711727 }···21261760 * passthrough domain if it is detached from any other domain.21271761 * Make sure we can deassign from the pt_domain itself.21281762 */21292129- if (iommu_pass_through &&17631763+ if (dev_data->passthrough &&21301764 (dev_data->domain == NULL && domain != pt_domain))21311765 __attach_device(dev_data, pt_domain);21321766}···21361770 */21371771static void detach_device(struct device *dev)21381772{17731773+ struct protection_domain *domain;21391774 struct iommu_dev_data *dev_data;21401775 unsigned long flags;2141177621421777 dev_data = get_dev_data(dev);17781778+ domain = dev_data->domain;2143177921441780 /* lock device table */21451781 write_lock_irqsave(&amd_iommu_devtable_lock, flags);21461782 __detach_device(dev_data);21471783 write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);2148178421492149- if (dev_data->ats.enabled) {17851785+ if (domain->flags & PD_IOMMUV2_MASK)17861786+ pdev_iommuv2_disable(to_pci_dev(dev));17871787+ else if (dev_data->ats.enabled)21501788 pci_disable_ats(to_pci_dev(dev));21512151- dev_data->ats.enabled = false;21522152- }17891789+17901790+ dev_data->ats.enabled = false;21531791}2154179221551793/*···21881818static int device_change_notifier(struct notifier_block *nb,21891819 unsigned long action, void *data)21901820{21912191- struct device *dev = data;21922192- u16 devid;21932193- struct protection_domain *domain;21941821 struct dma_ops_domain *dma_domain;18221822+ struct protection_domain *domain;18231823+ struct iommu_dev_data *dev_data;18241824+ struct device *dev = data;21951825 struct amd_iommu *iommu;21961826 unsigned long flags;18271827+ u16 devid;2197182821981829 if (!check_device(dev))21991830 return 0;2200183122012201- devid = get_device_id(dev);22022202- iommu = amd_iommu_rlookup_table[devid];18321832+ devid = get_device_id(dev);18331833+ iommu = amd_iommu_rlookup_table[devid];18341834+ dev_data = get_dev_data(dev);2203183522041836 switch (action) {22051837 case BUS_NOTIFY_UNBOUND_DRIVER:···2210183822111839 if (!domain)22121840 goto out;22132213- if (iommu_pass_through)18411841+ if (dev_data->passthrough)22141842 break;22151843 detach_device(dev);22161844 break;···28062434 */28072435static void prealloc_protection_domains(void)28082436{28092809- struct pci_dev *dev = NULL;24372437+ struct iommu_dev_data *dev_data;28102438 struct dma_ops_domain *dma_dom;24392439+ struct pci_dev *dev = NULL;28112440 u16 devid;2812244128132442 for_each_pci_dev(dev) {···28162443 /* Do we handle this device? */28172444 if (!check_device(&dev->dev))28182445 continue;24462446+24472447+ dev_data = get_dev_data(&dev->dev);24482448+ if (!amd_iommu_force_isolation && dev_data->iommu_v2) {24492449+ /* Make sure passthrough domain is allocated */24502450+ alloc_passthrough_domain();24512451+ dev_data->passthrough = true;24522452+ attach_device(&dev->dev, pt_domain);24532453+ pr_info("AMD-Vi: Using passthough domain for device %s\n",24542454+ dev_name(&dev->dev));24552455+ }2819245628202457 /* Is there already any domain for it? */28212458 if (domain_for_device(&dev->dev))···2857247428582475static unsigned device_dma_ops_init(void)28592476{24772477+ struct iommu_dev_data *dev_data;28602478 struct pci_dev *pdev = NULL;28612479 unsigned unhandled = 0;28622480···28672483 continue;28682484 }2869248528702870- pdev->dev.archdata.dma_ops = &amd_iommu_dma_ops;24862486+ dev_data = get_dev_data(&pdev->dev);24872487+24882488+ if (!dev_data->passthrough)24892489+ pdev->dev.archdata.dma_ops = &amd_iommu_dma_ops;24902490+ else24912491+ pdev->dev.archdata.dma_ops = &nommu_dma_ops;28712492 }2872249328732494 return unhandled;···29992610 return NULL;30002611}3001261226132613+static int __init alloc_passthrough_domain(void)26142614+{26152615+ if (pt_domain != NULL)26162616+ return 0;26172617+26182618+ /* allocate passthrough domain */26192619+ pt_domain = protection_domain_alloc();26202620+ if (!pt_domain)26212621+ return -ENOMEM;26222622+26232623+ pt_domain->mode = PAGE_MODE_NONE;26242624+26252625+ return 0;26262626+}30022627static int amd_iommu_domain_init(struct iommu_domain *dom)30032628{30042629 struct protection_domain *domain;···30252622 domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL);30262623 if (!domain->pt_root)30272624 goto out_free;26252625+26262626+ domain->iommu_domain = dom;3028262730292628 dom->priv = domain;30302629···3050264530512646 BUG_ON(domain->dev_cnt != 0);3052264730533053- free_pagetable(domain);26482648+ if (domain->mode != PAGE_MODE_NONE)26492649+ free_pagetable(domain);26502650+26512651+ if (domain->flags & PD_IOMMUV2_MASK)26522652+ free_gcr3_table(domain);3054265330552654 protection_domain_free(domain);30562655···31112702}3112270331132704static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,31143114- phys_addr_t paddr, int gfp_order, int iommu_prot)27052705+ phys_addr_t paddr, size_t page_size, int iommu_prot)31152706{31163116- unsigned long page_size = 0x1000UL << gfp_order;31172707 struct protection_domain *domain = dom->priv;31182708 int prot = 0;31192709 int ret;27102710+27112711+ if (domain->mode == PAGE_MODE_NONE)27122712+ return -EINVAL;3120271331212714 if (iommu_prot & IOMMU_READ)31222715 prot |= IOMMU_PROT_IR;···31322721 return ret;31332722}3134272331353135-static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,31363136- int gfp_order)27242724+static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,27252725+ size_t page_size)31372726{31382727 struct protection_domain *domain = dom->priv;31393139- unsigned long page_size, unmap_size;27282728+ size_t unmap_size;3140272931413141- page_size = 0x1000UL << gfp_order;27302730+ if (domain->mode == PAGE_MODE_NONE)27312731+ return -EINVAL;3142273231432733 mutex_lock(&domain->api_lock);31442734 unmap_size = iommu_unmap_page(domain, iova, page_size);···3147273531482736 domain_flush_tlb_pde(domain);3149273731503150- return get_order(unmap_size);27382738+ return unmap_size;31512739}3152274031532741static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,···31572745 unsigned long offset_mask;31582746 phys_addr_t paddr;31592747 u64 *pte, __pte;27482748+27492749+ if (domain->mode == PAGE_MODE_NONE)27502750+ return iova;3160275131612752 pte = fetch_pte(domain, iova);31622753···31972782 .unmap = amd_iommu_unmap,31982783 .iova_to_phys = amd_iommu_iova_to_phys,31992784 .domain_has_cap = amd_iommu_domain_has_cap,27852785+ .pgsize_bitmap = AMD_IOMMU_PGSIZES,32002786};3201278732022788/*****************************************************************************···3212279632132797int __init amd_iommu_init_passthrough(void)32142798{32153215- struct amd_iommu *iommu;27992799+ struct iommu_dev_data *dev_data;32162800 struct pci_dev *dev = NULL;28012801+ struct amd_iommu *iommu;32172802 u16 devid;28032803+ int ret;3218280432193219- /* allocate passthrough domain */32203220- pt_domain = protection_domain_alloc();32213221- if (!pt_domain)32223222- return -ENOMEM;32233223-32243224- pt_domain->mode |= PAGE_MODE_NONE;28052805+ ret = alloc_passthrough_domain();28062806+ if (ret)28072807+ return ret;3225280832262809 for_each_pci_dev(dev) {32272810 if (!check_device(&dev->dev))32282811 continue;28122812+28132813+ dev_data = get_dev_data(&dev->dev);28142814+ dev_data->passthrough = true;3229281532302816 devid = get_device_id(&dev->dev);32312817···32382820 attach_device(&dev->dev, pt_domain);32392821 }3240282228232823+ amd_iommu_stats_init();28242824+32412825 pr_info("AMD-Vi: Initialized for Passthrough Mode\n");3242282632432827 return 0;32442828}28292829+28302830+/* IOMMUv2 specific functions */28312831+int amd_iommu_register_ppr_notifier(struct notifier_block *nb)28322832+{28332833+ return atomic_notifier_chain_register(&ppr_notifier, nb);28342834+}28352835+EXPORT_SYMBOL(amd_iommu_register_ppr_notifier);28362836+28372837+int amd_iommu_unregister_ppr_notifier(struct notifier_block *nb)28382838+{28392839+ return atomic_notifier_chain_unregister(&ppr_notifier, nb);28402840+}28412841+EXPORT_SYMBOL(amd_iommu_unregister_ppr_notifier);28422842+28432843+void amd_iommu_domain_direct_map(struct iommu_domain *dom)28442844+{28452845+ struct protection_domain *domain = dom->priv;28462846+ unsigned long flags;28472847+28482848+ spin_lock_irqsave(&domain->lock, flags);28492849+28502850+ /* Update data structure */28512851+ domain->mode = PAGE_MODE_NONE;28522852+ domain->updated = true;28532853+28542854+ /* Make changes visible to IOMMUs */28552855+ update_domain(domain);28562856+28572857+ /* Page-table is not visible to IOMMU anymore, so free it */28582858+ free_pagetable(domain);28592859+28602860+ spin_unlock_irqrestore(&domain->lock, flags);28612861+}28622862+EXPORT_SYMBOL(amd_iommu_domain_direct_map);28632863+28642864+int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids)28652865+{28662866+ struct protection_domain *domain = dom->priv;28672867+ unsigned long flags;28682868+ int levels, ret;28692869+28702870+ if (pasids <= 0 || pasids > (PASID_MASK + 1))28712871+ return -EINVAL;28722872+28732873+ /* Number of GCR3 table levels required */28742874+ for (levels = 0; (pasids - 1) & ~0x1ff; pasids >>= 9)28752875+ levels += 1;28762876+28772877+ if (levels > amd_iommu_max_glx_val)28782878+ return -EINVAL;28792879+28802880+ spin_lock_irqsave(&domain->lock, flags);28812881+28822882+ /*28832883+ * Save us all sanity checks whether devices already in the28842884+ * domain support IOMMUv2. Just force that the domain has no28852885+ * devices attached when it is switched into IOMMUv2 mode.28862886+ */28872887+ ret = -EBUSY;28882888+ if (domain->dev_cnt > 0 || domain->flags & PD_IOMMUV2_MASK)28892889+ goto out;28902890+28912891+ ret = -ENOMEM;28922892+ domain->gcr3_tbl = (void *)get_zeroed_page(GFP_ATOMIC);28932893+ if (domain->gcr3_tbl == NULL)28942894+ goto out;28952895+28962896+ domain->glx = levels;28972897+ domain->flags |= PD_IOMMUV2_MASK;28982898+ domain->updated = true;28992899+29002900+ update_domain(domain);29012901+29022902+ ret = 0;29032903+29042904+out:29052905+ spin_unlock_irqrestore(&domain->lock, flags);29062906+29072907+ return ret;29082908+}29092909+EXPORT_SYMBOL(amd_iommu_domain_enable_v2);29102910+29112911+static int __flush_pasid(struct protection_domain *domain, int pasid,29122912+ u64 address, bool size)29132913+{29142914+ struct iommu_dev_data *dev_data;29152915+ struct iommu_cmd cmd;29162916+ int i, ret;29172917+29182918+ if (!(domain->flags & PD_IOMMUV2_MASK))29192919+ return -EINVAL;29202920+29212921+ build_inv_iommu_pasid(&cmd, domain->id, pasid, address, size);29222922+29232923+ /*29242924+ * IOMMU TLB needs to be flushed before Device TLB to29252925+ * prevent device TLB refill from IOMMU TLB29262926+ */29272927+ for (i = 0; i < amd_iommus_present; ++i) {29282928+ if (domain->dev_iommu[i] == 0)29292929+ continue;29302930+29312931+ ret = iommu_queue_command(amd_iommus[i], &cmd);29322932+ if (ret != 0)29332933+ goto out;29342934+ }29352935+29362936+ /* Wait until IOMMU TLB flushes are complete */29372937+ domain_flush_complete(domain);29382938+29392939+ /* Now flush device TLBs */29402940+ list_for_each_entry(dev_data, &domain->dev_list, list) {29412941+ struct amd_iommu *iommu;29422942+ int qdep;29432943+29442944+ BUG_ON(!dev_data->ats.enabled);29452945+29462946+ qdep = dev_data->ats.qdep;29472947+ iommu = amd_iommu_rlookup_table[dev_data->devid];29482948+29492949+ build_inv_iotlb_pasid(&cmd, dev_data->devid, pasid,29502950+ qdep, address, size);29512951+29522952+ ret = iommu_queue_command(iommu, &cmd);29532953+ if (ret != 0)29542954+ goto out;29552955+ }29562956+29572957+ /* Wait until all device TLBs are flushed */29582958+ domain_flush_complete(domain);29592959+29602960+ ret = 0;29612961+29622962+out:29632963+29642964+ return ret;29652965+}29662966+29672967+static int __amd_iommu_flush_page(struct protection_domain *domain, int pasid,29682968+ u64 address)29692969+{29702970+ INC_STATS_COUNTER(invalidate_iotlb);29712971+29722972+ return __flush_pasid(domain, pasid, address, false);29732973+}29742974+29752975+int amd_iommu_flush_page(struct iommu_domain *dom, int pasid,29762976+ u64 address)29772977+{29782978+ struct protection_domain *domain = dom->priv;29792979+ unsigned long flags;29802980+ int ret;29812981+29822982+ spin_lock_irqsave(&domain->lock, flags);29832983+ ret = __amd_iommu_flush_page(domain, pasid, address);29842984+ spin_unlock_irqrestore(&domain->lock, flags);29852985+29862986+ return ret;29872987+}29882988+EXPORT_SYMBOL(amd_iommu_flush_page);29892989+29902990+static int __amd_iommu_flush_tlb(struct protection_domain *domain, int pasid)29912991+{29922992+ INC_STATS_COUNTER(invalidate_iotlb_all);29932993+29942994+ return __flush_pasid(domain, pasid, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,29952995+ true);29962996+}29972997+29982998+int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid)29992999+{30003000+ struct protection_domain *domain = dom->priv;30013001+ unsigned long flags;30023002+ int ret;30033003+30043004+ spin_lock_irqsave(&domain->lock, flags);30053005+ ret = __amd_iommu_flush_tlb(domain, pasid);30063006+ spin_unlock_irqrestore(&domain->lock, flags);30073007+30083008+ return ret;30093009+}30103010+EXPORT_SYMBOL(amd_iommu_flush_tlb);30113011+30123012+static u64 *__get_gcr3_pte(u64 *root, int level, int pasid, bool alloc)30133013+{30143014+ int index;30153015+ u64 *pte;30163016+30173017+ while (true) {30183018+30193019+ index = (pasid >> (9 * level)) & 0x1ff;30203020+ pte = &root[index];30213021+30223022+ if (level == 0)30233023+ break;30243024+30253025+ if (!(*pte & GCR3_VALID)) {30263026+ if (!alloc)30273027+ return NULL;30283028+30293029+ root = (void *)get_zeroed_page(GFP_ATOMIC);30303030+ if (root == NULL)30313031+ return NULL;30323032+30333033+ *pte = __pa(root) | GCR3_VALID;30343034+ }30353035+30363036+ root = __va(*pte & PAGE_MASK);30373037+30383038+ level -= 1;30393039+ }30403040+30413041+ return pte;30423042+}30433043+30443044+static int __set_gcr3(struct protection_domain *domain, int pasid,30453045+ unsigned long cr3)30463046+{30473047+ u64 *pte;30483048+30493049+ if (domain->mode != PAGE_MODE_NONE)30503050+ return -EINVAL;30513051+30523052+ pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, true);30533053+ if (pte == NULL)30543054+ return -ENOMEM;30553055+30563056+ *pte = (cr3 & PAGE_MASK) | GCR3_VALID;30573057+30583058+ return __amd_iommu_flush_tlb(domain, pasid);30593059+}30603060+30613061+static int __clear_gcr3(struct protection_domain *domain, int pasid)30623062+{30633063+ u64 *pte;30643064+30653065+ if (domain->mode != PAGE_MODE_NONE)30663066+ return -EINVAL;30673067+30683068+ pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, false);30693069+ if (pte == NULL)30703070+ return 0;30713071+30723072+ *pte = 0;30733073+30743074+ return __amd_iommu_flush_tlb(domain, pasid);30753075+}30763076+30773077+int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid,30783078+ unsigned long cr3)30793079+{30803080+ struct protection_domain *domain = dom->priv;30813081+ unsigned long flags;30823082+ int ret;30833083+30843084+ spin_lock_irqsave(&domain->lock, flags);30853085+ ret = __set_gcr3(domain, pasid, cr3);30863086+ spin_unlock_irqrestore(&domain->lock, flags);30873087+30883088+ return ret;30893089+}30903090+EXPORT_SYMBOL(amd_iommu_domain_set_gcr3);30913091+30923092+int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid)30933093+{30943094+ struct protection_domain *domain = dom->priv;30953095+ unsigned long flags;30963096+ int ret;30973097+30983098+ spin_lock_irqsave(&domain->lock, flags);30993099+ ret = __clear_gcr3(domain, pasid);31003100+ spin_unlock_irqrestore(&domain->lock, flags);31013101+31023102+ return ret;31033103+}31043104+EXPORT_SYMBOL(amd_iommu_domain_clear_gcr3);31053105+31063106+int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid,31073107+ int status, int tag)31083108+{31093109+ struct iommu_dev_data *dev_data;31103110+ struct amd_iommu *iommu;31113111+ struct iommu_cmd cmd;31123112+31133113+ INC_STATS_COUNTER(complete_ppr);31143114+31153115+ dev_data = get_dev_data(&pdev->dev);31163116+ iommu = amd_iommu_rlookup_table[dev_data->devid];31173117+31183118+ build_complete_ppr(&cmd, dev_data->devid, pasid, status,31193119+ tag, dev_data->pri_tlp);31203120+31213121+ return iommu_queue_command(iommu, &cmd);31223122+}31233123+EXPORT_SYMBOL(amd_iommu_complete_ppr);31243124+31253125+struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev)31263126+{31273127+ struct protection_domain *domain;31283128+31293129+ domain = get_domain(&pdev->dev);31303130+ if (IS_ERR(domain))31313131+ return NULL;31323132+31333133+ /* Only return IOMMUv2 domains */31343134+ if (!(domain->flags & PD_IOMMUV2_MASK))31353135+ return NULL;31363136+31373137+ return domain->iommu_domain;31383138+}31393139+EXPORT_SYMBOL(amd_iommu_get_v2_domain);31403140+31413141+void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum)31423142+{31433143+ struct iommu_dev_data *dev_data;31443144+31453145+ if (!amd_iommu_v2_supported())31463146+ return;31473147+31483148+ dev_data = get_dev_data(&pdev->dev);31493149+ dev_data->errata |= (1 << erratum);31503150+}31513151+EXPORT_SYMBOL(amd_iommu_enable_device_erratum);31523152+31533153+int amd_iommu_device_info(struct pci_dev *pdev,31543154+ struct amd_iommu_device_info *info)31553155+{31563156+ int max_pasids;31573157+ int pos;31583158+31593159+ if (pdev == NULL || info == NULL)31603160+ return -EINVAL;31613161+31623162+ if (!amd_iommu_v2_supported())31633163+ return -EINVAL;31643164+31653165+ memset(info, 0, sizeof(*info));31663166+31673167+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS);31683168+ if (pos)31693169+ info->flags |= AMD_IOMMU_DEVICE_FLAG_ATS_SUP;31703170+31713171+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);31723172+ if (pos)31733173+ info->flags |= AMD_IOMMU_DEVICE_FLAG_PRI_SUP;31743174+31753175+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);31763176+ if (pos) {31773177+ int features;31783178+31793179+ max_pasids = 1 << (9 * (amd_iommu_max_glx_val + 1));31803180+ max_pasids = min(max_pasids, (1 << 20));31813181+31823182+ info->flags |= AMD_IOMMU_DEVICE_FLAG_PASID_SUP;31833183+ info->max_pasids = min(pci_max_pasids(pdev), max_pasids);31843184+31853185+ features = pci_pasid_features(pdev);31863186+ if (features & PCI_PASID_CAP_EXEC)31873187+ info->flags |= AMD_IOMMU_DEVICE_FLAG_EXEC_SUP;31883188+ if (features & PCI_PASID_CAP_PRIV)31893189+ info->flags |= AMD_IOMMU_DEVICE_FLAG_PRIV_SUP;31903190+ }31913191+31923192+ return 0;31933193+}31943194+EXPORT_SYMBOL(amd_iommu_device_info);
+120-13
drivers/iommu/amd_iommu_init.c
···2525#include <linux/interrupt.h>2626#include <linux/msi.h>2727#include <linux/amd-iommu.h>2828+#include <linux/export.h>2829#include <asm/pci-direct.h>2930#include <asm/iommu.h>3031#include <asm/gart.h>···141140/* IOMMUs have a non-present cache? */142141bool amd_iommu_np_cache __read_mostly;143142bool amd_iommu_iotlb_sup __read_mostly = true;143143+144144+u32 amd_iommu_max_pasids __read_mostly = ~0;145145+146146+bool amd_iommu_v2_present __read_mostly;147147+148148+bool amd_iommu_force_isolation __read_mostly;144149145150/*146151 * The ACPI table parsing functions set this variable on an error···303296304297 ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);305298 ctrl &= ~(1 << bit);299299+ writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);300300+}301301+302302+static void iommu_set_inv_tlb_timeout(struct amd_iommu *iommu, int timeout)303303+{304304+ u32 ctrl;305305+306306+ ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);307307+ ctrl &= ~CTRL_INV_TO_MASK;308308+ ctrl |= (timeout << CONTROL_INV_TIMEOUT) & CTRL_INV_TO_MASK;306309 writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);307310}308311···598581 free_pages((unsigned long)iommu->evt_buf, get_order(EVT_BUFFER_SIZE));599582}600583584584+/* allocates the memory where the IOMMU will log its events to */585585+static u8 * __init alloc_ppr_log(struct amd_iommu *iommu)586586+{587587+ iommu->ppr_log = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,588588+ get_order(PPR_LOG_SIZE));589589+590590+ if (iommu->ppr_log == NULL)591591+ return NULL;592592+593593+ return iommu->ppr_log;594594+}595595+596596+static void iommu_enable_ppr_log(struct amd_iommu *iommu)597597+{598598+ u64 entry;599599+600600+ if (iommu->ppr_log == NULL)601601+ return;602602+603603+ entry = (u64)virt_to_phys(iommu->ppr_log) | PPR_LOG_SIZE_512;604604+605605+ memcpy_toio(iommu->mmio_base + MMIO_PPR_LOG_OFFSET,606606+ &entry, sizeof(entry));607607+608608+ /* set head and tail to zero manually */609609+ writel(0x00, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);610610+ writel(0x00, iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);611611+612612+ iommu_feature_enable(iommu, CONTROL_PPFLOG_EN);613613+ iommu_feature_enable(iommu, CONTROL_PPR_EN);614614+}615615+616616+static void __init free_ppr_log(struct amd_iommu *iommu)617617+{618618+ if (iommu->ppr_log == NULL)619619+ return;620620+621621+ free_pages((unsigned long)iommu->ppr_log, get_order(PPR_LOG_SIZE));622622+}623623+624624+static void iommu_enable_gt(struct amd_iommu *iommu)625625+{626626+ if (!iommu_feature(iommu, FEATURE_GT))627627+ return;628628+629629+ iommu_feature_enable(iommu, CONTROL_GT_EN);630630+}631631+601632/* sets a specific bit in the device table entry. */602633static void set_dev_entry_bit(u16 devid, u8 bit)603634{604604- int i = (bit >> 5) & 0x07;605605- int _bit = bit & 0x1f;635635+ int i = (bit >> 6) & 0x03;636636+ int _bit = bit & 0x3f;606637607607- amd_iommu_dev_table[devid].data[i] |= (1 << _bit);638638+ amd_iommu_dev_table[devid].data[i] |= (1UL << _bit);608639}609640610641static int get_dev_entry_bit(u16 devid, u8 bit)611642{612612- int i = (bit >> 5) & 0x07;613613- int _bit = bit & 0x1f;643643+ int i = (bit >> 6) & 0x03;644644+ int _bit = bit & 0x3f;614645615615- return (amd_iommu_dev_table[devid].data[i] & (1 << _bit)) >> _bit;646646+ return (amd_iommu_dev_table[devid].data[i] & (1UL << _bit)) >> _bit;616647}617648618649···763698 high = readl(iommu->mmio_base + MMIO_EXT_FEATURES + 4);764699765700 iommu->features = ((u64)high << 32) | low;701701+702702+ if (iommu_feature(iommu, FEATURE_GT)) {703703+ int glxval;704704+ u32 pasids;705705+ u64 shift;706706+707707+ shift = iommu->features & FEATURE_PASID_MASK;708708+ shift >>= FEATURE_PASID_SHIFT;709709+ pasids = (1 << shift);710710+711711+ amd_iommu_max_pasids = min(amd_iommu_max_pasids, pasids);712712+713713+ glxval = iommu->features & FEATURE_GLXVAL_MASK;714714+ glxval >>= FEATURE_GLXVAL_SHIFT;715715+716716+ if (amd_iommu_max_glx_val == -1)717717+ amd_iommu_max_glx_val = glxval;718718+ else719719+ amd_iommu_max_glx_val = min(amd_iommu_max_glx_val, glxval);720720+ }721721+722722+ if (iommu_feature(iommu, FEATURE_GT) &&723723+ iommu_feature(iommu, FEATURE_PPR)) {724724+ iommu->is_iommu_v2 = true;725725+ amd_iommu_v2_present = true;726726+ }766727767728 if (!is_rd890_iommu(iommu->dev))768729 return;···992901{993902 free_command_buffer(iommu);994903 free_event_buffer(iommu);904904+ free_ppr_log(iommu);995905 iommu_unmap_mmio_space(iommu);996906}997907···1055963 init_iommu_from_pci(iommu);1056964 init_iommu_from_acpi(iommu, h);1057965 init_iommu_devices(iommu);966966+967967+ if (iommu_feature(iommu, FEATURE_PPR)) {968968+ iommu->ppr_log = alloc_ppr_log(iommu);969969+ if (!iommu->ppr_log)970970+ return -ENOMEM;971971+ }10589721059973 if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))1060974 amd_iommu_np_cache = true;···1147104911481050 iommu->int_enabled = true;11491051 iommu_feature_enable(iommu, CONTROL_EVT_INT_EN);10521052+10531053+ if (iommu->ppr_log != NULL)10541054+ iommu_feature_enable(iommu, CONTROL_PPFINT_EN);1150105511511056 return 0;11521057}···13101209 * make IOMMU memory accesses cache coherent13111210 */13121211 iommu_feature_enable(iommu, CONTROL_COHERENT_EN);12121212+12131213+ /* Set IOTLB invalidation timeout to 1s */12141214+ iommu_set_inv_tlb_timeout(iommu, CTRL_INV_TO_1S);13131215}1314121613151217static void iommu_apply_resume_quirks(struct amd_iommu *iommu)···13781274 iommu_set_device_table(iommu);13791275 iommu_enable_command_buffer(iommu);13801276 iommu_enable_event_buffer(iommu);12771277+ iommu_enable_ppr_log(iommu);12781278+ iommu_enable_gt(iommu);13811279 iommu_set_exclusion_range(iommu);13821280 iommu_init_msi(iommu);13831281 iommu_enable(iommu);···1409130314101304 /* re-load the hardware */14111305 enable_iommus();14121412-14131413- /*14141414- * we have to flush after the IOMMUs are enabled because a14151415- * disabled IOMMU will never execute the commands we send14161416- */14171417- for_each_iommu(iommu)14181418- iommu_flush_all_caches(iommu);14191306}1420130714211308static int amd_iommu_suspend(void)···16591560 amd_iommu_unmap_flush = true;16601561 if (strncmp(str, "off", 3) == 0)16611562 amd_iommu_disabled = true;15631563+ if (strncmp(str, "force_isolation", 15) == 0)15641564+ amd_iommu_force_isolation = true;16621565 }1663156616641567 return 1;···16731572 gart_iommu_hole_init,16741573 0,16751574 0);15751575+15761576+bool amd_iommu_v2_supported(void)15771577+{15781578+ return amd_iommu_v2_present;15791579+}15801580+EXPORT_SYMBOL(amd_iommu_v2_supported);
+24
drivers/iommu/amd_iommu_proto.h
···3131extern void amd_iommu_uninit_devices(void);3232extern void amd_iommu_init_notifier(void);3333extern void amd_iommu_init_api(void);3434+3535+/* IOMMUv2 specific functions */3636+struct iommu_domain;3737+3838+extern bool amd_iommu_v2_supported(void);3939+extern int amd_iommu_register_ppr_notifier(struct notifier_block *nb);4040+extern int amd_iommu_unregister_ppr_notifier(struct notifier_block *nb);4141+extern void amd_iommu_domain_direct_map(struct iommu_domain *dom);4242+extern int amd_iommu_domain_enable_v2(struct iommu_domain *dom, int pasids);4343+extern int amd_iommu_flush_page(struct iommu_domain *dom, int pasid,4444+ u64 address);4545+extern int amd_iommu_flush_tlb(struct iommu_domain *dom, int pasid);4646+extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid,4747+ unsigned long cr3);4848+extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid);4949+extern struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev);5050+5151+#define PPR_SUCCESS 0x05252+#define PPR_INVALID 0x15353+#define PPR_FAILURE 0xf5454+5555+extern int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid,5656+ int status, int tag);5757+3458#ifndef CONFIG_AMD_IOMMU_STATS35593660static inline void amd_iommu_stats_init(void) { }
+115-3
drivers/iommu/amd_iommu_types.h
···6969#define MMIO_EXCL_BASE_OFFSET 0x00207070#define MMIO_EXCL_LIMIT_OFFSET 0x00287171#define MMIO_EXT_FEATURES 0x00307272+#define MMIO_PPR_LOG_OFFSET 0x00387273#define MMIO_CMD_HEAD_OFFSET 0x20007374#define MMIO_CMD_TAIL_OFFSET 0x20087475#define MMIO_EVT_HEAD_OFFSET 0x20107576#define MMIO_EVT_TAIL_OFFSET 0x20187677#define MMIO_STATUS_OFFSET 0x20207878+#define MMIO_PPR_HEAD_OFFSET 0x20307979+#define MMIO_PPR_TAIL_OFFSET 0x2038778078817982/* Extended Feature Bits */···9087#define FEATURE_HE (1ULL<<8)9188#define FEATURE_PC (1ULL<<9)92899090+#define FEATURE_PASID_SHIFT 329191+#define FEATURE_PASID_MASK (0x1fULL << FEATURE_PASID_SHIFT)9292+9393+#define FEATURE_GLXVAL_SHIFT 149494+#define FEATURE_GLXVAL_MASK (0x03ULL << FEATURE_GLXVAL_SHIFT)9595+9696+#define PASID_MASK 0x000fffff9797+9398/* MMIO status bits */9494-#define MMIO_STATUS_COM_WAIT_INT_MASK 0x049999+#define MMIO_STATUS_COM_WAIT_INT_MASK (1 << 2)100100+#define MMIO_STATUS_PPR_INT_MASK (1 << 6)9510196102/* event logging constants */97103#define EVENT_ENTRY_SIZE 0x10···127115#define CONTROL_EVT_LOG_EN 0x02ULL128116#define CONTROL_EVT_INT_EN 0x03ULL129117#define CONTROL_COMWAIT_EN 0x04ULL118118+#define CONTROL_INV_TIMEOUT 0x05ULL130119#define CONTROL_PASSPW_EN 0x08ULL131120#define CONTROL_RESPASSPW_EN 0x09ULL132121#define CONTROL_COHERENT_EN 0x0aULL···135122#define CONTROL_CMDBUF_EN 0x0cULL136123#define CONTROL_PPFLOG_EN 0x0dULL137124#define CONTROL_PPFINT_EN 0x0eULL125125+#define CONTROL_PPR_EN 0x0fULL126126+#define CONTROL_GT_EN 0x10ULL127127+128128+#define CTRL_INV_TO_MASK (7 << CONTROL_INV_TIMEOUT)129129+#define CTRL_INV_TO_NONE 0130130+#define CTRL_INV_TO_1MS 1131131+#define CTRL_INV_TO_10MS 2132132+#define CTRL_INV_TO_100MS 3133133+#define CTRL_INV_TO_1S 4134134+#define CTRL_INV_TO_10S 5135135+#define CTRL_INV_TO_100S 6138136139137/* command specific defines */140138#define CMD_COMPL_WAIT 0x01141139#define CMD_INV_DEV_ENTRY 0x02142140#define CMD_INV_IOMMU_PAGES 0x03143141#define CMD_INV_IOTLB_PAGES 0x04142142+#define CMD_COMPLETE_PPR 0x07144143#define CMD_INV_ALL 0x08145144146145#define CMD_COMPL_WAIT_STORE_MASK 0x01147146#define CMD_COMPL_WAIT_INT_MASK 0x02148147#define CMD_INV_IOMMU_PAGES_SIZE_MASK 0x01149148#define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02149149+#define CMD_INV_IOMMU_PAGES_GN_MASK 0x04150150+151151+#define PPR_STATUS_MASK 0xf152152+#define PPR_STATUS_SHIFT 12150153151154#define CMD_INV_IOMMU_ALL_PAGES_ADDRESS 0x7fffffffffffffffULL152155···193164/* constants for event buffer handling */194165#define EVT_BUFFER_SIZE 8192 /* 512 entries */195166#define EVT_LEN_MASK (0x9ULL << 56)167167+168168+/* Constants for PPR Log handling */169169+#define PPR_LOG_ENTRIES 512170170+#define PPR_LOG_SIZE_SHIFT 56171171+#define PPR_LOG_SIZE_512 (0x9ULL << PPR_LOG_SIZE_SHIFT)172172+#define PPR_ENTRY_SIZE 16173173+#define PPR_LOG_SIZE (PPR_ENTRY_SIZE * PPR_LOG_ENTRIES)174174+175175+#define PPR_REQ_TYPE(x) (((x) >> 60) & 0xfULL)176176+#define PPR_FLAGS(x) (((x) >> 48) & 0xfffULL)177177+#define PPR_DEVID(x) ((x) & 0xffffULL)178178+#define PPR_TAG(x) (((x) >> 32) & 0x3ffULL)179179+#define PPR_PASID1(x) (((x) >> 16) & 0xffffULL)180180+#define PPR_PASID2(x) (((x) >> 42) & 0xfULL)181181+#define PPR_PASID(x) ((PPR_PASID2(x) << 16) | PPR_PASID1(x))182182+183183+#define PPR_REQ_FAULT 0x01196184197185#define PAGE_MODE_NONE 0x00198186#define PAGE_MODE_1_LEVEL 0x01···276230#define IOMMU_PTE_IR (1ULL << 61)277231#define IOMMU_PTE_IW (1ULL << 62)278232279279-#define DTE_FLAG_IOTLB 0x01233233+#define DTE_FLAG_IOTLB (0x01UL << 32)234234+#define DTE_FLAG_GV (0x01ULL << 55)235235+#define DTE_GLX_SHIFT (56)236236+#define DTE_GLX_MASK (3)237237+238238+#define DTE_GCR3_VAL_A(x) (((x) >> 12) & 0x00007ULL)239239+#define DTE_GCR3_VAL_B(x) (((x) >> 15) & 0x0ffffULL)240240+#define DTE_GCR3_VAL_C(x) (((x) >> 31) & 0xfffffULL)241241+242242+#define DTE_GCR3_INDEX_A 0243243+#define DTE_GCR3_INDEX_B 1244244+#define DTE_GCR3_INDEX_C 1245245+246246+#define DTE_GCR3_SHIFT_A 58247247+#define DTE_GCR3_SHIFT_B 16248248+#define DTE_GCR3_SHIFT_C 43249249+250250+#define GCR3_VALID 0x01ULL280251281252#define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL)282253#define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P)···320257 domain for an IOMMU */321258#define PD_PASSTHROUGH_MASK (1UL << 2) /* domain has no page322259 translation */260260+#define PD_IOMMUV2_MASK (1UL << 3) /* domain has gcr3 table */323261324262extern bool amd_iommu_dump;325263#define DUMP_printk(format, arg...) \···349285#define APERTURE_RANGE_INDEX(a) ((a) >> APERTURE_RANGE_SHIFT)350286#define APERTURE_PAGE_INDEX(a) (((a) >> 21) & 0x3fULL)351287288288+289289+/*290290+ * This struct is used to pass information about291291+ * incoming PPR faults around.292292+ */293293+struct amd_iommu_fault {294294+ u64 address; /* IO virtual address of the fault*/295295+ u32 pasid; /* Address space identifier */296296+ u16 device_id; /* Originating PCI device id */297297+ u16 tag; /* PPR tag */298298+ u16 flags; /* Fault flags */299299+300300+};301301+302302+#define PPR_FAULT_EXEC (1 << 1)303303+#define PPR_FAULT_READ (1 << 2)304304+#define PPR_FAULT_WRITE (1 << 5)305305+#define PPR_FAULT_USER (1 << 6)306306+#define PPR_FAULT_RSVD (1 << 7)307307+#define PPR_FAULT_GN (1 << 8)308308+309309+struct iommu_domain;310310+352311/*353312 * This structure contains generic data for IOMMU protection domains354313 * independent of their use.···384297 u16 id; /* the domain id written to the device table */385298 int mode; /* paging mode (0-6 levels) */386299 u64 *pt_root; /* page table root pointer */300300+ int glx; /* Number of levels for GCR3 table */301301+ u64 *gcr3_tbl; /* Guest CR3 table */387302 unsigned long flags; /* flags to find out type of domain */388303 bool updated; /* complete domain flush required */389304 unsigned dev_cnt; /* devices assigned to this domain */390305 unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */391306 void *priv; /* private data */307307+ struct iommu_domain *iommu_domain; /* Pointer to generic308308+ domain structure */392309393310};394311···406315 struct protection_domain *domain; /* Domain the device is bound to */407316 atomic_t bind; /* Domain attach reverent count */408317 u16 devid; /* PCI Device ID */318318+ bool iommu_v2; /* Device can make use of IOMMUv2 */319319+ bool passthrough; /* Default for device is pt_domain */409320 struct {410321 bool enabled;411322 int qdep;412323 } ats; /* ATS state */324324+ bool pri_tlp; /* PASID TLB required for325325+ PPR completions */326326+ u32 errata; /* Bitmap for errata to apply */413327};414328415329/*···495399 /* Extended features */496400 u64 features;497401402402+ /* IOMMUv2 */403403+ bool is_iommu_v2;404404+498405 /*499406 * Capability pointer. There could be more than one IOMMU per PCI500407 * device function if there are more than one AMD IOMMU capability···529430 u8 *evt_buf;530431 /* MSI number for event interrupt */531432 u16 evt_msi_num;433433+434434+ /* Base of the PPR log, if present */435435+ u8 *ppr_log;532436533437 /* true if interrupts for this IOMMU are already enabled */534438 bool int_enabled;···586484 * Structure defining one entry in the device table587485 */588486struct dev_table_entry {589589- u32 data[8];487487+ u64 data[4];590488};591489592490/*···650548 * they are reused651549 */652550extern bool amd_iommu_unmap_flush;551551+552552+/* Smallest number of PASIDs supported by any IOMMU in the system */553553+extern u32 amd_iommu_max_pasids;554554+555555+extern bool amd_iommu_v2_present;556556+557557+extern bool amd_iommu_force_isolation;558558+559559+/* Max levels of glxval supported */560560+extern int amd_iommu_max_glx_val;653561654562/* takes bus and device/function and returns the device id655563 * FIXME: should that be in generic PCI code? */
+994
drivers/iommu/amd_iommu_v2.c
···11+/*22+ * Copyright (C) 2010-2012 Advanced Micro Devices, Inc.33+ * Author: Joerg Roedel <joerg.roedel@amd.com>44+ *55+ * This program is free software; you can redistribute it and/or modify it66+ * under the terms of the GNU General Public License version 2 as published77+ * by the Free Software Foundation.88+ *99+ * This program is distributed in the hope that it will be useful,1010+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1111+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1212+ * GNU General Public License for more details.1313+ *1414+ * You should have received a copy of the GNU General Public License1515+ * along with this program; if not, write to the Free Software1616+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA1717+ */1818+1919+#include <linux/mmu_notifier.h>2020+#include <linux/amd-iommu.h>2121+#include <linux/mm_types.h>2222+#include <linux/profile.h>2323+#include <linux/module.h>2424+#include <linux/sched.h>2525+#include <linux/iommu.h>2626+#include <linux/wait.h>2727+#include <linux/pci.h>2828+#include <linux/gfp.h>2929+3030+#include "amd_iommu_types.h"3131+#include "amd_iommu_proto.h"3232+3333+MODULE_LICENSE("GPL v2");3434+MODULE_AUTHOR("Joerg Roedel <joerg.roedel@amd.com>");3535+3636+#define MAX_DEVICES 0x100003737+#define PRI_QUEUE_SIZE 5123838+3939+struct pri_queue {4040+ atomic_t inflight;4141+ bool finish;4242+ int status;4343+};4444+4545+struct pasid_state {4646+ struct list_head list; /* For global state-list */4747+ atomic_t count; /* Reference count */4848+ struct task_struct *task; /* Task bound to this PASID */4949+ struct mm_struct *mm; /* mm_struct for the faults */5050+ struct mmu_notifier mn; /* mmu_otifier handle */5151+ struct pri_queue pri[PRI_QUEUE_SIZE]; /* PRI tag states */5252+ struct device_state *device_state; /* Link to our device_state */5353+ int pasid; /* PASID index */5454+ spinlock_t lock; /* Protect pri_queues */5555+ wait_queue_head_t wq; /* To wait for count == 0 */5656+};5757+5858+struct device_state {5959+ atomic_t count;6060+ struct pci_dev *pdev;6161+ struct pasid_state **states;6262+ struct iommu_domain *domain;6363+ int pasid_levels;6464+ int max_pasids;6565+ amd_iommu_invalid_ppr_cb inv_ppr_cb;6666+ amd_iommu_invalidate_ctx inv_ctx_cb;6767+ spinlock_t lock;6868+ wait_queue_head_t wq;6969+};7070+7171+struct fault {7272+ struct work_struct work;7373+ struct device_state *dev_state;7474+ struct pasid_state *state;7575+ struct mm_struct *mm;7676+ u64 address;7777+ u16 devid;7878+ u16 pasid;7979+ u16 tag;8080+ u16 finish;8181+ u16 flags;8282+};8383+8484+struct device_state **state_table;8585+static spinlock_t state_lock;8686+8787+/* List and lock for all pasid_states */8888+static LIST_HEAD(pasid_state_list);8989+static DEFINE_SPINLOCK(ps_lock);9090+9191+static struct workqueue_struct *iommu_wq;9292+9393+/*9494+ * Empty page table - Used between9595+ * mmu_notifier_invalidate_range_start and9696+ * mmu_notifier_invalidate_range_end9797+ */9898+static u64 *empty_page_table;9999+100100+static void free_pasid_states(struct device_state *dev_state);101101+static void unbind_pasid(struct device_state *dev_state, int pasid);102102+static int task_exit(struct notifier_block *nb, unsigned long e, void *data);103103+104104+static u16 device_id(struct pci_dev *pdev)105105+{106106+ u16 devid;107107+108108+ devid = pdev->bus->number;109109+ devid = (devid << 8) | pdev->devfn;110110+111111+ return devid;112112+}113113+114114+static struct device_state *get_device_state(u16 devid)115115+{116116+ struct device_state *dev_state;117117+ unsigned long flags;118118+119119+ spin_lock_irqsave(&state_lock, flags);120120+ dev_state = state_table[devid];121121+ if (dev_state != NULL)122122+ atomic_inc(&dev_state->count);123123+ spin_unlock_irqrestore(&state_lock, flags);124124+125125+ return dev_state;126126+}127127+128128+static void free_device_state(struct device_state *dev_state)129129+{130130+ /*131131+ * First detach device from domain - No more PRI requests will arrive132132+ * from that device after it is unbound from the IOMMUv2 domain.133133+ */134134+ iommu_detach_device(dev_state->domain, &dev_state->pdev->dev);135135+136136+ /* Everything is down now, free the IOMMUv2 domain */137137+ iommu_domain_free(dev_state->domain);138138+139139+ /* Finally get rid of the device-state */140140+ kfree(dev_state);141141+}142142+143143+static void put_device_state(struct device_state *dev_state)144144+{145145+ if (atomic_dec_and_test(&dev_state->count))146146+ wake_up(&dev_state->wq);147147+}148148+149149+static void put_device_state_wait(struct device_state *dev_state)150150+{151151+ DEFINE_WAIT(wait);152152+153153+ prepare_to_wait(&dev_state->wq, &wait, TASK_UNINTERRUPTIBLE);154154+ if (!atomic_dec_and_test(&dev_state->count))155155+ schedule();156156+ finish_wait(&dev_state->wq, &wait);157157+158158+ free_device_state(dev_state);159159+}160160+161161+static struct notifier_block profile_nb = {162162+ .notifier_call = task_exit,163163+};164164+165165+static void link_pasid_state(struct pasid_state *pasid_state)166166+{167167+ spin_lock(&ps_lock);168168+ list_add_tail(&pasid_state->list, &pasid_state_list);169169+ spin_unlock(&ps_lock);170170+}171171+172172+static void __unlink_pasid_state(struct pasid_state *pasid_state)173173+{174174+ list_del(&pasid_state->list);175175+}176176+177177+static void unlink_pasid_state(struct pasid_state *pasid_state)178178+{179179+ spin_lock(&ps_lock);180180+ __unlink_pasid_state(pasid_state);181181+ spin_unlock(&ps_lock);182182+}183183+184184+/* Must be called under dev_state->lock */185185+static struct pasid_state **__get_pasid_state_ptr(struct device_state *dev_state,186186+ int pasid, bool alloc)187187+{188188+ struct pasid_state **root, **ptr;189189+ int level, index;190190+191191+ level = dev_state->pasid_levels;192192+ root = dev_state->states;193193+194194+ while (true) {195195+196196+ index = (pasid >> (9 * level)) & 0x1ff;197197+ ptr = &root[index];198198+199199+ if (level == 0)200200+ break;201201+202202+ if (*ptr == NULL) {203203+ if (!alloc)204204+ return NULL;205205+206206+ *ptr = (void *)get_zeroed_page(GFP_ATOMIC);207207+ if (*ptr == NULL)208208+ return NULL;209209+ }210210+211211+ root = (struct pasid_state **)*ptr;212212+ level -= 1;213213+ }214214+215215+ return ptr;216216+}217217+218218+static int set_pasid_state(struct device_state *dev_state,219219+ struct pasid_state *pasid_state,220220+ int pasid)221221+{222222+ struct pasid_state **ptr;223223+ unsigned long flags;224224+ int ret;225225+226226+ spin_lock_irqsave(&dev_state->lock, flags);227227+ ptr = __get_pasid_state_ptr(dev_state, pasid, true);228228+229229+ ret = -ENOMEM;230230+ if (ptr == NULL)231231+ goto out_unlock;232232+233233+ ret = -ENOMEM;234234+ if (*ptr != NULL)235235+ goto out_unlock;236236+237237+ *ptr = pasid_state;238238+239239+ ret = 0;240240+241241+out_unlock:242242+ spin_unlock_irqrestore(&dev_state->lock, flags);243243+244244+ return ret;245245+}246246+247247+static void clear_pasid_state(struct device_state *dev_state, int pasid)248248+{249249+ struct pasid_state **ptr;250250+ unsigned long flags;251251+252252+ spin_lock_irqsave(&dev_state->lock, flags);253253+ ptr = __get_pasid_state_ptr(dev_state, pasid, true);254254+255255+ if (ptr == NULL)256256+ goto out_unlock;257257+258258+ *ptr = NULL;259259+260260+out_unlock:261261+ spin_unlock_irqrestore(&dev_state->lock, flags);262262+}263263+264264+static struct pasid_state *get_pasid_state(struct device_state *dev_state,265265+ int pasid)266266+{267267+ struct pasid_state **ptr, *ret = NULL;268268+ unsigned long flags;269269+270270+ spin_lock_irqsave(&dev_state->lock, flags);271271+ ptr = __get_pasid_state_ptr(dev_state, pasid, false);272272+273273+ if (ptr == NULL)274274+ goto out_unlock;275275+276276+ ret = *ptr;277277+ if (ret)278278+ atomic_inc(&ret->count);279279+280280+out_unlock:281281+ spin_unlock_irqrestore(&dev_state->lock, flags);282282+283283+ return ret;284284+}285285+286286+static void free_pasid_state(struct pasid_state *pasid_state)287287+{288288+ kfree(pasid_state);289289+}290290+291291+static void put_pasid_state(struct pasid_state *pasid_state)292292+{293293+ if (atomic_dec_and_test(&pasid_state->count)) {294294+ put_device_state(pasid_state->device_state);295295+ wake_up(&pasid_state->wq);296296+ }297297+}298298+299299+static void put_pasid_state_wait(struct pasid_state *pasid_state)300300+{301301+ DEFINE_WAIT(wait);302302+303303+ prepare_to_wait(&pasid_state->wq, &wait, TASK_UNINTERRUPTIBLE);304304+305305+ if (atomic_dec_and_test(&pasid_state->count))306306+ put_device_state(pasid_state->device_state);307307+ else308308+ schedule();309309+310310+ finish_wait(&pasid_state->wq, &wait);311311+ mmput(pasid_state->mm);312312+ free_pasid_state(pasid_state);313313+}314314+315315+static void __unbind_pasid(struct pasid_state *pasid_state)316316+{317317+ struct iommu_domain *domain;318318+319319+ domain = pasid_state->device_state->domain;320320+321321+ amd_iommu_domain_clear_gcr3(domain, pasid_state->pasid);322322+ clear_pasid_state(pasid_state->device_state, pasid_state->pasid);323323+324324+ /* Make sure no more pending faults are in the queue */325325+ flush_workqueue(iommu_wq);326326+327327+ mmu_notifier_unregister(&pasid_state->mn, pasid_state->mm);328328+329329+ put_pasid_state(pasid_state); /* Reference taken in bind() function */330330+}331331+332332+static void unbind_pasid(struct device_state *dev_state, int pasid)333333+{334334+ struct pasid_state *pasid_state;335335+336336+ pasid_state = get_pasid_state(dev_state, pasid);337337+ if (pasid_state == NULL)338338+ return;339339+340340+ unlink_pasid_state(pasid_state);341341+ __unbind_pasid(pasid_state);342342+ put_pasid_state_wait(pasid_state); /* Reference taken in this function */343343+}344344+345345+static void free_pasid_states_level1(struct pasid_state **tbl)346346+{347347+ int i;348348+349349+ for (i = 0; i < 512; ++i) {350350+ if (tbl[i] == NULL)351351+ continue;352352+353353+ free_page((unsigned long)tbl[i]);354354+ }355355+}356356+357357+static void free_pasid_states_level2(struct pasid_state **tbl)358358+{359359+ struct pasid_state **ptr;360360+ int i;361361+362362+ for (i = 0; i < 512; ++i) {363363+ if (tbl[i] == NULL)364364+ continue;365365+366366+ ptr = (struct pasid_state **)tbl[i];367367+ free_pasid_states_level1(ptr);368368+ }369369+}370370+371371+static void free_pasid_states(struct device_state *dev_state)372372+{373373+ struct pasid_state *pasid_state;374374+ int i;375375+376376+ for (i = 0; i < dev_state->max_pasids; ++i) {377377+ pasid_state = get_pasid_state(dev_state, i);378378+ if (pasid_state == NULL)379379+ continue;380380+381381+ put_pasid_state(pasid_state);382382+ unbind_pasid(dev_state, i);383383+ }384384+385385+ if (dev_state->pasid_levels == 2)386386+ free_pasid_states_level2(dev_state->states);387387+ else if (dev_state->pasid_levels == 1)388388+ free_pasid_states_level1(dev_state->states);389389+ else if (dev_state->pasid_levels != 0)390390+ BUG();391391+392392+ free_page((unsigned long)dev_state->states);393393+}394394+395395+static struct pasid_state *mn_to_state(struct mmu_notifier *mn)396396+{397397+ return container_of(mn, struct pasid_state, mn);398398+}399399+400400+static void __mn_flush_page(struct mmu_notifier *mn,401401+ unsigned long address)402402+{403403+ struct pasid_state *pasid_state;404404+ struct device_state *dev_state;405405+406406+ pasid_state = mn_to_state(mn);407407+ dev_state = pasid_state->device_state;408408+409409+ amd_iommu_flush_page(dev_state->domain, pasid_state->pasid, address);410410+}411411+412412+static int mn_clear_flush_young(struct mmu_notifier *mn,413413+ struct mm_struct *mm,414414+ unsigned long address)415415+{416416+ __mn_flush_page(mn, address);417417+418418+ return 0;419419+}420420+421421+static void mn_change_pte(struct mmu_notifier *mn,422422+ struct mm_struct *mm,423423+ unsigned long address,424424+ pte_t pte)425425+{426426+ __mn_flush_page(mn, address);427427+}428428+429429+static void mn_invalidate_page(struct mmu_notifier *mn,430430+ struct mm_struct *mm,431431+ unsigned long address)432432+{433433+ __mn_flush_page(mn, address);434434+}435435+436436+static void mn_invalidate_range_start(struct mmu_notifier *mn,437437+ struct mm_struct *mm,438438+ unsigned long start, unsigned long end)439439+{440440+ struct pasid_state *pasid_state;441441+ struct device_state *dev_state;442442+443443+ pasid_state = mn_to_state(mn);444444+ dev_state = pasid_state->device_state;445445+446446+ amd_iommu_domain_set_gcr3(dev_state->domain, pasid_state->pasid,447447+ __pa(empty_page_table));448448+}449449+450450+static void mn_invalidate_range_end(struct mmu_notifier *mn,451451+ struct mm_struct *mm,452452+ unsigned long start, unsigned long end)453453+{454454+ struct pasid_state *pasid_state;455455+ struct device_state *dev_state;456456+457457+ pasid_state = mn_to_state(mn);458458+ dev_state = pasid_state->device_state;459459+460460+ amd_iommu_domain_set_gcr3(dev_state->domain, pasid_state->pasid,461461+ __pa(pasid_state->mm->pgd));462462+}463463+464464+static struct mmu_notifier_ops iommu_mn = {465465+ .clear_flush_young = mn_clear_flush_young,466466+ .change_pte = mn_change_pte,467467+ .invalidate_page = mn_invalidate_page,468468+ .invalidate_range_start = mn_invalidate_range_start,469469+ .invalidate_range_end = mn_invalidate_range_end,470470+};471471+472472+static void set_pri_tag_status(struct pasid_state *pasid_state,473473+ u16 tag, int status)474474+{475475+ unsigned long flags;476476+477477+ spin_lock_irqsave(&pasid_state->lock, flags);478478+ pasid_state->pri[tag].status = status;479479+ spin_unlock_irqrestore(&pasid_state->lock, flags);480480+}481481+482482+static void finish_pri_tag(struct device_state *dev_state,483483+ struct pasid_state *pasid_state,484484+ u16 tag)485485+{486486+ unsigned long flags;487487+488488+ spin_lock_irqsave(&pasid_state->lock, flags);489489+ if (atomic_dec_and_test(&pasid_state->pri[tag].inflight) &&490490+ pasid_state->pri[tag].finish) {491491+ amd_iommu_complete_ppr(dev_state->pdev, pasid_state->pasid,492492+ pasid_state->pri[tag].status, tag);493493+ pasid_state->pri[tag].finish = false;494494+ pasid_state->pri[tag].status = PPR_SUCCESS;495495+ }496496+ spin_unlock_irqrestore(&pasid_state->lock, flags);497497+}498498+499499+static void do_fault(struct work_struct *work)500500+{501501+ struct fault *fault = container_of(work, struct fault, work);502502+ int npages, write;503503+ struct page *page;504504+505505+ write = !!(fault->flags & PPR_FAULT_WRITE);506506+507507+ npages = get_user_pages(fault->state->task, fault->state->mm,508508+ fault->address, 1, write, 0, &page, NULL);509509+510510+ if (npages == 1) {511511+ put_page(page);512512+ } else if (fault->dev_state->inv_ppr_cb) {513513+ int status;514514+515515+ status = fault->dev_state->inv_ppr_cb(fault->dev_state->pdev,516516+ fault->pasid,517517+ fault->address,518518+ fault->flags);519519+ switch (status) {520520+ case AMD_IOMMU_INV_PRI_RSP_SUCCESS:521521+ set_pri_tag_status(fault->state, fault->tag, PPR_SUCCESS);522522+ break;523523+ case AMD_IOMMU_INV_PRI_RSP_INVALID:524524+ set_pri_tag_status(fault->state, fault->tag, PPR_INVALID);525525+ break;526526+ case AMD_IOMMU_INV_PRI_RSP_FAIL:527527+ set_pri_tag_status(fault->state, fault->tag, PPR_FAILURE);528528+ break;529529+ default:530530+ BUG();531531+ }532532+ } else {533533+ set_pri_tag_status(fault->state, fault->tag, PPR_INVALID);534534+ }535535+536536+ finish_pri_tag(fault->dev_state, fault->state, fault->tag);537537+538538+ put_pasid_state(fault->state);539539+540540+ kfree(fault);541541+}542542+543543+static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)544544+{545545+ struct amd_iommu_fault *iommu_fault;546546+ struct pasid_state *pasid_state;547547+ struct device_state *dev_state;548548+ unsigned long flags;549549+ struct fault *fault;550550+ bool finish;551551+ u16 tag;552552+ int ret;553553+554554+ iommu_fault = data;555555+ tag = iommu_fault->tag & 0x1ff;556556+ finish = (iommu_fault->tag >> 9) & 1;557557+558558+ ret = NOTIFY_DONE;559559+ dev_state = get_device_state(iommu_fault->device_id);560560+ if (dev_state == NULL)561561+ goto out;562562+563563+ pasid_state = get_pasid_state(dev_state, iommu_fault->pasid);564564+ if (pasid_state == NULL) {565565+ /* We know the device but not the PASID -> send INVALID */566566+ amd_iommu_complete_ppr(dev_state->pdev, iommu_fault->pasid,567567+ PPR_INVALID, tag);568568+ goto out_drop_state;569569+ }570570+571571+ spin_lock_irqsave(&pasid_state->lock, flags);572572+ atomic_inc(&pasid_state->pri[tag].inflight);573573+ if (finish)574574+ pasid_state->pri[tag].finish = true;575575+ spin_unlock_irqrestore(&pasid_state->lock, flags);576576+577577+ fault = kzalloc(sizeof(*fault), GFP_ATOMIC);578578+ if (fault == NULL) {579579+ /* We are OOM - send success and let the device re-fault */580580+ finish_pri_tag(dev_state, pasid_state, tag);581581+ goto out_drop_state;582582+ }583583+584584+ fault->dev_state = dev_state;585585+ fault->address = iommu_fault->address;586586+ fault->state = pasid_state;587587+ fault->tag = tag;588588+ fault->finish = finish;589589+ fault->flags = iommu_fault->flags;590590+ INIT_WORK(&fault->work, do_fault);591591+592592+ queue_work(iommu_wq, &fault->work);593593+594594+ ret = NOTIFY_OK;595595+596596+out_drop_state:597597+ put_device_state(dev_state);598598+599599+out:600600+ return ret;601601+}602602+603603+static struct notifier_block ppr_nb = {604604+ .notifier_call = ppr_notifier,605605+};606606+607607+static int task_exit(struct notifier_block *nb, unsigned long e, void *data)608608+{609609+ struct pasid_state *pasid_state;610610+ struct task_struct *task;611611+612612+ task = data;613613+614614+ /*615615+ * Using this notifier is a hack - but there is no other choice616616+ * at the moment. What I really want is a sleeping notifier that617617+ * is called when an MM goes down. But such a notifier doesn't618618+ * exist yet. The notifier needs to sleep because it has to make619619+ * sure that the device does not use the PASID and the address620620+ * space anymore before it is destroyed. This includes waiting621621+ * for pending PRI requests to pass the workqueue. The622622+ * MMU-Notifiers would be a good fit, but they use RCU and so623623+ * they are not allowed to sleep. Lets see how we can solve this624624+ * in a more intelligent way in the future.625625+ */626626+again:627627+ spin_lock(&ps_lock);628628+ list_for_each_entry(pasid_state, &pasid_state_list, list) {629629+ struct device_state *dev_state;630630+ int pasid;631631+632632+ if (pasid_state->task != task)633633+ continue;634634+635635+ /* Drop Lock and unbind */636636+ spin_unlock(&ps_lock);637637+638638+ dev_state = pasid_state->device_state;639639+ pasid = pasid_state->pasid;640640+641641+ if (pasid_state->device_state->inv_ctx_cb)642642+ dev_state->inv_ctx_cb(dev_state->pdev, pasid);643643+644644+ unbind_pasid(dev_state, pasid);645645+646646+ /* Task may be in the list multiple times */647647+ goto again;648648+ }649649+ spin_unlock(&ps_lock);650650+651651+ return NOTIFY_OK;652652+}653653+654654+int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid,655655+ struct task_struct *task)656656+{657657+ struct pasid_state *pasid_state;658658+ struct device_state *dev_state;659659+ u16 devid;660660+ int ret;661661+662662+ might_sleep();663663+664664+ if (!amd_iommu_v2_supported())665665+ return -ENODEV;666666+667667+ devid = device_id(pdev);668668+ dev_state = get_device_state(devid);669669+670670+ if (dev_state == NULL)671671+ return -EINVAL;672672+673673+ ret = -EINVAL;674674+ if (pasid < 0 || pasid >= dev_state->max_pasids)675675+ goto out;676676+677677+ ret = -ENOMEM;678678+ pasid_state = kzalloc(sizeof(*pasid_state), GFP_KERNEL);679679+ if (pasid_state == NULL)680680+ goto out;681681+682682+ atomic_set(&pasid_state->count, 1);683683+ init_waitqueue_head(&pasid_state->wq);684684+ pasid_state->task = task;685685+ pasid_state->mm = get_task_mm(task);686686+ pasid_state->device_state = dev_state;687687+ pasid_state->pasid = pasid;688688+ pasid_state->mn.ops = &iommu_mn;689689+690690+ if (pasid_state->mm == NULL)691691+ goto out_free;692692+693693+ mmu_notifier_register(&pasid_state->mn, pasid_state->mm);694694+695695+ ret = set_pasid_state(dev_state, pasid_state, pasid);696696+ if (ret)697697+ goto out_unregister;698698+699699+ ret = amd_iommu_domain_set_gcr3(dev_state->domain, pasid,700700+ __pa(pasid_state->mm->pgd));701701+ if (ret)702702+ goto out_clear_state;703703+704704+ link_pasid_state(pasid_state);705705+706706+ return 0;707707+708708+out_clear_state:709709+ clear_pasid_state(dev_state, pasid);710710+711711+out_unregister:712712+ mmu_notifier_unregister(&pasid_state->mn, pasid_state->mm);713713+714714+out_free:715715+ free_pasid_state(pasid_state);716716+717717+out:718718+ put_device_state(dev_state);719719+720720+ return ret;721721+}722722+EXPORT_SYMBOL(amd_iommu_bind_pasid);723723+724724+void amd_iommu_unbind_pasid(struct pci_dev *pdev, int pasid)725725+{726726+ struct device_state *dev_state;727727+ u16 devid;728728+729729+ might_sleep();730730+731731+ if (!amd_iommu_v2_supported())732732+ return;733733+734734+ devid = device_id(pdev);735735+ dev_state = get_device_state(devid);736736+ if (dev_state == NULL)737737+ return;738738+739739+ if (pasid < 0 || pasid >= dev_state->max_pasids)740740+ goto out;741741+742742+ unbind_pasid(dev_state, pasid);743743+744744+out:745745+ put_device_state(dev_state);746746+}747747+EXPORT_SYMBOL(amd_iommu_unbind_pasid);748748+749749+int amd_iommu_init_device(struct pci_dev *pdev, int pasids)750750+{751751+ struct device_state *dev_state;752752+ unsigned long flags;753753+ int ret, tmp;754754+ u16 devid;755755+756756+ might_sleep();757757+758758+ if (!amd_iommu_v2_supported())759759+ return -ENODEV;760760+761761+ if (pasids <= 0 || pasids > (PASID_MASK + 1))762762+ return -EINVAL;763763+764764+ devid = device_id(pdev);765765+766766+ dev_state = kzalloc(sizeof(*dev_state), GFP_KERNEL);767767+ if (dev_state == NULL)768768+ return -ENOMEM;769769+770770+ spin_lock_init(&dev_state->lock);771771+ init_waitqueue_head(&dev_state->wq);772772+ dev_state->pdev = pdev;773773+774774+ tmp = pasids;775775+ for (dev_state->pasid_levels = 0; (tmp - 1) & ~0x1ff; tmp >>= 9)776776+ dev_state->pasid_levels += 1;777777+778778+ atomic_set(&dev_state->count, 1);779779+ dev_state->max_pasids = pasids;780780+781781+ ret = -ENOMEM;782782+ dev_state->states = (void *)get_zeroed_page(GFP_KERNEL);783783+ if (dev_state->states == NULL)784784+ goto out_free_dev_state;785785+786786+ dev_state->domain = iommu_domain_alloc(&pci_bus_type);787787+ if (dev_state->domain == NULL)788788+ goto out_free_states;789789+790790+ amd_iommu_domain_direct_map(dev_state->domain);791791+792792+ ret = amd_iommu_domain_enable_v2(dev_state->domain, pasids);793793+ if (ret)794794+ goto out_free_domain;795795+796796+ ret = iommu_attach_device(dev_state->domain, &pdev->dev);797797+ if (ret != 0)798798+ goto out_free_domain;799799+800800+ spin_lock_irqsave(&state_lock, flags);801801+802802+ if (state_table[devid] != NULL) {803803+ spin_unlock_irqrestore(&state_lock, flags);804804+ ret = -EBUSY;805805+ goto out_free_domain;806806+ }807807+808808+ state_table[devid] = dev_state;809809+810810+ spin_unlock_irqrestore(&state_lock, flags);811811+812812+ return 0;813813+814814+out_free_domain:815815+ iommu_domain_free(dev_state->domain);816816+817817+out_free_states:818818+ free_page((unsigned long)dev_state->states);819819+820820+out_free_dev_state:821821+ kfree(dev_state);822822+823823+ return ret;824824+}825825+EXPORT_SYMBOL(amd_iommu_init_device);826826+827827+void amd_iommu_free_device(struct pci_dev *pdev)828828+{829829+ struct device_state *dev_state;830830+ unsigned long flags;831831+ u16 devid;832832+833833+ if (!amd_iommu_v2_supported())834834+ return;835835+836836+ devid = device_id(pdev);837837+838838+ spin_lock_irqsave(&state_lock, flags);839839+840840+ dev_state = state_table[devid];841841+ if (dev_state == NULL) {842842+ spin_unlock_irqrestore(&state_lock, flags);843843+ return;844844+ }845845+846846+ state_table[devid] = NULL;847847+848848+ spin_unlock_irqrestore(&state_lock, flags);849849+850850+ /* Get rid of any remaining pasid states */851851+ free_pasid_states(dev_state);852852+853853+ put_device_state_wait(dev_state);854854+}855855+EXPORT_SYMBOL(amd_iommu_free_device);856856+857857+int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev,858858+ amd_iommu_invalid_ppr_cb cb)859859+{860860+ struct device_state *dev_state;861861+ unsigned long flags;862862+ u16 devid;863863+ int ret;864864+865865+ if (!amd_iommu_v2_supported())866866+ return -ENODEV;867867+868868+ devid = device_id(pdev);869869+870870+ spin_lock_irqsave(&state_lock, flags);871871+872872+ ret = -EINVAL;873873+ dev_state = state_table[devid];874874+ if (dev_state == NULL)875875+ goto out_unlock;876876+877877+ dev_state->inv_ppr_cb = cb;878878+879879+ ret = 0;880880+881881+out_unlock:882882+ spin_unlock_irqrestore(&state_lock, flags);883883+884884+ return ret;885885+}886886+EXPORT_SYMBOL(amd_iommu_set_invalid_ppr_cb);887887+888888+int amd_iommu_set_invalidate_ctx_cb(struct pci_dev *pdev,889889+ amd_iommu_invalidate_ctx cb)890890+{891891+ struct device_state *dev_state;892892+ unsigned long flags;893893+ u16 devid;894894+ int ret;895895+896896+ if (!amd_iommu_v2_supported())897897+ return -ENODEV;898898+899899+ devid = device_id(pdev);900900+901901+ spin_lock_irqsave(&state_lock, flags);902902+903903+ ret = -EINVAL;904904+ dev_state = state_table[devid];905905+ if (dev_state == NULL)906906+ goto out_unlock;907907+908908+ dev_state->inv_ctx_cb = cb;909909+910910+ ret = 0;911911+912912+out_unlock:913913+ spin_unlock_irqrestore(&state_lock, flags);914914+915915+ return ret;916916+}917917+EXPORT_SYMBOL(amd_iommu_set_invalidate_ctx_cb);918918+919919+static int __init amd_iommu_v2_init(void)920920+{921921+ size_t state_table_size;922922+ int ret;923923+924924+ pr_info("AMD IOMMUv2 driver by Joerg Roedel <joerg.roedel@amd.com>");925925+926926+ spin_lock_init(&state_lock);927927+928928+ state_table_size = MAX_DEVICES * sizeof(struct device_state *);929929+ state_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,930930+ get_order(state_table_size));931931+ if (state_table == NULL)932932+ return -ENOMEM;933933+934934+ ret = -ENOMEM;935935+ iommu_wq = create_workqueue("amd_iommu_v2");936936+ if (iommu_wq == NULL)937937+ goto out_free;938938+939939+ ret = -ENOMEM;940940+ empty_page_table = (u64 *)get_zeroed_page(GFP_KERNEL);941941+ if (empty_page_table == NULL)942942+ goto out_destroy_wq;943943+944944+ amd_iommu_register_ppr_notifier(&ppr_nb);945945+ profile_event_register(PROFILE_TASK_EXIT, &profile_nb);946946+947947+ return 0;948948+949949+out_destroy_wq:950950+ destroy_workqueue(iommu_wq);951951+952952+out_free:953953+ free_pages((unsigned long)state_table, get_order(state_table_size));954954+955955+ return ret;956956+}957957+958958+static void __exit amd_iommu_v2_exit(void)959959+{960960+ struct device_state *dev_state;961961+ size_t state_table_size;962962+ int i;963963+964964+ profile_event_unregister(PROFILE_TASK_EXIT, &profile_nb);965965+ amd_iommu_unregister_ppr_notifier(&ppr_nb);966966+967967+ flush_workqueue(iommu_wq);968968+969969+ /*970970+ * The loop below might call flush_workqueue(), so call971971+ * destroy_workqueue() after it972972+ */973973+ for (i = 0; i < MAX_DEVICES; ++i) {974974+ dev_state = get_device_state(i);975975+976976+ if (dev_state == NULL)977977+ continue;978978+979979+ WARN_ON_ONCE(1);980980+981981+ put_device_state(dev_state);982982+ amd_iommu_free_device(dev_state->pdev);983983+ }984984+985985+ destroy_workqueue(iommu_wq);986986+987987+ state_table_size = MAX_DEVICES * sizeof(struct device_state *);988988+ free_pages((unsigned long)state_table, get_order(state_table_size));989989+990990+ free_page((unsigned long)empty_page_table);991991+}992992+993993+module_init(amd_iommu_v2_init);994994+module_exit(amd_iommu_v2_exit);
+23-7
drivers/iommu/intel-iommu.c
···7878#define LEVEL_STRIDE (9)7979#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)80808181+/*8282+ * This bitmap is used to advertise the page sizes our hardware support8383+ * to the IOMMU core, which will then use this information to split8484+ * physically contiguous memory regions it is mapping into page sizes8585+ * that we support.8686+ *8787+ * Traditionally the IOMMU core just handed us the mappings directly,8888+ * after making sure the size is an order of a 4KiB page and that the8989+ * mapping has natural alignment.9090+ *9191+ * To retain this behavior, we currently advertise that we support9292+ * all page sizes that are an order of 4KiB.9393+ *9494+ * If at some point we'd like to utilize the IOMMU core's new behavior,9595+ * we could change this to advertise the real page sizes we support.9696+ */9797+#define INTEL_IOMMU_PGSIZES (~0xFFFUL)9898+8199static inline int agaw_to_level(int agaw)82100{83101 return agaw + 2;···4002398440033985static int intel_iommu_map(struct iommu_domain *domain,40043986 unsigned long iova, phys_addr_t hpa,40054005- int gfp_order, int iommu_prot)39873987+ size_t size, int iommu_prot)40063988{40073989 struct dmar_domain *dmar_domain = domain->priv;40083990 u64 max_addr;40093991 int prot = 0;40104010- size_t size;40113992 int ret;4012399340133994 if (iommu_prot & IOMMU_READ)···40163999 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)40174000 prot |= DMA_PTE_SNP;4018400140194019- size = PAGE_SIZE << gfp_order;40204002 max_addr = iova + size;40214003 if (dmar_domain->max_addr < max_addr) {40224004 u64 end;···40384022 return ret;40394023}4040402440414041-static int intel_iommu_unmap(struct iommu_domain *domain,40424042- unsigned long iova, int gfp_order)40254025+static size_t intel_iommu_unmap(struct iommu_domain *domain,40264026+ unsigned long iova, size_t size)40434027{40444028 struct dmar_domain *dmar_domain = domain->priv;40454045- size_t size = PAGE_SIZE << gfp_order;40464029 int order;4047403040484031 order = dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,···40504035 if (dmar_domain->max_addr == iova + size)40514036 dmar_domain->max_addr = iova;4052403740534053- return order;40384038+ return PAGE_SIZE << order;40544039}4055404040564041static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,···40894074 .unmap = intel_iommu_unmap,40904075 .iova_to_phys = intel_iommu_iova_to_phys,40914076 .domain_has_cap = intel_iommu_domain_has_cap,40774077+ .pgsize_bitmap = INTEL_IOMMU_PGSIZES,40924078};4093407940944080static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
+105-10
drivers/iommu/iommu.c
···1616 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA1717 */18181919+#define pr_fmt(fmt) "%s: " fmt, __func__2020+1921#include <linux/device.h>2022#include <linux/kernel.h>2123#include <linux/bug.h>···159157EXPORT_SYMBOL_GPL(iommu_domain_has_cap);160158161159int iommu_map(struct iommu_domain *domain, unsigned long iova,162162- phys_addr_t paddr, int gfp_order, int prot)160160+ phys_addr_t paddr, size_t size, int prot)163161{164164- size_t size;162162+ unsigned long orig_iova = iova;163163+ unsigned int min_pagesz;164164+ size_t orig_size = size;165165+ int ret = 0;165166166167 if (unlikely(domain->ops->map == NULL))167168 return -ENODEV;168169169169- size = PAGE_SIZE << gfp_order;170170+ /* find out the minimum page size supported */171171+ min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);170172171171- BUG_ON(!IS_ALIGNED(iova | paddr, size));173173+ /*174174+ * both the virtual address and the physical one, as well as175175+ * the size of the mapping, must be aligned (at least) to the176176+ * size of the smallest page supported by the hardware177177+ */178178+ if (!IS_ALIGNED(iova | paddr | size, min_pagesz)) {179179+ pr_err("unaligned: iova 0x%lx pa 0x%lx size 0x%lx min_pagesz "180180+ "0x%x\n", iova, (unsigned long)paddr,181181+ (unsigned long)size, min_pagesz);182182+ return -EINVAL;183183+ }172184173173- return domain->ops->map(domain, iova, paddr, gfp_order, prot);185185+ pr_debug("map: iova 0x%lx pa 0x%lx size 0x%lx\n", iova,186186+ (unsigned long)paddr, (unsigned long)size);187187+188188+ while (size) {189189+ unsigned long pgsize, addr_merge = iova | paddr;190190+ unsigned int pgsize_idx;191191+192192+ /* Max page size that still fits into 'size' */193193+ pgsize_idx = __fls(size);194194+195195+ /* need to consider alignment requirements ? */196196+ if (likely(addr_merge)) {197197+ /* Max page size allowed by both iova and paddr */198198+ unsigned int align_pgsize_idx = __ffs(addr_merge);199199+200200+ pgsize_idx = min(pgsize_idx, align_pgsize_idx);201201+ }202202+203203+ /* build a mask of acceptable page sizes */204204+ pgsize = (1UL << (pgsize_idx + 1)) - 1;205205+206206+ /* throw away page sizes not supported by the hardware */207207+ pgsize &= domain->ops->pgsize_bitmap;208208+209209+ /* make sure we're still sane */210210+ BUG_ON(!pgsize);211211+212212+ /* pick the biggest page */213213+ pgsize_idx = __fls(pgsize);214214+ pgsize = 1UL << pgsize_idx;215215+216216+ pr_debug("mapping: iova 0x%lx pa 0x%lx pgsize %lu\n", iova,217217+ (unsigned long)paddr, pgsize);218218+219219+ ret = domain->ops->map(domain, iova, paddr, pgsize, prot);220220+ if (ret)221221+ break;222222+223223+ iova += pgsize;224224+ paddr += pgsize;225225+ size -= pgsize;226226+ }227227+228228+ /* unroll mapping in case something went wrong */229229+ if (ret)230230+ iommu_unmap(domain, orig_iova, orig_size - size);231231+232232+ return ret;174233}175234EXPORT_SYMBOL_GPL(iommu_map);176235177177-int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order)236236+size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)178237{179179- size_t size;238238+ size_t unmapped_page, unmapped = 0;239239+ unsigned int min_pagesz;180240181241 if (unlikely(domain->ops->unmap == NULL))182242 return -ENODEV;183243184184- size = PAGE_SIZE << gfp_order;244244+ /* find out the minimum page size supported */245245+ min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);185246186186- BUG_ON(!IS_ALIGNED(iova, size));247247+ /*248248+ * The virtual address, as well as the size of the mapping, must be249249+ * aligned (at least) to the size of the smallest page supported250250+ * by the hardware251251+ */252252+ if (!IS_ALIGNED(iova | size, min_pagesz)) {253253+ pr_err("unaligned: iova 0x%lx size 0x%lx min_pagesz 0x%x\n",254254+ iova, (unsigned long)size, min_pagesz);255255+ return -EINVAL;256256+ }187257188188- return domain->ops->unmap(domain, iova, gfp_order);258258+ pr_debug("unmap this: iova 0x%lx size 0x%lx\n", iova,259259+ (unsigned long)size);260260+261261+ /*262262+ * Keep iterating until we either unmap 'size' bytes (or more)263263+ * or we hit an area that isn't mapped.264264+ */265265+ while (unmapped < size) {266266+ size_t left = size - unmapped;267267+268268+ unmapped_page = domain->ops->unmap(domain, iova, left);269269+ if (!unmapped_page)270270+ break;271271+272272+ pr_debug("unmapped: iova 0x%lx size %lx\n", iova,273273+ (unsigned long)unmapped_page);274274+275275+ iova += unmapped_page;276276+ unmapped += unmapped_page;277277+ }278278+279279+ return unmapped;189280}190281EXPORT_SYMBOL_GPL(iommu_unmap);
+12-13
drivers/iommu/msm_iommu.c
···4242#define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0)4343#define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1)44444545+/* bitmap of the page sizes currently supported */4646+#define MSM_IOMMU_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M)4747+4548static int msm_iommu_tex_class[4];46494750DEFINE_SPINLOCK(msm_iommu_lock);···355352}356353357354static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,358358- phys_addr_t pa, int order, int prot)355355+ phys_addr_t pa, size_t len, int prot)359356{360357 struct msm_priv *priv;361358 unsigned long flags;···366363 unsigned long *sl_pte;367364 unsigned long sl_offset;368365 unsigned int pgprot;369369- size_t len = 0x1000UL << order;370366 int ret = 0, tex, sh;371367372368 spin_lock_irqsave(&msm_iommu_lock, flags);···465463 return ret;466464}467465468468-static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,469469- int order)466466+static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,467467+ size_t len)470468{471469 struct msm_priv *priv;472470 unsigned long flags;···476474 unsigned long *sl_table;477475 unsigned long *sl_pte;478476 unsigned long sl_offset;479479- size_t len = 0x1000UL << order;480477 int i, ret = 0;481478482479 spin_lock_irqsave(&msm_iommu_lock, flags);···545544546545 ret = __flush_iotlb(domain);547546548548- /*549549- * the IOMMU API requires us to return the order of the unmapped550550- * page (on success).551551- */552552- if (!ret)553553- ret = order;554547fail:555548 spin_unlock_irqrestore(&msm_iommu_lock, flags);556556- return ret;549549+550550+ /* the IOMMU API requires us to return how many bytes were unmapped */551551+ len = ret ? 0 : len;552552+ return len;557553}558554559555static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,···682684 .map = msm_iommu_map,683685 .unmap = msm_iommu_unmap,684686 .iova_to_phys = msm_iommu_iova_to_phys,685685- .domain_has_cap = msm_iommu_domain_has_cap687687+ .domain_has_cap = msm_iommu_domain_has_cap,688688+ .pgsize_bitmap = MSM_IOMMU_PGSIZES,686689};687690688691static int __init get_tex_class(int icp, int ocp, int mt, int nos)
+37-43
drivers/iommu/omap-iommu.c
···3333 (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \3434 __i++)35353636+/* bitmap of the page sizes currently supported */3737+#define OMAP_IOMMU_PGSIZES (SZ_4K | SZ_64K | SZ_1M | SZ_16M)3838+3639/**3740 * struct omap_iommu_domain - omap iommu domain3841 * @pgtable: the page table···89869087/**9188 * omap_iommu_save_ctx - Save registers for pm off-mode support9292- * @obj: target iommu8989+ * @dev: client device9390 **/9494-void omap_iommu_save_ctx(struct omap_iommu *obj)9191+void omap_iommu_save_ctx(struct device *dev)9592{9393+ struct omap_iommu *obj = dev_to_omap_iommu(dev);9494+9695 arch_iommu->save_ctx(obj);9796}9897EXPORT_SYMBOL_GPL(omap_iommu_save_ctx);999810099/**101100 * omap_iommu_restore_ctx - Restore registers for pm off-mode support102102- * @obj: target iommu101101+ * @dev: client device103102 **/104104-void omap_iommu_restore_ctx(struct omap_iommu *obj)103103+void omap_iommu_restore_ctx(struct device *dev)105104{105105+ struct omap_iommu *obj = dev_to_omap_iommu(dev);106106+106107 arch_iommu->restore_ctx(obj);107108}108109EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx);···827820}828821829822/**830830- * omap_find_iommu_device() - find an omap iommu device by name831831- * @name: name of the iommu device832832- *833833- * The generic iommu API requires the caller to provide the device834834- * he wishes to attach to a certain iommu domain.835835- *836836- * Drivers generally should not bother with this as it should just837837- * be taken care of by the DMA-API using dev_archdata.838838- *839839- * This function is provided as an interim solution until the latter840840- * materializes, and omap3isp is fully migrated to the DMA-API.841841- */842842-struct device *omap_find_iommu_device(const char *name)843843-{844844- return driver_find_device(&omap_iommu_driver.driver, NULL,845845- (void *)name,846846- device_match_by_alias);847847-}848848-EXPORT_SYMBOL_GPL(omap_find_iommu_device);849849-850850-/**851823 * omap_iommu_attach() - attach iommu device to an iommu domain852852- * @dev: target omap iommu device824824+ * @name: name of target omap iommu device853825 * @iopgd: page table854826 **/855855-static struct omap_iommu *omap_iommu_attach(struct device *dev, u32 *iopgd)827827+static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd)856828{857829 int err = -ENOMEM;858858- struct omap_iommu *obj = to_iommu(dev);830830+ struct device *dev;831831+ struct omap_iommu *obj;832832+833833+ dev = driver_find_device(&omap_iommu_driver.driver, NULL,834834+ (void *)name,835835+ device_match_by_alias);836836+ if (!dev)837837+ return NULL;838838+839839+ obj = to_iommu(dev);859840860841 spin_lock(&obj->iommu_lock);861842···10141019}1015102010161021static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,10171017- phys_addr_t pa, int order, int prot)10221022+ phys_addr_t pa, size_t bytes, int prot)10181023{10191024 struct omap_iommu_domain *omap_domain = domain->priv;10201025 struct omap_iommu *oiommu = omap_domain->iommu_dev;10211026 struct device *dev = oiommu->dev;10221022- size_t bytes = PAGE_SIZE << order;10231027 struct iotlb_entry e;10241028 int omap_pgsz;10251029 u32 ret, flags;···10431049 return ret;10441050}1045105110461046-static int omap_iommu_unmap(struct iommu_domain *domain, unsigned long da,10471047- int order)10521052+static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da,10531053+ size_t size)10481054{10491055 struct omap_iommu_domain *omap_domain = domain->priv;10501056 struct omap_iommu *oiommu = omap_domain->iommu_dev;10511057 struct device *dev = oiommu->dev;10521052- size_t unmap_size;1053105810541054- dev_dbg(dev, "unmapping da 0x%lx order %d\n", da, order);10591059+ dev_dbg(dev, "unmapping da 0x%lx size %u\n", da, size);1055106010561056- unmap_size = iopgtable_clear_entry(oiommu, da);10571057-10581058- return unmap_size ? get_order(unmap_size) : -EINVAL;10611061+ return iopgtable_clear_entry(oiommu, da);10591062}1060106310611064static int···10601069{10611070 struct omap_iommu_domain *omap_domain = domain->priv;10621071 struct omap_iommu *oiommu;10721072+ struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;10631073 int ret = 0;1064107410651075 spin_lock(&omap_domain->lock);···10731081 }1074108210751083 /* get a handle to and enable the omap iommu */10761076- oiommu = omap_iommu_attach(dev, omap_domain->pgtable);10841084+ oiommu = omap_iommu_attach(arch_data->name, omap_domain->pgtable);10771085 if (IS_ERR(oiommu)) {10781086 ret = PTR_ERR(oiommu);10791087 dev_err(dev, "can't get omap iommu: %d\n", ret);10801088 goto out;10811089 }1082109010831083- omap_domain->iommu_dev = oiommu;10911091+ omap_domain->iommu_dev = arch_data->iommu_dev = oiommu;10841092 oiommu->domain = domain;1085109310861094out:···10921100 struct device *dev)10931101{10941102 struct omap_iommu_domain *omap_domain = domain->priv;10951095- struct omap_iommu *oiommu = to_iommu(dev);11031103+ struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;11041104+ struct omap_iommu *oiommu = dev_to_omap_iommu(dev);1096110510971106 spin_lock(&omap_domain->lock);10981107···1107111411081115 omap_iommu_detach(oiommu);1109111611101110- omap_domain->iommu_dev = NULL;11171117+ omap_domain->iommu_dev = arch_data->iommu_dev = NULL;1111111811121119out:11131120 spin_unlock(&omap_domain->lock);···11761183 else if (iopte_is_large(*pte))11771184 ret = omap_iommu_translate(*pte, da, IOLARGE_MASK);11781185 else11791179- dev_err(dev, "bogus pte 0x%x", *pte);11861186+ dev_err(dev, "bogus pte 0x%x, da 0x%lx", *pte, da);11801187 } else {11811188 if (iopgd_is_section(*pgd))11821189 ret = omap_iommu_translate(*pgd, da, IOSECTION_MASK);11831190 else if (iopgd_is_super(*pgd))11841191 ret = omap_iommu_translate(*pgd, da, IOSUPER_MASK);11851192 else11861186- dev_err(dev, "bogus pgd 0x%x", *pgd);11931193+ dev_err(dev, "bogus pgd 0x%x, da 0x%lx", *pgd, da);11871194 }1188119511891196 return ret;···12041211 .unmap = omap_iommu_unmap,12051212 .iova_to_phys = omap_iommu_iova_to_phys,12061213 .domain_has_cap = omap_iommu_domain_has_cap,12141214+ .pgsize_bitmap = OMAP_IOMMU_PGSIZES,12071215};1208121612091217static int __init omap_iommu_init(void)
+26-22
drivers/iommu/omap-iovmm.c
···231231232232/**233233 * omap_find_iovm_area - find iovma which includes @da234234+ * @dev: client device234235 * @da: iommu device virtual address235236 *236237 * Find the existing iovma starting at @da237238 */238238-struct iovm_struct *omap_find_iovm_area(struct omap_iommu *obj, u32 da)239239+struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da)239240{241241+ struct omap_iommu *obj = dev_to_omap_iommu(dev);240242 struct iovm_struct *area;241243242244 mutex_lock(&obj->mmap_lock);···345343346344/**347345 * omap_da_to_va - convert (d) to (v)348348- * @obj: objective iommu346346+ * @dev: client device349347 * @da: iommu device virtual address350348 * @va: mpu virtual address351349 *352350 * Returns mpu virtual addr which corresponds to a given device virtual addr353351 */354354-void *omap_da_to_va(struct omap_iommu *obj, u32 da)352352+void *omap_da_to_va(struct device *dev, u32 da)355353{354354+ struct omap_iommu *obj = dev_to_omap_iommu(dev);356355 void *va = NULL;357356 struct iovm_struct *area;358357···413410 unsigned int i, j;414411 struct scatterlist *sg;415412 u32 da = new->da_start;416416- int order;417413418414 if (!domain || !sgt)419415 return -EINVAL;···431429 if (bytes_to_iopgsz(bytes) < 0)432430 goto err_out;433431434434- order = get_order(bytes);435435-436432 pr_debug("%s: [%d] %08x %08x(%x)\n", __func__,437433 i, da, pa, bytes);438434439439- err = iommu_map(domain, da, pa, order, flags);435435+ err = iommu_map(domain, da, pa, bytes, flags);440436 if (err)441437 goto err_out;442438···449449 size_t bytes;450450451451 bytes = sg->length + sg->offset;452452- order = get_order(bytes);453452454453 /* ignore failures.. we're already handling one */455455- iommu_unmap(domain, da, order);454454+ iommu_unmap(domain, da, bytes);456455457456 da += bytes;458457 }···466467 size_t total = area->da_end - area->da_start;467468 const struct sg_table *sgt = area->sgt;468469 struct scatterlist *sg;469469- int i, err;470470+ int i;471471+ size_t unmapped;470472471473 BUG_ON(!sgtable_ok(sgt));472474 BUG_ON((!total) || !IS_ALIGNED(total, PAGE_SIZE));···475475 start = area->da_start;476476 for_each_sg(sgt->sgl, sg, sgt->nents, i) {477477 size_t bytes;478478- int order;479478480479 bytes = sg->length + sg->offset;481481- order = get_order(bytes);482480483483- err = iommu_unmap(domain, start, order);484484- if (err < 0)481481+ unmapped = iommu_unmap(domain, start, bytes);482482+ if (unmapped < bytes)485483 break;486484487485 dev_dbg(obj->dev, "%s: unmap %08x(%x) %08x\n",···580582581583/**582584 * omap_iommu_vmap - (d)-(p)-(v) address mapper583583- * @obj: objective iommu585585+ * @domain: iommu domain586586+ * @dev: client device584587 * @sgt: address of scatter gather table585588 * @flags: iovma and page property586589 *587590 * Creates 1-n-1 mapping with given @sgt and returns @da.588591 * All @sgt element must be io page size aligned.589592 */590590-u32 omap_iommu_vmap(struct iommu_domain *domain, struct omap_iommu *obj, u32 da,593593+u32 omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da,591594 const struct sg_table *sgt, u32 flags)592595{596596+ struct omap_iommu *obj = dev_to_omap_iommu(dev);593597 size_t bytes;594598 void *va = NULL;595599···622622623623/**624624 * omap_iommu_vunmap - release virtual mapping obtained by 'omap_iommu_vmap()'625625- * @obj: objective iommu625625+ * @domain: iommu domain626626+ * @dev: client device626627 * @da: iommu device virtual address627628 *628629 * Free the iommu virtually contiguous memory area starting at629630 * @da, which was returned by 'omap_iommu_vmap()'.630631 */631632struct sg_table *632632-omap_iommu_vunmap(struct iommu_domain *domain, struct omap_iommu *obj, u32 da)633633+omap_iommu_vunmap(struct iommu_domain *domain, struct device *dev, u32 da)633634{635635+ struct omap_iommu *obj = dev_to_omap_iommu(dev);634636 struct sg_table *sgt;635637 /*636638 * 'sgt' is allocated before 'omap_iommu_vmalloc()' is called.···649647650648/**651649 * omap_iommu_vmalloc - (d)-(p)-(v) address allocator and mapper652652- * @obj: objective iommu650650+ * @dev: client device653651 * @da: contiguous iommu virtual memory654652 * @bytes: allocation size655653 * @flags: iovma and page property···658656 * @da again, which might be adjusted if 'IOVMF_DA_FIXED' is not set.659657 */660658u32661661-omap_iommu_vmalloc(struct iommu_domain *domain, struct omap_iommu *obj, u32 da,659659+omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev, u32 da,662660 size_t bytes, u32 flags)663661{662662+ struct omap_iommu *obj = dev_to_omap_iommu(dev);664663 void *va;665664 struct sg_table *sgt;666665···701698702699/**703700 * omap_iommu_vfree - release memory allocated by 'omap_iommu_vmalloc()'704704- * @obj: objective iommu701701+ * @dev: client device705702 * @da: iommu device virtual address706703 *707704 * Frees the iommu virtually continuous memory area starting at708705 * @da, as obtained from 'omap_iommu_vmalloc()'.709706 */710710-void omap_iommu_vfree(struct iommu_domain *domain, struct omap_iommu *obj,707707+void omap_iommu_vfree(struct iommu_domain *domain, struct device *dev,711708 const u32 da)712709{710710+ struct omap_iommu *obj = dev_to_omap_iommu(dev);713711 struct sg_table *sgt;714712715713 sgt = unmap_vm_area(domain, obj, da, vfree,
+5-25
drivers/media/video/omap3isp/isp.c
···8080#include "isph3a.h"8181#include "isphist.h"82828383-/*8484- * this is provided as an interim solution until omap3isp doesn't need8585- * any omap-specific iommu API8686- */8787-#define to_iommu(dev) \8888- (struct omap_iommu *)platform_get_drvdata(to_platform_device(dev))8989-9083static unsigned int autoidle;9184module_param(autoidle, int, 0444);9285MODULE_PARM_DESC(autoidle, "Enable OMAP3ISP AUTOIDLE support");···11071114static void isp_save_ctx(struct isp_device *isp)11081115{11091116 isp_save_context(isp, isp_reg_list);11101110- if (isp->iommu)11111111- omap_iommu_save_ctx(isp->iommu);11171117+ omap_iommu_save_ctx(isp->dev);11121118}1113111911141120/*···11201128static void isp_restore_ctx(struct isp_device *isp)11211129{11221130 isp_restore_context(isp, isp_reg_list);11231123- if (isp->iommu)11241124- omap_iommu_restore_ctx(isp->iommu);11311131+ omap_iommu_restore_ctx(isp->dev);11251132 omap3isp_ccdc_restore_context(isp);11261133 omap3isp_preview_restore_context(isp);11271134}···19741983 isp_cleanup_modules(isp);1975198419761985 omap3isp_get(isp);19771977- iommu_detach_device(isp->domain, isp->iommu_dev);19861986+ iommu_detach_device(isp->domain, &pdev->dev);19781987 iommu_domain_free(isp->domain);19791988 omap3isp_put(isp);19801989···21222131 }21232132 }2124213321252125- /* IOMMU */21262126- isp->iommu_dev = omap_find_iommu_device("isp");21272127- if (!isp->iommu_dev) {21282128- dev_err(isp->dev, "omap_find_iommu_device failed\n");21292129- ret = -ENODEV;21302130- goto error_isp;21312131- }21322132-21332133- /* to be removed once iommu migration is complete */21342134- isp->iommu = to_iommu(isp->iommu_dev);21352135-21362134 isp->domain = iommu_domain_alloc(pdev->dev.bus);21372135 if (!isp->domain) {21382136 dev_err(isp->dev, "can't alloc iommu domain\n");···21292149 goto error_isp;21302150 }2131215121322132- ret = iommu_attach_device(isp->domain, isp->iommu_dev);21522152+ ret = iommu_attach_device(isp->domain, &pdev->dev);21332153 if (ret) {21342154 dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret);21352155 goto free_domain;···21682188error_irq:21692189 free_irq(isp->irq_num, isp);21702190detach_dev:21712171- iommu_detach_device(isp->domain, isp->iommu_dev);21912191+ iommu_detach_device(isp->domain, &pdev->dev);21722192free_domain:21732193 iommu_domain_free(isp->domain);21742194error_isp:
-2
drivers/media/video/omap3isp/isp.h
···212212 unsigned int sbl_resources;213213 unsigned int subclk_resources;214214215215- struct omap_iommu *iommu;216215 struct iommu_domain *domain;217217- struct device *iommu_dev;218216219217 struct isp_platform_callback platform_cb;220218};
···323323 if (list_is_last(&entry->list, &dev->msi_list))324324 iounmap(entry->mask_base);325325 }326326+ kobject_del(&entry->kobj);327327+ kobject_put(&entry->kobj);326328 list_del(&entry->list);327329 kfree(entry);328330 }···405403}406404EXPORT_SYMBOL_GPL(pci_restore_msi_state);407405406406+407407+#define to_msi_attr(obj) container_of(obj, struct msi_attribute, attr)408408+#define to_msi_desc(obj) container_of(obj, struct msi_desc, kobj)409409+410410+struct msi_attribute {411411+ struct attribute attr;412412+ ssize_t (*show)(struct msi_desc *entry, struct msi_attribute *attr,413413+ char *buf);414414+ ssize_t (*store)(struct msi_desc *entry, struct msi_attribute *attr,415415+ const char *buf, size_t count);416416+};417417+418418+static ssize_t show_msi_mode(struct msi_desc *entry, struct msi_attribute *atr,419419+ char *buf)420420+{421421+ return sprintf(buf, "%s\n", entry->msi_attrib.is_msix ? "msix" : "msi");422422+}423423+424424+static ssize_t msi_irq_attr_show(struct kobject *kobj,425425+ struct attribute *attr, char *buf)426426+{427427+ struct msi_attribute *attribute = to_msi_attr(attr);428428+ struct msi_desc *entry = to_msi_desc(kobj);429429+430430+ if (!attribute->show)431431+ return -EIO;432432+433433+ return attribute->show(entry, attribute, buf);434434+}435435+436436+static const struct sysfs_ops msi_irq_sysfs_ops = {437437+ .show = msi_irq_attr_show,438438+};439439+440440+static struct msi_attribute mode_attribute =441441+ __ATTR(mode, S_IRUGO, show_msi_mode, NULL);442442+443443+444444+struct attribute *msi_irq_default_attrs[] = {445445+ &mode_attribute.attr,446446+ NULL447447+};448448+449449+void msi_kobj_release(struct kobject *kobj)450450+{451451+ struct msi_desc *entry = to_msi_desc(kobj);452452+453453+ pci_dev_put(entry->dev);454454+}455455+456456+static struct kobj_type msi_irq_ktype = {457457+ .release = msi_kobj_release,458458+ .sysfs_ops = &msi_irq_sysfs_ops,459459+ .default_attrs = msi_irq_default_attrs,460460+};461461+462462+static int populate_msi_sysfs(struct pci_dev *pdev)463463+{464464+ struct msi_desc *entry;465465+ struct kobject *kobj;466466+ int ret;467467+ int count = 0;468468+469469+ pdev->msi_kset = kset_create_and_add("msi_irqs", NULL, &pdev->dev.kobj);470470+ if (!pdev->msi_kset)471471+ return -ENOMEM;472472+473473+ list_for_each_entry(entry, &pdev->msi_list, list) {474474+ kobj = &entry->kobj;475475+ kobj->kset = pdev->msi_kset;476476+ pci_dev_get(pdev);477477+ ret = kobject_init_and_add(kobj, &msi_irq_ktype, NULL,478478+ "%u", entry->irq);479479+ if (ret)480480+ goto out_unroll;481481+482482+ count++;483483+ }484484+485485+ return 0;486486+487487+out_unroll:488488+ list_for_each_entry(entry, &pdev->msi_list, list) {489489+ if (!count)490490+ break;491491+ kobject_del(&entry->kobj);492492+ kobject_put(&entry->kobj);493493+ count--;494494+ }495495+ return ret;496496+}497497+408498/**409499 * msi_capability_init - configure device's MSI capability structure410500 * @dev: pointer to the pci_dev data structure of MSI device function···542448543449 /* Configure MSI capability structure */544450 ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);451451+ if (ret) {452452+ msi_mask_irq(entry, mask, ~mask);453453+ free_msi_irqs(dev);454454+ return ret;455455+ }456456+457457+ ret = populate_msi_sysfs(dev);545458 if (ret) {546459 msi_mask_irq(entry, mask, ~mask);547460 free_msi_irqs(dev);···674573 pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);675574676575 msix_program_entries(dev, entries);576576+577577+ ret = populate_msi_sysfs(dev);578578+ if (ret) {579579+ ret = 0;580580+ goto error;581581+ }677582678583 /* Set MSI-X enabled bits and unmask the function */679584 pci_intx_for_msi(dev, 0);···839732840733 pci_msi_shutdown(dev);841734 free_msi_irqs(dev);735735+ kset_unregister(dev->msi_kset);736736+ dev->msi_kset = NULL;842737}843738EXPORT_SYMBOL(pci_disable_msi);844739···939830940831 pci_msix_shutdown(dev);941832 free_msi_irqs(dev);833833+ kset_unregister(dev->msi_kset);834834+ dev->msi_kset = NULL;942835}943836EXPORT_SYMBOL(pci_disable_msix);944837···981870982871void pci_msi_init_pci_dev(struct pci_dev *dev)983872{873873+ int pos;984874 INIT_LIST_HEAD(&dev->msi_list);875875+876876+ /* Disable the msi hardware to avoid screaming interrupts877877+ * during boot. This is the power on reset default so878878+ * usually this should be a noop.879879+ */880880+ pos = pci_find_capability(dev, PCI_CAP_ID_MSI);881881+ if (pos)882882+ msi_set_enable(dev, pos, 0);883883+ msix_set_enable(dev, 0);985884}
+8-5
drivers/pci/pci-acpi.c
···4545{4646 struct pci_dev *pci_dev = context;47474848- if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) {4848+ if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev)4949+ return;5050+5151+ if (!pci_dev->pm_cap || !pci_dev->pme_support5252+ || pci_check_pme_status(pci_dev)) {4953 if (pci_dev->pme_poll)5054 pci_dev->pme_poll = false;51555256 pci_wakeup_event(pci_dev);5353- pci_check_pme_status(pci_dev);5457 pm_runtime_resume(&pci_dev->dev);5555- if (pci_dev->subordinate)5656- pci_pme_wakeup_bus(pci_dev->subordinate);5758 }5959+6060+ if (pci_dev->subordinate)6161+ pci_pme_wakeup_bus(pci_dev->subordinate);5862}59636064/**···399395400396 if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {401397 printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");402402- pcie_clear_aspm();403398 pcie_no_aspm();404399 }405400
+37-21
drivers/pci/pcie/aspm.c
···6868 struct aspm_latency acceptable[8];6969};70707171-static int aspm_disabled, aspm_force, aspm_clear_state;7171+static int aspm_disabled, aspm_force;7272static bool aspm_support_enabled = true;7373static DEFINE_MUTEX(aspm_lock);7474static LIST_HEAD(link_list);···500500 int pos;501501 u32 reg32;502502503503- if (aspm_clear_state)504504- return -EINVAL;505505-506503 /*507504 * Some functions in a slot might not all be PCIe functions,508505 * very strange. Disable ASPM for the whole slot···571574 pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)572575 return;573576574574- if (aspm_disabled && !aspm_clear_state)575575- return;576576-577577 /* VIA has a strange chipset, root port is under a bridge */578578 if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&579579 pdev->bus->self)···602608 * the BIOS's expectation, we'll do so once pci_enable_device() is603609 * called.604610 */605605- if (aspm_policy != POLICY_POWERSAVE || aspm_clear_state) {611611+ if (aspm_policy != POLICY_POWERSAVE) {606612 pcie_config_aspm_path(link);607613 pcie_set_clkpm(link, policy_to_clkpm_state(link));608614 }···643649 struct pci_dev *parent = pdev->bus->self;644650 struct pcie_link_state *link, *root, *parent_link;645651646646- if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||647647- !parent || !parent->link_state)652652+ if (!pci_is_pcie(pdev) || !parent || !parent->link_state)648653 return;649654 if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&650655 (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))···727734 * pci_disable_link_state - disable pci device's link state, so the link will728735 * never enter specific states729736 */730730-static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)737737+static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,738738+ bool force)731739{732740 struct pci_dev *parent = pdev->bus->self;733741 struct pcie_link_state *link;734742735735- if (aspm_disabled || !pci_is_pcie(pdev))743743+ if (aspm_disabled && !force)736744 return;745745+746746+ if (!pci_is_pcie(pdev))747747+ return;748748+737749 if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||738750 pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)739751 parent = pdev;···766768767769void pci_disable_link_state_locked(struct pci_dev *pdev, int state)768770{769769- __pci_disable_link_state(pdev, state, false);771771+ __pci_disable_link_state(pdev, state, false, false);770772}771773EXPORT_SYMBOL(pci_disable_link_state_locked);772774773775void pci_disable_link_state(struct pci_dev *pdev, int state)774776{775775- __pci_disable_link_state(pdev, state, true);777777+ __pci_disable_link_state(pdev, state, true, false);776778}777779EXPORT_SYMBOL(pci_disable_link_state);780780+781781+void pcie_clear_aspm(struct pci_bus *bus)782782+{783783+ struct pci_dev *child;784784+785785+ /*786786+ * Clear any ASPM setup that the firmware has carried out on this bus787787+ */788788+ list_for_each_entry(child, &bus->devices, bus_list) {789789+ __pci_disable_link_state(child, PCIE_LINK_STATE_L0S |790790+ PCIE_LINK_STATE_L1 |791791+ PCIE_LINK_STATE_CLKPM,792792+ false, true);793793+ }794794+}778795779796static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)780797{···948935static int __init pcie_aspm_disable(char *str)949936{950937 if (!strcmp(str, "off")) {938938+ aspm_policy = POLICY_DEFAULT;951939 aspm_disabled = 1;952940 aspm_support_enabled = false;953941 printk(KERN_INFO "PCIe ASPM is disabled\n");···961947962948__setup("pcie_aspm=", pcie_aspm_disable);963949964964-void pcie_clear_aspm(void)965965-{966966- if (!aspm_force)967967- aspm_clear_state = 1;968968-}969969-970950void pcie_no_aspm(void)971951{972972- if (!aspm_force)952952+ /*953953+ * Disabling ASPM is intended to prevent the kernel from modifying954954+ * existing hardware state, not to clear existing state. To that end:955955+ * (a) set policy to POLICY_DEFAULT in order to avoid changing state956956+ * (b) prevent userspace from changing policy957957+ */958958+ if (!aspm_force) {959959+ aspm_policy = POLICY_DEFAULT;973960 aspm_disabled = 1;961961+ }974962}975963976964/**
···2020#ifndef _ASM_X86_AMD_IOMMU_H2121#define _ASM_X86_AMD_IOMMU_H22222323-#include <linux/irqreturn.h>2323+#include <linux/types.h>24242525#ifdef CONFIG_AMD_IOMMU26262727+struct task_struct;2828+struct pci_dev;2929+2730extern int amd_iommu_detect(void);3131+3232+3333+/**3434+ * amd_iommu_enable_device_erratum() - Enable erratum workaround for device3535+ * in the IOMMUv2 driver3636+ * @pdev: The PCI device the workaround is necessary for3737+ * @erratum: The erratum workaround to enable3838+ *3939+ * The function needs to be called before amd_iommu_init_device().4040+ * Possible values for the erratum number are for now:4141+ * - AMD_PRI_DEV_ERRATUM_ENABLE_RESET - Reset PRI capability when PRI4242+ * is enabled4343+ * - AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE - Limit number of outstanding PRI4444+ * requests to one4545+ */4646+#define AMD_PRI_DEV_ERRATUM_ENABLE_RESET 04747+#define AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE 14848+4949+extern void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum);5050+5151+/**5252+ * amd_iommu_init_device() - Init device for use with IOMMUv2 driver5353+ * @pdev: The PCI device to initialize5454+ * @pasids: Number of PASIDs to support for this device5555+ *5656+ * This function does all setup for the device pdev so that it can be5757+ * used with IOMMUv2.5858+ * Returns 0 on success or negative value on error.5959+ */6060+extern int amd_iommu_init_device(struct pci_dev *pdev, int pasids);6161+6262+/**6363+ * amd_iommu_free_device() - Free all IOMMUv2 related device resources6464+ * and disable IOMMUv2 usage for this device6565+ * @pdev: The PCI device to disable IOMMUv2 usage for'6666+ */6767+extern void amd_iommu_free_device(struct pci_dev *pdev);6868+6969+/**7070+ * amd_iommu_bind_pasid() - Bind a given task to a PASID on a device7171+ * @pdev: The PCI device to bind the task to7272+ * @pasid: The PASID on the device the task should be bound to7373+ * @task: the task to bind7474+ *7575+ * The function returns 0 on success or a negative value on error.7676+ */7777+extern int amd_iommu_bind_pasid(struct pci_dev *pdev, int pasid,7878+ struct task_struct *task);7979+8080+/**8181+ * amd_iommu_unbind_pasid() - Unbind a PASID from its task on8282+ * a device8383+ * @pdev: The device of the PASID8484+ * @pasid: The PASID to unbind8585+ *8686+ * When this function returns the device is no longer using the PASID8787+ * and the PASID is no longer bound to its task.8888+ */8989+extern void amd_iommu_unbind_pasid(struct pci_dev *pdev, int pasid);9090+9191+/**9292+ * amd_iommu_set_invalid_ppr_cb() - Register a call-back for failed9393+ * PRI requests9494+ * @pdev: The PCI device the call-back should be registered for9595+ * @cb: The call-back function9696+ *9797+ * The IOMMUv2 driver invokes this call-back when it is unable to9898+ * successfully handle a PRI request. The device driver can then decide9999+ * which PRI response the device should see. Possible return values for100100+ * the call-back are:101101+ *102102+ * - AMD_IOMMU_INV_PRI_RSP_SUCCESS - Send SUCCESS back to the device103103+ * - AMD_IOMMU_INV_PRI_RSP_INVALID - Send INVALID back to the device104104+ * - AMD_IOMMU_INV_PRI_RSP_FAIL - Send Failure back to the device,105105+ * the device is required to disable106106+ * PRI when it receives this response107107+ *108108+ * The function returns 0 on success or negative value on error.109109+ */110110+#define AMD_IOMMU_INV_PRI_RSP_SUCCESS 0111111+#define AMD_IOMMU_INV_PRI_RSP_INVALID 1112112+#define AMD_IOMMU_INV_PRI_RSP_FAIL 2113113+114114+typedef int (*amd_iommu_invalid_ppr_cb)(struct pci_dev *pdev,115115+ int pasid,116116+ unsigned long address,117117+ u16);118118+119119+extern int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev,120120+ amd_iommu_invalid_ppr_cb cb);121121+122122+/**123123+ * amd_iommu_device_info() - Get information about IOMMUv2 support of a124124+ * PCI device125125+ * @pdev: PCI device to query information from126126+ * @info: A pointer to an amd_iommu_device_info structure which will contain127127+ * the information about the PCI device128128+ *129129+ * Returns 0 on success, negative value on error130130+ */131131+132132+#define AMD_IOMMU_DEVICE_FLAG_ATS_SUP 0x1 /* ATS feature supported */133133+#define AMD_IOMMU_DEVICE_FLAG_PRI_SUP 0x2 /* PRI feature supported */134134+#define AMD_IOMMU_DEVICE_FLAG_PASID_SUP 0x4 /* PASID context supported */135135+#define AMD_IOMMU_DEVICE_FLAG_EXEC_SUP 0x8 /* Device may request execution136136+ on memory pages */137137+#define AMD_IOMMU_DEVICE_FLAG_PRIV_SUP 0x10 /* Device may request138138+ super-user privileges */139139+140140+struct amd_iommu_device_info {141141+ int max_pasids;142142+ u32 flags;143143+};144144+145145+extern int amd_iommu_device_info(struct pci_dev *pdev,146146+ struct amd_iommu_device_info *info);147147+148148+/**149149+ * amd_iommu_set_invalidate_ctx_cb() - Register a call-back for invalidating150150+ * a pasid context. This call-back is151151+ * invoked when the IOMMUv2 driver needs to152152+ * invalidate a PASID context, for example153153+ * because the task that is bound to that154154+ * context is about to exit.155155+ *156156+ * @pdev: The PCI device the call-back should be registered for157157+ * @cb: The call-back function158158+ */159159+160160+typedef void (*amd_iommu_invalidate_ctx)(struct pci_dev *pdev, int pasid);161161+162162+extern int amd_iommu_set_invalidate_ctx_cb(struct pci_dev *pdev,163163+ amd_iommu_invalidate_ctx cb);2816429165#else30166
+20-6
include/linux/iommu.h
···48484949#ifdef CONFIG_IOMMU_API50505151+/**5252+ * struct iommu_ops - iommu ops and capabilities5353+ * @domain_init: init iommu domain5454+ * @domain_destroy: destroy iommu domain5555+ * @attach_dev: attach device to an iommu domain5656+ * @detach_dev: detach device from an iommu domain5757+ * @map: map a physically contiguous memory region to an iommu domain5858+ * @unmap: unmap a physically contiguous memory region from an iommu domain5959+ * @iova_to_phys: translate iova to physical address6060+ * @domain_has_cap: domain capabilities query6161+ * @commit: commit iommu domain6262+ * @pgsize_bitmap: bitmap of supported page sizes6363+ */5164struct iommu_ops {5265 int (*domain_init)(struct iommu_domain *domain);5366 void (*domain_destroy)(struct iommu_domain *domain);5467 int (*attach_dev)(struct iommu_domain *domain, struct device *dev);5568 void (*detach_dev)(struct iommu_domain *domain, struct device *dev);5669 int (*map)(struct iommu_domain *domain, unsigned long iova,5757- phys_addr_t paddr, int gfp_order, int prot);5858- int (*unmap)(struct iommu_domain *domain, unsigned long iova,5959- int gfp_order);7070+ phys_addr_t paddr, size_t size, int prot);7171+ size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,7272+ size_t size);6073 phys_addr_t (*iova_to_phys)(struct iommu_domain *domain,6174 unsigned long iova);6275 int (*domain_has_cap)(struct iommu_domain *domain,6376 unsigned long cap);7777+ unsigned long pgsize_bitmap;6478};65796680extern int bus_set_iommu(struct bus_type *bus, struct iommu_ops *ops);···8672extern void iommu_detach_device(struct iommu_domain *domain,8773 struct device *dev);8874extern int iommu_map(struct iommu_domain *domain, unsigned long iova,8989- phys_addr_t paddr, int gfp_order, int prot);9090-extern int iommu_unmap(struct iommu_domain *domain, unsigned long iova,9191- int gfp_order);7575+ phys_addr_t paddr, size_t size, int prot);7676+extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,7777+ size_t size);9278extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,9379 unsigned long iova);9480extern int iommu_domain_has_cap(struct iommu_domain *domain,
+3
include/linux/msi.h
···11#ifndef LINUX_MSI_H22#define LINUX_MSI_H3344+#include <linux/kobject.h>45#include <linux/list.h>5667struct msi_msg {···45444645 /* Last set MSI message */4746 struct msi_msg msg;4747+4848+ struct kobject kobj;4849};49505051/*