| .. | .. |
|---|
| 34 | 34 | #include <linux/swap.h> |
|---|
| 35 | 35 | #include <linux/string.h> |
|---|
| 36 | 36 | #include <linux/init.h> |
|---|
| 37 | +#include <linux/irq_pipeline.h> |
|---|
| 37 | 38 | #include <linux/sched/mm.h> |
|---|
| 38 | 39 | #include <linux/sched/coredump.h> |
|---|
| 39 | 40 | #include <linux/sched/signal.h> |
|---|
| .. | .. |
|---|
| 68 | 69 | #include <linux/uaccess.h> |
|---|
| 69 | 70 | #include <asm/mmu_context.h> |
|---|
| 70 | 71 | #include <asm/tlb.h> |
|---|
| 72 | +#include <asm/dovetail.h> |
|---|
| 71 | 73 | |
|---|
| 72 | 74 | #include <trace/events/task.h> |
|---|
| 73 | 75 | #include "internal.h" |
|---|
| .. | .. |
|---|
| 981 | 983 | struct task_struct *tsk; |
|---|
| 982 | 984 | struct mm_struct *old_mm, *active_mm; |
|---|
| 983 | 985 | int ret; |
|---|
| 986 | + unsigned long flags; |
|---|
| 984 | 987 | |
|---|
| 985 | 988 | /* Notify parent that we're no longer interested in the old VM */ |
|---|
| 986 | 989 | tsk = current; |
|---|
| .. | .. |
|---|
| 1013 | 1016 | |
|---|
| 1014 | 1017 | local_irq_disable(); |
|---|
| 1015 | 1018 | active_mm = tsk->active_mm; |
|---|
| 1019 | + protect_inband_mm(flags); |
|---|
| 1016 | 1020 | tsk->active_mm = mm; |
|---|
| 1017 | 1021 | tsk->mm = mm; |
|---|
| 1018 | 1022 | /* |
|---|
| .. | .. |
|---|
| 1021 | 1025 | * lazy tlb mm refcounting when these are updated by context |
|---|
| 1022 | 1026 | * switches. Not all architectures can handle irqs off over |
|---|
| 1023 | 1027 | * activate_mm yet. |
|---|
| 1028 | + * |
|---|
| 1029 | + * irq_pipeline: activate_mm() allowing irqs off context is a |
|---|
| 1030 | + * requirement. e.g. TLB shootdown must not involve IPIs. We |
|---|
| 1031 | + * make sure protect_inband_mm() is in effect while switching |
|---|
| 1032 | + * in and activating the new mm by forcing |
|---|
| 1033 | + * CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM on. |
|---|
| 1024 | 1034 | */ |
|---|
| 1025 | 1035 | if (!IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) |
|---|
| 1026 | 1036 | local_irq_enable(); |
|---|
| 1027 | 1037 | activate_mm(active_mm, mm); |
|---|
| 1038 | + unprotect_inband_mm(flags); |
|---|
| 1028 | 1039 | if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM)) |
|---|
| 1029 | 1040 | local_irq_enable(); |
|---|
| 1030 | 1041 | tsk->mm->vmacache_seqnum = 0; |
|---|
| .. | .. |
|---|
| 1302 | 1313 | if (retval) |
|---|
| 1303 | 1314 | goto out_unlock; |
|---|
| 1304 | 1315 | |
|---|
| 1316 | + /* Tell Dovetail about the ongoing exec(). */ |
|---|
| 1317 | + arch_dovetail_exec_prepare(); |
|---|
| 1318 | + |
|---|
| 1305 | 1319 | /* |
|---|
| 1306 | 1320 | * Ensure that the uaccess routines can actually operate on userspace |
|---|
| 1307 | 1321 | * pointers: |
|---|