Re: Protected mode transitions and big real mode... still an issue

Guillaume Thouvenin
2008-05-05T06:27:42Z

On Thu, 1 May 2008 16:13:31 -0300
Marcelo Tosatti <mtosatti@redhat.com> wrote:

> The code sequence is:
>
> 8235: 66 data16
> 8236: 0f 22 c0 mov %eax,%cr0
> 8239: ea 3e 02 00 08 b8 00 ljmp $0xb8,$0x800023e
>
> So it switches to realmode and then does a ljmp. Problem is that you're
> using the segment selector as a GDT index, but in realmode it should be
> shifted left by 4 to determine the segment base address. Following patch
> makes Plan9 happy.
>
> Other than that, load_segment_descriptor() can return a positive error
> on failure, should do a proper check.
>
> Index: kvm/arch/x86/kvm/x86_emulate.c
> ===================================================================
> --- kvm.orig/arch/x86/kvm/x86_emulate.c
> +++ kvm/arch/x86/kvm/x86_emulate.c
> @@ -1755,7 +1755,10 @@ special_insn:
> goto cannot_emulate;
> }
> sel = insn_fetch(u16, 2, c->eip);
> - if (load_segment_descriptor(ctxt->vcpu, sel, 9, VCPU_SREG_CS) < 0) {
> + if (ctxt->mode == X86EMUL_MODE_REAL)
> + eip |= (sel << 4);
> + else if (load_segment_descriptor(ctxt->vcpu, sel, 9,
> + VCPU_SREG_CS) < 0) {
> DPRINTF("jmp far: Failed to load CS descriptor\n");
> goto cannot_emulate;
> }
>

Thank you Marcelo for the report. Unfortunately it is not the same
problem I'm seeing. The problem I have now is that I can boot until the
gfxboot screen but when I choose to install openSuse it generates a
kernel panic like this:

[guill@enterprise][~/local/kvm-userspace.git/bin]$ ./qemu-system-x86_64
-hda ~/disk_images/hd_50G.qcow2 -cdrom /images_iso/openSUSE-10.3-GM-x86_64-mini.iso -boot d -s -m 1024 -serial stdio
Linux version 2.6.22.5-31-default (geeko@buildhost) (gcc version 4.2.1 (SUSE Linux)) #1 SMP 2007/09/21 22:29:00 UTC
Command line: BOOT_IMAGE=linux initrd=initrd,08000600.spl splash=silent vga=0x314 install=slp:/ console=ttyS0
BIOS-provided physical RAM map:
BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
BIOS-e820: 00000000000e8000 - 0000000000100000 (reserved)
BIOS-e820: 0000000000100000 - 000000003fff0000 (usable)
BIOS-e820: 000000003fff0000 - 0000000040000000 (ACPI data)
BIOS-e820: 00000000fffbd000 - 0000000100000000 (reserved)
end_pfn_map = 1048576
DMI 2.4 present.
ACPI: RSDP 000FB450, 0014 (r0 QEMU )
ACPI: RSDT 3FFF0000, 002C (r1 QEMU QEMURSDT 1 QEMU 1)
ACPI: FACP 3FFF002C, 0074 (r1 QEMU QEMUFACP 1 QEMU 1)
ACPI: DSDT 3FFF0100, 2464 (r1 BXPC BXDSDT 1 INTL 20061109)
ACPI: FACS 3FFF00C0, 0040
ACPI: APIC 3FFF2568, 00E0 (r1 QEMU QEMUAPIC 1 QEMU 1)
No NUMA configuration found
Faking a node at 0000000000000000-000000003fff0000
Bootmem setup node 0 0000000000000000-000000003fff0000
No mptable found.
Zone PFN ranges:
DMA 0 -> 4096
DMA32 4096 -> 1048576
Normal 1048576 -> 1048576
early_node_map[2] active PFN ranges
0: 0 -> 159
0: 256 -> 262128
ACPI: PM-Timer IO Port: 0xb008
ACPI: LAPIC (acpi_id[0x00] lapic_id[0x00] enabled)
Processor #0 (Bootup-CPU)
ACPI: LAPIC (acpi_id[0x01] lapic_id[0x01] disabled)
ACPI: LAPIC (acpi_id[0x02] lapic_id[0x02] disabled)
ACPI: LAPIC (acpi_id[0x03] lapic_id[0x03] disabled)
ACPI: LAPIC (acpi_id[0x04] lapic_id[0x04] disabled)
ACPI: LAPIC (acpi_id[0x05] lapic_id[0x05] disabled)
ACPI: LAPIC (acpi_id[0x06] lapic_id[0x06] disabled)
ACPI: LAPIC (acpi_id[0x07] lapic_id[0x07] disabled)
ACPI: LAPIC (acpi_id[0x08] lapic_id[0x08] disabled)
ACPI: LAPIC (acpi_id[0x09] lapic_id[0x09] disabled)
ACPI: LAPIC (acpi_id[0x0a] lapic_id[0x0a] disabled)
ACPI: LAPIC (acpi_id[0x0b] lapic_id[0x0b] disabled)
ACPI: LAPIC (acpi_id[0x0c] lapic_id[0x0c] disabled)
ACPI: LAPIC (acpi_id[0x0d] lapic_id[0x0d] disabled)
ACPI: LAPIC (acpi_id[0x0e] lapic_id[0x0e] disabled)
ACPI: LAPIC (acpi_id[0x0f] lapic_id[0x0f] disabled)
ACPI: IOAPIC (id[0x01] address[0xfec00000] gsi_base[0])
IOAPIC[0]: apic_id 1, address 0xfec00000, GSI 0-23
ACPI: INT_SRC_OVR (bus 0 bus_irq 5 global_irq 5 high level)
ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
ACPI: INT_SRC_OVR (bus 0 bus_irq 10 global_irq 10 high level)
ACPI: INT_SRC_OVR (bus 0 bus_irq 11 global_irq 11 high level)
Setting APIC routing to flat
Using ACPI (MADT) for SMP configuration information
swsusp: Registered nosave memory region: 000000000009f000 - 00000000000a0000
swsusp: Registered nosave memory region: 00000000000a0000 - 00000000000e8000
swsusp: Registered nosave memory region: 00000000000e8000 - 0000000000100000
Allocating PCI resources starting at 50000000 (gap: 40000000:bffbd000)
SMP: Allowing 16 CPUs, 15 hotplug CPUs
PERCPU: Allocating 50296 bytes of per cpu data
Built 1 zonelists. Total pages: 257180
Kernel command line: BOOT_IMAGE=linux initrd=initrd,08000600.spl splash=silent vga=0x314 install=slp:/ console=ttyS0
bootsplash: silent mode.
Initializing CPU#0
PID hash table entries: 4096 (order: 12, 32768 bytes)
time.c: Detected 3002.939 MHz processor.
Console: colour dummy device 80x25
Checking aperture...
Memory: 1012688k/1048512k available (2050k kernel code, 35436k reserved, 1017k data, 316k init)
Calibrating delay using timer specific routine.. 6034.80 BogoMIPS (lpj=12069613)
Security Framework v1.0.0 initialized
Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes)
Inode-cache hash table entries: 65536 (order: 7, 524288 bytes)
Mount-cache hash table entries: 256
CPU: L1 I cache: 32K, L1 D cache: 32K
CPU: L2 cache: 2048K
CPU 0/0 -> Node 0
invalid opcode: 0000 [1] SMP
last sysfs file:
CPU 0
Modules linked in:
Pid: 0, comm: swapper Not tainted 2.6.22.5-31-default #1
RIP: 0010:[<ffffffff80283be4>] [<ffffffff80283be4>] kmem_cache_zalloc+0x8d/0xad
RSP: 0018:ffffffff805c7f18 EFLAGS: 00010046
RAX: 000000000000000a RBX: 0000000000000046 RCX: 0000000000000000
RDX: ffff8100015dfa40 RSI: 0000000000000001 RDI: ffff81003ffd33d8
RBP: 00000000000000d0 R08: 0000000000000000 R09: ffffffff804b6870
R10: 0000000000000000 R11: 0000000000000000 R12: ffff8100015d2080
R13: ffffffff805cf298 R14: ffffffff805c9000 R15: ffffffff804673bd
FS: 0000000000000000(0000) GS:ffffffff804ff000(0000) knlGS:0000000000000000
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 0000000000000000 CR3: 0000000000201000 CR4: 00000000000006e0
Process swapper (pid: 0, threadinfo ffffffff805c6000, task ffffffff804b6870)
Stack: 0000000000000282 ffffffff804009a5 ffffffff80200000 ffffffff80210e10
0000000000000000 ffffffff802f3841 0000000000000000 0000000000000282
0000000000000000 0000000000000000 ffffffffffffffff ffffffff805f2700
Call Trace:
[<ffffffff804009a5>] _etext+0x0/0x1cf65b
[<ffffffff80210e10>] alternatives_smp_module_add+0x77/0x149
[<ffffffff802f3841>] __bitmap_weight+0x39/0x80
[<ffffffff805d607e>] alternative_instructions+0xdf/0xea
[<ffffffff805d076c>] start_kernel+0x2c0/0x2db
[<ffffffff805d0148>] _sinittext+0x148/0x14c

Code: 0f 0d 0a 48 85 d2 74 10 41 8b 8c 24 0c 04 00 00 31 c0 48 89
RIP [<ffffffff80283be4>] kmem_cache_zalloc+0x8d/0xad
RSP <ffffffff805c7f18>
Kernel panic - not syncing: Attempted to kill the idle task!
....................

Anyway your remark about the usage of the segment selector in real mode
or not is true and I added your patch in my series of patches. I will
also make proper check with return value of load_segment_descriptor().

Best regards,
Guillaume