summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJohn Levon <john.levon@joyent.com>2019-04-01 10:05:45 +0000
committerJohn Levon <john.levon@joyent.com>2019-04-08 08:43:36 +0000
commitfa83485c3551a3fd3848f1535acb98b30c6595a2 (patch)
treed1ab84da58bdbfaf128c634c000feebb17422123 /usr/src
parent9a8207fa35a4a0b13b30000d6ead058c47c0ccc3 (diff)
downloadillumos-joyent-fa83485c3551a3fd3848f1535acb98b30c6595a2.tar.gz
OS-7260 SmartOS should support booting with loader
OS-7271 proto.boot should include loader instead of grub OS-7332 RICHMOND-16 mitigation ensnares stock loaders OS-7584 MDB module for disk labelling would be useful OS-7585 Need workaround to EFI boot on AMI BIOS OS-7595 Triton-specific extensions to Loader Portions contributed by: Rob Johnston <rob.johnston@joyent.com> Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Toomas Soome <tsoome@me.com> Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/boot/sys/boot/common/console.c13
-rw-r--r--usr/src/boot/sys/boot/forth/Makefile.inc2
-rw-r--r--usr/src/boot/sys/boot/forth/brand-smartos.4th35
-rw-r--r--usr/src/boot/sys/boot/forth/loader.4th18
-rw-r--r--usr/src/boot/sys/boot/forth/logo-smartos.4th41
-rw-r--r--usr/src/boot/sys/boot/forth/menu-commands.4th85
-rw-r--r--usr/src/boot/sys/boot/forth/menu.4th36
-rw-r--r--usr/src/boot/sys/boot/forth/support.4th15
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/i386_copy.c20
-rw-r--r--usr/src/boot/sys/boot/i386/loader/loader.rc6
-rw-r--r--usr/src/boot/sys/boot/i386/pmbr/pmbr.s4
-rw-r--r--usr/src/cmd/mdb/common/modules/disk_label/disk_label.c501
-rw-r--r--usr/src/cmd/mdb/intel/amd64/Makefile5
-rw-r--r--usr/src/cmd/mdb/intel/amd64/disk_label/Makefile28
-rw-r--r--usr/src/cmd/mdb/intel/ia32/Makefile3
-rw-r--r--usr/src/cmd/mdb/intel/ia32/disk_label/Makefile27
-rw-r--r--usr/src/lib/libefi/common/crc32_efi.c5
-rw-r--r--usr/src/lib/libefi/common/rdwr_efi.c138
-rw-r--r--usr/src/uts/common/fs/zfs/zvol.c6
-rw-r--r--usr/src/uts/common/io/cmlb.c3
-rw-r--r--usr/src/uts/common/io/lofi.c72
-rw-r--r--usr/src/uts/common/sys/efi_partition.h14
-rw-r--r--usr/src/uts/i86pc/dboot/dboot_startkern.c125
-rw-r--r--usr/src/uts/i86pc/os/fakebop.c1
-rw-r--r--usr/src/uts/sun4v/io/vds.c5
25 files changed, 1088 insertions, 120 deletions
diff --git a/usr/src/boot/sys/boot/common/console.c b/usr/src/boot/sys/boot/common/console.c
index b84dfe0018..923ab5e5ab 100644
--- a/usr/src/boot/sys/boot/common/console.c
+++ b/usr/src/boot/sys/boot/common/console.c
@@ -23,7 +23,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
+/*
+ * Copyright (c) 2019, Joyent, Inc.
+ */
#include <sys/cdefs.h>
#include <stand.h>
@@ -281,15 +283,6 @@ cons_change(const char *string)
active++;
continue;
}
-
- if (active != 0) {
- /*
- * If no consoles have initialised we wouldn't
- * see this.
- */
- printf("console %s failed to initialize\n",
- consoles[cons]->c_name);
- }
}
}
diff --git a/usr/src/boot/sys/boot/forth/Makefile.inc b/usr/src/boot/sys/boot/forth/Makefile.inc
index eb2576bd64..09ac830835 100644
--- a/usr/src/boot/sys/boot/forth/Makefile.inc
+++ b/usr/src/boot/sys/boot/forth/Makefile.inc
@@ -4,6 +4,7 @@ FORTH = beastie.4th
FORTH += beadm.4th
FORTH += brand.4th
FORTH += brand-illumos.4th
+FORTH += brand-smartos.4th
FORTH += check-password.4th
FORTH += color.4th
FORTH += delay.4th
@@ -17,6 +18,7 @@ FORTH += logo-fbsdbw.4th
FORTH += logo-illumos.4th
FORTH += logo-orb.4th
FORTH += logo-orbbw.4th
+FORTH += logo-smartos.4th
FORTH += menu.4th
FORTH += menu-commands.4th
FORTH += menusets.4th
diff --git a/usr/src/boot/sys/boot/forth/brand-smartos.4th b/usr/src/boot/sys/boot/forth/brand-smartos.4th
new file mode 100644
index 0000000000..ec3c6a0782
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/brand-smartos.4th
@@ -0,0 +1,35 @@
+\
+\ This file and its contents are supplied under the terms of the
+\ Common Development and Distribution License ("CDDL"), version 1.0.
+\ You may only use this file in accordance with the terms of version
+\ 1.0 of the CDDL.
+\
+\ A full copy of the text of the CDDL should have accompanied this
+\ source. A copy of the CDDL is also available via the Internet at
+\ http://www.illumos.org/license/CDDL.
+\
+
+\
+\ Copyright 2019 Joyent, Inc.
+\
+
+2 brandX ! 1 brandY ! \ Initialize brand placement defaults
+
+: brand+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: brand ( x y -- ) \ "joyent" [wide] logo in B/W (7 rows x 42 columns)
+
+ s" # " brand+
+ s" # #### # # ###### # # ##### " brand+
+ s" # # # # # # ## # # " brand+
+ s" # # # # ##### # # # # " brand+
+ s" # # # # # # # # # # " brand+
+ s" # # # # # # # ## # " brand+
+ s" ##### #### # ###### # # # TM" brand+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/loader.4th b/usr/src/boot/sys/boot/forth/loader.4th
index 92c742c472..27188079f9 100644
--- a/usr/src/boot/sys/boot/forth/loader.4th
+++ b/usr/src/boot/sys/boot/forth/loader.4th
@@ -596,6 +596,24 @@ only forth definitions also support-functions
then
;
+create pathname 1024 chars allot
+
+: set-platform ( c-addr u -- )
+ 2dup
+ pathname place
+ s" /platform/i86pc/kernel/amd64/unix" pathname append
+ pathname count s" bootfile" setenv
+ pathname count erase
+ 2dup
+ pathname place
+ s" /platform/i86pc/amd64/boot_archive" pathname append
+ pathname count s" boot_archive" set-module-path
+ pathname count erase
+ pathname place
+ s" /platform/i86pc/amd64/boot_archive.hash" pathname append
+ pathname count s" boot_archive.hash" set-module-path
+;
+
\ Words to be used inside configuration files
: retry false ; \ For use in load error commands
diff --git a/usr/src/boot/sys/boot/forth/logo-smartos.4th b/usr/src/boot/sys/boot/forth/logo-smartos.4th
new file mode 100644
index 0000000000..9641a4fd81
--- /dev/null
+++ b/usr/src/boot/sys/boot/forth/logo-smartos.4th
@@ -0,0 +1,41 @@
+\
+\ This file and its contents are supplied under the terms of the
+\ Common Development and Distribution License ("CDDL"), version 1.0.
+\ You may only use this file in accordance with the terms of version
+\ 1.0 of the CDDL.
+\
+\ A full copy of the text of the CDDL should have accompanied this
+\ source. A copy of the CDDL is also available via the Internet at
+\ http://www.illumos.org/license/CDDL.
+\
+
+\
+\ Copyright 2019 Joyent, Inc.
+\
+
+52 logoX ! 11 logoY ! \ Initialize logo placement defaults
+
+: logo+ ( x y c-addr/u -- x y' )
+ 2swap 2dup at-xy 2swap \ position the cursor
+ [char] @ escc! \ replace @ with Esc
+ type \ print to the screen
+ 1+ \ increase y for next time we're called
+;
+
+: logo ( x y -- ) \ color Illumos logo
+
+ 0 0 0 0 0 s" /boot/illumos.png" fb-putimage if 2drop exit then
+
+ s" @[31m--@[0;31m+--@[1;31m*@[0;33m--@[1;33m*" logo+
+ s" @[31m|@[1m\@[0m @[31m|\ |@[33m\ @[1m|\" logo+
+ s" @[31m| @[1m\@[0;31m|@[37m @[31m\| @[33m\@[1m| \" logo+
+ s" @[31m+--@[1;31m*@[31m--+@[0;33m--@[1;33m*@[33m--@[33m*" logo+
+ s" |@[31m\ |\ |\ @[33m|@[1m\ |" logo+
+ s" | @[31m\| \| \@[33m| @[1m\|" logo+
+ s" @[1m*@[0m--+@[31m--+@[33m--+@[1m--+" logo+
+ s" @[1m \ |@[0;34m\ |\ |@[1m\ |" logo+
+ s" @[1m \| @[0;34m\| \| @[1m\|" logo+
+ s" @[1m *--+@[0;34m--@[1;34m*@[34m--@[34m*" logo+
+
+ 2drop
+;
diff --git a/usr/src/boot/sys/boot/forth/menu-commands.4th b/usr/src/boot/sys/boot/forth/menu-commands.4th
index d9d3dba411..c72868188c 100644
--- a/usr/src/boot/sys/boot/forth/menu-commands.4th
+++ b/usr/src/boot/sys/boot/forth/menu-commands.4th
@@ -24,6 +24,7 @@
\
\ Copyright 2015 Toomas Soome <tsoome@me.com>
\ Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
+\ Copyright (c) 2019 Joyent, Inc.
marker task-menu-commands.4th
@@ -46,6 +47,43 @@ variable debug_state
also menu-namespace also menu-command-helpers
+\ PATH_MAX + 6
+create chaincmd 1030 chars allot
+
+\
+\ Rollback to previous platform image.
+\ Used by Joyent Triton
+\
+: rollback_boot ( N -- NOTREACHED )
+ dup
+ s" prev-platform" getenv s" bootfile" setenv
+ s" prev-archive" getenv s" boot_archive" set-module-path
+ s" prev-hash" getenv s" boot_archive.hash" set-module-path
+ 0 boot ( state -- )
+;
+
+\
+\ Boot from ipxe kernel
+\ Used by Joyent Triton when booted in BIOS/CSM mode
+\
+: ipxe_boot ( N -- NOTREACHED )
+ dup
+ s" ipxe-bootfile" getenv s" bootfile" setenv
+ s" ipxe-archive" getenv s" boot_archive" set-module-path
+ s" boot_archive.hash" disable-module
+ 0 boot ( state -- )
+;
+
+\
+\ Chainload the ipxe EFI binary
+\ Used by Joyent Triton when booted in UEFI mode
+\
+: ipxe_chainload ( N -- NOTREACHED )
+ s" chain " chaincmd place
+ s" ipxe-efi" getenv chaincmd append
+ chaincmd count evaluate
+;
+
\
\ Boot
\
@@ -319,6 +357,53 @@ also menu-namespace also menu-command-helpers
;
\
+\ Disaster Recovery boot
+\
+
+: rescue_enabled? ( -- flag )
+ s" noimport" getenv -1 <> dup if
+ swap drop ( c-addr flag -- flag )
+ then
+;
+
+: rescue_enable ( -- )
+ s" set noimport=true" evaluate
+ s" smartos" getenv? if
+ s" set standalone=true" evaluate
+ s" set smartos=false" evaluate
+ then
+;
+
+: rescue_disable ( -- )
+ s" noimport" unsetenv
+ s" standalone" unsetenv
+ s" smartos" getenv? if
+ s" set smartos=true" evaluate
+ then
+;
+
+: init_rescue ( N -- N )
+ rescue_enabled? if
+ toggle_menuitem ( n -- n )
+ then
+;
+
+: toggle_rescue ( N -- N TRUE )
+ toggle_menuitem
+ menu-redraw
+
+ \ Now we're going to make the change effective
+
+ dup toggle_stateN @ 0= if
+ rescue_disable
+ else
+ rescue_enable
+ then
+
+ TRUE \ loop menu again
+;
+
+\
\ Escape to Prompt
\
diff --git a/usr/src/boot/sys/boot/forth/menu.4th b/usr/src/boot/sys/boot/forth/menu.4th
index efdd51b6a8..814445fac8 100644
--- a/usr/src/boot/sys/boot/forth/menu.4th
+++ b/usr/src/boot/sys/boot/forth/menu.4th
@@ -3,6 +3,7 @@
\ Copyright (c) 2006-2015 Devin Teske <dteske@FreeBSD.org>
\ Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
\ All rights reserved.
+\ Copyright 2019 Joyent, Inc.
\
\ Redistribution and use in source and binary forms, with or without
\ modification, are permitted provided that the following conditions
@@ -463,20 +464,20 @@ also menu-infrastructure definitions
: osconsole-captions ( N -- )
\ first entry
- dup s" Os[C]onsole.. text" rot 48 menu_caption[x][y] setenv
- dup s" Os^[1mC^[monsole.. ^[32;7mtext^[m" rot 48 ansi_caption[x][y] setenv
+ dup s" OS [C]onsole.......... text" rot 48 menu_caption[x][y] setenv
+ dup s" OS ^[1mC^[monsole........... ^[32;7mtext^[m" rot 48 ansi_caption[x][y] setenv
- dup s" Os[C]onsole.. ttya" rot 49 menu_caption[x][y] setenv
- dup s" Os^[1mC^[monsole.. ^[34;1mttya^[m" rot 49 ansi_caption[x][y] setenv
+ dup s" OS [C]onsole.......... ttya" rot 49 menu_caption[x][y] setenv
+ dup s" OS ^[1mC^[monsole........... ^[34;1mttya^[m" rot 49 ansi_caption[x][y] setenv
- dup s" Os[C]onsole.. ttyb" rot 50 menu_caption[x][y] setenv
- dup s" Os^[1mC^[monsole.. ^[34;1mttyb^[m" rot 50 ansi_caption[x][y] setenv
+ dup s" OS [C]onsole.......... ttyb" rot 50 menu_caption[x][y] setenv
+ dup s" OS ^[1mC^[monsole........... ^[34;1mttyb^[m" rot 50 ansi_caption[x][y] setenv
- dup s" Os[C]onsole.. ttyc" rot 51 menu_caption[x][y] setenv
- dup s" Os^[1mC^[monsole.. ^[34;1mttyc^[m" rot 51 ansi_caption[x][y] setenv
+ dup s" OS [C]onsole.......... ttyc" rot 51 menu_caption[x][y] setenv
+ dup s" OS ^[1mC^[monsole........... ^[34;1mttyc^[m" rot 51 ansi_caption[x][y] setenv
- dup s" Os[C]onsole.. ttyd" rot 52 menu_caption[x][y] setenv
- s" Os^[1mC^[monsole.. ^[34;1mttyd^[m" rot 52 ansi_caption[x][y] setenv
+ dup s" OS [C]onsole.......... ttyd" rot 52 menu_caption[x][y] setenv
+ s" OS ^[1mC^[monsole........... ^[34;1mttyd^[m" rot 52 ansi_caption[x][y] setenv
;
\ This function creates the list of menu items. This function is called by the
@@ -486,7 +487,7 @@ also menu-infrastructure definitions
\ Print the frame caption at (x,y)
s" loader_menu_title" getenv dup -1 = if
- drop s" Welcome to illumos"
+ drop s" Welcome to SmartOS"
then
TRUE ( use default alignment )
s" loader_menu_title_align" getenv dup -1 <> if
@@ -748,7 +749,18 @@ also menu-infrastructure definitions
dup 9 > if drop 9 then
dup 0 < if drop 0 then
- s" Autoboot in N seconds. [Space] to pause" ( n -- n c-addr/u )
+ \ getenv? leaves -1 on stack if the env var exists. Thus if both
+ \ headnode and ipxe exist then the sum of what will be left on the
+ \ stack should be -2.
+ s" headnode" getenv? s" ipxe" getenv? + -2 = if
+ s" ipxe" getenv s" true" compare 0= if
+ s" Autoboot in N seconds from PXE. [Space] to pause" ( n -- n c-addr/u )
+ else
+ s" Autoboot in N seconds from the USB Key. [Space] to pause" ( n -- n c-addr/u )
+ then
+ else
+ s" Autoboot in N seconds. [Space] to pause" ( n -- n c-addr/u )
+ then
2 pick 0> if
rot 48 + -rot ( n c-addr/u -- n' c-addr/u ) \ convert to ASCII
diff --git a/usr/src/boot/sys/boot/forth/support.4th b/usr/src/boot/sys/boot/forth/support.4th
index 31420929d9..8ea4d3812c 100644
--- a/usr/src/boot/sys/boot/forth/support.4th
+++ b/usr/src/boot/sys/boot/forth/support.4th
@@ -226,6 +226,21 @@ create last_module_option sizeof module.next allot 0 last_module_option !
then
;
+\ Place string into an allocated buffer
+\
+\ e.g
+\ create mystring 32 chars allot
+\ s" Burning down " mystring place
+\
+: place over over >r >r char+ swap chars move r> r> c! ;
+
+\ Append string
+\
+\ e.g.
+\ s" the house!" mystring append
+\
+: append over over >r >r count chars + swap chars move r> r> dup >r c@ + r> c! ;
+
\ Returns TRUE if the framebuffer is active, FALSE otherwise
: framebuffer? ( -- flag )
\ Use the screen-height variable as a proxy for framebuffer
diff --git a/usr/src/boot/sys/boot/i386/libi386/i386_copy.c b/usr/src/boot/sys/boot/i386/libi386/i386_copy.c
index b697b43143..562c66b37c 100644
--- a/usr/src/boot/sys/boot/i386/libi386/i386_copy.c
+++ b/usr/src/boot/sys/boot/i386/libi386/i386_copy.c
@@ -24,6 +24,10 @@
* SUCH DAMAGE.
*/
+/*
+ * Copyright (c) 2019, Joyent, Inc.
+ */
+
#include <sys/cdefs.h>
/*
@@ -93,6 +97,8 @@ smap_find(struct bios_smap *smap, int smaplen, vm_offset_t addr, size_t size)
return (0);
}
+#define SAFE_LOAD_BASE 0xc800000
+
/*
* Find usable address for loading. The address for the kernel is fixed, as
* it is determined by kernel linker map (dboot PT_LOAD address).
@@ -116,8 +122,13 @@ i386_loadaddr(u_int type, void *data, vm_offset_t addr)
if (type == LOAD_KERN)
return (addr);
+ /*
+ * Nothing is yet loaded. We shouldn't get to a module with a load
+ * address of zero still, and the kernel loads at its own multiboot
+ * address, so we don't need to make any adjustments here.
+ */
if (addr == 0)
- return (addr); /* nothing to do */
+ return (0);
if (type == LOAD_ELF)
return (0); /* not supported */
@@ -146,12 +157,19 @@ i386_loadaddr(u_int type, void *data, vm_offset_t addr)
/* Start from the end of the kernel. */
mfp = fp;
do {
+
+
if (mfp == NULL) {
off = roundup2(addr + 1, MULTIBOOT_MOD_ALIGN);
} else {
off = roundup2(mfp->f_addr + mfp->f_size + 1,
MULTIBOOT_MOD_ALIGN);
}
+
+ /* RICHMOND-16 work around. */
+ if (off < SAFE_LOAD_BASE)
+ off = SAFE_LOAD_BASE;
+
off = smap_find(smap, smaplen, off, size);
off = addr_verify(fp, off, size);
if (off != 0)
diff --git a/usr/src/boot/sys/boot/i386/loader/loader.rc b/usr/src/boot/sys/boot/i386/loader/loader.rc
index 32f6bf8043..298b54b2c8 100644
--- a/usr/src/boot/sys/boot/i386/loader/loader.rc
+++ b/usr/src/boot/sys/boot/i386/loader/loader.rc
@@ -2,6 +2,12 @@
\
\ Includes additional commands
include /boot/forth/loader.4th
+
+\ For SmartOS, override the default color scheme back to the more traditional
+\ black background and white foreground.
+set tem.fg_color=white
+set tem.bg_color=black
+
try-include /boot/loader.rc.local
\ Reads and processes loader.conf variables
diff --git a/usr/src/boot/sys/boot/i386/pmbr/pmbr.s b/usr/src/boot/sys/boot/i386/pmbr/pmbr.s
index 46088cc78c..e5f059e88b 100644
--- a/usr/src/boot/sys/boot/i386/pmbr/pmbr.s
+++ b/usr/src/boot/sys/boot/i386/pmbr/pmbr.s
@@ -31,10 +31,12 @@
#
# Partly from: src/sys/boot/i386/mbr/mbr.s 1.7
+# Copyright (c) 2019, Joyent, Inc.
+
# A 512 byte PMBR boot manager to read a boot program and run it.
# The embedded MBR is set up for PMBR and default bootblock sector
# is hardcoded to 256 and size 1. The actual values are supposed to be
-# updated by installboot.
+# updated by installboot (and smartos-live's format_image).
.set LOAD,0x7c00 # Load address
.set EXEC,0x600 # Execution address
diff --git a/usr/src/cmd/mdb/common/modules/disk_label/disk_label.c b/usr/src/cmd/mdb/common/modules/disk_label/disk_label.c
new file mode 100644
index 0000000000..05d71e4f5a
--- /dev/null
+++ b/usr/src/cmd/mdb/common/modules/disk_label/disk_label.c
@@ -0,0 +1,501 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright (c) 2019, Joyent, Inc.
+ */
+
+/*
+ * The on-disk elements here are all little-endian, and this code doesn't make
+ * any attempt to adjust for running on a big-endian system.
+ *
+ * We also currently assume a 512-byte sized logical block.
+ */
+
+#include <sys/types.h>
+#include <sys/crc32.h>
+#include <sys/debug.h>
+#include <sys/sysmacros.h>
+#include <sys/dktp/fdisk.h>
+#include <sys/efi_partition.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <uuid/uuid.h>
+
+#include <mdb/mdb_modapi.h>
+#include <mdb/mdb_debug.h>
+
+#include "installboot.h"
+
+#ifdef _BIG_ENDIAN
+#error needs porting for big-endian system
+#endif
+
+/* See usr/src/grub/grub-0.97/stage1/stage1.h */
+#define GRUB_VERSION_OFF (0x3e)
+#define GRUB_COMPAT_VERSION_MAJOR 3
+#define GRUB_COMPAT_VERSION_MINOR 2
+#define GRUB_VERSION (2 << 8 | 3) /* 3.2 */
+
+#define LOADER_VERSION (1)
+#define LOADER_JOYENT_VERSION (2)
+
+typedef enum {
+ MBR_TYPE_UNKNOWN,
+ MBR_TYPE_GRUB1,
+ MBR_TYPE_LOADER,
+ MBR_TYPE_LOADER_JOYENT,
+} mbr_type_t;
+
+static void
+print_fdisk_part(struct ipart *ip, size_t nr)
+{
+ char typestr[128];
+ char begchs[128];
+ char endchs[128];
+ char *c = NULL;
+
+ if (ip->systid == UNUSED) {
+ mdb_printf("%-4llu %s:%#lx\n", nr, "UNUSED", ip->systid);
+ return;
+ }
+
+ switch (ip->systid) {
+ case DOSOS12: c = "DOSOS12"; break;
+ case PCIXOS: c = "PCIXOS"; break;
+ case DOSOS16: c = "DOSOS16"; break;
+ case EXTDOS: c = "EXTDOS"; break;
+ case DOSHUGE: c = "DOSHUGE"; break;
+ case FDISK_IFS: c = "FDISK_IFS"; break;
+ case FDISK_AIXBOOT: c = "FDISK_AIXBOOT"; break;
+ case FDISK_AIXDATA: c = "FDISK_AIXDATA"; break;
+ case FDISK_OS2BOOT: c = "FDISK_OS2BOOT"; break;
+ case FDISK_WINDOWS: c = "FDISK_WINDOWS"; break;
+ case FDISK_EXT_WIN: c = "FDISK_EXT_WIN"; break;
+ case FDISK_FAT95: c = "FDISK_FAT95"; break;
+ case FDISK_EXTLBA: c = "FDISK_EXTLBA"; break;
+ case DIAGPART: c = "DIAGPART"; break;
+ case FDISK_LINUX: c = "FDISK_LINUX"; break;
+ case FDISK_LINUXDSWAP: c = "FDISK_LINUXDSWAP"; break;
+ case FDISK_LINUXDNAT: c = "FDISK_LINUXDNAT"; break;
+ case FDISK_CPM: c = "FDISK_CPM"; break;
+ case DOSDATA: c = "DOSDATA"; break;
+ case OTHEROS: c = "OTHEROS"; break;
+ case UNIXOS: c = "UNIXOS"; break;
+ case FDISK_NOVELL2: c = "FDISK_NOVELL2"; break;
+ case FDISK_NOVELL3: c = "FDISK_NOVELL3"; break;
+ case FDISK_QNX4: c = "FDISK_QNX4"; break;
+ case FDISK_QNX42: c = "FDISK_QNX42"; break;
+ case FDISK_QNX43: c = "FDISK_QNX43"; break;
+ case SUNIXOS: c = "SUNIXOS"; break;
+ case FDISK_LINUXNAT: c = "FDISK_LINUXNAT"; break;
+ case FDISK_NTFSVOL1: c = "FDISK_NTFSVOL1"; break;
+ case FDISK_NTFSVOL2: c = "FDISK_NTFSVOL2"; break;
+ case FDISK_BSD: c = "FDISK_BSD"; break;
+ case FDISK_NEXTSTEP: c = "FDISK_NEXTSTEP"; break;
+ case FDISK_BSDIFS: c = "FDISK_BSDIFS"; break;
+ case FDISK_BSDISWAP: c = "FDISK_BSDISWAP"; break;
+ case X86BOOT: c = "X86BOOT"; break;
+ case SUNIXOS2: c = "SUNIXOS2"; break;
+ case EFI_PMBR: c = "EFI_PMBR"; break;
+ case EFI_FS: c = "EFI_FS"; break;
+ default: c = NULL; break;
+ }
+
+ if (c != NULL) {
+ mdb_snprintf(typestr, sizeof (typestr), "%s:%#lx",
+ c, ip->systid);
+ } else {
+ mdb_snprintf(typestr, sizeof (typestr), "%#lx", ip->systid);
+ }
+
+ mdb_snprintf(begchs, sizeof (begchs), "%hu/%hu/%hu",
+ (uint16_t)ip->begcyl | (uint16_t)(ip->begsect & ~0x3f) << 2,
+ (uint16_t)ip->beghead, (uint16_t)ip->begsect & 0x3f);
+ mdb_snprintf(endchs, sizeof (endchs), "%hu/%hu/%hu",
+ (uint16_t)ip->endcyl | (uint16_t)(ip->endsect & ~0x3f) << 2,
+ (uint16_t)ip->endhead, (uint16_t)ip->endsect & 0x3f);
+
+ mdb_printf("%-4llu %-21s %#-7x %-11s %-11s %-10u %-9u\n",
+ nr, typestr, ip->bootid, begchs, endchs, ip->relsect, ip->numsect);
+}
+
+static int
+cmd_mbr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv __unused)
+{
+ struct mboot mbr;
+ mbr_type_t type = MBR_TYPE_UNKNOWN;
+
+ CTASSERT(sizeof (mbr) == SECTOR_SIZE);
+
+ if (argc != 0)
+ return (DCMD_USAGE);
+
+ if (!(flags & DCMD_ADDRSPEC))
+ addr = 0;
+
+ if (mdb_vread(&mbr, sizeof (mbr), addr) == -1) {
+ mdb_warn("failed to read MBR");
+ return (DCMD_ERR);
+ }
+
+ if (*((uint16_t *)&mbr.bootinst[GRUB_VERSION_OFF]) == GRUB_VERSION) {
+ type = MBR_TYPE_GRUB1;
+ } else if (mbr.bootinst[STAGE1_MBR_VERSION] == LOADER_VERSION) {
+ type = MBR_TYPE_LOADER;
+ } else if (mbr.bootinst[STAGE1_MBR_VERSION] == LOADER_JOYENT_VERSION) {
+ type = MBR_TYPE_LOADER_JOYENT;
+ }
+
+ switch (type) {
+ case MBR_TYPE_UNKNOWN:
+ mdb_printf("Format: unknown\n");
+ break;
+ case MBR_TYPE_GRUB1:
+ mdb_printf("Format: grub1\n");
+ break;
+ case MBR_TYPE_LOADER:
+ mdb_printf("Format: loader (illumos)\n");
+ break;
+ case MBR_TYPE_LOADER_JOYENT:
+ mdb_printf("Format: loader (joyent)\n");
+ break;
+ }
+
+ mdb_printf("Signature: 0x%hx (%s)\n", mbr.signature,
+ mbr.signature == MBB_MAGIC ? "valid" : "invalid");
+
+ mdb_printf("UniqueMBRDiskSignature: %#lx\n",
+ *(uint32_t *)&mbr.bootinst[STAGE1_SIG]);
+
+ if (type == MBR_TYPE_LOADER || type == MBR_TYPE_LOADER_JOYENT) {
+ char uuid[UUID_PRINTABLE_STRING_LENGTH];
+
+ mdb_printf("Loader STAGE1_STAGE2_LBA: %llu\n",
+ *(uint64_t *)&mbr.bootinst[STAGE1_STAGE2_LBA]);
+
+ mdb_printf("Loader STAGE1_STAGE2_SIZE: %hu\n",
+ *(uint16_t *)&mbr.bootinst[STAGE1_STAGE2_SIZE]);
+
+ uuid_unparse((uchar_t *)&mbr.bootinst[STAGE1_STAGE2_UUID],
+ uuid);
+
+ mdb_printf("Loader STAGE1_STAGE2_UUID: %s\n", uuid);
+ }
+
+ mdb_printf("\n%<u>%-4s %-21s %-7s %-11s %-11s %-10s %-9s%</u>\n",
+ "PART", "TYPE", "ACTIVE", "STARTCHS", "ENDCHS",
+ "SECTOR", "NUMSECT");
+
+ for (size_t i = 0; i < FD_NUMPART; i++) {
+ struct ipart *ip = (struct ipart *)
+ (mbr.parts + (sizeof (struct ipart) * i));
+ print_fdisk_part(ip, i);
+ }
+
+ return (DCMD_OK);
+}
+
+static unsigned int crc32_tab[] = { CRC32_TABLE };
+
+static unsigned int
+efi_crc32(const unsigned char *s, unsigned int len)
+{
+ unsigned int crc32val;
+
+ CRC32(crc32val, s, len, -1U, crc32_tab);
+
+ return (crc32val ^ -1U);
+}
+
+typedef struct {
+ struct uuid eg_uuid;
+ const char *eg_name;
+} efi_guid_t;
+
+static efi_guid_t efi_guids[] = {
+ { EFI_UNUSED, "EFI_UNUSED" },
+ { EFI_RESV1, "EFI_RESV1" },
+ { EFI_BOOT, "EFI_BOOT" },
+ { EFI_ROOT, "EFI_ROOT" },
+ { EFI_SWAP, "EFI_SWAP" },
+ { EFI_USR, "EFI_USR" },
+ { EFI_BACKUP, "EFI_BACKUP" },
+ { EFI_RESV2, "EFI_RESV2" },
+ { EFI_VAR, "EFI_VAR" },
+ { EFI_HOME, "EFI_HOME" },
+ { EFI_ALTSCTR, "EFI_ALTSCTR" },
+ { EFI_RESERVED, "EFI_RESERVED" },
+ { EFI_SYSTEM, "EFI_SYSTEM" },
+ { EFI_LEGACY_MBR, "EFI_LEGACY_MBR" },
+ { EFI_SYMC_PUB, "EFI_SYMC_PUB" },
+ { EFI_SYMC_CDS, "EFI_SYMC_CDS" },
+ { EFI_MSFT_RESV, "EFI_MSFT_RESV" },
+ { EFI_DELL_BASIC, "EFI_DELL_BASIC" },
+ { EFI_DELL_RAID, "EFI_DELL_RAID" },
+ { EFI_DELL_SWAP, "EFI_DELL_SWAP" },
+ { EFI_DELL_LVM, "EFI_DELL_LVM" },
+ { EFI_DELL_RESV, "EFI_DELL_RESV" },
+ { EFI_AAPL_BOOT, "EFI_AAPL_BOOT" },
+ { EFI_AAPL_HFS, "EFI_AAPL_HFS" },
+ { EFI_AAPL_UFS, "EFI_AAPL_UFS" },
+ { EFI_AAPL_ZFS, "EFI_AAPL_ZFS" },
+ { EFI_AAPL_APFS, "EFI_AAPL_APFS" },
+ { EFI_FREEBSD_BOOT, "EFI_FREEBSD_BOOT" },
+ { EFI_FREEBSD_NANDFS, "EFI_FREEBSD_NANDFS" },
+ { EFI_FREEBSD_SWAP, "EFI_FREEBSD_SWAP" },
+ { EFI_FREEBSD_UFS, "EFI_FREEBSD_UFS" },
+ { EFI_FREEBSD_VINUM, "EFI_FREEBSD_VINUM" },
+ { EFI_FREEBSD_ZFS, "EFI_FREEBSD_ZFS" },
+ { EFI_BIOS_BOOT, "EFI_BIOS_BOOT" },
+};
+
+static void
+print_gpe(efi_gpe_t *gpe, size_t nr, int show_guid)
+{
+ const char *type = "unknown";
+
+ for (size_t i = 0; i < ARRAY_SIZE(efi_guids); i++) {
+ if (memcmp((void *)&efi_guids[i].eg_uuid,
+ (void *)&gpe->efi_gpe_PartitionTypeGUID,
+ sizeof (efi_guids[i].eg_uuid)) == 0) {
+ type = efi_guids[i].eg_name;
+ break;
+ }
+ }
+
+ if (strcmp(type, "EFI_UNUSED") == 0) {
+ mdb_printf("%-4u %-19s\n", nr, type);
+ return;
+ }
+
+ if (show_guid) {
+ char guid[UUID_PRINTABLE_STRING_LENGTH];
+
+ uuid_unparse((uchar_t *)&gpe->efi_gpe_UniquePartitionGUID,
+ guid);
+
+ mdb_printf("%-4u %-19s %s\n", nr, type, guid);
+ } else {
+ char name[EFI_PART_NAME_LEN + 1] = "";
+
+ /*
+ * Hopefully, ASCII is sufficient for any naming we care about.
+ */
+ for (size_t i = 0; i < sizeof (name); i++) {
+ ushort_t wchar = gpe->efi_gpe_PartitionName[i];
+
+ name[i] = (char)(isascii(wchar) ? wchar : '?');
+ }
+
+ mdb_printf("%-4u %-19s %-13llu %-13llu %#-8llx %s\n",
+ nr, type, gpe->efi_gpe_StartingLBA, gpe->efi_gpe_EndingLBA,
+ gpe->efi_gpe_Attributes, name);
+ }
+}
+
+static int
+cmd_gpt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv __unused)
+{
+ char uuid[UUID_PRINTABLE_STRING_LENGTH];
+ int show_alternate = B_FALSE;
+ int show_guid = B_FALSE;
+ efi_gpt_t altheader;
+ size_t table_size;
+ efi_gpt_t header;
+ efi_gpe_t *gpet;
+ uint_t orig_crc;
+ uint_t crc;
+
+ if (mdb_getopts(argc, argv,
+ 'a', MDB_OPT_SETBITS, TRUE, &show_alternate,
+ 'g', MDB_OPT_SETBITS, TRUE, &show_guid,
+ NULL) != argc)
+ return (DCMD_USAGE);
+
+ /* Primary header is at LBA 1. */
+ if (!(flags & DCMD_ADDRSPEC))
+ addr = SECTOR_SIZE;
+
+ if (mdb_vread(&header, sizeof (header), addr) == -1) {
+ mdb_warn("failed to read GPT header");
+ return (DCMD_ERR);
+ }
+
+ if (show_alternate) {
+ addr = header.efi_gpt_AlternateLBA * SECTOR_SIZE;
+
+ if (mdb_vread(&header, sizeof (header), addr) == -1) {
+ mdb_warn("failed to read GPT header");
+ return (DCMD_ERR);
+ }
+ }
+
+ mdb_printf("Signature: %s (%s)\n", (char *)&header.efi_gpt_Signature,
+ strncmp((char *)&header.efi_gpt_Signature, "EFI PART", 8) == 0 ?
+ "valid" : "invalid");
+
+ mdb_printf("Revision: %hu.%hu\n", header.efi_gpt_Revision >> 16,
+ header.efi_gpt_Revision);
+
+ mdb_printf("HeaderSize: %u bytes\n", header.efi_gpt_HeaderSize);
+
+ if (header.efi_gpt_HeaderSize > SECTOR_SIZE) {
+ mdb_warn("invalid header size: skipping CRC\n");
+ } else {
+ orig_crc = header.efi_gpt_HeaderCRC32;
+
+ header.efi_gpt_HeaderCRC32 = 0;
+
+ crc = efi_crc32((unsigned char *)&header,
+ header.efi_gpt_HeaderSize);
+
+ mdb_printf("HeaderCRC32: %#x (should be %#x)\n", orig_crc, crc);
+ }
+
+ mdb_printf("Reserved1: %#x (should be 0x0)\n",
+ header.efi_gpt_Reserved1);
+
+ mdb_printf("MyLBA: %llu (should be %llu)\n",
+ header.efi_gpt_MyLBA, addr / SECTOR_SIZE);
+
+ mdb_printf("AlternateLBA: %llu\n", header.efi_gpt_AlternateLBA);
+ mdb_printf("FirstUsableLBA: %llu\n", header.efi_gpt_FirstUsableLBA);
+ mdb_printf("LastUsableLBA: %llu\n", header.efi_gpt_LastUsableLBA);
+
+ if (header.efi_gpt_MyLBA >= header.efi_gpt_FirstUsableLBA &&
+ header.efi_gpt_MyLBA <= header.efi_gpt_LastUsableLBA) {
+ mdb_warn("MyLBA is within usable LBA range\n");
+ }
+
+ if (header.efi_gpt_AlternateLBA >= header.efi_gpt_FirstUsableLBA &&
+ header.efi_gpt_AlternateLBA <= header.efi_gpt_LastUsableLBA) {
+ mdb_warn("AlternateLBA is within usable LBA range\n");
+ }
+
+ if (mdb_vread(&altheader, sizeof (altheader),
+ header.efi_gpt_AlternateLBA * SECTOR_SIZE) == -1) {
+ mdb_warn("failed to read alternate GPT header");
+ } else {
+ if (strncmp((char *)&altheader.efi_gpt_Signature,
+ "EFI PART", 8) != 0) {
+ mdb_warn("found invalid alternate GPT header with "
+ "Signature: %s\n",
+ (char *)&altheader.efi_gpt_Signature);
+ }
+
+ if (altheader.efi_gpt_MyLBA != header.efi_gpt_AlternateLBA) {
+ mdb_warn("alternate GPT header at offset %#llx has "
+ "invalid MyLBA %llu\n",
+ header.efi_gpt_AlternateLBA * SECTOR_SIZE,
+ altheader.efi_gpt_MyLBA);
+ }
+
+ if (altheader.efi_gpt_AlternateLBA != header.efi_gpt_MyLBA) {
+ mdb_warn("alternate GPT header at offset %#llx has "
+ "invalid AlternateLBA %llu\n",
+ header.efi_gpt_AlternateLBA * SECTOR_SIZE,
+ altheader.efi_gpt_AlternateLBA);
+ }
+
+ /*
+ * We could go ahead and verify all the alternate checksums,
+ * etc. here too...
+ */
+ }
+
+ uuid_unparse((uchar_t *)&header.efi_gpt_DiskGUID, uuid);
+ mdb_printf("DiskGUID: %s\n", uuid);
+
+ mdb_printf("PartitionEntryLBA: %llu\n",
+ header.efi_gpt_PartitionEntryLBA);
+
+ mdb_printf("NumberOfPartitionEntries: %u\n",
+ header.efi_gpt_NumberOfPartitionEntries);
+
+ /*
+ * While the spec allows a different size, in practice the table
+ * is always packed.
+ */
+ if (header.efi_gpt_SizeOfPartitionEntry != sizeof (efi_gpe_t)) {
+ mdb_warn("SizeOfPartitionEntry: %#x bytes "
+ "(expected %#x bytes)\n",
+ header.efi_gpt_SizeOfPartitionEntry, sizeof (efi_gpe_t));
+ return (DCMD_ERR);
+ }
+
+ mdb_printf("SizeOfPartitionEntry: %#x bytes\n",
+ header.efi_gpt_SizeOfPartitionEntry);
+
+ table_size = header.efi_gpt_SizeOfPartitionEntry *
+ header.efi_gpt_NumberOfPartitionEntries;
+
+ /*
+ * While this is a minimum reservation, it serves us ably as a
+ * maximum value to reasonably expect.
+ */
+ if (table_size > EFI_MIN_ARRAY_SIZE) {
+ mdb_warn("Skipping GPT array of %#lx bytes.\n", table_size);
+ return (DCMD_ERR);
+ }
+
+ gpet = mdb_alloc(header.efi_gpt_SizeOfPartitionEntry *
+ header.efi_gpt_NumberOfPartitionEntries, UM_SLEEP | UM_GC);
+
+ if (mdb_vread(gpet, table_size,
+ header.efi_gpt_PartitionEntryLBA * SECTOR_SIZE) == -1) {
+ mdb_warn("couldn't read GPT array");
+ return (DCMD_ERR);
+ }
+
+ crc = efi_crc32((unsigned char *)gpet, table_size);
+
+ mdb_printf("PartitionEntryArrayCRC32: %#x (should be %#x)\n",
+ header.efi_gpt_PartitionEntryArrayCRC32, crc);
+
+ if (show_guid) {
+ mdb_printf("\n%<u>%-4s %-19s %-37s%</u>\n",
+ "PART", "TYPE", "GUID");
+ } else {
+ mdb_printf("\n%<u>%-4s %-19s %-13s %-13s %-8s %s%</u>\n",
+ "PART", "TYPE", "STARTLBA", "ENDLBA", "ATTR", "NAME");
+ }
+
+ for (size_t i = 0; i < header.efi_gpt_NumberOfPartitionEntries; i++)
+ print_gpe(&gpet[i], i, show_guid);
+
+ return (DCMD_OK);
+}
+
+void
+gpt_help(void)
+{
+ mdb_printf("Display an EFI GUID Partition Table.\n\n"
+ "-a Display the alternate GPT\n"
+ "-g Show unique GUID for each table entry\n");
+}
+
+static const mdb_dcmd_t dcmds[] = {
+ { "mbr", NULL, "dump Master Boot Record information", cmd_mbr },
+ { "gpt", "?[-ag]", "dump an EFI GPT", cmd_gpt, gpt_help },
+ { NULL }
+};
+
+static const mdb_modinfo_t modinfo = {
+ MDB_API_VERSION, dcmds, NULL
+};
+
+const mdb_modinfo_t *
+_mdb_init(void)
+{
+ return (&modinfo);
+}
diff --git a/usr/src/cmd/mdb/intel/amd64/Makefile b/usr/src/cmd/mdb/intel/amd64/Makefile
index f7bc890fb5..6ddc6b59d5 100644
--- a/usr/src/cmd/mdb/intel/amd64/Makefile
+++ b/usr/src/cmd/mdb/intel/amd64/Makefile
@@ -21,12 +21,13 @@
#
# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
-# Copyright 2018 Joyent, Inc.
+# Copyright 2019 Joyent, Inc.
#
include ../../Makefile.common
-MODULES = $(COMMON_MODULES_PROC) $(COMMON_MODULES_KVM) uhci
+MODULES = $(COMMON_MODULES_PROC) $(COMMON_MODULES_KVM)
+MODULES += disk_label uhci
SUBDIRS = mdb mdb_ks kmdb libstandctf libstand .WAIT $(MODULES)
diff --git a/usr/src/cmd/mdb/intel/amd64/disk_label/Makefile b/usr/src/cmd/mdb/intel/amd64/disk_label/Makefile
new file mode 100644
index 0000000000..7b084ac28c
--- /dev/null
+++ b/usr/src/cmd/mdb/intel/amd64/disk_label/Makefile
@@ -0,0 +1,28 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# Copyright (c) 2019, Joyent, Inc.
+#
+
+MODULE = disk_label.so
+MDBTGT = raw
+
+MODSRCS = disk_label.c
+
+include ../../../../Makefile.cmd
+include ../../../../Makefile.cmd.64
+include ../../Makefile.amd64
+include ../../../Makefile.module
+
+MODSRCS_DIR = ../../../common/modules/disk_label
+
+CPPFLAGS += -I$(SRC)/uts/common -I$(SRC)/cmd/boot/installboot/i386
+
+LDLIBS += -luuid
diff --git a/usr/src/cmd/mdb/intel/ia32/Makefile b/usr/src/cmd/mdb/intel/ia32/Makefile
index f90ef4f824..cb544a52d2 100644
--- a/usr/src/cmd/mdb/intel/ia32/Makefile
+++ b/usr/src/cmd/mdb/intel/ia32/Makefile
@@ -22,10 +22,13 @@
# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+# Copyright (c) 2019, Joyent, Inc.
+#
include ../../Makefile.common
MODULES = $(COMMON_MODULES_PROC) $(COMMON_MODULES_PROC_32BIT)
+MODULES += disk_label
SUBDIRS = mdb .WAIT $(MODULES)
diff --git a/usr/src/cmd/mdb/intel/ia32/disk_label/Makefile b/usr/src/cmd/mdb/intel/ia32/disk_label/Makefile
new file mode 100644
index 0000000000..a50f3613da
--- /dev/null
+++ b/usr/src/cmd/mdb/intel/ia32/disk_label/Makefile
@@ -0,0 +1,27 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# Copyright (c) 2019, Joyent, Inc.
+#
+
+MODULE = disk_label.so
+MDBTGT = raw
+
+MODSRCS = disk_label.c
+
+include ../../../../Makefile.cmd
+include ../../Makefile.ia32
+include ../../../Makefile.module
+
+MODSRCS_DIR = ../../../common/modules/disk_label
+
+CPPFLAGS += -I$(SRC)/uts/common -I$(SRC)/cmd/boot/installboot/i386
+
+LDLIBS += -luuid
diff --git a/usr/src/lib/libefi/common/crc32_efi.c b/usr/src/lib/libefi/common/crc32_efi.c
index 1dba28ad72..73039f1478 100644
--- a/usr/src/lib/libefi/common/crc32_efi.c
+++ b/usr/src/lib/libefi/common/crc32_efi.c
@@ -23,8 +23,9 @@
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2019, Joyent, Inc.
+ */
#include <sys/crc32.h>
diff --git a/usr/src/lib/libefi/common/rdwr_efi.c b/usr/src/lib/libefi/common/rdwr_efi.c
index e0d866e3c4..6aaaba7b92 100644
--- a/usr/src/lib/libefi/common/rdwr_efi.c
+++ b/usr/src/lib/libefi/common/rdwr_efi.c
@@ -24,7 +24,7 @@
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright 2014 Toomas Soome <tsoome@me.com>
* Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
- * Copyright (c) 2018, Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
*/
#include <stdio.h>
@@ -132,12 +132,98 @@ int efi_debug = 0;
extern unsigned int efi_crc32(const unsigned char *, unsigned int);
static int efi_read(int, struct dk_gpt *);
+/*
+ * In normal operation, libefi just passes everything down to the kernel driver
+ * (and - usually - cmlb), as that code needs to react to any partitioning
+ * changes by changing device nodes under /dev/?dsk/ and the like.
+ *
+ * However, if we are running against an un-labeled lofi device on an older
+ * version of illumos, these ioctl()s aren't emulated. This can be a problem if
+ * we're in a non-global zone, which doesn't support labeled lofi, and our
+ * kernel is downrev.
+ *
+ * In this case, we'll simply emulate the ioctl()s that libefi actually needs,
+ * except those for efi_type(). They basically boil down to simple reads and
+ * writes, though this does skip a bunch of error checking.
+ *
+ * As a final wrinkle, rather than rely on an updated libefi, smartos-live's
+ * format_image tool directly builds and uses this source.
+ */
+static int
+do_ioctl(int fd, int cmd, void *arg)
+{
+ struct dk_cinfo cinfo;
+ struct dk_minfo minfo;
+ dk_efi_t *efi = arg;
+ int saved_errno;
+ size_t len;
+ int error;
+
+ error = ioctl(fd, cmd, arg);
+
+ saved_errno = errno;
+
+ if (error != -1 || errno != ENOTTY ||
+ ioctl(fd, DKIOCINFO, (caddr_t)&cinfo) != 0 ||
+ strcmp(cinfo.dki_cname, "lofi") != 0 ||
+ ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&minfo) != 0) {
+ errno = saved_errno;
+ return (error);
+ }
+
+ switch (cmd) {
+ case DKIOCGMBOOT:
+ len = (size_t)pread(fd, arg, minfo.dki_lbsize, 0);
+ error = (len == minfo.dki_lbsize) ? 0 : -1;
+ break;
+
+ case DKIOCSMBOOT:
+ len = (size_t)pwrite(fd, arg, minfo.dki_lbsize, 0);
+ error = (len == minfo.dki_lbsize) ? 0 : -1;
+ break;
+
+ case DKIOCGETEFI:
+ len = (size_t)pread(fd, (caddr_t)(uintptr_t)efi->dki_data_64,
+ efi->dki_length, efi->dki_lba * minfo.dki_lbsize);
+ error = (len == efi->dki_length) ? 0 : -1;
+ break;
+
+ case DKIOCSETEFI:
+ len = (size_t)pwrite(fd, (caddr_t)(uintptr_t)efi->dki_data_64,
+ efi->dki_length, efi->dki_lba * minfo.dki_lbsize);
+ error = (len == efi->dki_length) ? 0 : -1;
+ break;
+
+ default:
+ errno = saved_errno;
+ break;
+ }
+
+ if (error == 0)
+ errno = 0;
+
+ return (error);
+}
+
+static int
+efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc)
+{
+ void *data = dk_ioc->dki_data;
+ int error;
+
+ dk_ioc->dki_data_64 = (uint64_t)(uintptr_t)data;
+ error = do_ioctl(fd, cmd, (void *)dk_ioc);
+ dk_ioc->dki_data = data;
+
+ return (error);
+}
+
static int
read_disk_info(int fd, diskaddr_t *capacity, uint_t *lbsize)
{
struct dk_minfo disk_info;
- if ((ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&disk_info)) == -1)
+ if ((do_ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&disk_info)) == -1)
return (errno);
*capacity = disk_info.dki_capacity;
*lbsize = disk_info.dki_lbsize;
@@ -183,6 +269,7 @@ efi_alloc_and_init(int fd, uint32_t nparts, struct dk_gpt **vtoc)
"the maximum number of partitions supported is %lu\n",
MAX_PARTS);
}
+ errno = EINVAL;
return (-1);
}
@@ -233,7 +320,7 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
if ((mbr = calloc(1, lbsize)) == NULL)
return (VT_ERROR);
- if ((ioctl(fd, DKIOCGMBOOT, (caddr_t)mbr)) == -1) {
+ if ((do_ioctl(fd, DKIOCGMBOOT, (caddr_t)mbr)) == -1) {
free(mbr);
return (VT_ERROR);
}
@@ -292,19 +379,6 @@ efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
}
static int
-efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc)
-{
- void *data = dk_ioc->dki_data;
- int error;
-
- dk_ioc->dki_data_64 = (uint64_t)(uintptr_t)data;
- error = ioctl(fd, cmd, (void *)dk_ioc);
- dk_ioc->dki_data = data;
-
- return (error);
-}
-
-static int
check_label(int fd, dk_efi_t *dk_ioc)
{
efi_gpt_t *efi;
@@ -341,9 +415,8 @@ check_label(int fd, dk_efi_t *dk_ioc)
if (efi_debug)
(void) fprintf(stderr,
"Bad EFI CRC: 0x%x != 0x%x\n",
- crc,
- LE_32(efi_crc32((unsigned char *)efi,
- sizeof (struct efi_gpt))));
+ crc, LE_32(efi_crc32((unsigned char *)efi,
+ LE_32(efi->efi_gpt_HeaderSize))));
return (VT_EINVAL);
}
@@ -368,7 +441,7 @@ efi_read(int fd, struct dk_gpt *vtoc)
/*
* get the partition number for this file descriptor.
*/
- if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) {
+ if (do_ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) {
if (efi_debug) {
(void) fprintf(stderr, "DKIOCINFO errno 0x%x\n", errno);
}
@@ -392,7 +465,7 @@ efi_read(int fd, struct dk_gpt *vtoc)
}
/* get the LBA size */
- if (ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&disk_info) == -1) {
+ if (do_ioctl(fd, DKIOCGMEDIAINFO, (caddr_t)&disk_info) == -1) {
if (efi_debug) {
(void) fprintf(stderr,
"assuming LBA 512 bytes %d\n",
@@ -715,7 +788,7 @@ write_pmbr(int fd, struct dk_gpt *vtoc)
hardware_workarounds(&slot, &active);
len = (vtoc->efi_lbasize == 0) ? sizeof (mb) : vtoc->efi_lbasize;
- buf = calloc(len, 1);
+ buf = calloc(1, len);
/*
* Preserve any boot code and disk signature if the first block is
@@ -741,10 +814,10 @@ write_pmbr(int fd, struct dk_gpt *vtoc)
cp = (uchar_t *)&mb.parts[slot * sizeof (struct ipart)];
/* bootable or not */
*cp++ = active ? ACTIVE : NOTACTIVE;
- /* beginning CHS; 0xffffff if not representable */
- *cp++ = 0xff;
- *cp++ = 0xff;
- *cp++ = 0xff;
+ /* beginning CHS; same as starting LBA (but one-based) */
+ *cp++ = 0x0;
+ *cp++ = 0x2;
+ *cp++ = 0x0;
/* OS type */
*cp++ = EFI_PMBR;
/* ending CHS; 0xffffff if not representable */
@@ -985,7 +1058,7 @@ efi_write(int fd, struct dk_gpt *vtoc)
int nblocks;
diskaddr_t lba_backup_gpt_hdr;
- if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) {
+ if (do_ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) {
if (efi_debug)
(void) fprintf(stderr, "DKIOCINFO errno 0x%x\n", errno);
switch (errno) {
@@ -1029,7 +1102,7 @@ efi_write(int fd, struct dk_gpt *vtoc)
/* stuff user's input into EFI struct */
efi->efi_gpt_Signature = LE_64(EFI_SIGNATURE);
efi->efi_gpt_Revision = LE_32(vtoc->efi_version); /* 0x02000100 */
- efi->efi_gpt_HeaderSize = LE_32(sizeof (struct efi_gpt));
+ efi->efi_gpt_HeaderSize = LE_32(EFI_HEADER_SIZE);
efi->efi_gpt_Reserved1 = 0;
efi->efi_gpt_MyLBA = LE_64(1ULL);
efi->efi_gpt_AlternateLBA = LE_64(lba_backup_gpt_hdr);
@@ -1094,8 +1167,8 @@ efi_write(int fd, struct dk_gpt *vtoc)
efi->efi_gpt_PartitionEntryArrayCRC32 =
LE_32(efi_crc32((unsigned char *)efi_parts,
vtoc->efi_nparts * (int)sizeof (struct efi_gpe)));
- efi->efi_gpt_HeaderCRC32 =
- LE_32(efi_crc32((unsigned char *)efi, sizeof (struct efi_gpt)));
+ efi->efi_gpt_HeaderCRC32 = LE_32(efi_crc32((unsigned char *)efi,
+ EFI_HEADER_SIZE));
if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
free(dk_ioc.dki_data);
@@ -1142,8 +1215,7 @@ efi_write(int fd, struct dk_gpt *vtoc)
efi->efi_gpt_PartitionEntryLBA = LE_64(vtoc->efi_last_u_lba + 1);
efi->efi_gpt_HeaderCRC32 = 0;
efi->efi_gpt_HeaderCRC32 =
- LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data,
- sizeof (struct efi_gpt)));
+ LE_32(efi_crc32((unsigned char *)dk_ioc.dki_data, EFI_HEADER_SIZE));
if (efi_ioctl(fd, DKIOCSETEFI, &dk_ioc) == -1) {
if (efi_debug) {
@@ -1170,6 +1242,8 @@ efi_free(struct dk_gpt *ptr)
* Input: File descriptor
* Output: 1 if disk has an EFI label, or > 2TB with no VTOC or legacy MBR.
* Otherwise 0.
+ *
+ * This always returns 0 for an un-labeled lofi device.
*/
int
efi_type(int fd)
diff --git a/usr/src/uts/common/fs/zfs/zvol.c b/usr/src/uts/common/fs/zfs/zvol.c
index 196c98c602..33bac61d21 100644
--- a/usr/src/uts/common/fs/zfs/zvol.c
+++ b/usr/src/uts/common/fs/zfs/zvol.c
@@ -26,7 +26,7 @@
* Copyright 2017 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
- * Copyright 2018 Joyent, Inc.
+ * Copyright (c) 2019, Joyent, Inc.
*/
/*
@@ -1622,7 +1622,7 @@ zvol_getefi(void *arg, int flag, uint64_t vs, uint8_t bs)
gpt.efi_gpt_Signature = LE_64(EFI_SIGNATURE);
gpt.efi_gpt_Revision = LE_32(EFI_VERSION_CURRENT);
- gpt.efi_gpt_HeaderSize = LE_32(sizeof (gpt));
+ gpt.efi_gpt_HeaderSize = LE_32(EFI_HEADER_SIZE);
gpt.efi_gpt_MyLBA = LE_64(1ULL);
gpt.efi_gpt_FirstUsableLBA = LE_64(34ULL);
gpt.efi_gpt_LastUsableLBA = LE_64((vs >> bs) - 1);
@@ -1632,7 +1632,7 @@ zvol_getefi(void *arg, int flag, uint64_t vs, uint8_t bs)
LE_32(sizeof (efi_gpe_t));
CRC32(crc, &gpe, sizeof (gpe), -1U, crc32_table);
gpt.efi_gpt_PartitionEntryArrayCRC32 = LE_32(~crc);
- CRC32(crc, &gpt, sizeof (gpt), -1U, crc32_table);
+ CRC32(crc, &gpt, EFI_HEADER_SIZE, -1U, crc32_table);
gpt.efi_gpt_HeaderCRC32 = LE_32(~crc);
if (ddi_copyout(&gpt, ptr, MIN(sizeof (gpt), length),
flag))
diff --git a/usr/src/uts/common/io/cmlb.c b/usr/src/uts/common/io/cmlb.c
index 17eca53288..417010c8e9 100644
--- a/usr/src/uts/common/io/cmlb.c
+++ b/usr/src/uts/common/io/cmlb.c
@@ -24,6 +24,7 @@
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2016 Toomas Soome <tsoome@me.com>
+ * Copyright (c) 2019, Joyent, Inc.
*/
/*
@@ -2747,7 +2748,7 @@ cmlb_validate_efi(efi_gpt_t *labp)
{
if (labp->efi_gpt_Signature != EFI_SIGNATURE)
return (EINVAL);
- /* at least 96 bytes in this version of the spec. */
+ /* at least 92 bytes in this version of the spec. */
if (sizeof (efi_gpt_t) - sizeof (labp->efi_gpt_Reserved2) >
labp->efi_gpt_HeaderSize)
return (EINVAL);
diff --git a/usr/src/uts/common/io/lofi.c b/usr/src/uts/common/io/lofi.c
index e8d82a6688..5032452543 100644
--- a/usr/src/uts/common/io/lofi.c
+++ b/usr/src/uts/common/io/lofi.c
@@ -168,6 +168,8 @@
#include <sys/scsi/scsi.h> /* for DTYPE_DIRECT */
#include <sys/scsi/impl/uscsi.h>
#include <sys/sysevent/dev.h>
+#include <sys/efi_partition.h>
+#include <sys/note.h>
#include <LzmaDec.h>
#define NBLOCKS_PROP_NAME "Nblocks"
@@ -1741,26 +1743,58 @@ lofi_strategy(struct buf *bp)
return (0);
}
-/*ARGSUSED2*/
static int
lofi_read(dev_t dev, struct uio *uio, struct cred *credp)
{
+ _NOTE(ARGUNUSED(credp));
+
if (getminor(dev) == 0)
return (EINVAL);
UIO_CHECK(uio);
return (physio(lofi_strategy, NULL, dev, B_READ, minphys, uio));
}
-/*ARGSUSED2*/
static int
lofi_write(dev_t dev, struct uio *uio, struct cred *credp)
{
+ _NOTE(ARGUNUSED(credp));
+
if (getminor(dev) == 0)
return (EINVAL);
UIO_CHECK(uio);
return (physio(lofi_strategy, NULL, dev, B_WRITE, minphys, uio));
}
+static int
+lofi_urw(struct lofi_state *lsp, uint16_t fmode, diskaddr_t off, size_t size,
+ intptr_t arg, int flag, cred_t *credp)
+{
+ struct uio uio;
+ iovec_t iov;
+
+ /*
+ * 1024 * 1024 apes cmlb_tg_max_efi_xfer as a reasonable max.
+ */
+ if (size == 0 || size > 1024 * 1024 ||
+ (size % (1 << lsp->ls_lbshift)) != 0)
+ return (EINVAL);
+
+ iov.iov_base = (void *)arg;
+ iov.iov_len = size;
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_loffset = off;
+ uio.uio_segflg = (flag & FKIOCTL) ? UIO_SYSSPACE : UIO_USERSPACE;
+ uio.uio_llimit = MAXOFFSET_T;
+ uio.uio_resid = size;
+ uio.uio_fmode = fmode;
+ uio.uio_extflg = 0;
+
+ return (fmode == FREAD ?
+ lofi_read(lsp->ls_dev, &uio, credp) :
+ lofi_write(lsp->ls_dev, &uio, credp));
+}
+
/*ARGSUSED2*/
static int
lofi_aread(dev_t dev, struct aio_req *aio, struct cred *credp)
@@ -3185,10 +3219,11 @@ static int
lofi_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp,
int *rvalp)
{
- int error;
+ int error;
enum dkio_state dkstate;
struct lofi_state *lsp;
- int id;
+ dk_efi_t user_efi;
+ int id;
id = LOFI_MINOR2ID(getminor(dev));
@@ -3438,6 +3473,35 @@ lofi_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp,
#endif /* _MULTI_DATAMODEL */
return (0);
}
+
+ case DKIOCGMBOOT:
+ return (lofi_urw(lsp, FREAD, 0, 1 << lsp->ls_lbshift,
+ arg, flag, credp));
+
+ case DKIOCSMBOOT:
+ return (lofi_urw(lsp, FWRITE, 0, 1 << lsp->ls_lbshift,
+ arg, flag, credp));
+
+ case DKIOCGETEFI:
+ if (ddi_copyin((void *)arg, &user_efi,
+ sizeof (dk_efi_t), flag) != 0)
+ return (EFAULT);
+
+ return (lofi_urw(lsp, FREAD,
+ user_efi.dki_lba * (1 << lsp->ls_lbshift),
+ user_efi.dki_length, (intptr_t)user_efi.dki_data,
+ flag, credp));
+
+ case DKIOCSETEFI:
+ if (ddi_copyin((void *)arg, &user_efi,
+ sizeof (dk_efi_t), flag) != 0)
+ return (EFAULT);
+
+ return (lofi_urw(lsp, FWRITE,
+ user_efi.dki_lba * (1 << lsp->ls_lbshift),
+ user_efi.dki_length, (intptr_t)user_efi.dki_data,
+ flag, credp));
+
default:
#ifdef DEBUG
cmn_err(CE_WARN, "lofi_ioctl: %d is not implemented\n", cmd);
diff --git a/usr/src/uts/common/sys/efi_partition.h b/usr/src/uts/common/sys/efi_partition.h
index 5fa101cbb7..065f65f802 100644
--- a/usr/src/uts/common/sys/efi_partition.h
+++ b/usr/src/uts/common/sys/efi_partition.h
@@ -22,12 +22,14 @@
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
* Copyright 2014 Toomas Soome <tsoome@me.com>
+ * Copyright (c) 2019, Joyent, Inc.
*/
#ifndef _SYS_EFI_PARTITION_H
#define _SYS_EFI_PARTITION_H
#include <sys/uuid.h>
+#include <sys/stddef.h>
#ifdef __cplusplus
extern "C" {
@@ -46,6 +48,16 @@ extern "C" {
#define EFI_SIGNATURE 0x5452415020494645ULL
+/*
+ * Although the EFI spec is clear that sizeof (efi_gpt_t) is a valid value
+ * (512), at least one EFI system (AMI v4.6.4.1) incorrectly expects this to be
+ * exactly the size of the structure defined in the spec, that is, 92.
+ *
+ * As the reserved section is never used, the modified value works fine
+ * everywhere else.
+ */
+#define EFI_HEADER_SIZE (offsetof(efi_gpt_t, efi_gpt_Reserved2))
+
/* EFI Guid Partition Table Header -- little endian on-disk format */
typedef struct efi_gpt {
uint64_t efi_gpt_Signature;
@@ -222,7 +234,7 @@ typedef struct dk_efi {
diskaddr_t dki_lba; /* starting block */
len_t dki_length; /* length in bytes */
union {
- efi_gpt_t *_dki_data;
+ efi_gpt_t *_dki_data;
uint64_t _dki_data_64;
} dki_un;
#define dki_data dki_un._dki_data
diff --git a/usr/src/uts/i86pc/dboot/dboot_startkern.c b/usr/src/uts/i86pc/dboot/dboot_startkern.c
index dd9fef27fb..74e3504d11 100644
--- a/usr/src/uts/i86pc/dboot/dboot_startkern.c
+++ b/usr/src/uts/i86pc/dboot/dboot_startkern.c
@@ -23,7 +23,7 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
- * Copyright 2018 Joyent, Inc. All rights reserved.
+ * Copyright 2019 Joyent, Inc. All rights reserved.
*/
@@ -76,15 +76,6 @@ extern int have_cpuid(void);
#define SHA1_ASCII_LENGTH (SHA1_DIGEST_LENGTH * 2)
/*
- * Region of memory that may be corrupted by external actors. This can go away
- * once the firmware bug RICHMOND-16 is fixed and all systems with the bug are
- * upgraded.
- */
-#define CORRUPT_REGION_START 0xc700000
-#define CORRUPT_REGION_SIZE 0x100000
-#define CORRUPT_REGION_END (CORRUPT_REGION_START + CORRUPT_REGION_SIZE)
-
-/*
* This file contains code that runs to transition us from either a multiboot
* compliant loader (32 bit non-paging) or a XPV domain loader to
* regular kernel execution. Its task is to setup the kernel memory image
@@ -1469,6 +1460,80 @@ dboot_process_modules(void)
check_images();
}
+#define CORRUPT_REGION_START 0xc700000
+#define CORRUPT_REGION_SIZE 0x100000
+#define CORRUPT_REGION_END (CORRUPT_REGION_START + CORRUPT_REGION_SIZE)
+
+static void
+dboot_add_memlist(uint64_t start, uint64_t end)
+{
+ if (end > max_mem)
+ max_mem = end;
+
+ /*
+ * Well, this is sad. On some systems, there is a region of memory that
+ * can be corrupted until some number of seconds after we have booted.
+ * And the BIOS doesn't tell us that this memory is unsafe to use. And
+ * we don't know how long it's dangerous. So we'll chop out this range
+ * from any memory list that would otherwise be usable. Note that any
+ * system of this type will give us the new-style (0x40) memlist, so we
+ * need not fix up the other path below.
+ *
+ * However, if we're boot-loaded from something that doesn't have a
+ * RICHMOND-16 workaround (which on many systems is just fine), it could
+ * actually use this region for the boot modules; if we remove it from
+ * the memlist, we'll keel over when trying to access the region.
+ *
+ * So, if we see that a module intersects the region, we presume it's
+ * OK.
+ */
+
+ if (find_boot_prop("disable-RICHMOND-16") != NULL)
+ goto out;
+
+ for (uint32_t i = 0; i < bi->bi_module_cnt; i++) {
+ native_ptr_t mod_start = modules[i].bm_addr;
+ native_ptr_t mod_end = modules[i].bm_addr + modules[i].bm_size;
+
+ if (mod_start < CORRUPT_REGION_END &&
+ mod_end >= CORRUPT_REGION_START) {
+ if (prom_debug) {
+ dboot_printf("disabling RICHMOND-16 workaround "
+ "due to module #%u: "
+ "name %s addr %lx size %lx\n",
+ i, (char *)(uintptr_t)modules[i].bm_name,
+ (ulong_t)modules[i].bm_addr,
+ (ulong_t)modules[i].bm_size);
+ }
+ goto out;
+ }
+ }
+
+ if (start < CORRUPT_REGION_START && end > CORRUPT_REGION_START) {
+ memlists[memlists_used].addr = start;
+ memlists[memlists_used].size =
+ CORRUPT_REGION_START - start;
+ ++memlists_used;
+ if (end > CORRUPT_REGION_END)
+ start = CORRUPT_REGION_END;
+ else
+ return;
+ }
+
+ if (start >= CORRUPT_REGION_START && start < CORRUPT_REGION_END) {
+ if (end <= CORRUPT_REGION_END)
+ return;
+ start = CORRUPT_REGION_END;
+ }
+
+out:
+ memlists[memlists_used].addr = start;
+ memlists[memlists_used].size = end - start;
+ ++memlists_used;
+ if (memlists_used > MAX_MEMLIST)
+ dboot_panic("too many memlists");
+}
+
/*
* We then build the phys_install memlist from the multiboot information.
*/
@@ -1512,45 +1577,7 @@ dboot_process_mmap(void)
*/
switch (type) {
case 1:
- if (end > max_mem)
- max_mem = end;
-
- /*
- * Well, this is sad. One some systems, there
- * is a region of memory that can be corrupted
- * until some number of seconds after we have
- * booted. And the BIOS doesn't tell us that
- * this memory is unsafe to use. And we don't
- * know how long it's dangerous. So we'll
- * chop out this range from any memory list
- * that would otherwise be usable. Note that
- * any system of this type will give us the
- * new-style (0x40) memlist, so we need not
- * fix up the other path below.
- */
- if (start < CORRUPT_REGION_START &&
- end > CORRUPT_REGION_START) {
- memlists[memlists_used].addr = start;
- memlists[memlists_used].size =
- CORRUPT_REGION_START - start;
- ++memlists_used;
- if (end > CORRUPT_REGION_END)
- start = CORRUPT_REGION_END;
- else
- continue;
- }
- if (start >= CORRUPT_REGION_START &&
- start < CORRUPT_REGION_END) {
- if (end <= CORRUPT_REGION_END)
- continue;
- start = CORRUPT_REGION_END;
- }
-
- memlists[memlists_used].addr = start;
- memlists[memlists_used].size = end - start;
- ++memlists_used;
- if (memlists_used > MAX_MEMLIST)
- dboot_panic("too many memlists");
+ dboot_add_memlist(start, end);
break;
case 2:
rsvdmemlists[rsvdmemlists_used].addr = start;
diff --git a/usr/src/uts/i86pc/os/fakebop.c b/usr/src/uts/i86pc/os/fakebop.c
index 8ba2e74681..60982a49fc 100644
--- a/usr/src/uts/i86pc/os/fakebop.c
+++ b/usr/src/uts/i86pc/os/fakebop.c
@@ -2017,6 +2017,7 @@ bop_trap(ulong_t *tfp)
bop_printf(NULL, "flags register 0x%lx\n", tf->flags_reg);
bop_printf(NULL, "return %%rsp 0x%lx\n", tf->stk_ptr);
bop_printf(NULL, "return %%ss 0x%lx\n", tf->stk_seg & 0xffff);
+ bop_printf(NULL, "%%cr2 0x%lx\n", getcr2());
/* grab %[er]bp pushed by our code from the stack */
fakeframe.old_frame = (bop_frame_t *)*(tfp - 3);
diff --git a/usr/src/uts/sun4v/io/vds.c b/usr/src/uts/sun4v/io/vds.c
index dee390142b..15d263a1b9 100644
--- a/usr/src/uts/sun4v/io/vds.c
+++ b/usr/src/uts/sun4v/io/vds.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Joyent, Inc.
*/
/*
@@ -5832,7 +5833,7 @@ vd_setup_partition_efi(vd_t *vd)
gpt->efi_gpt_Signature = LE_64(EFI_SIGNATURE);
gpt->efi_gpt_Revision = LE_32(EFI_VERSION_CURRENT);
- gpt->efi_gpt_HeaderSize = LE_32(sizeof (efi_gpt_t));
+ gpt->efi_gpt_HeaderSize = LE_32(EFI_HEADER_SIZE);
gpt->efi_gpt_FirstUsableLBA = LE_64(first_u_lba);
gpt->efi_gpt_PartitionEntryLBA = LE_64(2ULL);
gpt->efi_gpt_SizeOfPartitionEntry = LE_32(sizeof (efi_gpe_t));
@@ -5869,7 +5870,7 @@ vd_setup_partition_efi(vd_t *vd)
CRC32(crc, gpe, sizeof (efi_gpe_t) * VD_MAXPART, -1U, crc32_table);
gpt->efi_gpt_PartitionEntryArrayCRC32 = LE_32(~crc);
- CRC32(crc, gpt, sizeof (efi_gpt_t), -1U, crc32_table);
+ CRC32(crc, gpt, EFI_HEADER_SIZE, -1U, crc32_table);
gpt->efi_gpt_HeaderCRC32 = LE_32(~crc);
return (0);