diff options
Diffstat (limited to 'arch/x86/ia32/ia32entry.S')
-rw-r--r-- | arch/x86/ia32/ia32entry.S | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index b5e329da166c..20371d0635e4 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
@@ -61,6 +61,19 @@ | |||
61 | CFI_UNDEFINED r15 | 61 | CFI_UNDEFINED r15 |
62 | .endm | 62 | .endm |
63 | 63 | ||
64 | #ifdef CONFIG_PARAVIRT | ||
65 | ENTRY(native_usergs_sysret32) | ||
66 | swapgs | ||
67 | sysretl | ||
68 | ENDPROC(native_usergs_sysret32) | ||
69 | |||
70 | ENTRY(native_irq_enable_sysexit) | ||
71 | swapgs | ||
72 | sti | ||
73 | sysexit | ||
74 | ENDPROC(native_irq_enable_sysexit) | ||
75 | #endif | ||
76 | |||
64 | /* | 77 | /* |
65 | * 32bit SYSENTER instruction entry. | 78 | * 32bit SYSENTER instruction entry. |
66 | * | 79 | * |
@@ -85,14 +98,14 @@ ENTRY(ia32_sysenter_target) | |||
85 | CFI_SIGNAL_FRAME | 98 | CFI_SIGNAL_FRAME |
86 | CFI_DEF_CFA rsp,0 | 99 | CFI_DEF_CFA rsp,0 |
87 | CFI_REGISTER rsp,rbp | 100 | CFI_REGISTER rsp,rbp |
88 | swapgs | 101 | SWAPGS_UNSAFE_STACK |
89 | movq %gs:pda_kernelstack, %rsp | 102 | movq %gs:pda_kernelstack, %rsp |
90 | addq $(PDA_STACKOFFSET),%rsp | 103 | addq $(PDA_STACKOFFSET),%rsp |
91 | /* | 104 | /* |
92 | * No need to follow this irqs on/off section: the syscall | 105 | * No need to follow this irqs on/off section: the syscall |
93 | * disabled irqs, here we enable it straight after entry: | 106 | * disabled irqs, here we enable it straight after entry: |
94 | */ | 107 | */ |
95 | sti | 108 | ENABLE_INTERRUPTS(CLBR_NONE) |
96 | movl %ebp,%ebp /* zero extension */ | 109 | movl %ebp,%ebp /* zero extension */ |
97 | pushq $__USER32_DS | 110 | pushq $__USER32_DS |
98 | CFI_ADJUST_CFA_OFFSET 8 | 111 | CFI_ADJUST_CFA_OFFSET 8 |
@@ -103,7 +116,7 @@ ENTRY(ia32_sysenter_target) | |||
103 | pushfq | 116 | pushfq |
104 | CFI_ADJUST_CFA_OFFSET 8 | 117 | CFI_ADJUST_CFA_OFFSET 8 |
105 | /*CFI_REL_OFFSET rflags,0*/ | 118 | /*CFI_REL_OFFSET rflags,0*/ |
106 | movl 8*3-THREAD_SIZE+threadinfo_sysenter_return(%rsp), %r10d | 119 | movl 8*3-THREAD_SIZE+TI_sysenter_return(%rsp), %r10d |
107 | CFI_REGISTER rip,r10 | 120 | CFI_REGISTER rip,r10 |
108 | pushq $__USER32_CS | 121 | pushq $__USER32_CS |
109 | CFI_ADJUST_CFA_OFFSET 8 | 122 | CFI_ADJUST_CFA_OFFSET 8 |
@@ -123,8 +136,9 @@ ENTRY(ia32_sysenter_target) | |||
123 | .quad 1b,ia32_badarg | 136 | .quad 1b,ia32_badarg |
124 | .previous | 137 | .previous |
125 | GET_THREAD_INFO(%r10) | 138 | GET_THREAD_INFO(%r10) |
126 | orl $TS_COMPAT,threadinfo_status(%r10) | 139 | orl $TS_COMPAT,TI_status(%r10) |
127 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) | 140 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \ |
141 | TI_flags(%r10) | ||
128 | CFI_REMEMBER_STATE | 142 | CFI_REMEMBER_STATE |
129 | jnz sysenter_tracesys | 143 | jnz sysenter_tracesys |
130 | sysenter_do_call: | 144 | sysenter_do_call: |
@@ -134,11 +148,11 @@ sysenter_do_call: | |||
134 | call *ia32_sys_call_table(,%rax,8) | 148 | call *ia32_sys_call_table(,%rax,8) |
135 | movq %rax,RAX-ARGOFFSET(%rsp) | 149 | movq %rax,RAX-ARGOFFSET(%rsp) |
136 | GET_THREAD_INFO(%r10) | 150 | GET_THREAD_INFO(%r10) |
137 | cli | 151 | DISABLE_INTERRUPTS(CLBR_NONE) |
138 | TRACE_IRQS_OFF | 152 | TRACE_IRQS_OFF |
139 | testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10) | 153 | testl $_TIF_ALLWORK_MASK,TI_flags(%r10) |
140 | jnz int_ret_from_sys_call | 154 | jnz int_ret_from_sys_call |
141 | andl $~TS_COMPAT,threadinfo_status(%r10) | 155 | andl $~TS_COMPAT,TI_status(%r10) |
142 | /* clear IF, that popfq doesn't enable interrupts early */ | 156 | /* clear IF, that popfq doesn't enable interrupts early */ |
143 | andl $~0x200,EFLAGS-R11(%rsp) | 157 | andl $~0x200,EFLAGS-R11(%rsp) |
144 | movl RIP-R11(%rsp),%edx /* User %eip */ | 158 | movl RIP-R11(%rsp),%edx /* User %eip */ |
@@ -151,10 +165,7 @@ sysenter_do_call: | |||
151 | CFI_ADJUST_CFA_OFFSET -8 | 165 | CFI_ADJUST_CFA_OFFSET -8 |
152 | CFI_REGISTER rsp,rcx | 166 | CFI_REGISTER rsp,rcx |
153 | TRACE_IRQS_ON | 167 | TRACE_IRQS_ON |
154 | swapgs | 168 | ENABLE_INTERRUPTS_SYSEXIT32 |
155 | sti /* sti only takes effect after the next instruction */ | ||
156 | /* sysexit */ | ||
157 | .byte 0xf, 0x35 | ||
158 | 169 | ||
159 | sysenter_tracesys: | 170 | sysenter_tracesys: |
160 | CFI_RESTORE_STATE | 171 | CFI_RESTORE_STATE |
@@ -200,7 +211,7 @@ ENTRY(ia32_cstar_target) | |||
200 | CFI_DEF_CFA rsp,PDA_STACKOFFSET | 211 | CFI_DEF_CFA rsp,PDA_STACKOFFSET |
201 | CFI_REGISTER rip,rcx | 212 | CFI_REGISTER rip,rcx |
202 | /*CFI_REGISTER rflags,r11*/ | 213 | /*CFI_REGISTER rflags,r11*/ |
203 | swapgs | 214 | SWAPGS_UNSAFE_STACK |
204 | movl %esp,%r8d | 215 | movl %esp,%r8d |
205 | CFI_REGISTER rsp,r8 | 216 | CFI_REGISTER rsp,r8 |
206 | movq %gs:pda_kernelstack,%rsp | 217 | movq %gs:pda_kernelstack,%rsp |
@@ -208,7 +219,7 @@ ENTRY(ia32_cstar_target) | |||
208 | * No need to follow this irqs on/off section: the syscall | 219 | * No need to follow this irqs on/off section: the syscall |
209 | * disabled irqs and here we enable it straight after entry: | 220 | * disabled irqs and here we enable it straight after entry: |
210 | */ | 221 | */ |
211 | sti | 222 | ENABLE_INTERRUPTS(CLBR_NONE) |
212 | SAVE_ARGS 8,1,1 | 223 | SAVE_ARGS 8,1,1 |
213 | movl %eax,%eax /* zero extension */ | 224 | movl %eax,%eax /* zero extension */ |
214 | movq %rax,ORIG_RAX-ARGOFFSET(%rsp) | 225 | movq %rax,ORIG_RAX-ARGOFFSET(%rsp) |
@@ -230,8 +241,9 @@ ENTRY(ia32_cstar_target) | |||
230 | .quad 1b,ia32_badarg | 241 | .quad 1b,ia32_badarg |
231 | .previous | 242 | .previous |
232 | GET_THREAD_INFO(%r10) | 243 | GET_THREAD_INFO(%r10) |
233 | orl $TS_COMPAT,threadinfo_status(%r10) | 244 | orl $TS_COMPAT,TI_status(%r10) |
234 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) | 245 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \ |
246 | TI_flags(%r10) | ||
235 | CFI_REMEMBER_STATE | 247 | CFI_REMEMBER_STATE |
236 | jnz cstar_tracesys | 248 | jnz cstar_tracesys |
237 | cstar_do_call: | 249 | cstar_do_call: |
@@ -241,11 +253,11 @@ cstar_do_call: | |||
241 | call *ia32_sys_call_table(,%rax,8) | 253 | call *ia32_sys_call_table(,%rax,8) |
242 | movq %rax,RAX-ARGOFFSET(%rsp) | 254 | movq %rax,RAX-ARGOFFSET(%rsp) |
243 | GET_THREAD_INFO(%r10) | 255 | GET_THREAD_INFO(%r10) |
244 | cli | 256 | DISABLE_INTERRUPTS(CLBR_NONE) |
245 | TRACE_IRQS_OFF | 257 | TRACE_IRQS_OFF |
246 | testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10) | 258 | testl $_TIF_ALLWORK_MASK,TI_flags(%r10) |
247 | jnz int_ret_from_sys_call | 259 | jnz int_ret_from_sys_call |
248 | andl $~TS_COMPAT,threadinfo_status(%r10) | 260 | andl $~TS_COMPAT,TI_status(%r10) |
249 | RESTORE_ARGS 1,-ARG_SKIP,1,1,1 | 261 | RESTORE_ARGS 1,-ARG_SKIP,1,1,1 |
250 | movl RIP-ARGOFFSET(%rsp),%ecx | 262 | movl RIP-ARGOFFSET(%rsp),%ecx |
251 | CFI_REGISTER rip,rcx | 263 | CFI_REGISTER rip,rcx |
@@ -254,8 +266,7 @@ cstar_do_call: | |||
254 | TRACE_IRQS_ON | 266 | TRACE_IRQS_ON |
255 | movl RSP-ARGOFFSET(%rsp),%esp | 267 | movl RSP-ARGOFFSET(%rsp),%esp |
256 | CFI_RESTORE rsp | 268 | CFI_RESTORE rsp |
257 | swapgs | 269 | USERGS_SYSRET32 |
258 | sysretl | ||
259 | 270 | ||
260 | cstar_tracesys: | 271 | cstar_tracesys: |
261 | CFI_RESTORE_STATE | 272 | CFI_RESTORE_STATE |
@@ -310,12 +321,12 @@ ENTRY(ia32_syscall) | |||
310 | /*CFI_REL_OFFSET rflags,EFLAGS-RIP*/ | 321 | /*CFI_REL_OFFSET rflags,EFLAGS-RIP*/ |
311 | /*CFI_REL_OFFSET cs,CS-RIP*/ | 322 | /*CFI_REL_OFFSET cs,CS-RIP*/ |
312 | CFI_REL_OFFSET rip,RIP-RIP | 323 | CFI_REL_OFFSET rip,RIP-RIP |
313 | swapgs | 324 | SWAPGS |
314 | /* | 325 | /* |
315 | * No need to follow this irqs on/off section: the syscall | 326 | * No need to follow this irqs on/off section: the syscall |
316 | * disabled irqs and here we enable it straight after entry: | 327 | * disabled irqs and here we enable it straight after entry: |
317 | */ | 328 | */ |
318 | sti | 329 | ENABLE_INTERRUPTS(CLBR_NONE) |
319 | movl %eax,%eax | 330 | movl %eax,%eax |
320 | pushq %rax | 331 | pushq %rax |
321 | CFI_ADJUST_CFA_OFFSET 8 | 332 | CFI_ADJUST_CFA_OFFSET 8 |
@@ -324,8 +335,9 @@ ENTRY(ia32_syscall) | |||
324 | this could be a problem. */ | 335 | this could be a problem. */ |
325 | SAVE_ARGS 0,0,1 | 336 | SAVE_ARGS 0,0,1 |
326 | GET_THREAD_INFO(%r10) | 337 | GET_THREAD_INFO(%r10) |
327 | orl $TS_COMPAT,threadinfo_status(%r10) | 338 | orl $TS_COMPAT,TI_status(%r10) |
328 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) | 339 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \ |
340 | TI_flags(%r10) | ||
329 | jnz ia32_tracesys | 341 | jnz ia32_tracesys |
330 | ia32_do_syscall: | 342 | ia32_do_syscall: |
331 | cmpl $(IA32_NR_syscalls-1),%eax | 343 | cmpl $(IA32_NR_syscalls-1),%eax |
@@ -370,13 +382,11 @@ quiet_ni_syscall: | |||
370 | PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi | 382 | PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi |
371 | PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi | 383 | PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi |
372 | PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx | 384 | PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx |
373 | PTREGSCALL stub32_sigsuspend, sys32_sigsuspend, %rcx | ||
374 | PTREGSCALL stub32_execve, sys32_execve, %rcx | 385 | PTREGSCALL stub32_execve, sys32_execve, %rcx |
375 | PTREGSCALL stub32_fork, sys_fork, %rdi | 386 | PTREGSCALL stub32_fork, sys_fork, %rdi |
376 | PTREGSCALL stub32_clone, sys32_clone, %rdx | 387 | PTREGSCALL stub32_clone, sys32_clone, %rdx |
377 | PTREGSCALL stub32_vfork, sys_vfork, %rdi | 388 | PTREGSCALL stub32_vfork, sys_vfork, %rdi |
378 | PTREGSCALL stub32_iopl, sys_iopl, %rsi | 389 | PTREGSCALL stub32_iopl, sys_iopl, %rsi |
379 | PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend, %rdx | ||
380 | 390 | ||
381 | ENTRY(ia32_ptregs_common) | 391 | ENTRY(ia32_ptregs_common) |
382 | popq %r11 | 392 | popq %r11 |
@@ -476,7 +486,7 @@ ia32_sys_call_table: | |||
476 | .quad sys_ssetmask | 486 | .quad sys_ssetmask |
477 | .quad sys_setreuid16 /* 70 */ | 487 | .quad sys_setreuid16 /* 70 */ |
478 | .quad sys_setregid16 | 488 | .quad sys_setregid16 |
479 | .quad stub32_sigsuspend | 489 | .quad sys32_sigsuspend |
480 | .quad compat_sys_sigpending | 490 | .quad compat_sys_sigpending |
481 | .quad sys_sethostname | 491 | .quad sys_sethostname |
482 | .quad compat_sys_setrlimit /* 75 */ | 492 | .quad compat_sys_setrlimit /* 75 */ |
@@ -583,7 +593,7 @@ ia32_sys_call_table: | |||
583 | .quad sys32_rt_sigpending | 593 | .quad sys32_rt_sigpending |
584 | .quad compat_sys_rt_sigtimedwait | 594 | .quad compat_sys_rt_sigtimedwait |
585 | .quad sys32_rt_sigqueueinfo | 595 | .quad sys32_rt_sigqueueinfo |
586 | .quad stub32_rt_sigsuspend | 596 | .quad sys_rt_sigsuspend |
587 | .quad sys32_pread /* 180 */ | 597 | .quad sys32_pread /* 180 */ |
588 | .quad sys32_pwrite | 598 | .quad sys32_pwrite |
589 | .quad sys_chown16 | 599 | .quad sys_chown16 |