Handle the Facility Unavailable exception as a SIGILL

Currently Facility Unavailable is absent and once an application
tries to use or access a register from a feature disabled in the
CPU it causes a kernel panic.

A simple test-case is:

int main() { asm volatile ("tbegin.;"); }

which will use TM (Hardware Transactional Memory) feature which
is not supported by the kernel and so will trigger the following
kernel panic:

----

fatal user trap:

    exception       = 0xf60 (unknown)
    srr0            = 0x10000890
    srr1            = 0x800000000000f032
    lr              = 0x100004e4
    curthread       = 0x5f93000
    pid = 1021, comm = htm

panic: unknown trap
cpuid = 40
KDB: stack backtrace:
Uptime: 3m18s
Dumping 10 MB (3 chunks)
    chunk 0: 11MB (2648 pages) ... ok
    chunk 1: 1MB (24 pages) ... ok
    chunk 2: 1MB (2 pages)panic: IOMMU mapping error: -4

cpuid = 40
Uptime: 3m18s

----

Since Hardware Transactional Memory is not yet supported by FreeBSD, treat
this as an illegal instruction.

PR:		224350
Submitted by:	Gustavo Romero <gromero_AT_ibm_DOT_com>
MFC after:	2 weeks
This commit is contained in:
Justin Hibbits 2017-12-15 04:11:20 +00:00
parent 24c9699cdd
commit 7cd4e55c43
2 changed files with 9 additions and 0 deletions

View File

@ -80,6 +80,9 @@
#define EXC_HEA 0x0e40 /* Hypervisor Emulation Assistance */
#define EXC_VSX 0x0f40 /* VSX Unavailable */
/* Power ISA 2.07+: */
#define EXC_FAC 0x0f60 /* Facility Unavailable */
/* The following are available on 4xx and 85xx */
#define EXC_CRIT 0x0100 /* Critical Input Interrupt */
#define EXC_PIT 0x1000 /* Programmable Interval Timer */

View File

@ -135,6 +135,7 @@ static struct powerpc_exception powerpc_exceptions[] = {
{ EXC_PERF, "performance monitoring" },
{ EXC_VEC, "altivec unavailable" },
{ EXC_VSX, "vsx unavailable" },
{ EXC_FAC, "facility unavailable" },
{ EXC_ITMISS, "instruction tlb miss" },
{ EXC_DLMISS, "data load tlb miss" },
{ EXC_DSMISS, "data store tlb miss" },
@ -279,6 +280,11 @@ trap(struct trapframe *frame)
enable_fpu(td);
break;
case EXC_FAC:
sig = SIGILL;
ucode = ILL_ILLOPC;
break;
case EXC_VECAST_E:
case EXC_VECAST_G4:
case EXC_VECAST_G5: