Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu/amd: Implement function to send PPR completions

To send completions for PPR requests this patch adds a
function which can be used by the IOMMUv2 driver.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>

+63
+51
drivers/iommu/amd_iommu.c
··· 736 736 CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES); 737 737 } 738 738 739 + static void build_complete_ppr(struct iommu_cmd *cmd, u16 devid, int pasid, 740 + int status, int tag, bool gn) 741 + { 742 + memset(cmd, 0, sizeof(*cmd)); 743 + 744 + cmd->data[0] = devid; 745 + if (gn) { 746 + cmd->data[1] = pasid & PASID_MASK; 747 + cmd->data[2] = CMD_INV_IOMMU_PAGES_GN_MASK; 748 + } 749 + cmd->data[3] = tag & 0x1ff; 750 + cmd->data[3] |= (status & PPR_STATUS_MASK) << PPR_STATUS_SHIFT; 751 + 752 + CMD_SET_TYPE(cmd, CMD_COMPLETE_PPR); 753 + } 754 + 739 755 static void build_inv_all(struct iommu_cmd *cmd) 740 756 { 741 757 memset(cmd, 0, sizeof(*cmd)); ··· 1966 1950 return ret; 1967 1951 } 1968 1952 1953 + /* FIXME: Move this to PCI code */ 1954 + #define PCI_PRI_TLP_OFF (1 << 2) 1955 + 1956 + bool pci_pri_tlp_required(struct pci_dev *pdev) 1957 + { 1958 + u16 control; 1959 + int pos; 1960 + 1961 + pos = pci_find_ext_capability(pdev, PCI_PRI_CAP); 1962 + if (!pos) 1963 + return false; 1964 + 1965 + pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control); 1966 + 1967 + return (control & PCI_PRI_TLP_OFF) ? true : false; 1968 + } 1969 + 1969 1970 /* 1970 1971 * If a device is not yet associated with a domain, this function does 1971 1972 * assigns it visible for the hardware ··· 2006 1973 2007 1974 dev_data->ats.enabled = true; 2008 1975 dev_data->ats.qdep = pci_ats_queue_depth(pdev); 1976 + dev_data->pri_tlp = pci_pri_tlp_required(pdev); 2009 1977 } else if (amd_iommu_iotlb_sup && 2010 1978 pci_enable_ats(pdev, PAGE_SHIFT) == 0) { 2011 1979 dev_data->ats.enabled = true; ··· 3446 3412 return ret; 3447 3413 } 3448 3414 EXPORT_SYMBOL(amd_iommu_domain_clear_gcr3); 3415 + 3416 + int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid, 3417 + int status, int tag) 3418 + { 3419 + struct iommu_dev_data *dev_data; 3420 + struct amd_iommu *iommu; 3421 + struct iommu_cmd cmd; 3422 + 3423 + dev_data = get_dev_data(&pdev->dev); 3424 + iommu = amd_iommu_rlookup_table[dev_data->devid]; 3425 + 3426 + build_complete_ppr(&cmd, dev_data->devid, pasid, status, 3427 + tag, dev_data->pri_tlp); 3428 + 3429 + return iommu_queue_command(iommu, &cmd); 3430 + } 3431 + EXPORT_SYMBOL(amd_iommu_complete_ppr);
+6
drivers/iommu/amd_iommu_proto.h
··· 47 47 unsigned long cr3); 48 48 extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid); 49 49 50 + #define PPR_SUCCESS 0x0 51 + #define PPR_INVALID 0x1 52 + #define PPR_FAILURE 0xf 53 + 54 + extern int amd_iommu_complete_ppr(struct pci_dev *pdev, int pasid, 55 + int status, int tag); 50 56 51 57 #ifndef CONFIG_AMD_IOMMU_STATS 52 58
+6
drivers/iommu/amd_iommu_types.h
··· 142 142 #define CMD_INV_DEV_ENTRY 0x02 143 143 #define CMD_INV_IOMMU_PAGES 0x03 144 144 #define CMD_INV_IOTLB_PAGES 0x04 145 + #define CMD_COMPLETE_PPR 0x07 145 146 #define CMD_INV_ALL 0x08 146 147 147 148 #define CMD_COMPL_WAIT_STORE_MASK 0x01 ··· 150 149 #define CMD_INV_IOMMU_PAGES_SIZE_MASK 0x01 151 150 #define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02 152 151 #define CMD_INV_IOMMU_PAGES_GN_MASK 0x04 152 + 153 + #define PPR_STATUS_MASK 0xf 154 + #define PPR_STATUS_SHIFT 12 153 155 154 156 #define CMD_INV_IOMMU_ALL_PAGES_ADDRESS 0x7fffffffffffffffULL 155 157 ··· 398 394 bool enabled; 399 395 int qdep; 400 396 } ats; /* ATS state */ 397 + bool pri_tlp; /* PASID TLB required for 398 + PPR completions */ 401 399 }; 402 400 403 401 /*