arch/x86_64: inherit the kernel low memory mapping in an address environment.

copy_kernel_mappings() copies exactly one PDPT entry, the 1GB linear window
that maps physical 0-1GB at 4GB-5GB.  The boot identity mapping of the low
4GB, which lives in PDPT entries 0-3 of g_pdpt_low (intel64_head.S:756, one
page directory per 1GB) and is where every MMIO register is reached, is not
carried over.

A kernel thread never gets an address environment of its own and
addrenv_switch() leaves the last one in place for it, so as soon as any
process exists, kernel code touching MMIO faults.  The HPET at 0xfed00000
finds it immediately -- CR2=fed000f0, in intel64_hpet_getreg() under
clock_systime_ticks() on the lpwork thread -- and any MMIO driver would.

Inherit the four boot PDPT entries.  They point at the boot page directories
rather than at copies, so anything intel64_map_region() adds later is
inherited too, and they carry no X86_PAGE_USER, so user code still cannot
reach them.

Impact: runtime, CONFIG_ARCH_ADDRENV builds only.  User-space access is
unchanged; the entries added are supervisor-only.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
This commit is contained in:
Marco Casaroli 2026-07-26 17:24:57 +02:00 committed by Alan C. Assis
parent a8ed107fa0
commit 97dcbc010b
2 changed files with 14 additions and 0 deletions

View file

@ -70,6 +70,8 @@
#include <nuttx/spinlock.h>
#include <arch/arch.h>
#include "addrenv.h"
#include "pgalloc.h"
#include "x86_64_mmu.h"
@ -192,10 +194,18 @@ static int create_spgtables(arch_addrenv_t *addrenv)
static void copy_kernel_mappings(arch_addrenv_t *addrenv)
{
uintptr_t *pdpt = (uintptr_t *)x86_64_pgvaddr(addrenv->spgtables[1]);
int i;
/* Kernel mapping - lower 1GB maps to 4GB-5GB */
pdpt[4] = X86_PDPT_KERNEL_MAP;
/* Inherit the boot identity mapping of the low 4GB. */
for (i = 0; i < X86_MMU_LOWMEM_PDPTS; i++)
{
pdpt[i] = g_pdpt[i];
}
}
/****************************************************************************

View file

@ -57,6 +57,10 @@
#define X86_MMU_VADDR_INDEX(vaddr, ptlevel) \
((vaddr >> X86_MMU_VADDR_SHIFT(ptlevel)) & X86_MMU_VPN_MASK)
/* Number of PDPT entries in the boot low-memory identity mapping. */
#define X86_MMU_LOWMEM_PDPTS 4
/****************************************************************************
* Public Function Prototypes
****************************************************************************/