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>
This commit is contained in:
parent
b16137b11b
commit
c99afa25b6
|
@ -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);
|
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)
|
static void build_inv_all(struct iommu_cmd *cmd)
|
||||||
{
|
{
|
||||||
memset(cmd, 0, sizeof(*cmd));
|
memset(cmd, 0, sizeof(*cmd));
|
||||||
|
@ -1950,6 +1966,23 @@ out_err:
|
||||||
return ret;
|
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
|
* If a device is not yet associated with a domain, this function does
|
||||||
* assigns it visible for the hardware
|
* assigns it visible for the hardware
|
||||||
|
@ -1973,6 +2006,7 @@ static int attach_device(struct device *dev,
|
||||||
|
|
||||||
dev_data->ats.enabled = true;
|
dev_data->ats.enabled = true;
|
||||||
dev_data->ats.qdep = pci_ats_queue_depth(pdev);
|
dev_data->ats.qdep = pci_ats_queue_depth(pdev);
|
||||||
|
dev_data->pri_tlp = pci_pri_tlp_required(pdev);
|
||||||
} else if (amd_iommu_iotlb_sup &&
|
} else if (amd_iommu_iotlb_sup &&
|
||||||
pci_enable_ats(pdev, PAGE_SHIFT) == 0) {
|
pci_enable_ats(pdev, PAGE_SHIFT) == 0) {
|
||||||
dev_data->ats.enabled = true;
|
dev_data->ats.enabled = true;
|
||||||
|
@ -3412,3 +3446,20 @@ int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(amd_iommu_domain_clear_gcr3);
|
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);
|
||||||
|
|
|
@ -47,6 +47,12 @@ extern int amd_iommu_domain_set_gcr3(struct iommu_domain *dom, int pasid,
|
||||||
unsigned long cr3);
|
unsigned long cr3);
|
||||||
extern int amd_iommu_domain_clear_gcr3(struct iommu_domain *dom, int pasid);
|
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
|
#ifndef CONFIG_AMD_IOMMU_STATS
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,7 @@
|
||||||
#define CMD_INV_DEV_ENTRY 0x02
|
#define CMD_INV_DEV_ENTRY 0x02
|
||||||
#define CMD_INV_IOMMU_PAGES 0x03
|
#define CMD_INV_IOMMU_PAGES 0x03
|
||||||
#define CMD_INV_IOTLB_PAGES 0x04
|
#define CMD_INV_IOTLB_PAGES 0x04
|
||||||
|
#define CMD_COMPLETE_PPR 0x07
|
||||||
#define CMD_INV_ALL 0x08
|
#define CMD_INV_ALL 0x08
|
||||||
|
|
||||||
#define CMD_COMPL_WAIT_STORE_MASK 0x01
|
#define CMD_COMPL_WAIT_STORE_MASK 0x01
|
||||||
|
@ -150,6 +151,9 @@
|
||||||
#define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02
|
#define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02
|
||||||
#define CMD_INV_IOMMU_PAGES_GN_MASK 0x04
|
#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
|
#define CMD_INV_IOMMU_ALL_PAGES_ADDRESS 0x7fffffffffffffffULL
|
||||||
|
|
||||||
/* macros and definitions for device table entries */
|
/* macros and definitions for device table entries */
|
||||||
|
@ -394,6 +398,8 @@ struct iommu_dev_data {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
int qdep;
|
int qdep;
|
||||||
} ats; /* ATS state */
|
} ats; /* ATS state */
|
||||||
|
bool pri_tlp; /* PASID TLB required for
|
||||||
|
PPR completions */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue