Date: Mon, 19 Nov 2018 23:54:49 +0000 (UTC) From: Justin Hibbits <jhibbits@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r340653 - in head/sys/powerpc: fpu include powerpc Message-ID: <201811192354.wAJNsnUu065339@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhibbits Date: Mon Nov 19 23:54:49 2018 New Revision: 340653 URL: https://svnweb.freebsd.org/changeset/base/340653 Log: powerpc: Sync icache on SIGILL, in case of cache issues The update of jemalloc to 5.1.0 exposed a cache syncing issue on a Freescale e500 base system. There was already code in the FPU emulator to address this, but it was limited to a single static variable, and did not attempt to sync the cache. This pulls that out to the higher level program exception handler, and syncs the cache. If a SIGILL is hit a second time at the same address, it will be treated as a real illegal instruction, and handled accordingly. Modified: head/sys/powerpc/fpu/fpu_emu.c head/sys/powerpc/include/pcb.h head/sys/powerpc/powerpc/exec_machdep.c Modified: head/sys/powerpc/fpu/fpu_emu.c ============================================================================== --- head/sys/powerpc/fpu/fpu_emu.c Mon Nov 19 22:18:18 2018 (r340652) +++ head/sys/powerpc/fpu/fpu_emu.c Mon Nov 19 23:54:49 2018 (r340653) @@ -189,7 +189,6 @@ fpu_emulate(struct trapframe *frame, struct fpu *fpf) { union instr insn; struct fpemu fe; - static int lastill = 0; int sig; /* initialize insn.is_datasize to tell it is *not* initialized */ @@ -243,17 +242,11 @@ fpu_emulate(struct trapframe *frame, struct fpu *fpf) opc_disasm(frame->srr0, insn.i_int); } #endif - /* - * XXXX retry an illegal insn once due to cache issues. - */ - if (lastill == frame->srr0) { - sig = SIGILL; + sig = SIGILL; #ifdef DEBUG - if (fpe_debug & FPE_EX) - kdb_enter(KDB_WHY_UNSET, "illegal instruction"); + if (fpe_debug & FPE_EX) + kdb_enter(KDB_WHY_UNSET, "illegal instruction"); #endif - } - lastill = frame->srr0; break; } Modified: head/sys/powerpc/include/pcb.h ============================================================================== --- head/sys/powerpc/include/pcb.h Mon Nov 19 22:18:18 2018 (r340652) +++ head/sys/powerpc/include/pcb.h Mon Nov 19 23:54:49 2018 (r340653) @@ -89,6 +89,7 @@ struct pcb { register_t dbcr0; } booke; } pcb_cpu; + vm_offset_t pcb_lastill; /* Last illegal instruction */ }; #endif Modified: head/sys/powerpc/powerpc/exec_machdep.c ============================================================================== --- head/sys/powerpc/powerpc/exec_machdep.c Mon Nov 19 22:18:18 2018 (r340652) +++ head/sys/powerpc/powerpc/exec_machdep.c Mon Nov 19 23:54:49 2018 (r340653) @@ -94,6 +94,8 @@ __FBSDID("$FreeBSD$"); #include <machine/trap.h> #include <machine/vmparam.h> +#include <vm/pmap.h> + #ifdef FPU_EMU #include <powerpc/fpu/fpu_extern.h> #endif @@ -1099,6 +1101,14 @@ ppc_instr_emulate(struct trapframe *frame, struct pcb } sig = fpu_emulate(frame, &pcb->pcb_fpu); #endif + if (sig == SIGILL) { + if (pcb->pcb_lastill != frame->srr0) { + /* Allow a second chance, in case of cache sync issues. */ + sig = 0; + pmap_sync_icache(PCPU_GET(curpmap), frame->srr0, 4); + pcb->pcb_lastill = frame->srr0; + } + } return (sig); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811192354.wAJNsnUu065339>