qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Funny -m arguments can crash


From: Markus Armbruster
Subject: Re: [Qemu-devel] Funny -m arguments can crash
Date: Tue, 14 Aug 2012 10:44:30 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)

Anthony Liguori <address@hidden> writes:

> Markus Armbruster <address@hidden> writes:
>
>> Avi Kivity <address@hidden> writes:
>>
>>> On 08/08/2012 12:04 PM, Markus Armbruster wrote:
>>>>>
>>>>> Yes please, maybe with a notice to the user.
>>>> 
>>>> Next problem: minimum RAM size.
>>>> 
>>>> For instance, -M pc -m X, where X < 32KiB dies "qemu: fatal: Trying to
>>>> execute code outside RAM or ROM at [...] Aborted (core dumped)" with
>>>> TCG, and "KVM internal error. Suberror: 1" with KVM.
>>>> 
>>>> Should a minimum RAM size be enforced?  Board-specific?
>>>> 
>>>
>>> It's really a BIOS bug causing a limitation of both kvm and tcg to be
>>> hit.  The BIOS should recognize it doesn't have sufficient memory and
>>> hang gracefully (if you can picture that).  It just assumes some low
>>> memory is available and tries to execute it with the results you got.
>>
>> SeaBIOS indeed assumes it got at least 1MiB of RAM.  It doesn't bother
>> to check CMOS for a smaller RAM size.  However, that bug / feature is
>> currently masked by a QEMU bug: we screw up CMOS contents when there's
>> less than 1 MiB of RAM.  pc_cmos_init():
>>
>>     int val, nb, i;
>> [...]
>>     /* memory size */
>>     val = 640; /* base memory in K */
>>     rtc_set_memory(s, 0x15, val);
>>     rtc_set_memory(s, 0x16, val >> 8);
>>
>>     val = (ram_size / 1024) - 1024;
>>     if (val > 65535)
>>         val = 65535;
>>     rtc_set_memory(s, 0x17, val);
>>     rtc_set_memory(s, 0x18, val >> 8);
>>
>> If ram_size < 1MiB, val goes negative.  Oops.
>>
>> For instance, with -m 500k, we happily promise 640KiB base memory (CMOS
>> addr 0x15..16), almost 64MiB extended memory (0x17..18 and 0x30..31),
>> yet no memory above 16MiB (0x34..35).
>>
>> An easy way to fix this is to require 1MiB of RAM :)
>>
>> But if you like, I'll put sane values in CMOS instead.  That'll expose
>> the SeaBIOS bug.
>>
>> Anthony, you're the PC maintainer, got a preference?
>>
>> SeaBIOS thread:
>> http://comments.gmane.org/gmane.comp.bios.coreboot.seabios/4341
>
> I'd prefer fixing the CMOS values over limiting to 1MB of RAM.
>
> Having a 1MB limit is purely theoritical--not practical.  There's no
> good reason for anyone to ask for < 1MB unless they know what they're
> doing.  If it's truly a mistake, then asking for 2MB is just as much of
> a mistake because no real guest will run with 2MB of memory anyway (you
> can't even load a kernel).
>
> So if we're just going for theoritical correctness, we ought to do it
> the Right Way which is fixing the CMOS values and putting the check in
> SeaBIOS.

Next error:

    $ gdb --args qemu-system-x86_64 -nodefaults --enable-kvm -vnc :0 -monitor 
stdio -m 640k
    [...]
    Program received signal SIGSEGV, Segmentation fault.
    [...]
    (gdb) bt
    #0  0x0000003b0de884ac in __memcmp_sse2 () from /lib64/libc.so.6
    #1  0x000000000063f1ad in patch_hypercalls (s=0x139b350)
        at /work/armbru/qemu/hw/i386/../kvmvapic.c:532
    #2  0x000000000063f3fe in vapic_prepare (s=0x139b350)
        at /work/armbru/qemu/hw/i386/../kvmvapic.c:597
    #3  0x000000000063f4ed in vapic_write (opaque=0x139b350, addr=0, data=32, 
size=
        2) at /work/armbru/qemu/hw/i386/../kvmvapic.c:634
    #4  0x0000000000677a44 in memory_region_write_accessor (opaque=0x139d670, 
