We add the necessary call to task_isolation_enter() in the
prepare_exit_to_usermode() routine.  We already unconditionally
call into this routine if TIF_NOHZ is set, since that's where
we do the user_enter() call.

We add calls to task_isolation_check_exception() in places
where exceptions may not generate signals to the application.

Signed-off-by: Chris Metcalf <cmetc...@ezchip.com>
---
 arch/tile/kernel/process.c     |  6 +++++-
 arch/tile/kernel/ptrace.c      |  6 ++++++
 arch/tile/kernel/single_step.c |  5 +++++
 arch/tile/kernel/smp.c         | 26 ++++++++++++++------------
 arch/tile/kernel/unaligned.c   |  3 +++
 arch/tile/mm/fault.c           |  3 +++
 arch/tile/mm/homecache.c       |  2 ++
 7 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index b5f30d376ce1..832febfd65df 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -29,6 +29,7 @@
 #include <linux/signal.h>
 #include <linux/delay.h>
 #include <linux/context_tracking.h>
+#include <linux/isolation.h>
 #include <asm/stack.h>
 #include <asm/switch_to.h>
 #include <asm/homecache.h>
@@ -495,10 +496,13 @@ void prepare_exit_to_usermode(struct pt_regs *regs, u32 
thread_info_flags)
                        tracehook_notify_resume(regs);
                }
 
+               task_isolation_enter();
+
                local_irq_disable();
                thread_info_flags = READ_ONCE(current_thread_info()->flags);
 
