[Lguest] lguest: unhandled trap 13 and CONFIG_MICROCODE_INTEL_EARLY
rusty at rustcorp.com.au
Mon May 6 14:22:32 EST 2013
Paul Bolle <pebolle at tiscali.nl> writes:
> 0) Since v3.9 launching a guest kernel with the lguest tool triggers an
> "unhandled trap 13" error if CONFIG_MICROCODE_INTEL_EARLY is set (and
> one runs on an Intel CPU). That option was introduced in v3.9.
Yech... me too:
lguest: unhandled trap 13 at 0x537b8d (0x0)
> 1) For instance, on qemu I ran into this error:
> lguest: unhandled trap 13 at 0x97087d (0x0)
> 2) Disassembling that address (with the page offset added) in vmlinux
> (in gdb) showed:
> Dump of assembler code for function collect_cpu_info_early:
> 0xc09707e4 <+0>: push %ebp
> 0xc097087d <+153>: wrmsr
> 0xc09708a5 <+193>: ret
> End of assembler dump.
> 3) The internet tells me wrmsr will trigger a general protection fault
> if the CPU is not running in ring 0. And a guest kernel seems to do that
> since v3.9:
> arch/x86/kernel/head_32.S:call load_ucode_bsp
Yes, there's also the known issue that CONFIG_OLPC breaks lguest boot.
HPA, how about we extend the KEEP_SEGMENTS flag to mean "don't touch
privileged registers" in general? That's what it used to do when it
was introduced, and AFAIK only lguest uses it. Xen folk CC'd.
%ebx seems to be free, how about something like this?
Subject: x86: treat KEEP_SEGMENTS flag as advice not to try any privileged operations
The i386 boot path used to only do one privileged thing before entering the
per-platform boot-path: load segments. Thus KEEP_SEGMENTS was born, used
by lguest (and could be used by others like Xen).
CONFIG_OLPC and CONFIG_MICROCODE_EARLY were added since then, so with those
options, lguest guest crash. I've been telling people to turn them off, but
that's a bit naff.
Expand KEEP_SEGMENTS to mean "don't try to do ring0 stuff" and it does the
Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 73afd11..8b50829 100644
@@ -89,8 +89,9 @@ ENTRY(startup_32)
/* test KEEP_SEGMENTS flag to see if the bootloader is asking
- us to not reload segments */
- testb $(1<<6), BP_loadflags(%esi)
+ us to not reload segments: keep in %ebx. */
+ movb BP_loadflags(%esi),%ebx
+ andb $(1<<6),%ebx
@@ -138,6 +139,9 @@ ENTRY(startup_32)
+ /* KEEP_SEGMENTS implies we don't touch priv regs at all. */
+ andb %ebx,%ebx
+ jnz 2f
/* save OFW's pgdir table for later use when calling into OFW */
movl %cr3, %eax
@@ -149,6 +153,7 @@ ENTRY(startup_32)
* Initialize page tables. This creates a PDE and a set of page
* tables, which are located immediately beyond __brk_base. The variable
More information about the Lguest