addr=
        0, value=0x7ffff654bbf0, size=2, shift=0, mask=65535)
        at /work/armbru/qemu/memory.c:329
    #5  0x0000000000677b26 in access_with_adjusted_size (addr=0, value=
        0x7ffff654bbf0, size=2, access_size_min=1, access_size_max=4, access=
        0x6779d0 <memory_region_write_accessor>, opaque=0x139d670)
        at /work/armbru/qemu/memory.c:359
    #6  0x0000000000677f80 in memory_region_iorange_write (iorange=0x139e050, 
        offset=0, width=2, data=32) at /work/armbru/qemu/memory.c:436
    #7  0x00000000006709a5 in ioport_writew_thunk (opaque=0x139e050, addr=126, 
        data=32) at /work/armbru/qemu/ioport.c:219
    #8  0x0000000000670384 in ioport_write (index=1, address=126, data=32)
        at /work/armbru/qemu/ioport.c:83
    #9  0x0000000000670e32 in cpu_outw (addr=126, val=32)
        at /work/armbru/qemu/ioport.c:296
    #10 0x0000000000674637 in kvm_handle_io (port=126, data=0x7ffff7ffb000, 
        direction=1, size=2, count=1) at /work/armbru/qemu/kvm-all.c:1411
    #11 0x0000000000674bc5 in kvm_cpu_exec (env=0x1389b30)
        at /work/armbru/qemu/kvm-all.c:1556
    #12 0x000000000060e0b4 in qemu_kvm_cpu_thread_fn (arg=0x1389b30)
        at /work/armbru/qemu/cpus.c:757
    #13 0x0000003b0ea07d14 in start_thread () from /lib64/libpthread.so.0
    #14 0x0000003b0def197d in clone () from /lib64/libc.so.6

Happens when -m argument is a multiple of 4k in [648k..768k].  Only with
--enable-kvm.  With and without my CMOS fix applied.

And another one:

    $  qemu-system-x86_64 -nodefaults --enable-kvm -vnc :0 -monitor stdio -m 
900k
    QEMU 1.1.50 monitor - type 'help' for more information
    (qemu) KVM internal error. Suberror: 1
    emulation failure
    EAX=000fdb78 EBX=00000000 ECX=00000000 EDX=000fdb64
    ESI=00000000 EDI=000fdb64 EBP=00000000 ESP=00006f98
    EIP=000e3492 EFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
    ES =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
    CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
    SS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
    DS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
    FS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
    GS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
    LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
    TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
    GDT=     000fcd68 00000037
    IDT=     000fdb60 00000000
    CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
    DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 
DR3=0000000000000000 
    DR6=00000000ffff0ff0 DR7=0000000000000400
    EFER=0000000000000000
    Code=00 00 b8 26 00 00 00 eb 95 83 c8 ff 83 c4 4c 5b 5e 5f 5d c3 <57> 56 53 
89 d6 39 c2 72 06 89 c7 f3 a4 eb 1b 8d 51 ff 01 d0 01 d6 89 cf 31 d2 eb 08 8a 1c
    q

Breakpoint on kvm_handle_internal_error() yields backtrace:

    #0  kvm_handle_internal_error (env=0x1389b30, run=0x7ffff7ffa000)
        at /work/armbru/qemu/kvm-all.c:1424
    #1  0x0000000000674c5a in kvm_cpu_exec (env=0x1389b30)
        at /work/armbru/qemu/kvm-all.c:1586
    #2  0x000000000060e0b4 in qemu_kvm_cpu_thread_fn (arg=0x1389b30)
        at /work/armbru/qemu/cpus.c:757
    #3  0x0000003b0ea07d14 in start_thread () from /lib64/libpthread.so.0
    #4  0x0000003b0def197d in clone () from /lib64/libc.so.6

Also seen with 904k, 908k, 964k, 968k, 972k 976k, and a whole lot more.
Not reproduced with 1024k+.

An easy way to "fix" these is to require 1MiB of RAM :)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]