All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-03  0:06 ` suravee.suthikulpanit
  0 siblings, 0 replies; 14+ messages in thread
From: suravee.suthikulpanit @ 2013-04-03  0:06 UTC (permalink / raw)
  To: iommu, joro; +Cc: linux-kernel, Suravee Suthikulpanit

From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>

Add logic to decode AMD IOMMU event flag based on information from AMD IOMMU specification.
This should simplify debugging IOMMU errors.  Also, dump DTE information in additional cases.

This is an example:
AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0000000000000000 flags=0x0fff]
AMD-Vi: Flags details: Guest NX=1 User Intr Present Write No-Perm Rsrv-Bit Translation
AMD-Vi: Type of error: (0x7) 
AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)
AMD-Vi: DTE[0]: 6000003fa75e2403
AMD-Vi: DTE[1]: 0000000000000014
AMD-Vi: DTE[2]: 2000003fa5e09011
AMD-Vi: DTE[3]: 0000000000000000

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
Changelog:
V3:
	* Move comments to end of line
	* Shorten the print out to be within one line
V2:
	* Fix printing format to reduce noise
	* Use string table instead of switch/case
	* Use pr_cont instead of printk

 drivers/iommu/amd_iommu.c |  171 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 137 insertions(+), 34 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index b287ca3..593a1a3 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -601,6 +601,94 @@ static void amd_iommu_stats_init(void)
  *
  ****************************************************************************/
 
+struct _event_log_flags {
+	u32	gn:1,		/* 16 */
+		nx:1,		/* 17 */
+		us:1,		/* 18 */
+		 i:1,		/* 19 */
+		pr:1,		/* 20 */
+		rw:1,		/* 21 */
+		pe:1,		/* 22 */
+		rz:1,		/* 23 */
+		tr:1,		/* 24 */
+		type:3,		/* [27:25] */
+		_reserved_:20;	/* Reserved */
+};
+
+static const char * const _type_field_encodings[] = {
+	"Reserved",		/* 00 */
+	"Master Abort",		/* 01 */
+	"Target Abort",		/* 10 */
+	"Data Error",		/* 11 */
+};
+
+static const char * const _invalid_transaction_desc[] = {
+	"Read request or non-posted write in the interrupt "
+		 "addres range",				/* 000 */
+	"Pretranslated transaction received from an "
+		"I/O device that has I=0 or V=0 in DTE",	/* 001 */
+	"Port I/O space transaction received from an "
+		"I/O device that has IoCtl=00b in DTE",		/* 010 */
+	"Posted write to invalid address range",		/* 011 */
+	"Invalid read request or non-posted write",		/* 100 */
+	"Posted write to the interrupt/EOI range from an "
+		"I/O device that has IntCtl=00b in DTE",	/* 101 */
+	"Posted write to a reserved interrupt address range",	/* 110 */
+	"Invalid transaction to the system management "
+		"address range",				/* 111 */
+};
+
+static const char * const _invalid_translation_desc[] = {
+	"Translation request received from an I/O device "
+		"that has I=0, or has V=0, or has V=1 and "
+		"TV=0 in DTE",					/* 000 */
+	"Translation request in invalid address range",		/* 001 */
+	"Invalid translation request",				/* 010 */
+	"Reserved",						/* 011 */
+	"Reserved",						/* 100 */
+	"Reserved",						/* 101 */
+	"Reserved",						/* 110 */
+	"Reserved",						/* 111 */
+};
+
+static void dump_flags(int flags, int ev_type)
+{
+	struct _event_log_flags *p = (struct _event_log_flags *) &flags;
+	u32 err_type = p->type;
+
+	pr_err("AMD-Vi: Flags details: %s NX=%u %s %s %s %s %s %s %s\n",
+		(p->gn ? "Guest" : "Nested"),
+		(p->nx),
+		(p->us ? "User" : "Super"),
+		(p->i ? "Intr" : "Mem"),
+		(p->pr ? "Present" : "Absent"),
+		(p->rw ? "Write" : "Read"),
+		(p->pe ? "No-Perm" : "Has-Perm"),
+		(p->rz ? "Rsrv-Bit" : "Ill-Level"),
+		(p->tr ? "Translation" : "Transaction"));
+
+	pr_err("AMD-Vi: Type of error: (0x%x) ", err_type);
+	if ((ev_type == EVENT_TYPE_DEV_TAB_ERR)  ||
+	    (ev_type == EVENT_TYPE_PAGE_TAB_ERR) ||
+	    (ev_type == EVENT_TYPE_CMD_HARD_ERR)) {
+		if (err_type < ARRAY_SIZE(_type_field_encodings)) {
+			pr_cont("%s\n",
+				_type_field_encodings[err_type]);
+		}
+	} else if (ev_type == EVENT_TYPE_INV_DEV_REQ) {
+		if (p->tr == 0) {
+			if (err_type < ARRAY_SIZE(_invalid_translation_desc))
+				pr_cont("%s\n",
+					_invalid_translation_desc[err_type]);
+		} else {
+			if (err_type < ARRAY_SIZE(_invalid_transaction_desc))
+				pr_cont("%s\n",
+					_invalid_transaction_desc[err_type]);
+		}
+	}
+	pr_err("AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)\n");
+}
+
 static void dump_dte_entry(u16 devid)
 {
 	int i;
@@ -619,81 +707,95 @@ static void dump_command(unsigned long phys_addr)
 		pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]);
 }
 
-static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
+void amd_iommu_print_event(int type, int devid, int domid,
+			      int flags, u64 address)
 {
-	int type, devid, domid, flags;
-	volatile u32 *event = __evt;
-	int count = 0;
-	u64 address;
-
-retry:
-	type    = (event[1] >> EVENT_TYPE_SHIFT)  & EVENT_TYPE_MASK;
-	devid   = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
-	domid   = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
-	flags   = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
-	address = (u64)(((u64)event[3]) << 32) | event[2];
-
-	if (type == 0) {
-		/* Did we hit the erratum? */
-		if (++count == LOOP_TIMEOUT) {
-			pr_err("AMD-Vi: No event written to event log\n");
-			return;
-		}
-		udelay(1);
-		goto retry;
-	}
-
-	printk(KERN_ERR "AMD-Vi: Event logged [");
+	pr_err("AMD-Vi: Event logged [");
 
 	switch (type) {
 	case EVENT_TYPE_ILL_DEV:
-		printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
+		pr_cont("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);
+		dump_flags(flags, type);
 		dump_dte_entry(devid);
 		break;
 	case EVENT_TYPE_IO_FAULT:
-		printk("IO_PAGE_FAULT device=%02x:%02x.%x "
+		pr_cont("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);
+		dump_flags(flags, type);
+		dump_dte_entry(devid);
 		break;
 	case EVENT_TYPE_DEV_TAB_ERR:
-		printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+		pr_cont("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);
+		dump_flags(flags, type);
 		break;
 	case EVENT_TYPE_PAGE_TAB_ERR:
-		printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+		pr_cont("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);
+		dump_flags(flags, type);
 		break;
 	case EVENT_TYPE_ILL_CMD:
-		printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
+		pr_cont("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
 		dump_command(address);
 		break;
 	case EVENT_TYPE_CMD_HARD_ERR:
-		printk("COMMAND_HARDWARE_ERROR address=0x%016llx "
+		pr_cont("COMMAND_HARDWARE_ERROR address=0x%016llx "
 		       "flags=0x%04x]\n", address, flags);
+		dump_flags(flags, type);
 		break;
 	case EVENT_TYPE_IOTLB_INV_TO:
-		printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
+		pr_cont("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 "
+		pr_cont("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);
+		dump_flags(flags, type);
+		dump_dte_entry(devid);
 		break;
 	default:
-		printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
+		pr_cont("UNKNOWN type=0x%02x]\n", type);
 	}
+}
+
+static void iommu_handle_event(struct amd_iommu *iommu, void *__evt)
+{
+	int type, devid, domid, flags;
+	u32 *event = __evt;
+	int count = 0;
+	u64 address;
+
+retry:
+	type    = (event[1] >> EVENT_TYPE_SHIFT)  & EVENT_TYPE_MASK;
+	devid   = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
+	domid   = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
+	flags   = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
+	address = (u64)(((u64)event[3]) << 32) | event[2];
+
+	if (type == 0) {
+		/* Did we hit the erratum? */
+		if (++count == LOOP_TIMEOUT) {
+			pr_err("AMD-Vi: No event written to event log\n");
+			return;
+		}
+		udelay(1);
+		goto retry;
+	}
+
+	amd_iommu_print_event(type, devid, domid, flags, address);
 
 	memset(__evt, 0, 4 * sizeof(u32));
 }
@@ -709,7 +811,7 @@ static void iommu_poll_events(struct amd_iommu *iommu)
 	tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET);
 
 	while (head != tail) {
-		iommu_print_event(iommu, iommu->evt_buf + head);
+		iommu_handle_event(iommu, iommu->evt_buf + head);
 		head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size;
 	}
 
@@ -3268,6 +3370,7 @@ static int __init alloc_passthrough_domain(void)
 
 	return 0;
 }
+
 static int amd_iommu_domain_init(struct iommu_domain *dom)
 {
 	struct protection_domain *domain;
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-03  0:06 ` suravee.suthikulpanit
  0 siblings, 0 replies; 14+ messages in thread
