b/arch/x86/include/asm/amd_iommu_types.h
@@ -96,6 +96,16 @@
#define EVENT_FLAGS_MASK 0xfff
#define EVENT_FLAGS_SHIFT 0x10
+#define EVENT_FLAGS_RESERVED1 0x0
+#define EVENT_FLAGS_RESERVED_SIZE 0x3
+#define EVENT_FLAGS_INT (EVENT_FLAGS_RESERVED1 + EVENT_FLAGS_RESERVED_SIZE)
+#define EVENT_FLAGS_PR (EVENT_FLAGS_INT + 0x1)
+#define EVENT_FLAGS_RW (EVENT_FLAGS_PR + 0x1)
+#define EVENT_FLAGS_PE (EVENT_FLAGS_RW + 0x1)
+#define EVENT_FLAGS_RZ (EVENT_FLAGS_PE + 0x1)
+#define EVENT_FLAGS_TR (EVENT_FLAGS_RZ + 0x1)
+#define EVENT_FLAGS_RESERVED2 (EVENT_FLAGS_TR + 0x1)
+
/* feature control bits */
#define CONTROL_IOMMU_EN 0x00ULL
#define CONTROL_HT_TUN_EN 0x01ULL
@@ -283,6 +283,44 @@ static void dump_command(unsigned long phys_addr)
pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]);
}
+static void inline dump_page_fault(int flags)
+{
+ int i = (flags >> EVENT_FLAGS_INT) & 0x1;
+ int pr = (flags >> EVENT_FLAGS_PR) & 0x1;
+ int rw = (flags >> EVENT_FLAGS_RW) & 0x1;
+ int pe = (flags >> EVENT_FLAGS_PE) & 0x1;
+ int rz = (flags >> EVENT_FLAGS_RZ) & 0x1;
+ int tr = (flags >> EVENT_FLAGS_TR) & 0x1;
+
+ const char *i_pr[] = {
+ "to page marked not present",
+ "to page marked present",
+ "to interrupt marked blocked",
+ "to interrupt marked remapped"
+ };
+
+ const char *tr_s[2] = {
+ "transaction",
+ "translation"
+ };
+
+ const char *type[2] = {
+ "read",
+ "write"
+ };
+
+ const char *permission[2] = {
+ "peripheral had permission",
+ "peripheral had no permission",
+ };
+
+ pr_err("AMD-Vi: \t%s %s", tr_s[tr], i_pr[(i<<1)|pr]);
+ pr_err("AMD-Vi: \t%s type: %s", tr_s[tr], type[rw]);
+ if (pr) {
+ pr_err("AMD-Vi: \t%s", permission[pe]);
+ }
+}
+
static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
{
u32 *event = __evt;
@@ -307,6 +345,7 @@ static void iommu_print_event(struct amd_iommu
*iommu, void *__evt)
"domain=0x%04x address=0x%016llx flags=0x%04x]\n",
PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid),
domid, address, flags);
+ dump_page_fault(flags);
break;
case EVENT_TYPE_DEV_TAB_ERR: