Hi,

The bug reported by Ryan, pulse.purge at gmail.com demonstraits the
memory map should be determined after calling efi_cleanup().

  amd64 UEFI machine fails to load kernel; displays "ExitBootServices"
  and reboots
  http://marc.info/?l=openbsd-bugs&m=148253785924157&w=2

I tested it on a BIOS machine as well.

ok?

Move efi_cleanup() to before the mem_prove() since efi_cleanup() might
change the memory map.  diff from Ryan, pulse.purge at gmail.com.

Index: libsa/exec_i386.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/stand/libsa/exec_i386.c,v
retrieving revision 1.18
diff -u -p -r1.18 exec_i386.c
--- libsa/exec_i386.c   11 Sep 2016 17:51:21 -0000      1.18
+++ libsa/exec_i386.c   8 Feb 2017 04:02:59 -0000
@@ -73,7 +73,7 @@ run_loadfile(u_long *marks, int howto)
        bios_bootsr_t bootsr;
        struct sr_boot_volume *bv;
 #endif
-#if defined(EFIBOOT)
+#ifdef EFIBOOT
        int i;
        u_long delta;
        extern u_long efi_loadaddr;
@@ -81,6 +81,7 @@ run_loadfile(u_long *marks, int howto)
        if ((av = alloc(ac)) == NULL)
                panic("alloc for bootarg");
        efi_makebootargs();
+       delta = DEFAULT_KERNEL_ADDRESS - efi_loadaddr;
 #endif
        if (sa_cleanup != NULL)
                (*sa_cleanup)();
@@ -117,6 +118,19 @@ run_loadfile(u_long *marks, int howto)
        sr_clear_keys();
 #endif
 
+       entry = marks[MARK_ENTRY] & 0x0fffffff;
+#ifdef EFIBOOT
+       entry += delta;
+#endif
+
+       printf("entry point at 0x%lx [%x, %x, %x, %x]\n", entry,
+           ((int *)entry)[0], ((int *)entry)[1],
+           ((int *)entry)[2], ((int *)entry)[3]);
+
+#ifdef EFIBOOT
+       /* Sync the memory map and call ExitBootServices() */
+       efi_cleanup();
+#endif
        /* Pass memory map to the kernel */
        mem_pass();
 
@@ -130,34 +144,24 @@ run_loadfile(u_long *marks, int howto)
        makebootargs(av, &ac);
 #endif
 
-       entry = marks[MARK_ENTRY] & 0x0fffffff;
-
-       printf("entry point at 0x%lx [%x, %x, %x, %x]\n", entry,
-           ((int *)entry)[0], ((int *)entry)[1],
-           ((int *)entry)[2], ((int *)entry)[3]);
-#ifndef EFIBOOT
-       /* stack and the gung is ok at this point, so, no need for asm setup */
-       (*(startfuncp)entry)(howto, bootdev, BOOTARG_APIVER, marks[MARK_END],
-           extmem, cnvmem, ac, (int)av);
-#else
+#ifdef EFIBOOT
        /*
         * Move the loaded kernel image to the usual place after calling
         * ExitBootServices().
         */
-       delta = DEFAULT_KERNEL_ADDRESS - efi_loadaddr;
-       efi_cleanup();
        memcpy((void *)marks[MARK_START] + delta, (void *)marks[MARK_START],
            marks[MARK_END] - marks[MARK_START]);
        for (i = 0; i < MARK_MAX; i++)
                marks[i] += delta;
-       entry += delta;
+#endif
+
 #ifdef __amd64__
        (*run_i386)((u_long)run_i386, entry, howto, bootdev, BOOTARG_APIVER,
            marks[MARK_END], extmem, cnvmem, ac, (intptr_t)av);
 #else
+       /* stack and the gung is ok at this point, so, no need for asm setup */
        (*(startfuncp)entry)(howto, bootdev, BOOTARG_APIVER, marks[MARK_END],
            extmem, cnvmem, ac, (int)av);
-#endif
 #endif
        /* not reached */
 }

Reply via email to