iommu/amd: Add support for RMP_PAGE_FAULT and RMP_HW_ERR
IOMMU SNP support introduces two new IOMMU events: * RMP Page Fault event * RMP Hardware Error event Hence, add reporting functions for these events. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Link: https://lore.kernel.org/r/20200923121347.25365-3-suravee.suthikulpanit@amd.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
c69d89aff3
commit
2818de6e87
|
@ -128,6 +128,8 @@
|
|||
#define EVENT_TYPE_IOTLB_INV_TO 0x7
|
||||
#define EVENT_TYPE_INV_DEV_REQ 0x8
|
||||
#define EVENT_TYPE_INV_PPR_REQ 0x9
|
||||
#define EVENT_TYPE_RMP_FAULT 0xd
|
||||
#define EVENT_TYPE_RMP_HW_ERR 0xe
|
||||
#define EVENT_DEVID_MASK 0xffff
|
||||
#define EVENT_DEVID_SHIFT 0
|
||||
#define EVENT_DOMID_MASK_LO 0xffff
|
||||
|
|
|
@ -486,6 +486,67 @@ static void dump_command(unsigned long phys_addr)
|
|||
pr_err("CMD[%d]: %08x\n", i, cmd->data[i]);
|
||||
}
|
||||
|
||||
static void amd_iommu_report_rmp_hw_error(volatile u32 *event)
|
||||
{
|
||||
struct iommu_dev_data *dev_data = NULL;
|
||||
int devid, vmg_tag, flags;
|
||||
struct pci_dev *pdev;
|
||||
u64 spa;
|
||||
|
||||
devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
|
||||
vmg_tag = (event[1]) & 0xFFFF;
|
||||
flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
|
||||
spa = ((u64)event[3] << 32) | (event[2] & 0xFFFFFFF8);
|
||||
|
||||
pdev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(devid),
|
||||
devid & 0xff);
|
||||
if (pdev)
|
||||
dev_data = dev_iommu_priv_get(&pdev->dev);
|
||||
|
||||
if (dev_data && __ratelimit(&dev_data->rs)) {
|
||||
pci_err(pdev, "Event logged [RMP_HW_ERROR vmg_tag=0x%04x, spa=0x%llx, flags=0x%04x]\n",
|
||||
vmg_tag, spa, flags);
|
||||
} else {
|
||||
pr_err_ratelimited("Event logged [RMP_HW_ERROR device=%02x:%02x.%x, vmg_tag=0x%04x, spa=0x%llx, flags=0x%04x]\n",
|
||||
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
|
||||
vmg_tag, spa, flags);
|
||||
}
|
||||
|
||||
if (pdev)
|
||||
pci_dev_put(pdev);
|
||||
}
|
||||
|
||||
static void amd_iommu_report_rmp_fault(volatile u32 *event)
|
||||
{
|
||||
struct iommu_dev_data *dev_data = NULL;
|
||||
int devid, flags_rmp, vmg_tag, flags;
|
||||
struct pci_dev *pdev;
|
||||
u64 gpa;
|
||||
|
||||
devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
|
||||
flags_rmp = (event[0] >> EVENT_FLAGS_SHIFT) & 0xFF;
|
||||
vmg_tag = (event[1]) & 0xFFFF;
|
||||
flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
|
||||
gpa = ((u64)event[3] << 32) | event[2];
|
||||
|
||||
pdev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(devid),
|
||||
devid & 0xff);
|
||||
if (pdev)
|
||||
dev_data = dev_iommu_priv_get(&pdev->dev);
|
||||
|
||||
if (dev_data && __ratelimit(&dev_data->rs)) {
|
||||
pci_err(pdev, "Event logged [RMP_PAGE_FAULT vmg_tag=0x%04x, gpa=0x%llx, flags_rmp=0x%04x, flags=0x%04x]\n",
|
||||
vmg_tag, gpa, flags_rmp, flags);
|
||||
} else {
|
||||
pr_err_ratelimited("Event logged [RMP_PAGE_FAULT device=%02x:%02x.%x, vmg_tag=0x%04x, gpa=0x%llx, flags_rmp=0x%04x, flags=0x%04x]\n",
|
||||
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
|
||||
vmg_tag, gpa, flags_rmp, flags);
|
||||
}
|
||||
|
||||
if (pdev)
|
||||
pci_dev_put(pdev);
|
||||
}
|
||||
|
||||
static void amd_iommu_report_page_fault(u16 devid, u16 domain_id,
|
||||
u64 address, int flags)
|
||||
{
|
||||
|
@ -577,6 +638,12 @@ retry:
|
|||
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
|
||||
pasid, address, flags);
|
||||
break;
|
||||
case EVENT_TYPE_RMP_FAULT:
|
||||
amd_iommu_report_rmp_fault(event);
|
||||
break;
|
||||
case EVENT_TYPE_RMP_HW_ERR:
|
||||
amd_iommu_report_rmp_hw_error(event);
|
||||
break;
|
||||
case EVENT_TYPE_INV_PPR_REQ:
|
||||
pasid = PPR_PASID(*((u64 *)__evt));
|
||||
tag = event[1] & 0x03FF;
|
||||
|
|
Loading…
Reference in New Issue