public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "H. Peter Anvin" <hpa@zytor.com>
To: Mikael Pettersson <mikpe@it.uu.se>
Cc: linux-kernel@vger.kernel.org, mingo@redhat.com, tglx@linutronix.de
Subject: Re: [PATCH] fix i486 boot failure due to stale %ds
Date: Sun, 04 Nov 2007 10:29:34 -0800	[thread overview]
Message-ID: <472E0F8E.1010609@zytor.com> (raw)
In-Reply-To: <200711041644.lA4Gi4Ms013028@harpo.it.uu.se>

[-- Attachment #1: Type: text/plain, Size: 2939 bytes --]

Mikael Pettersson wrote:
> 
> The machine in question is a ca 1993 vintage Siemens 486 with
> a Quadtel S3 / Phoenix BIOS from 1994, booting via grub-0.95-13
> from Fedora Core 4.
> 
> Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
> ---
>  arch/x86/boot/compressed/head_32.S |    5 +++++
>  1 files changed, 5 insertions(+)
> 
> --- linux-2.6.24-rc1-git13/arch/x86/boot/compressed/head_32.S.~1~	2007-11-04 16:34:33.000000000 +0100
> +++ linux-2.6.24-rc1-git13/arch/x86/boot/compressed/head_32.S	2007-11-04 16:44:15.000000000 +0100
> @@ -33,6 +33,11 @@
>  	.globl startup_32
>  
>  startup_32:
> +	/* workaround for BIOSen or boot loaders that don't reload %ds
> +	   after changing the GDT (insane but unfortunately true) */
> +	movl %ds,%eax
> +	movl %eax,%ds
> +
>  	cld
>  	/* test KEEP_SEGMENTS flag to see if the bootloader is asking
>  	 * us to not reload segments */

Double bogus flag here.

It's not an issue of the BIOS or the boot loader (in your case, Grub) 
unless you have a boot loader that does 32-bit entry (e.g. kexec or ELILO.)

Second, the "workaround" you have here effectively disables the meaning 
of the KEEP_SEGMENTS flag, so it's unacceptable.

If one couldn't rely on %ds, then we could load the loadflags with a 
%cs: override, but there is something much more bizarre going on here. 
Since you're doing a normal 16-bit entry (unless your Grub is 
configured/patched to do something extremely weird, not that that would 
be anything out of the ordinary for Grub) the code that should have been 
executed immediately before this point is this code from 
arch/x86/boot/pm_jump.S:

protected_mode_jump:
         xorl    %ebx, %ebx              # Flag to indicate this is a boot
         movl    %edx, %esi              # Pointer to boot_params table
         movl    %eax, 2f                # Patch ljmpl instruction
         jmp     1f                      # Short jump to flush 
instruction q.

1:
         movw    $__BOOT_DS, %cx

         movl    %cr0, %edx
         orb     $1, %dl                 # Protected mode (PE) bit
         movl    %edx, %cr0

         movw    %cx, %ds
         movw    %cx, %es
         movw    %cx, %fs
         movw    %cx, %gs
         movw    %cx, %ss

         # Jump to the 32-bit entrypoint
         .byte   0x66, 0xea              # ljmpl opcode
2:      .long   0                       # offset
         .word   __BOOT_CS               # segment

         .size   protected_mode_jump, .-protected_mode_jump


As you can see, all the segments should have been properly set up.  I'm 
somewhat wondering if you have found one lone CPU revision in the entire 
x86 menagerie which doesn't properly serialize on mov to %cr0, which 
would casue the mov to %ds immediately after to be misexecuted.  If 
that's the case, I believe I owe Eric Biederman a drink of choice.

Could you send me your /proc/cpuinfo?

Also, I would be very interested if you could try out this patch:


[-- Attachment #2: diff --]
[-- Type: text/plain, Size: 902 bytes --]

diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S
index 2e55923..97cf407 100644
--- a/arch/x86/boot/pmjump.S
+++ b/arch/x86/boot/pmjump.S
@@ -30,7 +30,6 @@
 protected_mode_jump:
 	xorl	%ebx, %ebx		# Flag to indicate this is a boot
 	movl	%edx, %esi		# Pointer to boot_params table
-	movl	%eax, 2f		# Patch ljmpl instruction
 	jmp	1f			# Short jump to flush instruction q.
 
 1:
@@ -39,16 +38,17 @@ protected_mode_jump:
 	movl	%cr0, %edx
 	orb	$1, %dl			# Protected mode (PE) bit
 	movl	%edx, %cr0
+	ljmpw	__BOOT_CS, 2f
 
-	movw	%cx, %ds
-	movw	%cx, %es
-	movw	%cx, %fs
-	movw	%cx, %gs
-	movw	%cx, %ss
+	.code32
+2:
+	movl	%ecx, %ds
+	movl	%ecx, %es
+	movl	%ecx, %fs
+	movl	%ecx, %gs
+	movl	%ecx, %ss
 
 	# Jump to the 32-bit entrypoint
-	.byte	0x66, 0xea		# ljmpl opcode
-2:	.long	0			# offset
-	.word	__BOOT_CS		# segment
-
+	jmpl	%eax
+	
 	.size	protected_mode_jump, .-protected_mode_jump

  reply	other threads:[~2007-11-04 18:33 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-04 16:44 [PATCH] fix i486 boot failure due to stale %ds Mikael Pettersson
2007-11-04 18:29 ` H. Peter Anvin [this message]
2007-11-04 19:00   ` H. Peter Anvin
  -- strict thread matches above, loose matches on Subject: below --
2007-11-04 19:38 Mikael Pettersson
2007-11-04 19:41 ` H. Peter Anvin
2007-11-04 21:58 Mikael Pettersson
2007-11-04 22:20 ` H. Peter Anvin
2007-11-04 23:05 ` Andi Kleen
2007-11-04 23:07 ` Jeremy Fitzhardinge
2007-11-04 23:12   ` H. Peter Anvin
2007-11-04 23:50   ` H. Peter Anvin
2007-11-05  0:15     ` Linus Torvalds
2007-11-05  0:23       ` Linus Torvalds
2007-11-04 23:51   ` H. Peter Anvin
2007-11-05  1:18 Mikael Pettersson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=472E0F8E.1010609@zytor.com \
    --to=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikpe@it.uu.se \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox