* [PATCH 1/2] powerpc: Add workaround for P9 vector CI load issue
@ 2017-09-15 5:25 Michael Neuling
2017-09-15 5:25 ` [PATCH 2/2] powerpc: Handle MCE on POWER9 with only DSISR bit 33 set Michael Neuling
2017-09-27 10:32 ` [1/2] powerpc: Add workaround for P9 vector CI load issue Michael Ellerman
0 siblings, 2 replies; 6+ messages in thread
From: Michael Neuling @ 2017-09-15 5:25 UTC (permalink / raw)
To: mpe; +Cc: linuxppc-dev, mikey, benh
POWER9 DD2.1 and earlier has an issue where some cache inhibited
vector load will return bad data. The workaround is two part, one
firmware/microcode part triggers HMI interrupts when hitting such
loads, the other part is this patch which then emulates the
instructions in Linux.
The affected instructions are limited to lxvd2x, lxvw4x, lxvb16x and
lxvh8x.
When an instruction triggers the HMI, all threads in the core will be
sent to the HMI handler, not just the one running the vector load.
In general, these spurious HMIs are detected by the emulation code and
we just return back to the running process. Unfortunately, if a
spurious interrupt occurs on a vector load that's to normal memory we
have no way to detect that it's spurious (unless we walk the page
tables, which is very expensive). In this case we emulate the load but
we need do so using a vector load itself to ensure 128bit atomicity is
preserved.
Some additional debugfs emulated instruction counters are added also.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/emulated_ops.h | 4 +
arch/powerpc/include/asm/paca.h | 1 +
arch/powerpc/include/asm/uaccess.h | 17 +++
arch/powerpc/kernel/exceptions-64s.S | 16 ++-
arch/powerpc/kernel/mce.c | 30 ++++-
arch/powerpc/kernel/traps.c | 201 ++++++++++++++++++++++++++++++++
arch/powerpc/platforms/powernv/smp.c | 7 ++
7 files changed, 271 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h
index f00e10e2a3..651e135449 100644
--- a/arch/powerpc/include/asm/emulated_ops.h
+++ b/arch/powerpc/include/asm/emulated_ops.h
@@ -55,6 +55,10 @@ extern struct ppc_emulated {
struct ppc_emulated_entry mfdscr;
struct ppc_emulated_entry mtdscr;
struct ppc_emulated_entry lq_stq;
+ struct ppc_emulated_entry lxvw4x;
+ struct ppc_emulated_entry lxvh8x;
+ struct ppc_emulated_entry lxvd2x;
+ struct ppc_emulated_entry lxvb16x;
#endif
} ppc_emulated;
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 04b60af027..1e06310ccc 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -210,6 +210,7 @@ struct paca_struct {
*/
u16 in_mce;
u8 hmi_event_available; /* HMI event is available */
+ u8 hmi_p9_special_emu; /* HMI P9 special emulation */
#endif
/* Stuff for accurate time accounting */
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 9c0e60ca16..e34f15e727 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -173,6 +173,23 @@ do { \
extern long __get_user_bad(void);
+/*
+ * This does an atomic 128 byte aligned load from userspace.
+ * Upto caller to do enable_kernel_vmx() before calling!
+ */
+#define __get_user_atomic_128_aligned(kaddr, uaddr, err) \
+ __asm__ __volatile__( \
+ "1: lvx 0,0,%1 # get user\n" \
+ " stvx 0,0,%2 # put kernel\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,%3\n" \
+ " b 2b\n" \
+ ".previous\n" \
+ EX_TABLE(1b, 3b) \
+ : "=r" (err) \
+ : "b" (uaddr), "b" (kaddr), "i" (-EFAULT), "0" (err))
+
#define __get_user_asm(x, addr, err, op) \
__asm__ __volatile__( \
"1: "op" %1,0(%2) # get_user\n" \
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 48da0f5d2f..8c32dd4cac 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1010,6 +1010,8 @@ TRAMP_REAL_BEGIN(hmi_exception_early)
EXCEPTION_PROLOG_COMMON_3(0xe60)
addi r3,r1,STACK_FRAME_OVERHEAD
BRANCH_LINK_TO_FAR(hmi_exception_realmode) /* Function call ABI */
+ cmpdi cr0,r3,0
+
/* Windup the stack. */
/* Move original HSRR0 and HSRR1 into the respective regs */
ld r9,_MSR(r1)
@@ -1026,10 +1028,15 @@ TRAMP_REAL_BEGIN(hmi_exception_early)
REST_8GPRS(2, r1)
REST_GPR(10, r1)
ld r11,_CCR(r1)
+ REST_2GPRS(12, r1)
+ bne 1f
mtcr r11
REST_GPR(11, r1)
- REST_2GPRS(12, r1)
- /* restore original r1. */
+ ld r1,GPR1(r1)
+ hrfid
+
+1: mtcr r11
+ REST_GPR(11, r1)
ld r1,GPR1(r1)
/*
@@ -1042,8 +1049,9 @@ hmi_exception_after_realmode:
EXCEPTION_PROLOG_0(PACA_EXGEN)
b tramp_real_hmi_exception
-EXC_COMMON_ASYNC(hmi_exception_common, 0xe60, handle_hmi_exception)
-
+EXC_COMMON_BEGIN(hmi_exception_common)
+EXCEPTION_COMMON(PACA_EXGEN, 0xe60, hmi_exception_common, handle_hmi_exception,
+ ret_from_except, FINISH_NAP;ADD_NVGPRS;ADD_RECONCILE;RUNLATCH_ON)
EXC_REAL_OOL_MASKABLE_HV(h_doorbell, 0xe80, 0x20)
EXC_VIRT_OOL_MASKABLE_HV(h_doorbell, 0x4e80, 0x20, 0xe80)
diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c
index 9b2ea7e71c..f588951b17 100644
--- a/arch/powerpc/kernel/mce.c
+++ b/arch/powerpc/kernel/mce.c
@@ -470,6 +470,34 @@ long hmi_exception_realmode(struct pt_regs *regs)
{
__this_cpu_inc(irq_stat.hmi_exceptions);
+#ifdef CONFIG_PPC_BOOK3S_64
+ /* Workaround for P9 vector CI loads (see p9_hmi_special_emu) */
+ if (pvr_version_is(PVR_POWER9)) {
+ unsigned long hmer = mfspr(SPRN_HMER);
+
+ /* Do we have the debug bit set */
+ if (hmer & PPC_BIT(17)) {
+ hmer &= ~PPC_BIT(17);
+ mtspr(SPRN_HMER, hmer);
+
+ /*
+ * Now to avoid problems with soft-disable we
+ * only do the emulation if we are coming from
+ * user space
+ */
+ if (user_mode(regs))
+ local_paca->hmi_p9_special_emu = 1;
+
+ /*
+ * Don't bother going to OPAL if that's the
+ * only relevant bit.
+ */
+ if (!(hmer & mfspr(SPRN_HMEER)))
+ return local_paca->hmi_p9_special_emu;
+ }
+ }
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
wait_for_subcore_guest_exit();
if (ppc_md.hmi_exception_early)
@@ -477,5 +505,5 @@ long hmi_exception_realmode(struct pt_regs *regs)
wait_for_tb_resync();
- return 0;
+ return 1;
}
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index ec74e203ee..9b9bdf15e4 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -37,6 +37,7 @@
#include <linux/kdebug.h>
#include <linux/ratelimit.h>
#include <linux/context_tracking.h>
+#include <linux/smp.h>
#include <asm/emulated_ops.h>
#include <asm/pgtable.h>
@@ -691,6 +692,187 @@ void SMIException(struct pt_regs *regs)
die("System Management Interrupt", regs, SIGABRT);
}
+#ifdef CONFIG_PPC_BOOK3S_64
+static void p9_hmi_special_emu(struct pt_regs *regs)
+{
+ unsigned int ra, rb, t, i, sel, instr, rc;
+ const void __user *addr;
+ u8 vbuf[16], *vdst;
+ unsigned long ea, msr, msr_mask;
+ bool swap;
+
+ if (__get_user_inatomic(instr, (unsigned int __user *)regs->nip))
+ return;
+
+ /*
+ * lxvb16x opcode: 0x7c0006d8
+ * lxvd2x opcode: 0x7c000698
+ * lxvh8x opcode: 0x7c000658
+ * lxvw4x opcode: 0x7c000618
+ */
+ if ((instr & 0xfc00073e) != 0x7c000618) {
+ pr_devel("HMI vec emu: not vector CI %i:%s[%d] nip=%016lx"
+ " instr=%08x\n",
+ smp_processor_id(), current->comm, current->pid,
+ regs->nip, instr);
+ return;
+ }
+
+ /* Grab vector registers into the task struct */
+ msr = regs->msr; /* Grab msr before we flush the bits */
+ flush_vsx_to_thread(current);
+ enable_kernel_altivec();
+
+ /*
+ * Is userspace running with a different endian (this is rare but
+ * impossible
+ */
+ swap = (msr & MSR_LE) != (MSR_KERNEL & MSR_LE);
+
+ /* Decode the instruction */
+ ra = (instr >> 16) & 0x1f;
+ rb = (instr >> 11) & 0x1f;
+ t = (instr >> 21) & 0x1f;
+ if (instr & 1)
+ vdst = (u8 *)¤t->thread.vr_state.vr[t];
+ else
+ vdst = (u8 *)¤t->thread.fp_state.fpr[t][0];
+
+ /* Grab the vector address */
+ ea = regs->gpr[rb] + (ra ? regs->gpr[ra] : 0);
+ if (is_32bit_task())
+ ea &= 0xfffffffful;
+ addr = (__force const void __user *)ea;
+
+ /* Check it */
+ if (!access_ok(VERIFY_READ, addr, 16)) {
+ pr_devel("HMI vec emu: bad access %i:%s[%d] nip=%016lx"
+ " instr=%08x addr=%016lx\n",
+ smp_processor_id(), current->comm, current->pid,
+ regs->nip, instr, (unsigned long)addr);
+ return;
+ }
+
+ /* Read the vector */
+ rc = 0;
+ if ((unsigned long)addr & 0xfUL)
+ /* unaligned case */
+ rc = __copy_from_user_inatomic(vbuf, addr, 16);
+ else
+ __get_user_atomic_128_aligned(vbuf, addr, rc);
+ if (rc) {
+ pr_devel("HMI vec emu: page fault %i:%s[%d] nip=%016lx"
+ " instr=%08x addr=%016lx\n",
+ smp_processor_id(), current->comm, current->pid,
+ regs->nip, instr, (unsigned long)addr);
+ return;
+ }
+
+ pr_devel("HMI vec emu: emulated vector CI %i:%s[%d] nip=%016lx"
+ " instr=%08x addr=%016lx\n",
+ smp_processor_id(), current->comm, current->pid, regs->nip,
+ instr, (unsigned long) addr);
+
+ /* Grab instruction "selector" */
+ sel = (instr >> 6) & 3;
+
+ /*
+ * Check to make sure the facility is actually enabled. This
+ * could happen if we get a false positive hit.
+ *
+ * lxvd2x/lxvw4x always check MSR VSX sel = 0,2
+ * lxvh8x/lxvb16x check MSR VSX or VEC depending on VSR used sel = 1,3
+ */
+ msr_mask = MSR_VSX;
+ if ((sel & 1) && (instr & 1)) /* lxvh8x & lxvb16x + VSR >= 32 */
+ msr_mask = MSR_VEC;
+ if (!(msr & msr_mask)) {
+ pr_devel("HMI vec emu: MSR fac clear %i:%s[%d] nip=%016lx"
+ " instr=%08x msr:%016lx\n",
+ smp_processor_id(), current->comm, current->pid,
+ regs->nip, instr, msr);
+ return;
+ }
+
+ /* Do logging here before we modify sel based on endian */
+ switch (sel) {
+ case 0: /* lxvw4x */
+ PPC_WARN_EMULATED(lxvw4x, regs);
+ break;
+ case 1: /* lxvh8x */
+ PPC_WARN_EMULATED(lxvh8x, regs);
+ break;
+ case 2: /* lxvd2x */
+ PPC_WARN_EMULATED(lxvd2x, regs);
+ break;
+ case 3: /* lxvb16x */
+ PPC_WARN_EMULATED(lxvb16x, regs);
+ break;
+ }
+
+#ifdef __LITTLE_ENDIAN__
+ /*
+ * An LE kernel stores the vector in the task struct as an LE
+ * byte array (effectively swapping both the components and
+ * the content of the components). Those instructions expect
+ * the components to remain in ascending address order, so we
+ * swap them back.
+ *
+ * If we are running a BE user space, the expectation is that
+ * of a simple memcpy, so forcing the emulation to look like
+ * a lxvb16x should do the trick.
+ */
+ if (swap)
+ sel = 3;
+
+ switch (sel) {
+ case 0: /* lxvw4x */
+ for (i = 0; i < 4; i++)
+ ((u32 *)vdst)[i] = ((u32 *)vbuf)[3-i];
+ break;
+ case 1: /* lxvh8x */
+ for (i = 0; i < 8; i++)
+ ((u16 *)vdst)[i] = ((u16 *)vbuf)[7-i];
+ break;
+ case 2: /* lxvd2x */
+ for (i = 0; i < 2; i++)
+ ((u64 *)vdst)[i] = ((u64 *)vbuf)[1-i];
+ break;
+ case 3: /* lxvb16x */
+ for (i = 0; i < 16; i++)
+ vdst[i] = vbuf[15-i];
+ break;
+ }
+#else /* __LITTLE_ENDIAN__ */
+ /* On a big endian kernel, a BE userspace only needs a memcpy */
+ if (!swap)
+ sel = 3;
+
+ /* Otherwise, we need to swap the content of the components */
+ switch (sel) {
+ case 0: /* lxvw4x */
+ for (i = 0; i < 4; i++)
+ ((u32 *)vdst)[i] = cpu_to_le32(((u32 *)vbuf)[i]);
+ break;
+ case 1: /* lxvh8x */
+ for (i = 0; i < 8; i++)
+ ((u16 *)vdst)[i] = cpu_to_le16(((u16 *)vbuf)[i]);
+ break;
+ case 2: /* lxvd2x */
+ for (i = 0; i < 2; i++)
+ ((u64 *)vdst)[i] = cpu_to_le64(((u64 *)vbuf)[i]);
+ break;
+ case 3: /* lxvb16x */
+ memcpy(vdst, vbuf, 16);
+ break;
+ }
+#endif /* !__LITTLE_ENDIAN__ */
+
+ /* Go to next instruction */
+ regs->nip += 4;
+}
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
void handle_hmi_exception(struct pt_regs *regs)
{
struct pt_regs *old_regs;
@@ -698,6 +880,21 @@ void handle_hmi_exception(struct pt_regs *regs)
old_regs = set_irq_regs(regs);
irq_enter();
+#ifdef CONFIG_PPC_BOOK3S_64
+ /* Real mode flagged P9 special emu is needed */
+ if (local_paca->hmi_p9_special_emu) {
+ local_paca->hmi_p9_special_emu = 0;
+
+ /*
+ * We don't want to take page faults while doing the
+ * emulation, we just replay the instruction if necessary.
+ */
+ pagefault_disable();
+ p9_hmi_special_emu(regs);
+ pagefault_enable();
+ }
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
if (ppc_md.handle_hmi_exception)
ppc_md.handle_hmi_exception(regs);
@@ -1916,6 +2113,10 @@ struct ppc_emulated ppc_emulated = {
WARN_EMULATED_SETUP(mfdscr),
WARN_EMULATED_SETUP(mtdscr),
WARN_EMULATED_SETUP(lq_stq),
+ WARN_EMULATED_SETUP(lxvw4x),
+ WARN_EMULATED_SETUP(lxvh8x),
+ WARN_EMULATED_SETUP(lxvd2x),
+ WARN_EMULATED_SETUP(lxvb16x),
#endif
};
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index c17f81e433..355d3f99ca 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -49,6 +49,13 @@
static void pnv_smp_setup_cpu(int cpu)
{
+ /*
+ * P9 workaround for CI vector load (see traps.c),
+ * enable the corresponding HMI interrupt
+ */
+ if (pvr_version_is(PVR_POWER9))
+ mtspr(SPRN_HMEER, mfspr(SPRN_HMEER) | PPC_BIT(17));
+
if (xive_enabled())
xive_smp_setup_cpu();
else if (cpu != boot_cpuid)
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] powerpc: Handle MCE on POWER9 with only DSISR bit 33 set
2017-09-15 5:25 [PATCH 1/2] powerpc: Add workaround for P9 vector CI load issue Michael Neuling
@ 2017-09-15 5:25 ` Michael Neuling
2017-09-19 10:13 ` Balbir Singh
2017-09-20 11:43 ` Michael Ellerman
2017-09-27 10:32 ` [1/2] powerpc: Add workaround for P9 vector CI load issue Michael Ellerman
1 sibling, 2 replies; 6+ messages in thread
From: Michael Neuling @ 2017-09-15 5:25 UTC (permalink / raw)
To: mpe; +Cc: linuxppc-dev, mikey, benh
On POWER9 DD2.1 and below, it's possible to get Machine Check
Exception (MCE) where only DSISR bit 33 is set. This will result in
the linux MCE handler seeing an unknown event, which triggers linux to
crash.
We change this by detecting unknown events in the MCE handler and
marking them as handled so that we no longer crash. We do this only on
chip revisions known to have this problem.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
arch/powerpc/kernel/mce_power.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index b76ca198e0..72ec667136 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -595,6 +595,7 @@ static long mce_handle_error(struct pt_regs *regs,
uint64_t addr;
uint64_t srr1 = regs->msr;
long handled;
+ unsigned long pvr;
if (SRR1_MC_LOADSTORE(srr1))
handled = mce_handle_derror(regs, dtable, &mce_err, &addr);
@@ -604,6 +605,20 @@ static long mce_handle_error(struct pt_regs *regs,
if (!handled && mce_err.error_type == MCE_ERROR_TYPE_UE)
handled = mce_handle_ue_error(regs);
+ /*
+ * On POWER9 DD2.1 and below, it's possible to get machine
+ * check where only DSISR bit 33 is set. This will result in
+ * the MCE handler seeing an unknown event and us crashing.
+ * Change this to mark as handled on these revisions.
+ */
+ pvr = mfspr(SPRN_PVR);
+ if (((PVR_VER(pvr) == PVR_POWER9) &&
+ (PVR_CFG(pvr) == 2) &&
+ (PVR_MIN(pvr) <= 1)) || cpu_has_feature(CPU_FTR_POWER9_DD1))
+ /* DD2.1 and below */
+ if (mce_err.error_type == MCE_ERROR_TYPE_UNKNOWN)
+ handled = 1;
+
save_mce_event(regs, handled, &mce_err, regs->nip, addr);
return handled;
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] powerpc: Handle MCE on POWER9 with only DSISR bit 33 set
2017-09-15 5:25 ` [PATCH 2/2] powerpc: Handle MCE on POWER9 with only DSISR bit 33 set Michael Neuling
@ 2017-09-19 10:13 ` Balbir Singh
2017-09-21 1:50 ` Michael Neuling
2017-09-20 11:43 ` Michael Ellerman
1 sibling, 1 reply; 6+ messages in thread
From: Balbir Singh @ 2017-09-19 10:13 UTC (permalink / raw)
To: Michael Neuling
Cc: Michael Ellerman, open list:LINUX FOR POWERPC (32-BIT AND 64-BIT)
On Fri, Sep 15, 2017 at 3:25 PM, Michael Neuling <mikey@neuling.org> wrote:
> On POWER9 DD2.1 and below, it's possible to get Machine Check
> Exception (MCE) where only DSISR bit 33 is set. This will result in
> the linux MCE handler seeing an unknown event, which triggers linux to
> crash.
>
> We change this by detecting unknown events in the MCE handler and
> marking them as handled so that we no longer crash. We do this only on
> chip revisions known to have this problem.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> ---
> arch/powerpc/kernel/mce_power.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
> index b76ca198e0..72ec667136 100644
> --- a/arch/powerpc/kernel/mce_power.c
> +++ b/arch/powerpc/kernel/mce_power.c
> @@ -595,6 +595,7 @@ static long mce_handle_error(struct pt_regs *regs,
> uint64_t addr;
> uint64_t srr1 = regs->msr;
> long handled;
> + unsigned long pvr;
>
> if (SRR1_MC_LOADSTORE(srr1))
> handled = mce_handle_derror(regs, dtable, &mce_err, &addr);
> @@ -604,6 +605,20 @@ static long mce_handle_error(struct pt_regs *regs,
> if (!handled && mce_err.error_type == MCE_ERROR_TYPE_UE)
> handled = mce_handle_ue_error(regs);
>
> + /*
> + * On POWER9 DD2.1 and below, it's possible to get machine
> + * check where only DSISR bit 33 is set. This will result in
> + * the MCE handler seeing an unknown event and us crashing.
> + * Change this to mark as handled on these revisions.
> + */
> + pvr = mfspr(SPRN_PVR);
> + if (((PVR_VER(pvr) == PVR_POWER9) &&
> + (PVR_CFG(pvr) == 2) &&
> + (PVR_MIN(pvr) <= 1)) || cpu_has_feature(CPU_FTR_POWER9_DD1))
> + /* DD2.1 and below */
> + if (mce_err.error_type == MCE_ERROR_TYPE_UNKNOWN)
> + handled = 1;
> +
What does this mean in terms of handling? Since we do not know the event,
how do we recover/handle? The system will anyway crash for not-recovered
cases. Does this prevent us from seeing the same exception several times?
Balbir Singh.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] powerpc: Handle MCE on POWER9 with only DSISR bit 33 set
2017-09-15 5:25 ` [PATCH 2/2] powerpc: Handle MCE on POWER9 with only DSISR bit 33 set Michael Neuling
2017-09-19 10:13 ` Balbir Singh
@ 2017-09-20 11:43 ` Michael Ellerman
1 sibling, 0 replies; 6+ messages in thread
From: Michael Ellerman @ 2017-09-20 11:43 UTC (permalink / raw)
To: Michael Neuling; +Cc: linuxppc-dev, mikey, benh
Michael Neuling <mikey@neuling.org> writes:
> On POWER9 DD2.1 and below, it's possible to get Machine Check
> Exception (MCE) where only DSISR bit 33 is set. This will result in
> the linux MCE handler seeing an unknown event, which triggers linux to
> crash.
Why do we get a machine check with just one bit set, and why is it OK to
just treat it as handled without doing anything?
Is it just entirely spurious?
cheers
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] powerpc: Handle MCE on POWER9 with only DSISR bit 33 set
2017-09-19 10:13 ` Balbir Singh
@ 2017-09-21 1:50 ` Michael Neuling
0 siblings, 0 replies; 6+ messages in thread
From: Michael Neuling @ 2017-09-21 1:50 UTC (permalink / raw)
To: Balbir Singh
Cc: Michael Ellerman, open list:LINUX FOR POWERPC (32-BIT AND 64-BIT)
Cj4gPiArwqDCoMKgwqDCoMKgwqAvKgo+ID4gK8KgwqDCoMKgwqDCoMKgwqAqIE9uIFBPV0VSOSBE
RDIuMSBhbmQgYmVsb3csIGl0J3MgcG9zc2libGUgdG8gZ2V0IG1hY2hpbmUKPiA+ICvCoMKgwqDC
oMKgwqDCoMKgKiBjaGVjayB3aGVyZSBvbmx5IERTSVNSIGJpdCAzMyBpcyBzZXQuIFRoaXMgd2ls
bCByZXN1bHQgaW4KPiA+ICvCoMKgwqDCoMKgwqDCoMKgKiB0aGUgTUNFIGhhbmRsZXIgc2VlaW5n
IGFuIHVua25vd24gZXZlbnQgYW5kIHVzIGNyYXNoaW5nLgo+ID4gK8KgwqDCoMKgwqDCoMKgwqAq
IENoYW5nZSB0aGlzIHRvIG1hcmsgYXMgaGFuZGxlZCBvbiB0aGVzZSByZXZpc2lvbnMuCj4gPiAr
wqDCoMKgwqDCoMKgwqDCoCovCj4gPiArwqDCoMKgwqDCoMKgwqBwdnIgPSBtZnNwcihTUFJOX1BW
Uik7Cj4gPiArwqDCoMKgwqDCoMKgwqBpZiAoKChQVlJfVkVSKHB2cikgPT0gUFZSX1BPV0VSOSkg
JiYKPiA+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAoUFZSX0NGRyhwdnIpID09IDIpICYmCj4g
PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgKFBWUl9NSU4ocHZyKSA8PSAxKSkgfHwgY3B1X2hh
c19mZWF0dXJlKENQVV9GVFJfUE9XRVI5X0REMSkpCj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDC
oMKgwqDCoMKgLyogREQyLjEgYW5kIGJlbG93ICovCj4gPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDC
oMKgwqDCoMKgaWYgKG1jZV9lcnIuZXJyb3JfdHlwZSA9PSBNQ0VfRVJST1JfVFlQRV9VTktOT1dO
KQo+ID4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgaGFuZGxlZCA9IDE7
Cj4gPiArCj4gCj4gV2hhdCBkb2VzIHRoaXMgbWVhbiBpbiB0ZXJtcyBvZiBoYW5kbGluZz8gU2lu
Y2Ugd2UgZG8gbm90IGtub3cgdGhlIGV2ZW50LAo+IGhvdyBkbyB3ZSByZWNvdmVyL2hhbmRsZT8g
VGhlIHN5c3RlbSB3aWxsIGFueXdheSBjcmFzaCBmb3Igbm90LXJlY292ZXJlZAo+IGNhc2VzLiBE
b2VzIHRoaXMgcHJldmVudCB1cyBmcm9tIHNlZWluZyB0aGUgc2FtZSBleGNlcHRpb24gc2V2ZXJh
bCB0aW1lcz8KClNvIHRoZSBNQ0UgaXMgc3B1cmlvdXMsIHNvIHdlIGRvbid0IG5lZWQgdG8gZG8g
YW55dGhpbmcgaW4gdGVybXMgb2Ygc2VydmljaW5nCml0LiBJZiB0aGVyZSBpcyBzb21ldGhpbmcg
dGhhdCBuZWVkcyB0byBiZSBzZXJ2aWNlZCwgdGhlIENQVSB3aWxsIHJhaXNlIHRoZSBNQ0UKYWdh
aW4gd2l0aCB0aGUgY29ycmVjdCBEU0lTUiBzbyB0aGF0IGl0IGNhbiBiZSBzZXJ2aWNlZC4KCkkn
bGwgYWRkIGEgY29tbWVudCB0byB0aGF0IGVmZmVjdCBhbmQgcmVwb3J0LgoKVGhhbmtzCk1pa2V5
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [1/2] powerpc: Add workaround for P9 vector CI load issue
2017-09-15 5:25 [PATCH 1/2] powerpc: Add workaround for P9 vector CI load issue Michael Neuling
2017-09-15 5:25 ` [PATCH 2/2] powerpc: Handle MCE on POWER9 with only DSISR bit 33 set Michael Neuling
@ 2017-09-27 10:32 ` Michael Ellerman
1 sibling, 0 replies; 6+ messages in thread
From: Michael Ellerman @ 2017-09-27 10:32 UTC (permalink / raw)
To: Michael Neuling; +Cc: mikey, linuxppc-dev
On Fri, 2017-09-15 at 05:25:48 UTC, Michael Neuling wrote:
> POWER9 DD2.1 and earlier has an issue where some cache inhibited
> vector load will return bad data. The workaround is two part, one
> firmware/microcode part triggers HMI interrupts when hitting such
> loads, the other part is this patch which then emulates the
> instructions in Linux.
>
> The affected instructions are limited to lxvd2x, lxvw4x, lxvb16x and
> lxvh8x.
>
> When an instruction triggers the HMI, all threads in the core will be
> sent to the HMI handler, not just the one running the vector load.
>
> In general, these spurious HMIs are detected by the emulation code and
> we just return back to the running process. Unfortunately, if a
> spurious interrupt occurs on a vector load that's to normal memory we
> have no way to detect that it's spurious (unless we walk the page
> tables, which is very expensive). In this case we emulate the load but
> we need do so using a vector load itself to ensure 128bit atomicity is
> preserved.
>
> Some additional debugfs emulated instruction counters are added also.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Patch 1 applied to powerpc next, thanks.
https://git.kernel.org/powerpc/c/5080332c2c893118dbc18755f35c8b
cheers
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-09-27 10:32 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-15 5:25 [PATCH 1/2] powerpc: Add workaround for P9 vector CI load issue Michael Neuling
2017-09-15 5:25 ` [PATCH 2/2] powerpc: Handle MCE on POWER9 with only DSISR bit 33 set Michael Neuling
2017-09-19 10:13 ` Balbir Singh
2017-09-21 1:50 ` Michael Neuling
2017-09-20 11:43 ` Michael Ellerman
2017-09-27 10:32 ` [1/2] powerpc: Add workaround for P9 vector CI load issue Michael Ellerman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).