Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 112602
b: refs/heads/master
c: 90008ee
h: refs/heads/master
v: v3
  • Loading branch information
Joerg Roedel authored and Ingo Molnar committed Sep 19, 2008
1 parent c6c824e commit 2e6076e
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a80dc3e0e0dc8393158de317d66ae0f345dc58f9
refs/heads/master: 90008ee4b811c944455752dcb72b291a5ba81b53
87 changes: 86 additions & 1 deletion trunk/arch/x86/kernel/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,94 @@ static int iommu_has_npcache(struct amd_iommu *iommu)
*
****************************************************************************/

static void iommu_print_event(void *__evt)
{
u32 *event = __evt;
int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK;
int devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
int domid = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
u64 address = (u64)(((u64)event[3]) << 32) | event[2];

printk(KERN_ERR "AMD IOMMU: Event logged [");

switch (type) {
case EVENT_TYPE_ILL_DEV:
printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
"address=0x%016llx flags=0x%04x]\n",
PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid),
address, flags);
break;
case EVENT_TYPE_IO_FAULT:
printk("IO_PAGE_FAULT device=%02x:%02x.%x "
"domain=0x%04x address=0x%016llx flags=0x%04x]\n",
PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid),
domid, address, flags);
break;
case EVENT_TYPE_DEV_TAB_ERR:
printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
"address=0x%016llx flags=0x%04x]\n",
PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid),
address, flags);
break;
case EVENT_TYPE_PAGE_TAB_ERR:
printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
"domain=0x%04x address=0x%016llx flags=0x%04x]\n",
PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid),
domid, address, flags);
break;
case EVENT_TYPE_ILL_CMD:
printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
break;
case EVENT_TYPE_CMD_HARD_ERR:
printk("COMMAND_HARDWARE_ERROR address=0x%016llx "
"flags=0x%04x]\n", address, flags);
break;
case EVENT_TYPE_IOTLB_INV_TO:
printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
"address=0x%016llx]\n",
PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid),
address);
break;
case EVENT_TYPE_INV_DEV_REQ:
printk("INVALID_DEVICE_REQUEST device=%02x:%02x.%x "
"address=0x%016llx flags=0x%04x]\n",
PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid),
address, flags);
break;
default:
printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
}
}

static void iommu_poll_events(struct amd_iommu *iommu)
{
u32 head, tail;
unsigned long flags;

spin_lock_irqsave(&iommu->lock, flags);

head = readl(iommu->mmio_base + MMIO_EVT_HEAD_OFFSET);
tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET);

while (head != tail) {
iommu_print_event(iommu->evt_buf + head);
head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size;
}

writel(head, iommu->mmio_base + MMIO_EVT_HEAD_OFFSET);

spin_unlock_irqrestore(&iommu->lock, flags);
}

irqreturn_t amd_iommu_int_handler(int irq, void *data)
{
return IRQ_NONE;
struct amd_iommu *iommu;

list_for_each_entry(iommu, &amd_iommu_list, list)
iommu_poll_events(iommu);

return IRQ_HANDLED;
}

/****************************************************************************
Expand Down
1 change: 0 additions & 1 deletion trunk/arch/x86/kernel/amd_iommu_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
/*
* definitions for the ACPI scanning code
*/
#define PCI_BUS(x) (((x) >> 8) & 0xff)
#define IVRS_HEADER_LENGTH 48

#define ACPI_IVHD_TYPE 0x10
Expand Down
22 changes: 22 additions & 0 deletions trunk/include/asm-x86/amd_iommu_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,25 @@
/* MMIO status bits */
#define MMIO_STATUS_COM_WAIT_INT_MASK 0x04

/* event logging constants */
#define EVENT_ENTRY_SIZE 0x10
#define EVENT_TYPE_SHIFT 28
#define EVENT_TYPE_MASK 0xf
#define EVENT_TYPE_ILL_DEV 0x1
#define EVENT_TYPE_IO_FAULT 0x2
#define EVENT_TYPE_DEV_TAB_ERR 0x3
#define EVENT_TYPE_PAGE_TAB_ERR 0x4
#define EVENT_TYPE_ILL_CMD 0x5
#define EVENT_TYPE_CMD_HARD_ERR 0x6
#define EVENT_TYPE_IOTLB_INV_TO 0x7
#define EVENT_TYPE_INV_DEV_REQ 0x8
#define EVENT_DEVID_MASK 0xffff
#define EVENT_DEVID_SHIFT 0
#define EVENT_DOMID_MASK 0xffff
#define EVENT_DOMID_SHIFT 0
#define EVENT_FLAGS_MASK 0xfff
#define EVENT_FLAGS_SHIFT 0x10

/* feature control bits */
#define CONTROL_IOMMU_EN 0x00ULL
#define CONTROL_HT_TUN_EN 0x01ULL
Expand Down Expand Up @@ -165,6 +184,9 @@

#define MAX_DOMAIN_ID 65536

/* FIXME: move this macro to <linux/pci.h> */
#define PCI_BUS(x) (((x) >> 8) & 0xff)

/*
* This structure contains generic data for IOMMU protection domains
* independent of their use.
Expand Down

0 comments on commit 2e6076e

Please sign in to comment.