> ## Documentation Index
> Fetch the complete documentation index at: https://kernel.mvhcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MVH Kernel Memory Model: PMM, VMM, Flags, and Heap

> How MVH Kernel manages physical pages, virtual address mappings, and the kernel heap — including page flags, heap canaries, and security protections.

MVH Kernel divides memory management into three co-operating layers: the Physical Memory Manager (PMM) tracks raw 4 KiB page frames; the Virtual Memory Manager (VMM) builds and manipulates the four-level x86\_64 page tables that map virtual addresses to those frames; and the kernel heap provides byte-granularity `kmalloc` / `kfree` allocations backed by a contiguous 1 MiB VMM region. Each layer exposes its own API and statistics, and each adds its own hardening measures so that memory bugs are caught as early and as loudly as possible.

<Note>
  User/kernel address-space separation is **not yet active** in this release (`user_kernel_separation: false`). The `VMM_USER` page flag is defined but the kernel does not switch page tables on any privilege boundary. All execution happens in ring 0 with a single shared address space.
</Note>

***

## Physical Memory (PMM)

### Page Size and Identity Map

The PMM works exclusively in **4 KiB (4 096 byte) pages**. It builds its free-page bitmap from the total usable RAM figure supplied by your bootloader at entry time. The identity map — where virtual address `V` maps to physical address `V` — covers only the **first 1 024 MiB** of physical address space. Physical memory above 1 GiB is tracked by the PMM but cannot be accessed through the identity map; you must create explicit VMM mappings for it.

### Allocation API

```c theme={null}
// Allocate `count` contiguous physical pages.
// Returns a pointer to the first page, or NULL on failure.
void *pmm_alloc_pages(uint32_t count);

// Release `count` contiguous physical pages starting at `address`.
void  pmm_free_pages(void *address, uint32_t count);

// Fill `stats` with current PMM counters.
void  pmm_get_stats(pmm_stats_t *stats);
```

### PMM Statistics

`pmm_get_stats` fills a `pmm_stats_t` struct with the following counters:

| Field                 | Description                                     |
| --------------------- | ----------------------------------------------- |
| `total_pages`         | Total physical pages visible to the kernel      |
| `used_pages`          | Pages currently allocated or reserved           |
| `free_pages`          | Pages available for allocation                  |
| `reserved_pages`      | Pages permanently reserved (kernel image, etc.) |
| `allocation_requests` | Cumulative `pmm_alloc_pages` calls              |
| `free_requests`       | Cumulative `pmm_free_pages` calls               |
| `failed_allocations`  | Allocation calls that returned `NULL`           |
| `peak_used_pages`     | Highest `used_pages` value observed since boot  |

***

## Virtual Memory (VMM)

### Paging Model

The VMM implements the standard **x86\_64 four-level paging** hierarchy (PML4 → PDPT → PD → PT). Each leaf entry maps exactly one 4 KiB page. The VMM supports dynamic mapping and unmapping of individual pages at runtime; there is no large-page (2 MiB / 1 GiB) support in this release.

### Mapping API

```c theme={null}
// Map virtual_address → physical_address with the given flags.
// Returns 0 on success, negative on error.
int vmm_map_page(uintptr_t virtual_address,
                 uintptr_t physical_address,
                 uint64_t  flags);

// Remove the mapping for virtual_address.
int vmm_unmap_page(uintptr_t virtual_address);

// Query the physical address and flags for a virtual address.
int vmm_query_page(uintptr_t  virtual_address,
                   uintptr_t *physical_address,
                   uint64_t  *flags);

// Return the total number of pages currently mapped.
uint64_t vmm_mapped_pages(void);
```

### Page Flags

Pass a bitwise-OR combination of the constants below as the `flags` argument to `vmm_map_page`:

| Constant            | Bit                   | Meaning                                        |
| ------------------- | --------------------- | ---------------------------------------------- |
| `VMM_PRESENT`       | bit 0 (`1ull << 0`)   | Page is present in memory                      |
| `VMM_WRITABLE`      | bit 1 (`1ull << 1`)   | Page is writable                               |
| `VMM_USER`          | bit 2 (`1ull << 2`)   | Page is accessible from user mode (ring 3)     |
| `VMM_WRITE_THROUGH` | bit 3 (`1ull << 3`)   | Write-through caching                          |
| `VMM_CACHE_DISABLE` | bit 4 (`1ull << 4`)   | Cache disabled for this page                   |
| `VMM_GLOBAL`        | bit 8 (`1ull << 8`)   | TLB entry is global (not flushed on CR3 write) |
| `VMM_NO_EXECUTE`    | bit 63 (`1ull << 63`) | Execution from this page is forbidden (NX/XD)  |

<Tip>
  Always set `VMM_PRESENT` in every mapping; a page-table entry without this bit is treated as not-present by the CPU and will trigger a `#PF` on access.
</Tip>

### Security Protections

MVH Kernel enables the following hardware security features during VMM initialisation, conditional on CPU support detected via CPUID:

