or $0x20, %eax /* CR4.PAE = bit 5 */
mov %eax, %cr4
+ /* Enable NXE in IA32_EFER on this AP if the CPU supports NX. */
+ mov $0x80000000, %eax
+ cpuid
+ cmp $0x80000001, %eax
+ jb 1f
+ mov $0x80000001, %eax
+ cpuid
+ bt $20, %edx
+ jnc 1f
+ mov $0xC0000080, %ecx
+ rdmsr
+ or $0x800, %eax
+ wrmsr
+1:
+
/* Load CR3 (PDPT physical address) from data area */
mov (AP_DATA_BASE + 8), %eax
mov %eax, %cr3
return -1;
}
+/* Local PROT_* definitions for fb0_mmap */
+enum {
+ PROT_NONE = 0x0,
+ PROT_READ = 0x1,
+ PROT_WRITE = 0x2,
+ PROT_EXEC = 0x4,
+};
+
static uintptr_t fb0_mmap(fs_node_t* node, uintptr_t addr, uint32_t length, uint32_t prot, uint32_t offset) {
- (void)node; (void)prot; (void)offset;
+ (void)node; (void)offset;
if (!g_vbe_ready) return 0;
+ /* Respect prot argument - deny execution, apply NX by default */
+ if (prot & PROT_EXEC) return 0; /* Framebuffer is not executable */
+
+ uint32_t vmm_flags = VMM_FLAG_PRESENT | VMM_FLAG_USER | VMM_FLAG_NOCACHE;
+ if (prot & PROT_WRITE) vmm_flags |= VMM_FLAG_RW;
+ else if (prot & PROT_READ) vmm_flags |= VMM_FLAG_RW; /* No RO flag in VMM, use RW for read */
+ else vmm_flags |= VMM_FLAG_RW; /* Default to RW if no prot specified */
+ /* NX by default */
+ vmm_flags |= VMM_FLAG_NX;
+
uint32_t aligned_len = (length + 0xFFFU) & ~(uint32_t)0xFFFU;
if (aligned_len > ((g_vbe.size + 0xFFFU) & ~(uint32_t)0xFFFU))
aligned_len = (g_vbe.size + 0xFFFU) & ~(uint32_t)0xFFFU;
for (uint32_t i = 0; i < aligned_len; i += 0x1000U) {
vmm_map_page((uint64_t)(g_vbe.phys_addr + i),
(uint64_t)(addr + i),
- VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER | VMM_FLAG_NOCACHE);
+ vmm_flags);
}
return addr;
/* Map physical pages into user address space.
* vmm_map_page signature: (phys, virt, flags)
- * K24: NX flag deferred until IA32_EFER.NXE MSR is enabled (A01) */
+ * NX by default - IA32_EFER.NXE MSR is now enabled (A01 completed) */
for (uint32_t i = 0; i < seg->npages; i++) {
vmm_map_page((uint64_t)seg->pages[i],
(uint64_t)(vaddr + i * PAGE_SIZE),
- VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER);
+ VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER | VMM_FLAG_NX);
}
/* Record mapping in process mmap table with shmid for detach lookup */
/* Anonymous mmap: allocate fresh zeroed pages */
uint32_t vmm_flags = VMM_FLAG_PRESENT | VMM_FLAG_USER;
if (prot & PROT_WRITE) vmm_flags |= VMM_FLAG_RW;
+ /* NX by default, remove only if PROT_EXEC is explicitly requested */
+ if (!(prot & PROT_EXEC)) vmm_flags |= VMM_FLAG_NX;
uintptr_t mapped_va[1024];
int mapped_count = 0;
}
vmm_as_map_page(current_process->addr_space,
(uint64_t)(uintptr_t)frame, (uint64_t)va,
- VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER);
+ VMM_FLAG_PRESENT | VMM_FLAG_RW | VMM_FLAG_USER | VMM_FLAG_NX);
memset((void*)va, 0, 0x1000U);
if (mapped_count < 1024) mapped_va[mapped_count++] = va;
}