--- linux-2.6.18-rc2-mm1/arch/i386/kernel/traps.c 2006-07-29 15:32:14.000000000 +0400 +++ linux-2.6.18-rc2-mm1/arch/i386/kernel/traps.c 2006-07-30 02:19:59.000000000 +0400 @@ -1018,13 +1018,13 @@ #endif } -fastcall unsigned long patch_espfix_gdt(struct pt_regs *regs, +fastcall unsigned long patch_espfix_base(unsigned long uesp, unsigned long kesp) { int cpu = smp_processor_id(); struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr->address; - unsigned long base = (kesp - regs->esp) & -THREAD_SIZE; + unsigned long base = (kesp - uesp) & -THREAD_SIZE; __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS]; /* Set up base for espfix segment */ desc &= 0x00ffff000000ffffULL; @@ -1034,14 +1034,13 @@ return kesp - base; } -fastcall unsigned long get_orig_kesp(unsigned long kesp, unsigned long cpu) +fastcall unsigned long get_espfix_base(unsigned long cpu) { /* Since we are on a wrong stack, the smp_processor_id() cannot * be used. So the cpu number is passed from an assembly. */ struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr->address; - unsigned long base = get_desc_base(&gdt[GDT_ENTRY_ESPFIX_SS].a); - return base + kesp; + return get_desc_base(&gdt[GDT_ENTRY_ESPFIX_SS].a); } /* --- linux-2.6.18-rc2-mm1/arch/i386/kernel/entry.S 2006-07-29 15:29:00.000000000 +0400 +++ linux-2.6.18-rc2-mm1/arch/i386/kernel/entry.S 2006-07-30 02:19:47.000000000 +0400 @@ -401,9 +401,9 @@ * This is an "official" bug of all the x86-compatible * CPUs, which we can try to work around to make * dosemu and wine happy. */ - movl %esp, %eax # pt_regs pointer + movl OLDESP(%esp), %eax movl %esp, %edx - call patch_espfix_gdt + call patch_espfix_base pushl $__ESPFIX_SS CFI_ADJUST_CFA_OFFSET 4 pushl %eax @@ -502,10 +502,10 @@ CFI_ENDPROC #define FIXUP_ESPFIX_STACK \ - movl %esp, %eax; \ GET_THREAD_INFO(%ebp); \ - movl TI_cpu(%ebp), %edx; \ - call get_orig_kesp; \ + movl TI_cpu(%ebp), %eax; \ + call get_espfix_base; \ + addl %esp, %eax; \ pushl $__KERNEL_DS; \ pushl %eax; \ lss (%esp), %esp;