Author: kib
Date: Mon May 15 20:52:43 2017
New Revision: 318318
URL: https://svnweb.freebsd.org/changeset/base/318318

Log:
  Ensure that resume path on amd64 only accesses page tables for normal
  operation after processor is configured to allow all required
  features.
  
  In particular, NX must be enabled in EFER, otherwise load of page
  table element with nx bit set causes reserved bit page fault.  Since
  malloc uses direct mapping for small allocations, in particular for
  the suspension pcbs, and DMAP is nx after r316767, this commit tripped
  fault on resume path.
  
  Restore complete state of EFER while wakeup code is still executing
  with custom page table, before calling resumectx, instead of trying to
  guess which features might be needed before resumectx restored EFER on
  its own.
  
  Bisected and tested by:       trasz
  Sponsored by: The FreeBSD Foundation
  MFC after:    2 weeks

Modified:
  head/sys/amd64/acpica/acpi_wakecode.S
  head/sys/amd64/amd64/cpu_switch.S
  head/sys/x86/acpica/acpi_wakeup.c

Modified: head/sys/amd64/acpica/acpi_wakecode.S
==============================================================================
--- head/sys/amd64/acpica/acpi_wakecode.S       Mon May 15 20:41:29 2017        
(r318317)
+++ head/sys/amd64/acpica/acpi_wakecode.S       Mon May 15 20:52:43 2017        
(r318318)
@@ -156,11 +156,12 @@ wakeup_32:
        /*
         * Enable EFER.LME so that we get long mode when all the prereqs are
         * in place.  In this case, it turns on when CR0_PG is finally enabled.
-        * Pick up a few other EFER bits that we'll use need we're here.
+        * Also it picks up a few other EFER bits that we'll use need we're
+        * here, like SYSCALL and NX enable.
         */
        movl    $MSR_EFER, %ecx
-       rdmsr
-       orl     $EFER_LME | EFER_SCE, %eax
+       movl    wakeup_efer - wakeup_start(%ebx), %eax
+       movl    wakeup_efer + 4 - wakeup_start(%ebx), %edx
        wrmsr
 
        /*
@@ -276,6 +277,8 @@ wakeup_pcb:
        .quad   0
 wakeup_ret:
        .quad   0
+wakeup_efer:
+       .quad   0
 wakeup_gdt:
        .word   0
        .quad   0

Modified: head/sys/amd64/amd64/cpu_switch.S
==============================================================================
--- head/sys/amd64/amd64/cpu_switch.S   Mon May 15 20:41:29 2017        
(r318317)
+++ head/sys/amd64/amd64/cpu_switch.S   Mon May 15 20:52:43 2017        
(r318318)
@@ -396,7 +396,7 @@ ENTRY(resumectx)
        movl    4 + PCB_KGSBASE(%rdi),%edx
        wrmsr
 
-       /* Restore EFER. */
+       /* Restore EFER one more time. */
        movl    $MSR_EFER,%ecx
        movl    PCB_EFER(%rdi),%eax
        wrmsr

Modified: head/sys/x86/acpica/acpi_wakeup.c
==============================================================================
--- head/sys/x86/acpica/acpi_wakeup.c   Mon May 15 20:41:29 2017        
(r318317)
+++ head/sys/x86/acpica/acpi_wakeup.c   Mon May 15 20:52:43 2017        
(r318318)
@@ -223,7 +223,9 @@ acpi_sleep_machdep(struct acpi_softc *sc
                WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0));
                WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0));
 
-#ifndef __amd64__
+#ifdef __amd64__
+               WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER));
+#else
                WAKECODE_FIXUP(wakeup_cr4, register_t, pcb->pcb_cr4);
 #endif
                WAKECODE_FIXUP(wakeup_pcb, struct pcb *, pcb);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to