diff -urN 2.4.5ac4/arch/i386/kernel/entry.S 2.4.5ac5/arch/i386/kernel/entry.S --- 2.4.5ac4/arch/i386/kernel/entry.S Tue Nov 28 18:39:59 2000 +++ 2.4.5ac5/arch/i386/kernel/entry.S Wed May 30 22:04:04 2001 @@ -106,10 +106,14 @@ popl %edi; \ popl %ebp; \ popl %eax; \ + cmpl $__KERNEL_DS,(%esp); \ + je 4f ; \ 1: popl %ds; \ 2: popl %es; \ addl $4,%esp; \ 3: iret; \ +4: addl $12,%esp; \ + iret; \ .section .fixup,"ax"; \ 4: movl $0,(%esp); \ jmp 1b; \ @@ -313,9 +317,11 @@ pushl %esi # push the error code pushl %edx # push the pt_regs pointer movl $(__KERNEL_DS),%edx + cmpl %edx,%ecx + jz 1f movl %edx,%ds movl %edx,%es - GET_CURRENT(%ebx) +1: GET_CURRENT(%ebx) call *%edi addl $8,%esp jmp ret_from_exception diff -urN 2.4.5ac4/include/asm-i386/hw_irq.h 2.4.5ac5/include/asm-i386/hw_irq.h --- 2.4.5ac4/include/asm-i386/hw_irq.h Tue May 29 18:26:59 2001 +++ 2.4.5ac5/include/asm-i386/hw_irq.h Wed May 30 22:04:16 2001 @@ -95,6 +95,10 @@ #define __STR(x) #x #define STR(x) __STR(x) +/* + * A segment register reload is rather expensive. Try to avoid it + * if possible. + */ #define SAVE_ALL \ "cld\n\t" \ "pushl %es\n\t" \ @@ -106,9 +110,12 @@ "pushl %edx\n\t" \ "pushl %ecx\n\t" \ "pushl %ebx\n\t" \ - "movl $" STR(__KERNEL_DS) ",%edx\n\t" \ - "movl %edx,%ds\n\t" \ - "movl %edx,%es\n\t" + "movl $" STR(__KERNEL_DS) ",%eax\n\t" \ + "cmpl %eax,7*4(%esp)\n\t" \ + "je 1f\n\t" \ + "movl %eax,%ds\n\t" \ + "movl %eax,%es\n\t" \ + "1:\n\t" #define IRQ_NAME2(nr) nr##_interrupt(void) #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)