This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 97dcbc010b830a2417858a8dba521ac4e4123390
Author: Marco Casaroli <[email protected]>
AuthorDate: Sun Jul 26 17:24:57 2026 +0200

    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 <[email protected]>
---
 arch/x86_64/src/common/x86_64_addrenv.c | 10 ++++++++++
 arch/x86_64/src/common/x86_64_mmu.h     |  4 ++++
 2 files changed, 14 insertions(+)

diff --git a/arch/x86_64/src/common/x86_64_addrenv.c 
b/arch/x86_64/src/common/x86_64_addrenv.c
index b8396b84bc0..1473987b37b 100644
--- a/arch/x86_64/src/common/x86_64_addrenv.c
+++ b/arch/x86_64/src/common/x86_64_addrenv.c
@@ -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];
+    }
 }
 
 /****************************************************************************
diff --git a/arch/x86_64/src/common/x86_64_mmu.h 
b/arch/x86_64/src/common/x86_64_mmu.h
index e029075a194..634a60d1b97 100644
--- a/arch/x86_64/src/common/x86_64_mmu.h
+++ b/arch/x86_64/src/common/x86_64_mmu.h
@@ -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
  ****************************************************************************/

Reply via email to