Loading drivers/iommu/amd_iommu.c +51 −0 Original line number Diff line number Diff line Loading @@ -736,6 +736,22 @@ static void build_inv_iotlb_pasid(struct iommu_cmd *cmd, u16 devid, int pasid, CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES); } static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid, int status, int tag, bool gn) { memset(cmd, 0, sizeof(*cmd)); cmd->data[0] = devid; if (gn) { cmd->data[1] = pasid & PASID_MASK; cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK; } cmd->data[3] = tag & 0x1ff; cmd->data[3] |= (status & PPR_STATUS_MASK) << PPR_STATUS_SHIFT; CMD_SET_TYPE(cmd, CMD_COMPLETE_PPR); } static void build_inv_all(struct iommu_cmd *cmd) { memset(cmd, 0, sizeof(*cmd)); Loading Loading @@ -1950,6 +1966,23 @@ static int pdev_iommuv2_enable(struct pci_dev *pdev) return ret; } /* FIXME: Move this to PCI code */ #define PCI_PRI_TLP_OFF (1 << 2) bool pci_pri_tlp_required(struct pci_dev *pdev) { u16 control; int pos; pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); if (!pos) return false; pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); return (control & PCI_PRI_TLP_OFF) ? true : false; } /* * If a device is not yet associated with a domain, this function does * assigns it visible for the hardware Loading @@ -1973,6 +2006,7 @@ static int attach_device(struct device *dev, dev_data->ats.enabled = true; dev_data->ats.qdep = pci_ats_queue_depth(pdev); dev_data->pri_tlp = pci_pri_tlp_required(pdev); } else if (amd_iommu_iotlb_sup && pci_enable_ats(pdev, PAGE_SHIFT) == 0) { dev_data->ats.enabled = true; Loading Loading @@ -3412,3 +3446,20 @@ int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid) return ret; } EXPORT_SYMBOL(amd_iommu_domain_clear_gcr3); int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid, int status, int tag) { struct iommu_dev_data *dev_data; struct amd_iommu *iommu; struct iommu_cmd cmd; dev_data = get_dev_data(&pdev->dev); iommu = amd_iommu_rlookup_table[dev_data->devid]; build_complete_ppr(&cmd, dev_data->devid, pasid, status, tag, dev_data->pri_tlp); return iommu_queue_command(iommu, &cmd); } EXPORT_SYMBOL(amd_iommu_complete_ppr); drivers/iommu/amd_iommu_proto.h +6 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,12 @@ extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, unsigned long cr3); extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid); #define PPR_SUCCESS 0x0 #define PPR_INVALID 0x1 #define PPR_FAILURE 0xf extern int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid, int status, int tag); #ifndef CONFIG_AMD_IOMMU_STATS Loading drivers/iommu/amd_iommu_types.h +6 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ #define CMD_INV_DEV_ENTRY 0x02 #define CMD_INV_IOMMU_PAGES 0x03 #define CMD_INV_IOTLB_PAGES 0x04 #define CMD_COMPLETE_PPR 0x07 #define CMD_INV_ALL 0x08 #define CMD_COMPL_WAIT_STORE_MASK 0x01 Loading @@ -150,6 +151,9 @@ #define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02 #define CMD_INV_IOMMU_PAGES_GN_MASK 0x04 #define PPR_STATUS_MASK 0xf #define PPR_STATUS_SHIFT 12 #define CMD_INV_IOMMU_ALL_PAGES_ADDRESS 0x7fffffffffffffffULL /* macros and definitions for device table entries */ Loading Loading @@ -394,6 +398,8 @@ struct iommu_dev_data { bool enabled; int qdep; } ats; /* ATS state */ bool pri_tlp; /* PASID TLB required for PPR completions */ }; /* Loading Loading
drivers/iommu/amd_iommu.c +51 −0 Original line number Diff line number Diff line Loading @@ -736,6 +736,22 @@ static void build_inv_iotlb_pasid(struct iommu_cmd *cmd, u16 devid, int pasid, CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES); } static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid, int status, int tag, bool gn) { memset(cmd, 0, sizeof(*cmd)); cmd->data[0] = devid; if (gn) { cmd->data[1] = pasid & PASID_MASK; cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK; } cmd->data[3] = tag & 0x1ff; cmd->data[3] |= (status & PPR_STATUS_MASK) << PPR_STATUS_SHIFT; CMD_SET_TYPE(cmd, CMD_COMPLETE_PPR); } static void build_inv_all(struct iommu_cmd *cmd) { memset(cmd, 0, sizeof(*cmd)); Loading Loading @@ -1950,6 +1966,23 @@ static int pdev_iommuv2_enable(struct pci_dev *pdev) return ret; } /* FIXME: Move this to PCI code */ #define PCI_PRI_TLP_OFF (1 << 2) bool pci_pri_tlp_required(struct pci_dev *pdev) { u16 control; int pos; pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); if (!pos) return false; pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); return (control & PCI_PRI_TLP_OFF) ? true : false; } /* * If a device is not yet associated with a domain, this function does * assigns it visible for the hardware Loading @@ -1973,6 +2006,7 @@ static int attach_device(struct device *dev, dev_data->ats.enabled = true; dev_data->ats.qdep = pci_ats_queue_depth(pdev); dev_data->pri_tlp = pci_pri_tlp_required(pdev); } else if (amd_iommu_iotlb_sup && pci_enable_ats(pdev, PAGE_SHIFT) == 0) { dev_data->ats.enabled = true; Loading Loading @@ -3412,3 +3446,20 @@ int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid) return ret; } EXPORT_SYMBOL(amd_iommu_domain_clear_gcr3); int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid, int status, int tag) { struct iommu_dev_data *dev_data; struct amd_iommu *iommu; struct iommu_cmd cmd; dev_data = get_dev_data(&pdev->dev); iommu = amd_iommu_rlookup_table[dev_data->devid]; build_complete_ppr(&cmd, dev_data->devid, pasid, status, tag, dev_data->pri_tlp); return iommu_queue_command(iommu, &cmd); } EXPORT_SYMBOL(amd_iommu_complete_ppr);
drivers/iommu/amd_iommu_proto.h +6 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,12 @@ extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid, unsigned long cr3); extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid); #define PPR_SUCCESS 0x0 #define PPR_INVALID 0x1 #define PPR_FAILURE 0xf extern int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid, int status, int tag); #ifndef CONFIG_AMD_IOMMU_STATS Loading
drivers/iommu/amd_iommu_types.h +6 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ #define CMD_INV_DEV_ENTRY 0x02 #define CMD_INV_IOMMU_PAGES 0x03 #define CMD_INV_IOTLB_PAGES 0x04 #define CMD_COMPLETE_PPR 0x07 #define CMD_INV_ALL 0x08 #define CMD_COMPL_WAIT_STORE_MASK 0x01 Loading @@ -150,6 +151,9 @@ #define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02 #define CMD_INV_IOMMU_PAGES_GN_MASK 0x04 #define PPR_STATUS_MASK 0xf #define PPR_STATUS_SHIFT 12 #define CMD_INV_IOMMU_ALL_PAGES_ADDRESS 0x7fffffffffffffffULL /* macros and definitions for device table entries */ Loading Loading @@ -394,6 +398,8 @@ struct iommu_dev_data { bool enabled; int qdep; } ats; /* ATS state */ bool pri_tlp; /* PASID TLB required for PPR completions */ }; /* Loading