In prepare_exit_to_usermode(), call task_isolation_start() for TIF_TASK_ISOLATION tasks.
In syscall_trace_enter_phase1(), add the necessary support for reporting syscalls for task-isolation processes. Add task_isolation_remote() calls for the kernel exception types that do not result in signals, namely non-signalling page faults and non-signalling MPX fixups. Signed-off-by: Chris Metcalf <cmetc...@mellanox.com> --- arch/x86/Kconfig | 1 + arch/x86/entry/common.c | 14 ++++++++++++++ arch/x86/include/asm/apic.h | 3 +++ arch/x86/include/asm/thread_info.h | 8 +++++--- arch/x86/kernel/smp.c | 2 ++ arch/x86/kernel/traps.c | 3 +++ arch/x86/mm/fault.c | 5 +++++ 7 files changed, 33 insertions(+), 3 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 971feac13506..45967840b81a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -114,6 +114,7 @@ config X86 select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT select HAVE_ARCH_COMPAT_MMAP_BASES if MMU && COMPAT select HAVE_ARCH_SECCOMP_FILTER + select HAVE_ARCH_TASK_ISOLATION select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if X86_64 diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 03505ffbe1b6..2c70b915d1f2 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -24,6 +24,7 @@ #include <linux/uprobes.h> #include <linux/livepatch.h> #include <linux/syscalls.h> +#include <linux/isolation.h> #include <asm/desc.h> #include <asm/traps.h> @@ -87,6 +88,16 @@ static long syscall_trace_enter(struct pt_regs *regs) if (emulated) return -1L; + /* + * In task isolation mode, we may prevent the syscall from + * running, and if so we also deliver a signal to the process. + */ + if (work & _TIF_TASK_ISOLATION) { + if (task_isolation_syscall(regs->orig_ax) == -1) + return -1L; + work &= ~_TIF_TASK_ISOLATION; + } + #ifdef CONFIG_SECCOMP /* * Do seccomp after ptrace, to catch any tracer changes. @@ -196,6 +207,9 @@ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs) if (unlikely(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS)) exit_to_usermode_loop(regs, cached_flags); + if (cached_flags & _TIF_TASK_ISOLATION) + task_isolation_start(); + #ifdef CONFIG_COMPAT /* * Compat syscalls set TS_COMPAT. Make sure we clear it before diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 5f01671c68f2..c70cb9cacfc0 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -2,6 +2,7 @@ #define _ASM_X86_APIC_H #include <linux/cpumask.h> +#include <linux/isolation.h> #include <asm/alternative.h> #include <asm/cpufeature.h> @@ -618,6 +619,7 @@ extern void irq_exit(void); static inline void entering_irq(void) { + task_isolation_interrupt("irq"); irq_enter(); } @@ -629,6 +631,7 @@ static inline void entering_ack_irq(void) static inline void ipi_entering_ack_irq(void) { + task_isolation_interrupt("ack irq"); irq_enter(); ack_APIC_irq(); } diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 89e7eeb5cec1..aa9d9d817f8b 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -85,6 +85,7 @@ struct thread_info { #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ #define TIF_UPROBE 12 /* breakpointed or singlestepping */ #define TIF_PATCH_PENDING 13 /* pending live patching update */ +#define TIF_TASK_ISOLATION 14 /* task isolation enabled for task */ #define TIF_NOCPUID 15 /* CPUID is not accessible in userland */ #define TIF_NOTSC 16 /* TSC is not accessible in userland */ #define TIF_IA32 17 /* IA32 compatibility process */ @@ -111,6 +112,7 @@ struct thread_info { #define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY) #define _TIF_UPROBE (1 << TIF_UPROBE) #define _TIF_PATCH_PENDING (1 << TIF_PATCH_PENDING) +#define _TIF_TASK_ISOLATION (1 << TIF_TASK_ISOLATION) #define _TIF_NOCPUID (1 << TIF_NOCPUID) #define _TIF_NOTSC (1 << TIF_NOTSC) #define _TIF_IA32 (1 << TIF_IA32) @@ -132,15 +134,15 @@ struct thread_info { #define _TIF_WORK_SYSCALL_ENTRY \ (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT | \ _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \ - _TIF_NOHZ) + _TIF_NOHZ | _TIF_TASK_ISOLATION) /* work to do on any return to user space */ #define _TIF_ALLWORK_MASK \ (_TIF_SYSCALL_TRACE | _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ _TIF_NEED_RESCHED | _TIF_SINGLESTEP | _TIF_SYSCALL_EMU | \ _TIF_SYSCALL_AUDIT | _TIF_USER_RETURN_NOTIFY | _TIF_UPROBE | \ - _TIF_PATCH_PENDING | _TIF_NOHZ | _TIF_SYSCALL_TRACEPOINT | \ - _TIF_FSCHECK) + _TIF_PATCH_PENDING | _TIF_TASK_ISOLATION | _TIF_NOHZ | \ + _TIF_SYSCALL_TRACEPOINT | _TIF_NOHZ | _TIF_FSCHECK) /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 5c574dff4c1a..73bc58029292 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -23,6 +23,7 @@ #include <linux/interrupt.h> #include <linux/cpu.h> #include <linux/gfp.h> +#include <linux/isolation.h> #include <asm/mtrr.h> #include <asm/tlbflush.h> @@ -128,6 +129,7 @@ static void native_smp_send_reschedule(int cpu) WARN(1, "sched: Unexpected reschedule of offline CPU#%d!\n", cpu); return; } + task_isolation_remote(cpu, "reschedule IPI"); apic->send_IPI(cpu, RESCHEDULE_VECTOR); } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 67db4f43309e..a48ebfc7b98c 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -37,6 +37,7 @@ #include <linux/mm.h> #include <linux/smp.h> #include <linux/io.h> +#include <linux/isolation.h> #if defined(CONFIG_EDAC) #include <linux/edac.h> @@ -467,6 +468,8 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) case 2: /* Bound directory has invalid entry. */ if (mpx_handle_bd_fault()) goto exit_trap; + /* No signal was generated, but notify task-isolation tasks. */ + task_isolation_interrupt("bounds check"); break; /* Success, it was handled */ case 1: /* Bound violation. */ info = mpx_generate_siginfo(regs); diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index e2baeaa053a5..bd479142e3ca 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -15,6 +15,7 @@ #include <linux/prefetch.h> /* prefetchw */ #include <linux/context_tracking.h> /* exception_enter(), ... */ #include <linux/uaccess.h> /* faulthandler_disabled() */ +#include <linux/isolation.h> /* task_isolation_interrupt */ #include <asm/cpufeature.h> /* boot_cpu_has, ... */ #include <asm/traps.h> /* dotraplinkage, ... */ @@ -1486,6 +1487,10 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); } + /* No signal was generated, but notify task-isolation tasks. */ + if (flags & PF_USER) + task_isolation_interrupt("page fault at %#lx", address); + check_v8086_mode(regs, address, tsk); } NOKPROBE_SYMBOL(__do_page_fault); -- 2.1.2