diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-03-24 19:43:21 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-17 11:41:29 -0400 |
commit | d93c870bad38e8daaaf9f7e900a13431f24becbb (patch) | |
tree | 9fa51e506bf6cddf362b25dfb2048941c8f24e1e /arch/x86/kernel/entry_32.S | |
parent | 687c80540975709844699d9a96070e2cf3bad39d (diff) |
x86: only enable interrupts when kernel state has been set up
The sysenter path tries to enable interrupts immediately. Unfortunately
this doesn't work in a paravirt environment, because not enough kernel
state has been set up at that point (namely, pointing %fs to the kernel
percpu data segment). To fix this, defer ENABLE_INTERRUPTS until after
the kernel state has been set up.
Unfortunately this means that we're running with interrupts disabled
for a while without calling the IRQ tracing code, but that can't be
called without setting up %fs either.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/entry_32.S')
-rw-r--r-- | arch/x86/kernel/entry_32.S | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 4b87c32b639f..a664d5726d8d 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -291,10 +291,10 @@ ENTRY(ia32_sysenter_target) | |||
291 | movl TSS_sysenter_sp0(%esp),%esp | 291 | movl TSS_sysenter_sp0(%esp),%esp |
292 | sysenter_past_esp: | 292 | sysenter_past_esp: |
293 | /* | 293 | /* |
294 | * No need to follow this irqs on/off section: the syscall | 294 | * Interrupts are disabled here, but we can't trace it until |
295 | * disabled irqs and here we enable it straight after entry: | 295 | * enough kernel state to call TRACE_IRQS_OFF can be called - but |
296 | * we immediately enable interrupts at that point anyway. | ||
296 | */ | 297 | */ |
297 | ENABLE_INTERRUPTS(CLBR_NONE) | ||
298 | pushl $(__USER_DS) | 298 | pushl $(__USER_DS) |
299 | CFI_ADJUST_CFA_OFFSET 4 | 299 | CFI_ADJUST_CFA_OFFSET 4 |
300 | /*CFI_REL_OFFSET ss, 0*/ | 300 | /*CFI_REL_OFFSET ss, 0*/ |
@@ -302,6 +302,7 @@ sysenter_past_esp: | |||
302 | CFI_ADJUST_CFA_OFFSET 4 | 302 | CFI_ADJUST_CFA_OFFSET 4 |
303 | CFI_REL_OFFSET esp, 0 | 303 | CFI_REL_OFFSET esp, 0 |
304 | pushfl | 304 | pushfl |
305 | orl $X86_EFLAGS_IF, (%esp) | ||
305 | CFI_ADJUST_CFA_OFFSET 4 | 306 | CFI_ADJUST_CFA_OFFSET 4 |
306 | pushl $(__USER_CS) | 307 | pushl $(__USER_CS) |
307 | CFI_ADJUST_CFA_OFFSET 4 | 308 | CFI_ADJUST_CFA_OFFSET 4 |
@@ -315,6 +316,11 @@ sysenter_past_esp: | |||
315 | CFI_ADJUST_CFA_OFFSET 4 | 316 | CFI_ADJUST_CFA_OFFSET 4 |
316 | CFI_REL_OFFSET eip, 0 | 317 | CFI_REL_OFFSET eip, 0 |
317 | 318 | ||
319 | pushl %eax | ||
320 | CFI_ADJUST_CFA_OFFSET 4 | ||
321 | SAVE_ALL | ||
322 | ENABLE_INTERRUPTS(CLBR_NONE) | ||
323 | |||
318 | /* | 324 | /* |
319 | * Load the potential sixth argument from user stack. | 325 | * Load the potential sixth argument from user stack. |
320 | * Careful about security. | 326 | * Careful about security. |
@@ -322,14 +328,12 @@ sysenter_past_esp: | |||
322 | cmpl $__PAGE_OFFSET-3,%ebp | 328 | cmpl $__PAGE_OFFSET-3,%ebp |
323 | jae syscall_fault | 329 | jae syscall_fault |
324 | 1: movl (%ebp),%ebp | 330 | 1: movl (%ebp),%ebp |
331 | movl %ebp,PT_EBP(%esp) | ||
325 | .section __ex_table,"a" | 332 | .section __ex_table,"a" |
326 | .align 4 | 333 | .align 4 |
327 | .long 1b,syscall_fault | 334 | .long 1b,syscall_fault |
328 | .previous | 335 | .previous |
329 | 336 | ||
330 | pushl %eax | ||
331 | CFI_ADJUST_CFA_OFFSET 4 | ||
332 | SAVE_ALL | ||
333 | GET_THREAD_INFO(%ebp) | 337 | GET_THREAD_INFO(%ebp) |
334 | 338 | ||
335 | /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ | 339 | /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ |
@@ -543,9 +547,6 @@ END(syscall_exit_work) | |||
543 | 547 | ||
544 | RING0_INT_FRAME # can't unwind into user space anyway | 548 | RING0_INT_FRAME # can't unwind into user space anyway |
545 | syscall_fault: | 549 | syscall_fault: |
546 | pushl %eax # save orig_eax | ||
547 | CFI_ADJUST_CFA_OFFSET 4 | ||
548 | SAVE_ALL | ||
549 | GET_THREAD_INFO(%ebp) | 550 | GET_THREAD_INFO(%ebp) |
550 | movl $-EFAULT,PT_EAX(%esp) | 551 | movl $-EFAULT,PT_EAX(%esp) |
551 | jmp resume_userspace | 552 | jmp resume_userspace |