-       } while (thread_info_flags & _TIF_WORK_MASK);
+       } while ((thread_info_flags & _TIF_WORK_MASK) ||
+                !task_isolation_ready());
 
        if (thread_info_flags & _TIF_SINGLESTEP) {
                single_step_once(regs);
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
index 54e7b723db99..f76f2d8b8923 100644
--- a/arch/tile/kernel/ptrace.c
+++ b/arch/tile/kernel/ptrace.c
@@ -23,6 +23,7 @@
 #include <linux/elf.h>
 #include <linux/tracehook.h>
 #include <linux/context_tracking.h>
+#include <linux/isolation.h>
 #include <asm/traps.h>
 #include <arch/chip.h>
 
@@ -255,6 +256,11 @@ int do_syscall_trace_enter(struct pt_regs *regs)
 {
        u32 work = ACCESS_ONCE(current_thread_info()->flags);
 
+       if (work & _TIF_NOHZ) {
+               if (task_isolation_check_syscall(regs->regs[TREG_SYSCALL_NR]))
+                       return -1;
+       }
+
        if (secure_computing() == -1)
                return -1;
 
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 862973074bf9..ba01eacde7a3 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/err.h>
 #include <linux/prctl.h>
+#include <linux/isolation.h>
 #include <asm/cacheflush.h>
 #include <asm/traps.h>
 #include <asm/uaccess.h>
@@ -320,6 +321,8 @@ void single_step_once(struct pt_regs *regs)
        int size = 0, sign_ext = 0;  /* happy compiler */
        int align_ctl;
 
+       task_isolation_check_exception("single step at %#lx", regs->pc);
+
        align_ctl = unaligned_fixup;
        switch (task_thread_info(current)->align_ctl) {
        case PR_UNALIGN_NOPRINT:
@@ -767,6 +770,8 @@ void single_step_once(struct pt_regs *regs)
        unsigned long *ss_pc = this_cpu_ptr(&ss_saved_pc);
        unsigned long control = __insn_mfspr(SPR_SINGLE_STEP_CONTROL_K);
 
+       task_isolation_check_exception("single step at %#lx", regs->pc);
+
        *ss_pc = regs->pc;
        control |= SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK;
        control |= SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK;
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
index 07e3ff5cc740..7298d68d4584 100644
--- a/arch/tile/kernel/smp.c
+++ b/arch/tile/kernel/smp.c
@@ -20,6 +20,7 @@
 #include <linux/irq.h>
 #include <linux/irq_work.h>
 #include <linux/module.h>
+#include <linux/isolation.h>
 #include <asm/cacheflush.h>
 #include <asm/homecache.h>
 
@@ -181,10 +182,11 @@ void flush_icache_range(unsigned long start, unsigned 
long end)
        struct ipi_flush flush = { start, end };
 
        /* If invoked with irqs disabled, we can not issue IPIs. */
-       if (irqs_disabled())
+       if (irqs_disabled()) {
+               task_isolation_debug_cpumask(&task_isolation_map);
                flush_remote(0, HV_FLUSH_EVICT_L1I, NULL, 0, 0, 0,
                        NULL, NULL, 0);
-       else {
+       } else {
                preempt_disable();
                on_each_cpu(ipi_flush_icache_range, &flush, 1);
                preempt_enable();
@@ -258,10 +260,8 @@ void __init ipi_init(void)
 
 #if CHIP_HAS_IPI()
 
-void smp_send_reschedule(int cpu)
+static void __smp_send_reschedule(int cpu)
 {
-       WARN_ON(cpu_is_offline(cpu));
-
        /*
         * We just want to do an MMIO store.  The traditional writeq()
         * functions aren't really correct here, since they're always
@@ -273,15 +273,17 @@ void smp_send_reschedule(int cpu)
 
 #else
 
-void smp_send_reschedule(int cpu)
+static void __smp_send_reschedule(int cpu)
 {
-       HV_Coord coord;
-
-       WARN_ON(cpu_is_offline(cpu));
-
-       coord.y = cpu_y(cpu);
-       coord.x = cpu_x(cpu);
+       HV_Coord coord = { .y = cpu_y(cpu), .x = cpu_x(cpu) };
        hv_trigger_ipi(coord, IRQ_RESCHEDULE);
 }
 
 #endif /* CHIP_HAS_IPI() */
+
+void smp_send_reschedule(int cpu)
+{
+       WARN_ON(cpu_is_offline(cpu));
+       task_isolation_debug(cpu);
+       __smp_send_reschedule(cpu);
+}
diff --git a/arch/tile/kernel/unaligned.c b/arch/tile/kernel/unaligned.c
index 0db5f7c9d9e5..b1e229a1ff62 100644
--- a/arch/tile/kernel/unaligned.c
+++ b/arch/tile/kernel/unaligned.c
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/compat.h>
 #include <linux/prctl.h>
+#include <linux/isolation.h>
 #include <asm/cacheflush.h>
 #include <asm/traps.h>
 #include <asm/uaccess.h>
@@ -1545,6 +1546,8 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
                return;
        }
 
+       task_isolation_check_exception("unaligned JIT at %#lx", regs->pc);
+
        if (!info->unalign_jit_base) {
                void __user *user_page;
 
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index 26734214818c..1dee18d3ffbd 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -35,6 +35,7 @@
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <linux/kdebug.h>
+#include <linux/isolation.h>
 
 #include <asm/pgalloc.h>
 #include <asm/sections.h>
@@ -844,6 +845,8 @@ static inline void __do_page_fault(struct pt_regs *regs, 
int fault_num,
 void do_page_fault(struct pt_regs *regs, int fault_num,
                   unsigned long address, unsigned long write)
 {
+       task_isolation_check_exception("page fault interrupt %d at %#lx (%#lx)",
+                                      fault_num, regs->pc, address);
        __do_page_fault(regs, fault_num, address, write);
 }
 
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c
index 40ca30a9fee3..e044e8dd8372 100644
--- a/arch/tile/mm/homecache.c
+++ b/arch/tile/mm/homecache.c
@@ -31,6 +31,7 @@
 #include <linux/smp.h>
 #include <linux/module.h>
 #include <linux/hugetlb.h>
+#include <linux/isolation.h>
 
 #include <asm/page.h>
 #include <asm/sections.h>
@@ -83,6 +84,7 @@ static void hv_flush_update(const struct cpumask 
*cache_cpumask,
         * Don't bother to update atomically; losing a count
         * here is not that critical.
         */
+       task_isolation_debug_cpumask(&mask);
        for_each_cpu(cpu, &mask)
                ++per_cpu(irq_stat, cpu).irq_hv_flush_count;
 }
-- 
2.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to