powerpc/mm: Update definitions of DSISR bits
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 19 Jul 2017 04:49:26 +0000 (14:49 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 3 Aug 2017 06:06:43 +0000 (16:06 +1000)
This updates the definitions for the various DSISR bits to
match both some historical stuff and to match new bits on
POWER9.

In addition, we define some masks corresponding to the "bad"
faults on Book3S, and some masks corresponding to the bits
that match between DSISR and SRR1 for a DSI and an ISI.

This comes with a small code update to change the definition
of DSISR_PGDIRFAULT which becomes DSISR_PRTABLE_FAULT to
match architecture 3.0B

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/reg.h
arch/powerpc/kvm/book3s_64_mmu_radix.c

index a3b6575..73be2f7 100644 (file)
 #define SPRN_DAR       0x013   /* Data Address Register */
 #define SPRN_DBCR      0x136   /* e300 Data Breakpoint Control Reg */
 #define SPRN_DSISR     0x012   /* Data Storage Interrupt Status Register */
-#define   DSISR_NOHPTE         0x40000000      /* no translation found */
-#define   DSISR_PROTFAULT      0x08000000      /* protection fault */
-#define   DSISR_BADACCESS      0x04000000      /* bad access to CI or G */
-#define   DSISR_ISSTORE                0x02000000      /* access was a store */
-#define   DSISR_DABRMATCH      0x00400000      /* hit data breakpoint */
-#define   DSISR_NOSEGMENT      0x00200000      /* SLB miss */
-#define   DSISR_KEYFAULT       0x00200000      /* Key fault */
-#define   DSISR_UNSUPP_MMU     0x00080000      /* Unsupported MMU config */
-#define   DSISR_SET_RC         0x00040000      /* Failed setting of R/C bits */
-#define   DSISR_PGDIRFAULT      0x00020000      /* Fault on page directory */
+#define   DSISR_BAD_DIRECT_ST  0x80000000 /* Obsolete: Direct store error */
+#define   DSISR_NOHPTE         0x40000000 /* no translation found */
+#define   DSISR_ATTR_CONFLICT  0x20000000 /* P9: Process vs. Partition attr */
+#define   DSISR_NOEXEC_OR_G    0x10000000 /* Alias of SRR1 bit, see below */
+#define   DSISR_PROTFAULT      0x08000000 /* protection fault */
+#define   DSISR_BADACCESS      0x04000000 /* bad access to CI or G */
+#define   DSISR_ISSTORE                0x02000000 /* access was a store */
+#define   DSISR_DABRMATCH      0x00400000 /* hit data breakpoint */
+#define   DSISR_NOSEGMENT      0x00200000 /* STAB miss (unsupported) */
+#define   DSISR_KEYFAULT       0x00200000 /* Storage Key fault */
+#define   DSISR_BAD_EXT_CTRL   0x00100000 /* Obsolete: External ctrl error */
+#define   DSISR_UNSUPP_MMU     0x00080000 /* P9: Unsupported MMU config */
+#define   DSISR_SET_RC         0x00040000 /* P9: Failed setting of R/C bits */
+#define   DSISR_PRTABLE_FAULT   0x00020000 /* P9: Fault on process table */
+#define   DSISR_ICSWX_NO_CT     0x00004000 /* P7: icswx unavailable cp type */
+#define   DSISR_BAD_COPYPASTE   0x00000008 /* P9: Copy/Paste on wrong memtype */
+#define   DSISR_BAD_AMO                0x00000004 /* P9: Incorrect AMO opcode */
+#define   DSISR_BAD_CI_LDST    0x00000002 /* P8: Bad HV CI load/store */
+
+/*
+ * DSISR_NOEXEC_OR_G doesn't actually exist. This bit is always
+ * 0 on DSIs. However, on ISIs, the corresponding bit in SRR1
+ * indicates an attempt at executing from a no-execute PTE
+ * or segment or from a guarded page.
+ *
+ * We add a definition here for completeness as we alias
+ * DSISR and SRR1 in do_page_fault.
+ */
+
+/*
+ * DSISR bits that are treated as a fault. Any bit set
+ * here will skip hash_page, and cause do_page_fault to
+ * trigger a SIGBUS or SIGSEGV:
+ */
+#define   DSISR_BAD_FAULT_32S  (DSISR_BAD_DIRECT_ST    | \
+                                DSISR_BADACCESS        | \
+                                DSISR_BAD_EXT_CTRL)
+#define          DSISR_BAD_FAULT_64S   (DSISR_BAD_FAULT_32S    | \
+                                DSISR_ATTR_CONFLICT    | \
+                                DSISR_KEYFAULT         | \
+                                DSISR_UNSUPP_MMU       | \
+                                DSISR_PRTABLE_FAULT    | \
+                                DSISR_ICSWX_NO_CT      | \
+                                DSISR_BAD_COPYPASTE    | \
+                                DSISR_BAD_AMO          | \
+                                DSISR_BAD_CI_LDST)
+/*
+ * These bits are equivalent in SRR1 and DSISR for 0x400
+ * instruction access interrupts on Book3S
+ */
+#define   DSISR_SRR1_MATCH_32S (DSISR_NOHPTE           | \
+                                DSISR_NOEXEC_OR_G      | \
+                                DSISR_PROTFAULT)
+#define   DSISR_SRR1_MATCH_64S (DSISR_SRR1_MATCH_32S   | \
+                                DSISR_KEYFAULT         | \
+                                DSISR_UNSUPP_MMU       | \
+                                DSISR_SET_RC           | \
+                                DSISR_PRTABLE_FAULT)
+
 #define SPRN_TBRL      0x10C   /* Time Base Read Lower Register (user, R/O) */
 #define SPRN_TBRU      0x10D   /* Time Base Read Upper Register (user, R/O) */
 #define SPRN_CIR       0x11B   /* Chip Information Register (hyper, R/0) */
index f6b3e67..6d677c7 100644 (file)
@@ -322,13 +322,13 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
        gpa = vcpu->arch.fault_gpa & ~0xfffUL;
        gpa &= ~0xF000000000000000ul;
        gfn = gpa >> PAGE_SHIFT;
-       if (!(dsisr & DSISR_PGDIRFAULT))
+       if (!(dsisr & DSISR_PRTABLE_FAULT))
                gpa |= ea & 0xfff;
        memslot = gfn_to_memslot(kvm, gfn);
 
        /* No memslot means it's an emulated MMIO region */
        if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) {
-               if (dsisr & (DSISR_PGDIRFAULT | DSISR_BADACCESS |
+               if (dsisr & (DSISR_PRTABLE_FAULT | DSISR_BADACCESS |
                             DSISR_SET_RC)) {
                        /*
                         * Bad address in guest page table tree, or other