Page 1 of 1

UEFI GetMemoryMap is crashed

Posted: Sat Dec 03, 2022 8:07 am
by cyberfined
Hi, all! I am trying to get memory map, but it is crashing the qemu. Please help me to fix it.

Qemu error:

Code: Select all

[code]
KVM internal error. Suberror: 1
emulation failure
RAX=0000000007f28240 RBX=0000000007f11588 RCX=000000000685f398 RDX=0000000006727100
RSI=0000000007f116e8 RDI=000000000685f318 RBP=0000000007f11578 RSP=0000000007f11518
R8 =0000000007f11588 R9 =0000000000006000 R10=000000000685f188 R11=00000000d848021d
R12=0000000000000000 R13=000000000685fa18 R14=0000000006727100 R15=000000000678c1e8
RIP=00000000000b0000 RFL=00000282 [--S----] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0038 0000000000000000 ffffffff 00a09b00 DPL=0 CS64 [-RA]
SS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0030 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     00000000079de000 00000047
IDT=     0000000007272018 00000fff
CR0=80010033 CR2=0000000000000000 CR3=0000000007c01000 CR4=00000668
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
EFER=0000000000000d00
Code=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <ff> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[/code]

The code to get memory map:

Code: Select all

#define ROUNDUP(x,b) (((unsigned long)x+b-1)&(~(b-1)))
#define PAGEUP(x) ROUNDUP(x, PAGE_SIZE)
#define PAGE_SIZE 4096

#define handle_error(err) do { \
    printf(L"Error: %s\r\n", str_status(err)); \
    exit(2); \
} while(0)
EfiMemoryDescriptor* get_memory_map(size_t *map_key) {
    puts(L"Retrieve size for memory map buffer");
    size_t descriptor_size;
    uint32_t descriptor_version;
    size_t buffer_size = 0;
    size_t err = system_table->boot_services->get_memory_map(
        &buffer_size,
        NULL,
        map_key,
        &descriptor_size,
        &descriptor_version
    );
    if(error_code(err) != EfiBufferTooSmall)
        handle_error(err);

    puts(L"Allocate memory for memory map buffer");
    EfiMemoryDescriptor *buffer = NULL;
    size_t num_pages = PAGEUP(buffer_size) / PAGE_SIZE;
    buffer_size = num_pages * PAGE_SIZE;
    err = system_table->boot_services->allocate_pages(
        AllocateAnyPages,
        EfiLoaderData,
        num_pages,
        (uint64_t*)&buffer
    );
    if(err != 0)
        handle_error(err);

    puts(L"Retrieve memory map");
    err = system_table->boot_services->get_memory_map(
        &buffer_size,
        buffer,
        map_key,
        &descriptor_size,
        &descriptor_version
    );
    if(err != 0)
        handle_error(err);

    return buffer;
}

Re: UEFI GetMemoryMap is crashed

Posted: Sun Dec 04, 2022 11:47 pm
by Octocontrabass
I don't see anything obviously wrong with that code. Have you tried stepping through it in a debugger to see how far it gets before it jumps to an invalid address?

Re: UEFI GetMemoryMap is crashed

Posted: Mon Dec 05, 2022 12:09 am
by kzinti
Are you calling AllocatePages() anywhere with a custom memory type? This will make GetMemoryMap() crash on some firmwares.

Re: UEFI GetMemoryMap is crashed

Posted: Mon Dec 05, 2022 6:26 am
by cyberfined
I call AllocatePages only before GetMemoryMap with memory type EfiLoaderData

Re: UEFI GetMemoryMap is crashed

Posted: Mon Dec 05, 2022 11:00 am
by kzinti
KVM internal error. Suberror: 1
This doesn't seem related to your code. Can you try running again without kvm acceleration?

Re: UEFI GetMemoryMap is crashed

Posted: Mon Dec 05, 2022 11:17 am
by cyberfined
Thank you, it does not crash