Skip to content

Mapping aliased memory regions will fail on the HAXM module #21

Closed
@AlexAltea

Description

@AlexAltea

Background

Many emulators, e.g. QEMU, represent the guest physical address space as an acyclic directed graph whose leaves provide backing memory (for RAM/ROM) and/or hooks for reading/writing (for IO). See: https://github.com/qemu/qemu/blob/master/docs/devel/memory.rst

As a result, the same backing HVA can be referenced at two different locations: For example, the 256 KB (0x40000 bytes) BIOS image is mapped into 0xFFFC0000-0xFFFFFFFF. But an alias into 128 KB at the bottom of the BIOS image region is mapped at 0xE0000-0xFFFFF.

Issue

The implementation of MapGuestMemory and MapGuestMemoryLarge in the HAXM module calls each two ioctl's in succession. Specifically:

  • MapGuestMemory:
    • HAX_VM_IOCTL_ALLOC_RAM
    • HAX_VM_IOCTL_SET_RAM
  • MapGuestMemoryLarge:
    • HAX_VM_IOCTL_ADD_RAMBLOCK
    • HAX_VM_IOCTL_SET_RAM2

If I understand HAXM correctly, The first ioctl is supposed to create the HVA-to-HPA mappings, and the second one is actually taking care of the GPA-to-HPA mappings (via EPT).

EPT-translation works in the same way as CR3-translation turns HVAs into HPAs, so it allows overlapping HPA ranges, so the second ioctl has no issue with overlapping ranges (like the BIOS one mentioned above). However, the first ioctl won't allow adding the same HVA range twice.

Since your approach merges the two steps, it won't allow aliases.

Possible solution

This might not be the most efficient way of dealing with this, but to fix it without changing your API, you could cache which HVA ranges have been already "added" to HAXM, and avoid them in future MapGuestMemory calls.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions