aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/entry_32.S
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-03-24 19:43:21 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-17 11:41:29 -0400
commitd93c870bad38e8daaaf9f7e900a13431f24becbb (patch)
tree9fa51e506bf6cddf362b25dfb2048941c8f24e1e /arch/x86/kernel/entry_32.S
parent687c80540975709844699d9a96070e2cf3bad39d (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.S19
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
292sysenter_past_esp: 292sysenter_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
3241: movl (%ebp),%ebp 3301: 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
545syscall_fault: 549syscall_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