From: suravee.suthikulpanit @ 2013-04-03  0:06 UTC (permalink / raw)
  To: iommu, joro; +Cc: linux-kernel, Suravee Suthikulpanit

From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>

Add logic to decode AMD IOMMU event flag based on information from AMD IOMMU specification.
This should simplify debugging IOMMU errors.  Also, dump DTE information in additional cases.

This is an example:
AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0000000000000000 flags=0x0fff]
AMD-Vi: Flags details: Guest NX=1 User Intr Present Write No-Perm Rsrv-Bit Translation
AMD-Vi: Type of error: (0x7) 
AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)
AMD-Vi: DTE[0]: 6000003fa75e2403
AMD-Vi: DTE[1]: 0000000000000014
AMD-Vi: DTE[2]: 2000003fa5e09011
AMD-Vi: DTE[3]: 0000000000000000

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
Changelog:
V3:
	* Move comments to end of line
	* Shorten the print out to be within one line
V2:
	* Fix printing format to reduce noise
	* Use string table instead of switch/case
	* Use pr_cont instead of printk

 drivers/iommu/amd_iommu.c |  171 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 137 insertions(+), 34 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index b287ca3..593a1a3 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -601,6 +601,94 @@ static void amd_iommu_stats_init(void)
  *
  ****************************************************************************/
 