| Protection                   | Mechanism                   | Effect                                                                                    |
| ---------------------------- | --------------------------- | ----------------------------------------------------------------------------------------- |
| **Supervisor Write Protect** | CR0.WP                      | Prevents the kernel from writing to read-only pages even in ring 0                        |
| **NX Enforcement**           | EFER.NXE + `VMM_NO_EXECUTE` | Non-executable pages raise `#PF` on instruction fetch                                     |
| **Null Page Guard**          | Page not mapped             | Dereferencing a null pointer faults immediately                                           |
| **SMEP**                     | CR4.SMEP                    | Supervisor Mode Execution Prevention — kernel cannot execute user-mode pages              |
| **SMAP**                     | CR4.SMAP                    | Supervisor Mode Access Prevention — kernel cannot implicitly read user-mode pages         |
| **UMIP**                     | CR4.UMIP                    | User Mode Instruction Prevention — blocks `SGDT`, `SIDT`, `SLDT`, `SMSW`, `STR` in ring 3 |

### Kernel Memory Permissions

| Region                        | Flags                                               |
| ----------------------------- | --------------------------------------------------- |
| Kernel text (`.text`)         | `VMM_PRESENT` — read-only, executable               |
| Kernel data (`.data`, `.bss`) | `VMM_PRESENT` \| `VMM_WRITABLE` \| `VMM_NO_EXECUTE` |

***

## Kernel Heap

### Overview

The kernel heap occupies a contiguous **1 MiB** region of kernel virtual address space and is managed with a coalescing free-list allocator. Adjacent free blocks are merged on every `kfree` call, keeping fragmentation low over long-running sessions.

### Allocation API

```c theme={null}
// Allocate `size` bytes. Returns a pointer, or NULL on failure.
void *kmalloc(uint64_t size);

// Free a previously allocated pointer.
void  kfree(void *address);

// Convenience statistics helpers.
uint64_t heap_total_bytes(void);
uint64_t heap_used_bytes(void);
uint64_t heap_allocation_count(void);

// Fill `stats` with full heap counters.
void heap_get_stats(heap_stats_t *stats);

// Walk every block and verify all canaries. Returns 0 on success.
int  heap_validate(void);
```

### Hardening

MVH Kernel's heap implements three independent hardening layers:

<Steps>
  <Step title="Canary Protection">
    Every allocated block stores a magic canary value immediately after the user data. When you call `kfree`, the canary is verified before the block is returned to the free list. A mismatched canary means a buffer overrun has occurred and the kernel panics immediately with a descriptive message, rather than silently corrupting later allocations.
  </Step>

  <Step title="Free Poisoning">
    After a block is freed its memory is overwritten with a poison byte pattern. Any code that reads from the freed region will see nonsense data, and any code that dereferences a poisoned pointer will quickly fault, making use-after-free bugs detectable at the point of access rather than at a distant, confusing downstream failure.
  </Step>

  <Step title="Invalid-Free Tracking">
    Calls to `kfree` with a pointer that was never returned by `kmalloc`, has already been freed, or falls outside the heap region are counted in the `invalid_frees` statistics field. The kernel does not silently ignore these calls — each one increments the counter and, depending on severity, can trigger a panic.
  </Step>
</Steps>

### Heap Statistics

`heap_get_stats` fills a `heap_stats_t` struct:

| Field                 | Type       | Description                               |
| --------------------- | ---------- | ----------------------------------------- |
| `total_bytes`         | `uint64_t` | Total heap capacity in bytes              |
| `used_bytes`          | `uint64_t` | Bytes currently allocated by live objects |
| `free_bytes`          | `uint64_t` | Bytes available for new allocations       |
| `largest_free_block`  | `uint64_t` | Size of the largest contiguous free block |
| `allocations`         | `uint64_t` | Cumulative successful `kmalloc` calls     |
| `allocation_failures` | `uint64_t` | `kmalloc` calls that returned `NULL`      |
| `invalid_frees`       | `uint64_t` | `kfree` calls with invalid pointers       |
| `blocks`              | `uint32_t` | Total number of heap blocks (free + used) |
| `free_blocks`         | `uint32_t` | Number of free blocks                     |

***

## Memory Layout Summary

The table below gives a high-level view of the kernel's virtual address space as established during boot.

| Region                                            | Contents                     | Notes                                                |
| ------------------------------------------------- | ---------------------------- | ---------------------------------------------------- |
| `0x0000_0000_0000_0000`                           | Null guard page              | Unmapped; null dereferences fault here               |
| `0x0000_0000_0000_1000` – `0x0000_0000_3FFF_FFFF` | Identity-mapped physical RAM | First 1 GiB; virtual address equals physical address |
| Kernel load address                               | Kernel text                  | Read-only, executable                                |
| Immediately after text                            | Kernel data / BSS            | Writable, non-executable                             |
| Heap region                                       | Kernel heap (1 MiB)          | Managed by `kmalloc` / `kfree`                       |
| Above identity map                                | High physical RAM            | Accessible only via explicit `vmm_map_page` calls    |
