wraplinux: use an actual ljmp after %cr0 transition
authorH. Peter Anvin <hpa@zytor.com>
Sat, 12 Jan 2008 01:20:26 +0000 (17:20 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Sat, 12 Jan 2008 01:20:26 +0000 (17:20 -0800)
Be even more paranoid and use an actual ljmp (instead of lretw) after
a %cr0 transition.

reloc/reloc_init.S

index eb3e31f..fdb224e 100644 (file)
@@ -79,9 +79,14 @@ _start:
                lretl
 2:
                /* Adjust the real-mode segment bases */
-               addl    %ebx,my_gdt+CS16+2(%ebx)
-               addl    %ebx,my_gdt+DS16+2(%ebx)
-               addl    %ebx,intcall_rm_ret_jmp+2(%ebx)
+               addl    %ebx, my_gdt+CS16+2(%ebx)
+               addl    %ebx, my_gdt+DS16+2(%ebx)
+               addl    %ebx, .L_intcall_rm_ret_jmp+2(%ebx)
+
+               /* Equivalent real-mode segment */
+               movl    %ebx, %eax
+               shrl    $4, %eax
+               movw    %ax, .L_intcall_rm_jmp+3(%ebx)
 
                /* Zero the .bss - stack must be empty here! */
                leal    __bss_start(%ebx), %edi
@@ -158,13 +163,13 @@ intcall_rm:
                movw    %dx,%fs
                movw    %dx,%gs
 
-               pushw   %ax             /* Real mode segment */
-               pushw   $1f
-
                movl    %cr0,%edx
                andb    $~1,%dl
                movl    %edx,%cr0
-               lretw
+.L_intcall_rm_jmp:
+               .byte   0xea            /* ljmpw */
+               .word   1f              /* offset */
+               .word   0               /* segment */
 1:
                movw    %ax,%ss
                popw    %gs
@@ -191,7 +196,7 @@ intcall_rm_return:
                movl    %cr0,%eax
                orb     $1,%al
                movl    %eax,%cr0
-intcall_rm_ret_jmp:
+.L_intcall_rm_ret_jmp:
                .byte   0x66, 0xea      /* ljmpl */
                .long   intcall_pm_return
                .short  CS32