+struct _event_log_flags {
+	u32	gn:1,		/* 16 */
+		nx:1,		/* 17 */
+		us:1,		/* 18 */
+		 i:1,		/* 19 */
+		pr:1,		/* 20 */
+		rw:1,		/* 21 */
+		pe:1,		/* 22 */
+		rz:1,		/* 23 */
+		tr:1,		/* 24 */
+		type:3,		/* [27:25] */
+		_reserved_:20;	/* Reserved */
+};
+
+static const char * const _type_field_encodings[] = {
+	"Reserved",		/* 00 */
+	"Master Abort",		/* 01 */
+	"Target Abort",		/* 10 */
+	"Data Error",		/* 11 */
+};
+
+static const char * const _invalid_transaction_desc[] = {
+	"Read request or non-posted write in the interrupt "
+		 "addres range",				/* 000 */
+	"Pretranslated transaction received from an "
+		"I/O device that has I=0 or V=0 in DTE",	/* 001 */
+	"Port I/O space transaction received from an "
+		"I/O device that has IoCtl=00b in DTE",		/* 010 */
+	"Posted write to invalid address range",		/* 011 */
+	"Invalid read request or non-posted write",		/* 100 */
+	"Posted write to the interrupt/EOI range from an "
+		"I/O device that has IntCtl=00b in DTE",	/* 101 */
+	"Posted write to a reserved interrupt address range",	/* 110 */
+	"Invalid transaction to the system management "
+		"address range",				/* 111 */
+};
+
+static const char * const _invalid_translation_desc[] = {
+	"Translation request received from an I/O device "
+		"that has I=0, or has V=0, or has V=1 and "
+		"TV=0 in DTE",					/* 000 */
+	"Translation request in invalid address range",		/* 001 */
+	"Invalid translation request",				/* 010 */
+	"Reserved",						/* 011 */
+	"Reserved",						/* 100 */
+	"Reserved",						/* 101 */
+	"Reserved",						/* 110 */
+	"Reserved",						/* 111 */
+};
+
+static void dump_flags(int flags, int ev_type)
+{
+	struct _event_log_flags *p = (struct _event_log_flags *) &flags;
+	u32 err_type = p->type;
+
+	pr_err("AMD-Vi: Flags details: %s NX=%u %s %s %s %s %s %s %s\n",
+		(p->gn ? "Guest" : "Nested"),
+		(p->nx),
+		(p->us ? "User" : "Super"),
+		(p->i ? "Intr" : "Mem"),
+		(p->pr ? "Present" : "Absent"),
+		(p->rw ? "Write" : "Read"),
+		(p->pe ? "No-Perm" : "Has-Perm"),
+		(p->rz ? "Rsrv-Bit" : "Ill-Level"),
+		(p->tr ? "Translation" : "Transaction"));
+
+	pr_err("AMD-Vi: Type of error: (0x%x) ", err_type);
+	if ((ev_type == EVENT_TYPE_DEV_TAB_ERR)  ||
+	    (ev_type == EVENT_TYPE_PAGE_TAB_ERR) ||
+	    (ev_type == EVENT_TYPE_CMD_HARD_ERR)) {
+		if (err_type < ARRAY_SIZE(_type_field_encodings)) {
+			pr_cont("%s\n",
+				_type_field_encodings[err_type]);
+		}
+	} else if (ev_type == EVENT_TYPE_INV_DEV_REQ) {
+		if (p->tr == 0) {
+			if (err_type < ARRAY_SIZE(_invalid_translation_desc))
+				pr_cont("%s\n",
+					_invalid_translation_desc[err_type]);
+		} else {
+			if (err_type < ARRAY_SIZE(_invalid_transaction_desc))
+				pr_cont("%s\n",
+					_invalid_transaction_desc[err_type]);
+		}
+	}
+	pr_err("AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)\n");
+}
+
 static void dump_dte_entry(u16 devid)
 {
 	int i;
@@ -619,81 +707,95 @@ static void dump_command(unsigned long phys_addr)
 		pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]);
 }
 
