Everything is crap. That includes UEFI. So apparently some UEFI firmware thinks it is ok to write to the code segment. And technically the standard allows this unless the EFI_MEMORY_RO attribute is set. But of course nobody does.
Anyway, give in. I'll still restrict setting PROT_EXEC a bit even if it violates the standard. At least until the first firmware shows up that genuinly tries to execute code in the data segment. ok? Index: arch/arm64/dev/efi.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/dev/efi.c,v retrieving revision 1.3 diff -u -p -r1.3 efi.c --- arch/arm64/dev/efi.c 12 Jan 2018 14:52:55 -0000 1.3 +++ arch/arm64/dev/efi.c 6 Apr 2018 10:19:41 -0000 @@ -125,7 +125,7 @@ efi_attach(struct device *parent, struct vaddr_t va = desc->VirtualStart; paddr_t pa = desc->PhysicalStart; int npages = desc->NumberOfPages; - vm_prot_t prot = PROT_READ; + vm_prot_t prot = PROT_READ | PROT_WRITE; #ifdef EFI_DEBUG printf("type 0x%x pa 0x%llx va 0x%llx pages 0x%llx attr 0x%llx\n", @@ -142,10 +142,20 @@ efi_attach(struct device *parent, struct if ((desc->Attribute & EFI_MEMORY_WB) == 0) pa |= PMAP_DEVICE; + /* + * Only make pages marked as runtime service code + * executable. This violates the standard but it + * seems we can get away with it. + */ if (desc->Type == EfiRuntimeServicesCode) prot |= PROT_EXEC; - else - prot |= PROT_WRITE; + + if (desc->Attribute & EFI_MEMORY_RP) + prot &= ~PROT_READ; + if (desc->Attribute & EFI_MEMORY_XP) + prot &= ~PROT_EXEC; + if (desc->Attribute & EFI_MEMORY_RO) + prot &= ~PROT_WRITE; while (npages--) { pmap_enter(sc->sc_pm, va, pa, prot,