Index: sys/i386/acpica/acpi_wakecode.S =================================================================== --- sys/i386/acpica/acpi_wakecode.S +++ sys/i386/acpica/acpi_wakecode.S @@ -143,16 +143,26 @@ mov $bootdata32 - bootgdt, %eax mov %ax, %ds - /* Get PCB and return address. */ - movl wakeup_pcb - wakeup_start(%ebx), %ecx - movl wakeup_ret - wakeup_start(%ebx), %edx - - /* Restore CR4 and CR3. */ - movl wakeup_cr4 - wakeup_start(%ebx), %eax + /* Restore EFER, CR4 and CR3. */ + movl wakeup_efer - wakeup_start(%ebx), %eax + movl wakeup_efer - wakeup_start + 4(%ebx), %edx + cmpl $0, %eax + jne 1f + cmpl $0, %edx + je 2f +1: movl $MSR_EFER, %ecx + wrmsr +2: movl wakeup_cr4 - wakeup_start(%ebx), %eax + cmpl $0, %eax + je 3f mov %eax, %cr4 - movl wakeup_cr3 - wakeup_start(%ebx), %eax +3: movl wakeup_cr3 - wakeup_start(%ebx), %eax mov %eax, %cr3 + /* Get PCB and return address. */ + movl wakeup_ret - wakeup_start(%ebx), %edx + movl wakeup_pcb - wakeup_start(%ebx), %ecx + /* Enable paging. */ mov %cr0, %eax orl $CR0_PG, %eax @@ -187,6 +197,9 @@ .long bootgdt - wakeup_start /* Offset plus %ds << 4 */ ALIGN_DATA +wakeup_efer: + .long 0 + .long 0 wakeup_cr4: .long 0 wakeup_cr3: Index: sys/vm/vm_kern.c =================================================================== --- sys/vm/vm_kern.c +++ sys/vm/vm_kern.c @@ -184,6 +184,7 @@ vm_offset_t addr, i, offset; vm_page_t m; int pflags, tries; + vm_prot_t prot; size = round_page(size); vmem = vm_dom[domain].vmd_kernel_arena; @@ -193,6 +194,7 @@ pflags = malloc2vm_flags(flags) | VM_ALLOC_NOBUSY | VM_ALLOC_WIRED; pflags &= ~(VM_ALLOC_NOWAIT | VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL); pflags |= VM_ALLOC_NOWAIT; + prot = (flags & M_EXEC) != 0 ? VM_PROT_ALL : VM_PROT_RW; VM_OBJECT_WLOCK(object); for (i = 0; i < size; i += PAGE_SIZE) { tries = 0; @@ -220,8 +222,8 @@ if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0) pmap_zero_page(m); m->valid = VM_PAGE_BITS_ALL; - pmap_enter(kernel_pmap, addr + i, m, VM_PROT_RW, - VM_PROT_RW | PMAP_ENTER_WIRED, 0); + pmap_enter(kernel_pmap, addr + i, m, prot, + prot | PMAP_ENTER_WIRED, 0); } VM_OBJECT_WUNLOCK(object); return (addr); Index: sys/x86/acpica/acpi_wakeup.c =================================================================== --- sys/x86/acpica/acpi_wakeup.c +++ sys/x86/acpica/acpi_wakeup.c @@ -260,6 +260,8 @@ WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER) & ~(EFER_LMA)); #else + if ((amd_feature & AMDID_NX) != 0) + WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER)); WAKECODE_FIXUP(wakeup_cr4, register_t, pcb->pcb_cr4); #endif WAKECODE_FIXUP(wakeup_pcb, struct pcb *, pcb); @@ -375,8 +377,12 @@ * page-aligned. */ for (i = 0; i < ACPI_WAKEPAGES; i++) { - wakepages[i] = contigmalloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT, - 0x500, 0xa0000, PAGE_SIZE, 0ul); + wakepages[i] = contigmalloc(PAGE_SIZE, M_DEVBUF, + M_NOWAIT +#ifdef __i386__ + | M_EXEC +#endif + , 0x500, 0xa0000, PAGE_SIZE, 0ul); if (wakepages[i] == NULL) { printf("%s: can't alloc wake memory\n", __func__); goto freepages;