Commit 870cfe77 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Michael Ellerman

powerpc/mm: Update definitions of DSISR bits

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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent d300627c
...@@ -272,16 +272,65 @@ ...@@ -272,16 +272,65 @@
#define SPRN_DAR 0x013 /* Data Address Register */ #define SPRN_DAR 0x013 /* Data Address Register */
#define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */ #define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
#define DSISR_BAD_DIRECT_ST 0x80000000 /* Obsolete: Direct store error */
#define DSISR_NOHPTE 0x40000000 /* no translation found */ #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_PROTFAULT 0x08000000 /* protection fault */
#define DSISR_BADACCESS 0x04000000 /* bad access to CI or G */ #define DSISR_BADACCESS 0x04000000 /* bad access to CI or G */
#define DSISR_ISSTORE 0x02000000 /* access was a store */ #define DSISR_ISSTORE 0x02000000 /* access was a store */
#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
#define DSISR_NOSEGMENT 0x00200000 /* SLB miss */ #define DSISR_NOSEGMENT 0x00200000 /* STAB miss (unsupported) */
#define DSISR_KEYFAULT 0x00200000 /* Key fault */ #define DSISR_KEYFAULT 0x00200000 /* Storage Key fault */
#define DSISR_UNSUPP_MMU 0x00080000 /* Unsupported MMU config */ #define DSISR_BAD_EXT_CTRL 0x00100000 /* Obsolete: External ctrl error */
#define DSISR_SET_RC 0x00040000 /* Failed setting of R/C bits */ #define DSISR_UNSUPP_MMU 0x00080000 /* P9: Unsupported MMU config */
#define DSISR_PGDIRFAULT 0x00020000 /* Fault on page directory */ #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_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */
#define SPRN_TBRU 0x10D /* Time Base Read Upper 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) */ #define SPRN_CIR 0x11B /* Chip Information Register (hyper, R/0) */
......
...@@ -322,13 +322,13 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, ...@@ -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 = vcpu->arch.fault_gpa & ~0xfffUL;
gpa &= ~0xF000000000000000ul; gpa &= ~0xF000000000000000ul;
gfn = gpa >> PAGE_SHIFT; gfn = gpa >> PAGE_SHIFT;
if (!(dsisr & DSISR_PGDIRFAULT)) if (!(dsisr & DSISR_PRTABLE_FAULT))
gpa |= ea & 0xfff; gpa |= ea & 0xfff;
memslot = gfn_to_memslot(kvm, gfn); memslot = gfn_to_memslot(kvm, gfn);
/* No memslot means it's an emulated MMIO region */ /* No memslot means it's an emulated MMIO region */
if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) { if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) {
if (dsisr & (DSISR_PGDIRFAULT | DSISR_BADACCESS | if (dsisr & (DSISR_PRTABLE_FAULT | DSISR_BADACCESS |
DSISR_SET_RC)) { DSISR_SET_RC)) {
/* /*
* Bad address in guest page table tree, or other * Bad address in guest page table tree, or other
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment