aarch64/mem: Add fast GPA-to-HVA translation helper

In emulating guests with a simple, flat memory model, we frequently need
to translate a guest physical address (GPA) into a host virtual address
(HVA). This is a hot path operation that must be efficient as possible.

This commit introduces gpa_to_hva(), a static inline helper function
designed for this purpose. The implementation relies on the fundamental
pre-condition that the guest's physical RAM is backed by a single,
contiguous region of host virtual memory (typically acquired via mmap).
It treats the GPA not as a pointer but as a direct byte offset from the
base of this host mapping.

This approach is optimal for performance for two key reasons:

1. The translation is a single pointer-offset calculation, which
   typically compiles to a single LEA intruction on x86-64.

2. It preserves memory access  locality. When a guest performs
   sequential accesses, the host's accesses are also sequential,
   allowing the host CPU's hardware prefetcher to function effectively.

This helper provides the fast path for simple RAM accesses. More
complex address spaces involving discontiguous memory or MMIO regions
will require a slower, lookup-based translation mechanism. This
function is not intended for those cases.

Signed-off-by: Ronald Caesar <github43132@proton.me>
This commit is contained in:
Ronald Caesar 2025-08-13 15:00:48 -04:00
parent f15417802d
commit 55af4bebda
2 changed files with 57 additions and 1 deletions

16
core/aarch64/isa.cpp Executable file → Normal file
View file

@ -1,9 +1,25 @@
#include "isa.h"
#include "Base/Assert.h"
#include "memory/arena.h"
static inline void* aarch64::memory::gpa_to_hva(aarch64::memory::guest_memory_t* memory, uint64_t gpa)
{
ASSERT(nullptr != memory);
ASSERT(nullptr != memory->base);
ASSERT(gpa < memory->size);
void* hva = memory->base + gpa;
return hva;
}
void cpuTest()
{
aarch64::vcpu_state_t vcpu_states[CPU_CORES] = {};
memory::arena_t guest_memory_arena = memory::arena_init(GUEST_RAM_SIZE);
ASSERT(nullptr != guest_memory_arena.data);
aarch64::memory::guest_memory_t guest_ram = {};
guest_ram.base = guest_memory_arena.data;
guest_ram.size = guest_memory_arena.capacity;
// Outdated Code
CPU cpu;

View file

@ -2,8 +2,8 @@
#pragma once
#include <cstring>
#include <cstdlib>
#include <cstring>
#include "Base/Logging/Log.h"
@ -16,6 +16,7 @@ namespace aarch64
#define FP_REGISTERS 32
#define CACHE_LINE_SIZE 64
#define GUEST_RAM_SIZE 10240 // 10KiB
#define CPU_CORES 8
/*
@ -36,6 +37,45 @@ typedef struct alignas(CACHE_LINE_SIZE)
uint64_t pc;
uint32_t pstate;
} vcpu_state_t;
namespace memory
{
/*
* guest_memory_t - Describes a contiguous block of guest physical RAM.
* @base: Pointer to the start of the host-allocated memory block.
* @size: The size of the memory block in bytes.
*/
typedef struct
{
void* base;
uint64_t size;
} guest_memory_t;
/*
* gpa_to_hva() - Translate a Guest Physical Address to a Host Virtual Address.
* @memory: The guest memory region to translate within.
* @gpa: The Guest Physical Address (offset) to translate.
*
* This function provides a fast, direct translation for a flat guest memory
* model. It relies on the critical pre-condition that the guest's physical
* RAM is backed by a single, contiguous block of virtual memory in the host's
* userspace (typically allocated with mmap()).
*
* In this model, memory->base is the Host Virtual Address (HVA) of the start of
* the backing host memory. The provided Guest Physical Address (gpa) is not
* treated as a pointer, but as a simple byte offset from the start of the guest's
* physical address space (PAS).
*
* The translatiom is therefore a single pointer-offset calculation. This establishes
* a direct 1:1 mapping between the guest's PAS and the host's virtual memory block.
*
* The function asserts that GPA is within bounds. The caller is responsible for
* ensuring the validity of the GPA prior to calling.
*
* Return: A valid host virtual address pointer corresponding to the GPA.
*/
static inline void* gpa_to_hva(guest_memory_t* memory, uint64_t gpa);
} // namespace memory
} // namespace aarch64
//=========================================================