-static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
+void amd_iommu_print_event(int type, int devid, int domid,
+			      int flags, u64 address)
 {
-	int type, devid, domid, flags;
-	volatile u32 *event = __evt;
-	int count = 0;
-	u64 address;
-
-retry:
-	type    = (event[1] >> EVENT_TYPE_SHIFT)  & EVENT_TYPE_MASK;
-	devid   = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
-	domid   = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
-	flags   = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
-	address = (u64)(((u64)event[3]) << 32) | event[2];
-
-	if (type == 0) {
-		/* Did we hit the erratum? */
-		if (++count == LOOP_TIMEOUT) {
-			pr_err("AMD-Vi: No event written to event log\n");
-			return;
-		}
-		udelay(1);
-		goto retry;
-	}
-
-	printk(KERN_ERR "AMD-Vi: Event logged [");
+	pr_err("AMD-Vi: Event logged [");
 
 	switch (type) {
 	case EVENT_TYPE_ILL_DEV:
-		printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
+		pr_cont("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);
+		dump_flags(flags, type);
 		dump_dte_entry(devid);
 		break;
 	case EVENT_TYPE_IO_FAULT:
-		printk("IO_PAGE_FAULT device=%02x:%02x.%x "
+		pr_cont("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);
+		dump_flags(flags, type);
+		dump_dte_entry(devid);
 		break;
 	case EVENT_TYPE_DEV_TAB_ERR:
-		printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+		pr_cont("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);
+		dump_flags(flags, type);
 		break;
 	case EVENT_TYPE_PAGE_TAB_ERR:
-		printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+		pr_cont("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);
+		dump_flags(flags, type);
 		break;
 	case EVENT_TYPE_ILL_CMD:
-		printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
+		pr_cont("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
 		dump_command(address);
 		break;
 	case EVENT_TYPE_CMD_HARD_ERR:
-		printk("COMMAND_HARDWARE_ERROR address=0x%016llx "
+		pr_cont("COMMAND_HARDWARE_ERROR address=0x%016llx "
 		       "flags=0x%04x]\n", address, flags);
+		dump_flags(flags, type);
 		break;
 	case EVENT_TYPE_IOTLB_INV_TO:
-		printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
+		pr_cont("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 "
+		pr_cont("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);
+		dump_flags(flags, type);
+		dump_dte_entry(devid);
 		break;
 	default:
-		printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
+		pr_cont("UNKNOWN type=0x%02x]\n", type);
 	}
+}
+
+static void iommu_handle_event(struct amd_iommu *iommu, void *__evt)
+{
+	int type, devid, domid, flags;
+	u32 *event = __evt;
+	int count = 0;
+	u64 address;
+
+retry:
+	type    = (event[1] >> EVENT_TYPE_SHIFT)  & EVENT_TYPE_MASK;
+	devid   = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
+	domid   = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
+	flags   = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
+	address = (u64)(((u64)event[3]) << 32) | event[2];
+
+	if (type == 0) {
+		/* Did we hit the erratum? */
+		if (++count == LOOP_TIMEOUT) {
+			pr_err("AMD-Vi: No event written to event log\n");
+			return;
+		}
+		udelay(1);
+		goto retry;
+	}
+
+	amd_iommu_print_event(type, devid, domid, flags, address);
 
 	memset(__evt, 0, 4 * sizeof(u32));
 }
@@ -709,7 +811,7 @@ static void iommu_poll_events(struct amd_iommu *iommu)
 	tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET);
 
 	while (head != tail) {
-		iommu_print_event(iommu, iommu->evt_buf + head);
+		iommu_handle_event(iommu, iommu->evt_buf + head);
 		head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size;
 	}
 
@@ -3268,6 +3370,7 @@ static int __init alloc_passthrough_domain(void)
 
 	return 0;
 }
+
 static int amd_iommu_domain_init(struct iommu_domain *dom)
 {
 	struct protection_domain *domain;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* RE: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
  2013-04-03  0:06 ` suravee.suthikulpanit
  (?)
@ 2013-04-08 14:33 ` Suthikulpanit, Suravee
  2013-04-08 14:50     ` Borislav Petkov
  -1 siblings, 1 reply; 14+ messages in thread
From: Suthikulpanit, Suravee @ 2013-04-08 14:33 UTC (permalink / raw)
  To: iommu, joro; +Cc: linux-kernel

Joerg,

Do you have any more feedback about this patch?

Thanks,

Suravee
________________________________________
From: suravee.suthikulpanit@amd.com [suravee.suthikulpanit@amd.com]
Sent: Tuesday, April 02, 2013 7:06 PM
To: iommu@lists.linux-foundation.org; joro@8bytes.org
Cc: linux-kernel@vger.kernel.org; Suthikulpanit, Suravee
Subject: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag

From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>

Add logic to decode AMD IOMMU event flag based on information from AMD IOMMU specification.
This should simplify debugging IOMMU errors.  Also, dump DTE information in additional cases.

This is an example:
AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0000000000000000 flags=0x0fff]
AMD-Vi: Flags details: Guest NX=1 User Intr Present Write No-Perm Rsrv-Bit Translation
AMD-Vi: Type of error: (0x7)
AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)
AMD-Vi: DTE[0]: 6000003fa75e2403
AMD-Vi: DTE[1]: 0000000000000014
AMD-Vi: DTE[2]: 2000003fa5e09011
AMD-Vi: DTE[3]: 0000000000000000

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
Changelog:
V3:
        * Move comments to end of line
        * Shorten the print out to be within one line
V2:
        * Fix printing format to reduce noise
        * Use string table instead of switch/case
        * Use pr_cont instead of printk

 drivers/iommu/amd_iommu.c |  171 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 137 insertions(+), 34 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index b287ca3..593a1a3 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -601,6 +601,94 @@ static void amd_iommu_stats_init(void)
  *
  ****************************************************************************/

+struct _event_log_flags {
+       u32     gn:1,           /* 16 */
+               nx:1,           /* 17 */
+               us:1,           /* 18 */
+                i:1,           /* 19 */
+               pr:1,           /* 20 */
+               rw:1,           /* 21 */
+               pe:1,           /* 22 */
+               rz:1,           /* 23 */
+               tr:1,           /* 24 */
+               type:3,         /* [27:25] */
+               _reserved_:20;  /* Reserved */
+};
+
+static const char * const _type_field_encodings[] = {
+       "Reserved",             /* 00 */
+       "Master Abort",         /* 01 */
+       "Target Abort",         /* 10 */
+       "Data Error",           /* 11 */
+};
+
+static const char * const _invalid_transaction_desc[] = {
+       "Read request or non-posted write in the interrupt "
+                "addres range",                                /* 000 */
+       "Pretranslated transaction received from an "
+               "I/O device that has I=0 or V=0 in DTE",        /* 001 */
+       "Port I/O space transaction received from an "
+               "I/O device that has IoCtl=00b in DTE",         /* 010 */
+       "Posted write to invalid address range",                /* 011 */
+       "Invalid read request or non-posted write",             /* 100 */
+       "Posted write to the interrupt/EOI range from an "
+               "I/O device that has IntCtl=00b in DTE",        /* 101 */
+       "Posted write to a reserved interrupt address range",   /* 110 */
+       "Invalid transaction to the system management "
+               "address range",                                /* 111 */
+};
+
+static const char * const _invalid_translation_desc[] = {
+       "Translation request received from an I/O device "
+               "that has I=0, or has V=0, or has V=1 and "
+               "TV=0 in DTE",                                  /* 000 */
+       "Translation request in invalid address range",         /* 001 */
+       "Invalid translation request",                          /* 010 */
+       "Reserved",                                             /* 011 */
+       "Reserved",                                             /* 100 */
+       "Reserved",                                             /* 101 */
+       "Reserved",                                             /* 110 */
+       "Reserved",                                             /* 111 */
+};
+
+static void dump_flags(int flags, int ev_type)
+{
+       struct _event_log_flags *p = (struct _event_log_flags *) &flags;
+       u32 err_type = p->type;
+
+       pr_err("AMD-Vi: Flags details: %s NX=%u %s %s %s %s %s %s %s\n",
+               (p->gn ? "Guest" : "Nested"),
+               (p->nx),
+               (p->us ? "User" : "Super"),
+               (p->i ? "Intr" : "Mem"),
+               (p->pr ? "Present" : "Absent"),
+               (p->rw ? "Write" : "Read"),
+               (p->pe ? "No-Perm" : "Has-Perm"),
+               (p->rz ? "Rsrv-Bit" : "Ill-Level"),
+               (p->tr ? "Translation" : "Transaction"));
+
+       pr_err("AMD-Vi: Type of error: (0x%x) ", err_type);
+       if ((ev_type == EVENT_TYPE_DEV_TAB_ERR)  ||
+           (ev_type == EVENT_TYPE_PAGE_TAB_ERR) ||
+           (ev_type == EVENT_TYPE_CMD_HARD_ERR)) {
+               if (err_type < ARRAY_SIZE(_type_field_encodings)) {
+                       pr_cont("%s\n",
+                               _type_field_encodings[err_type]);
+               }
+       } else if (ev_type == EVENT_TYPE_INV_DEV_REQ) {
+               if (p->tr == 0) {
+                       if (err_type < ARRAY_SIZE(_invalid_translation_desc))
+                               pr_cont("%s\n",
+                                       _invalid_translation_desc[err_type]);
+               } else {
+                       if (err_type < ARRAY_SIZE(_invalid_transaction_desc))
+                               pr_cont("%s\n",
+                                       _invalid_transaction_desc[err_type]);
+               }
+       }
+       pr_err("AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)\n");
+}
+
 static void dump_dte_entry(u16 devid)
 {
        int i;
@@ -619,81 +707,95 @@ static void dump_command(unsigned long phys_addr)
                pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]);
 }

-static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
+void amd_iommu_print_event(int type, int devid, int domid,
+                             int flags, u64 address)
 {
-       int type, devid, domid, flags;
-       volatile u32 *event = __evt;
-       int count = 0;
-       u64 address;
-
-retry:
-       type    = (event[1] >> EVENT_TYPE_SHIFT)  & EVENT_TYPE_MASK;
-       devid   = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
-       domid   = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
-       flags   = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
-       address = (u64)(((u64)event[3]) << 32) | event[2];
-
-       if (type == 0) {
-               /* Did we hit the erratum? */
-               if (++count == LOOP_TIMEOUT) {
-                       pr_err("AMD-Vi: No event written to event log\n");
-                       return;
-               }
-               udelay(1);
-               goto retry;
-       }
-
-       printk(KERN_ERR "AMD-Vi: Event logged [");
+       pr_err("AMD-Vi: Event logged [");

        switch (type) {
        case EVENT_TYPE_ILL_DEV:
-               printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
+               pr_cont("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);
+               dump_flags(flags, type);
                dump_dte_entry(devid);
                break;
        case EVENT_TYPE_IO_FAULT:
-               printk("IO_PAGE_FAULT device=%02x:%02x.%x "
+               pr_cont("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);
+               dump_flags(flags, type);
+               dump_dte_entry(devid);
                break;
        case EVENT_TYPE_DEV_TAB_ERR:
-               printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+               pr_cont("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);
+               dump_flags(flags, type);
                break;
        case EVENT_TYPE_PAGE_TAB_ERR:
-               printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+               pr_cont("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);
+               dump_flags(flags, type);
                break;
        case EVENT_TYPE_ILL_CMD:
-               printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
+               pr_cont("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
                dump_command(address);
                break;
        case EVENT_TYPE_CMD_HARD_ERR:
-               printk("COMMAND_HARDWARE_ERROR address=0x%016llx "
+               pr_cont("COMMAND_HARDWARE_ERROR address=0x%016llx "
                       "flags=0x%04x]\n", address, flags);
+               dump_flags(flags, type);
                break;
        case EVENT_TYPE_IOTLB_INV_TO:
-               printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
+               pr_cont("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 "
+               pr_cont("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);
+               dump_flags(flags, type);
+               dump_dte_entry(devid);
                break;
        default:
-               printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
+               pr_cont("UNKNOWN type=0x%02x]\n", type);
        }
+}
+
+static void iommu_handle_event(struct amd_iommu *iommu, void *__evt)
+{
+       int type, devid, domid, flags;
+       u32 *event = __evt;
+       int count = 0;
+       u64 address;
+
+retry:
+       type    = (event[1] >> EVENT_TYPE_SHIFT)  & EVENT_TYPE_MASK;
+       devid   = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
+       domid   = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
+       flags   = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
+       address = (u64)(((u64)event[3]) << 32) | event[2];
+
+       if (type == 0) {
+               /* Did we hit the erratum? */
+               if (++count == LOOP_TIMEOUT) {
+                       pr_err("AMD-Vi: No event written to event log\n");
+                       return;
+               }
+               udelay(1);
+               goto retry;
+       }
+
+       amd_iommu_print_event(type, devid, domid, flags, address);

        memset(__evt, 0, 4 * sizeof(u32));
 }
@@ -709,7 +811,7 @@ static void iommu_poll_events(struct amd_iommu *iommu)
        tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET);

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

@@ -3268,6 +3370,7 @@ static int __init alloc_passthrough_domain(void)

        return 0;
 }
+
 static int amd_iommu_domain_init(struct iommu_domain *dom)
 {
        struct protection_domain *domain;
--
1.7.10.4



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-08 14:50     ` Borislav Petkov
  0 siblings, 0 replies; 14+ messages in thread
From: Borislav Petkov @ 2013-04-08 14:50 UTC (permalink / raw)
  To: Suthikulpanit, Suravee; +Cc: iommu, joro, linux-kernel

On Mon, Apr 08, 2013 at 02:33:32PM +0000, Suthikulpanit, Suravee wrote:
> Joerg,
> 
> Do you have any more feedback about this patch?
> 
> Thanks,
> 
> Suravee
> ________________________________________
> From: suravee.suthikulpanit@amd.com [suravee.suthikulpanit@amd.com]
> Sent: Tuesday, April 02, 2013 7:06 PM
> To: iommu@lists.linux-foundation.org; joro@8bytes.org
> Cc: linux-kernel@vger.kernel.org; Suthikulpanit, Suravee
> Subject: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
> 
> From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> 
> Add logic to decode AMD IOMMU event flag based on information from AMD IOMMU specification.
> This should simplify debugging IOMMU errors.  Also, dump DTE information in additional cases.
> 
> This is an example:
> AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0000000000000000 flags=0x0fff]
> AMD-Vi: Flags details: Guest NX=1 User Intr Present Write No-Perm Rsrv-Bit Translation
> AMD-Vi: Type of error: (0x7)
> AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)

Independent from Joerg's feedback on this, I have only one question:
you're not seriously considering on dumping this "Note:..." line above
on *every* IO-PF, right?

I very positively assume that people who stare at that output should, as
a first prerequisite, know where to find those fields' descriptions. :-)

Thanks.

-- 
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-08 14:50     ` Borislav Petkov
  0 siblings, 0 replies; 14+ messages in thread
From: Borislav Petkov @ 2013-04-08 14:50 UTC (permalink / raw)
  To: Suthikulpanit, Suravee
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Mon, Apr 08, 2013 at 02:33:32PM +0000, Suthikulpanit, Suravee wrote:
> Joerg,
> 
> Do you have any more feedback about this patch?
> 
> Thanks,
> 
> Suravee
> ________________________________________
> From: suravee.suthikulpanit-5C7GfCeVMHo@public.gmane.org [suravee.suthikulpanit-5C7GfCeVMHo@public.gmane.org]
> Sent: Tuesday, April 02, 2013 7:06 PM
> To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org; joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org
> Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; Suthikulpanit, Suravee
> Subject: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
> 
> From: Suravee Suthikulpanit <suravee.suthikulpanit-5C7GfCeVMHo@public.gmane.org>
> 
> Add logic to decode AMD IOMMU event flag based on information from AMD IOMMU specification.
> This should simplify debugging IOMMU errors.  Also, dump DTE information in additional cases.
> 
> This is an example:
> AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0000000000000000 flags=0x0fff]
> AMD-Vi: Flags details: Guest NX=1 User Intr Present Write No-Perm Rsrv-Bit Translation
> AMD-Vi: Type of error: (0x7)
> AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)

Independent from Joerg's feedback on this, I have only one question:
you're not seriously considering on dumping this "Note:..." line above
on *every* IO-PF, right?

I very positively assume that people who stare at that output should, as
a first prerequisite, know where to find those fields' descriptions. :-)

Thanks.

-- 
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
       [not found]     ` <20130408145003.GC4723-fF5Pk5pvG8Y@public.gmane.org>
@ 2013-04-08 15:43       ` Suravee Suthikulanit
  2013-04-08 18:48           ` Borislav Petkov
  0 siblings, 1 reply; 14+ messages in thread
From: Suravee Suthikulanit @ 2013-04-08 15:43 UTC (permalink / raw)
  To: Borislav Petkov,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	joro-zLv9SwRftAIdnm+yROfE0A, linux-kernel-u79uwXL29TY76Z2rM5mHXA


[-- Attachment #1.1: Type: text/plain, Size: 290 bytes --]

On 4/8/2013 9:50 AM, Borislav Petkov wrote:
> Independent from Joerg's feedback on this, I have only one question:
> you're not seriously considering on dumping this "Note:..." line above
> on*every*  IO-PF, right?
Boris,

If you think that is obvious, I can get rid of this also.

Suravee

[-- Attachment #1.2: Type: text/html, Size: 766 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-08 18:48           ` Borislav Petkov
  0 siblings, 0 replies; 14+ messages in thread
From: Borislav Petkov @ 2013-04-08 18:48 UTC (permalink / raw)
  To: Suravee Suthikulanit; +Cc: iommu, joro, linux-kernel

On Mon, Apr 08, 2013 at 10:43:45AM -0500, Suravee Suthikulanit wrote:
> On 4/8/2013 9:50 AM, Borislav Petkov wrote:
> >Independent from Joerg's feedback on this, I have only one question:
> >you're not seriously considering on dumping this "Note:..." line above
> >on*every*  IO-PF, right?
> If you think that is obvious, I can get rid of this also.

I don't know whether it is obvious or not, but this thing doesn't belong
there. I'm sure you can think of a much better fitting location to point
to the documentation. And while you do that, you can simply add a link
to the pdf version of the spec so that people don't have to look for it
at all.

-- 
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-08 18:48           ` Borislav Petkov
  0 siblings, 0 replies; 14+ messages in thread
From: Borislav Petkov @ 2013-04-08 18:48 UTC (permalink / raw)
  To: Suravee Suthikulanit
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Mon, Apr 08, 2013 at 10:43:45AM -0500, Suravee Suthikulanit wrote:
> On 4/8/2013 9:50 AM, Borislav Petkov wrote:
> >Independent from Joerg's feedback on this, I have only one question:
> >you're not seriously considering on dumping this "Note:..." line above
> >on*every*  IO-PF, right?
> If you think that is obvious, I can get rid of this also.

I don't know whether it is obvious or not, but this thing doesn't belong
there. I'm sure you can think of a much better fitting location to point
to the documentation. And while you do that, you can simply add a link
to the pdf version of the spec so that people don't have to look for it
at all.

-- 
Regards/Gruss,
    Boris.

Sent from a fat crate under my desk. Formatting is fine.
--

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-09  9:41   ` Joerg Roedel
  0 siblings, 0 replies; 14+ messages in thread
From: Joerg Roedel @ 2013-04-09  9:41 UTC (permalink / raw)
  To: suravee.suthikulpanit; +Cc: iommu, linux-kernel

On Tue, Apr 02, 2013 at 07:06:50PM -0500, Suthikulpanit, Suravee wrote:
> From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> 
> Add logic to decode AMD IOMMU event flag based on information from AMD IOMMU specification.
> This should simplify debugging IOMMU errors.  Also, dump DTE information in additional cases.
> 
> This is an example:
> AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0000000000000000 flags=0x0fff]
> AMD-Vi: Flags details: Guest NX=1 User Intr Present Write No-Perm Rsrv-Bit Translation
> AMD-Vi: Type of error: (0x7) 
> AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)
> AMD-Vi: DTE[0]: 6000003fa75e2403
> AMD-Vi: DTE[1]: 0000000000000014
> AMD-Vi: DTE[2]: 2000003fa5e09011
> AMD-Vi: DTE[3]: 0000000000000000

This example should look like this instead:

AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0 flags: G NX US I P Wr Rsvd Tr]

by default. When the user passes amd_iommu=verbose on the cmd-line then
you can print additional information like "type of error" or the dump
the DTE.


	Joerg



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-09  9:41   ` Joerg Roedel
  0 siblings, 0 replies; 14+ messages in thread
From: Joerg Roedel @ 2013-04-09  9:41 UTC (permalink / raw)
  To: suravee.suthikulpanit-5C7GfCeVMHo
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tue, Apr 02, 2013 at 07:06:50PM -0500, Suthikulpanit, Suravee wrote:
> From: Suravee Suthikulpanit <suravee.suthikulpanit-5C7GfCeVMHo@public.gmane.org>
> 
> Add logic to decode AMD IOMMU event flag based on information from AMD IOMMU specification.
> This should simplify debugging IOMMU errors.  Also, dump DTE information in additional cases.
> 
> This is an example:
> AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0000000000000000 flags=0x0fff]
> AMD-Vi: Flags details: Guest NX=1 User Intr Present Write No-Perm Rsrv-Bit Translation
> AMD-Vi: Type of error: (0x7) 
> AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)
> AMD-Vi: DTE[0]: 6000003fa75e2403
> AMD-Vi: DTE[1]: 0000000000000014
> AMD-Vi: DTE[2]: 2000003fa5e09011
> AMD-Vi: DTE[3]: 0000000000000000

This example should look like this instead:

AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0 flags: G NX US I P Wr Rsvd Tr]

by default. When the user passes amd_iommu=verbose on the cmd-line then
you can print additional information like "type of error" or the dump
the DTE.


	Joerg

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-09 15:12     ` Suravee Suthikulanit
  0 siblings, 0 replies; 14+ messages in thread
From: Suravee Suthikulanit @ 2013-04-09 15:12 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: iommu, linux-kernel

On 4/9/2013 4:41 AM, Joerg Roedel wrote:
> On Tue, Apr 02, 2013 at 07:06:50PM -0500, Suthikulpanit, Suravee wrote:
>> From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
>>
>> Add logic to decode AMD IOMMU event flag based on information from AMD IOMMU specification.
>> This should simplify debugging IOMMU errors.  Also, dump DTE information in additional cases.
>>
>> This is an example:
>> AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0000000000000000 flags=0x0fff]
>> AMD-Vi: Flags details: Guest NX=1 User Intr Present Write No-Perm Rsrv-Bit Translation
>> AMD-Vi: Type of error: (0x7)
>> AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)
>> AMD-Vi: DTE[0]: 6000003fa75e2403
>> AMD-Vi: DTE[1]: 0000000000000014
>> AMD-Vi: DTE[2]: 2000003fa5e09011
>> AMD-Vi: DTE[3]: 0000000000000000
> This example should look like this instead:
>
> AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0 flags: G NX US I P Wr Rsvd Tr]
>
> by default. When the user passes amd_iommu=verbose on the cmd-line then
> you can print additional information like "type of error" or the dump
> the DTE.
>
>
> 	Joerg
Joerg,

- I can fit DTE dump all in one line (to reduce the number of lines). 
But it is necessary for debugging certain events.
- The "type of error" is also part of the flag translation for certain 
event.  It will only print if it is necessary.
- I can remove the "Note: ... " per Boris's request.
- I can shorten the flag details even more.

Here are some new examples:
[  156.177883] AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 
domain=0x0000 address=0x0000000000000000]
[  156.177895] AMD-Vi: Flags: Gst NX Usr Int P W N-Perm Rsrv Trnslt
[  156.177898] AMD-Vi: Type of error: (0x7)
[  156.177899] AMD-Vi: DTE[0 .. 3]: 6000007fa764f403 0000000000000014 
2000003fabb41811 0000000000000000

[  197.353900] AMD-Vi: Event logged [PAGE_TAB_HARDWARE_ERROR 
device=51:00.0 domain=0x0000 address=0x0000000000000000]
[  197.353917] AMD-Vi: Flags: Gst NX Usr Int P W N-Perm Rsrv Trnslt

These messages are not "high volumn".  What I am trying to achieve is 
for users to be able to just send the errors to developers once they are 
encountered without having to tell them to go back and reboot with the 
"amd_iommu=verbose". In facts, they often difficult to reproduce from my 
experience.  This should reduce the amount of communications and efforts 
required to debug the issue.

If you are ok with this, I will send out V4 in the next email.

Thank you,

Suravee


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-09 15:12     ` Suravee Suthikulanit
  0 siblings, 0 replies; 14+ messages in thread
From: Suravee Suthikulanit @ 2013-04-09 15:12 UTC (permalink / raw)
  To: Joerg Roedel
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 4/9/2013 4:41 AM, Joerg Roedel wrote:
> On Tue, Apr 02, 2013 at 07:06:50PM -0500, Suthikulpanit, Suravee wrote:
>> From: Suravee Suthikulpanit <suravee.suthikulpanit-5C7GfCeVMHo@public.gmane.org>
>>
>> Add logic to decode AMD IOMMU event flag based on information from AMD IOMMU specification.
>> This should simplify debugging IOMMU errors.  Also, dump DTE information in additional cases.
>>
>> This is an example:
>> AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0000000000000000 flags=0x0fff]
>> AMD-Vi: Flags details: Guest NX=1 User Intr Present Write No-Perm Rsrv-Bit Translation
>> AMD-Vi: Type of error: (0x7)
>> AMD-Vi: (Note: Please refer to AMD IOMMU specification for details.)
>> AMD-Vi: DTE[0]: 6000003fa75e2403
>> AMD-Vi: DTE[1]: 0000000000000014
>> AMD-Vi: DTE[2]: 2000003fa5e09011
>> AMD-Vi: DTE[3]: 0000000000000000
> This example should look like this instead:
>
> AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 domain=0x0000 address=0x0 flags: G NX US I P Wr Rsvd Tr]
>
> by default. When the user passes amd_iommu=verbose on the cmd-line then
> you can print additional information like "type of error" or the dump
> the DTE.
>
>
> 	Joerg
Joerg,

- I can fit DTE dump all in one line (to reduce the number of lines). 
But it is necessary for debugging certain events.
- The "type of error" is also part of the flag translation for certain 
event.  It will only print if it is necessary.
- I can remove the "Note: ... " per Boris's request.
- I can shorten the flag details even more.

Here are some new examples:
[  156.177883] AMD-Vi: Event logged [IO_PAGE_FAULT device=51:00.0 
domain=0x0000 address=0x0000000000000000]
[  156.177895] AMD-Vi: Flags: Gst NX Usr Int P W N-Perm Rsrv Trnslt
[  156.177898] AMD-Vi: Type of error: (0x7)
[  156.177899] AMD-Vi: DTE[0 .. 3]: 6000007fa764f403 0000000000000014 
2000003fabb41811 0000000000000000

[  197.353900] AMD-Vi: Event logged [PAGE_TAB_HARDWARE_ERROR 
device=51:00.0 domain=0x0000 address=0x0000000000000000]
[  197.353917] AMD-Vi: Flags: Gst NX Usr Int P W N-Perm Rsrv Trnslt

These messages are not "high volumn".  What I am trying to achieve is 
for users to be able to just send the errors to developers once they are 
encountered without having to tell them to go back and reboot with the 
"amd_iommu=verbose". In facts, they often difficult to reproduce from my 
experience.  This should reduce the amount of communications and efforts 
required to debug the issue.

If you are ok with this, I will send out V4 in the next email.

Thank you,

Suravee

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-09 19:52       ` Joerg Roedel
  0 siblings, 0 replies; 14+ messages in thread
From: Joerg Roedel @ 2013-04-09 19:52 UTC (permalink / raw)
  To: Suravee Suthikulanit; +Cc: iommu, linux-kernel

On Tue, Apr 09, 2013 at 10:12:13AM -0500, Suthikulpanit, Suravee wrote:
> These messages are not "high volumn".  What I am trying to achieve
> is for users to be able to just send the errors to developers once
> they are encountered without having to tell them to go back and
> reboot with the "amd_iommu=verbose". In facts, they often difficult
> to reproduce from my experience.  This should reduce the amount of
> communications and efforts required to debug the issue.

More than one line per io-page-fault _is_ high volume. The current code
that prints only one line was sufficient to debug all related AMD IOMMU
driver problems in the past 5 years I am working on this driver.

What makes sense is decoding the flags field in the kernel. Doing this
by hand always costs some time that could be saved this way. If your
patch does more than that by default I am not going to merge it.


	Joerg



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag
@ 2013-04-09 19:52       ` Joerg Roedel
  0 siblings, 0 replies; 14+ messages in thread
From: Joerg Roedel @ 2013-04-09 19:52 UTC (permalink / raw)
  To: Suravee Suthikulanit
  Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tue, Apr 09, 2013 at 10:12:13AM -0500, Suthikulpanit, Suravee wrote:
> These messages are not "high volumn".  What I am trying to achieve
> is for users to be able to just send the errors to developers once
> they are encountered without having to tell them to go back and
> reboot with the "amd_iommu=verbose". In facts, they often difficult
> to reproduce from my experience.  This should reduce the amount of
> communications and efforts required to debug the issue.

More than one line per io-page-fault _is_ high volume. The current code
that prints only one line was sufficient to debug all related AMD IOMMU
driver problems in the past 5 years I am working on this driver.

What makes sense is decoding the flags field in the kernel. Doing this
by hand always costs some time that could be saved this way. If your
patch does more than that by default I am not going to merge it.


	Joerg

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-04-09 19:52 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-03  0:06 [PATCH V3] iommu/amd: Add logic to decode AMD IOMMU event flag suravee.suthikulpanit
2013-04-03  0:06 ` suravee.suthikulpanit
2013-04-08 14:33 ` Suthikulpanit, Suravee
2013-04-08 14:50   ` Borislav Petkov
2013-04-08 14:50     ` Borislav Petkov
     [not found]     ` <20130408145003.GC4723-fF5Pk5pvG8Y@public.gmane.org>
2013-04-08 15:43       ` Suravee Suthikulanit
2013-04-08 18:48         ` Borislav Petkov
2013-04-08 18:48           ` Borislav Petkov
2013-04-09  9:41 ` Joerg Roedel
2013-04-09  9:41   ` Joerg Roedel
2013-04-09 15:12   ` Suravee Suthikulanit
2013-04-09 15:12     ` Suravee Suthikulanit
2013-04-09 19:52     ` Joerg Roedel
2013-04-09 19:52       ` Joerg Roedel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.