| .. | .. |
|---|
| 40 | 40 | { |
|---|
| 41 | 41 | nr = syscall_enter_from_user_mode(regs, nr); |
|---|
| 42 | 42 | |
|---|
| 43 | + if (dovetailing()) { |
|---|
| 44 | + if (nr == EXIT_SYSCALL_OOB) { |
|---|
| 45 | + hard_local_irq_disable(); |
|---|
| 46 | + return; |
|---|
| 47 | + } |
|---|
| 48 | + if (nr == EXIT_SYSCALL_TAIL) |
|---|
| 49 | + goto done; |
|---|
| 50 | + } |
|---|
| 51 | + |
|---|
| 43 | 52 | instrumentation_begin(); |
|---|
| 44 | 53 | if (likely(nr < NR_syscalls)) { |
|---|
| 45 | 54 | nr = array_index_nospec(nr, NR_syscalls); |
|---|
| .. | .. |
|---|
| 53 | 62 | #endif |
|---|
| 54 | 63 | } |
|---|
| 55 | 64 | instrumentation_end(); |
|---|
| 65 | +done: |
|---|
| 56 | 66 | syscall_exit_to_user_mode(regs); |
|---|
| 57 | 67 | } |
|---|
| 58 | 68 | #endif |
|---|
| .. | .. |
|---|
| 89 | 99 | * or may not be necessary, but it matches the old asm behavior. |
|---|
| 90 | 100 | */ |
|---|
| 91 | 101 | nr = (unsigned int)syscall_enter_from_user_mode(regs, nr); |
|---|
| 102 | + |
|---|
| 103 | + if (dovetailing()) { |
|---|
| 104 | + if (nr == EXIT_SYSCALL_OOB) { |
|---|
| 105 | + hard_local_irq_disable(); |
|---|
| 106 | + return; |
|---|
| 107 | + } |
|---|
| 108 | + if (nr == EXIT_SYSCALL_TAIL) |
|---|
| 109 | + goto done; |
|---|
| 110 | + } |
|---|
| 111 | + |
|---|
| 92 | 112 | instrumentation_begin(); |
|---|
| 93 | 113 | |
|---|
| 94 | 114 | do_syscall_32_irqs_on(regs, nr); |
|---|
| 95 | 115 | |
|---|
| 96 | 116 | instrumentation_end(); |
|---|
| 117 | +done: |
|---|
| 97 | 118 | syscall_exit_to_user_mode(regs); |
|---|
| 98 | 119 | } |
|---|
| 99 | 120 | |
|---|
| .. | .. |
|---|
| 136 | 157 | /* The case truncates any ptrace induced syscall nr > 2^32 -1 */ |
|---|
| 137 | 158 | nr = (unsigned int)syscall_enter_from_user_mode_work(regs, nr); |
|---|
| 138 | 159 | |
|---|
| 160 | + if (dovetailing()) { |
|---|
| 161 | + if (nr == EXIT_SYSCALL_OOB) { |
|---|
| 162 | + instrumentation_end(); |
|---|
| 163 | + hard_local_irq_disable(); |
|---|
| 164 | + return true; |
|---|
| 165 | + } |
|---|
| 166 | + if (nr == EXIT_SYSCALL_TAIL) |
|---|
| 167 | + goto done; |
|---|
| 168 | + } |
|---|
| 169 | + |
|---|
| 139 | 170 | /* Now this is just like a normal syscall. */ |
|---|
| 140 | 171 | do_syscall_32_irqs_on(regs, nr); |
|---|
| 141 | 172 | |
|---|
| 173 | +done: |
|---|
| 142 | 174 | instrumentation_end(); |
|---|
| 143 | 175 | syscall_exit_to_user_mode(regs); |
|---|
| 144 | 176 | return true; |
|---|