Skip to content

Commit

Permalink
iommu/amd: Implement function to send PPR completions
Browse files Browse the repository at this point in the history
To send completions for PPR requests this patch adds a
function which can be used by the IOMMUv2 driver.

Signed-off-by: Joerg Roedel <[email protected]>
  • Loading branch information
Joerg Roedel committed Dec 12, 2011
1 parent b16137b commit c99afa2
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
51 changes: 51 additions & 0 deletions drivers/iommu/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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);
6 changes: 6 additions & 0 deletions drivers/iommu/amd_iommu_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions drivers/iommu/amd_iommu_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 */
Expand Down Expand Up @@ -394,6 +398,8 @@ struct iommu_dev_data {
bool enabled;
int qdep;
} ats; /* ATS state */
bool pri_tlp; /* PASID TLB required for
PPR completions */
};

/*
Expand Down

0 comments on commit c99afa2

Please sign in to comment.