--- old/usr/src/lib/libefi/common/rdwr_efi.c	Tue Apr 16 05:23:03 2019
+++ new/usr/src/lib/libefi/common/rdwr_efi.c	Tue Apr 16 05:23:03 2019
@@ -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>
@@ -341,9 +341,8 @@
 		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);
 	}
 
@@ -715,7 +714,7 @@
 	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 +740,10 @@
 	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 */
@@ -1029,7 +1028,7 @@
 	/* 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 +1093,8 @@
 	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 +1141,7 @@
 	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) {
--- old/usr/src/uts/common/fs/zfs/zvol.c	Tue Apr 16 05:23:05 2019
+++ new/usr/src/uts/common/fs/zfs/zvol.c	Tue Apr 16 05:23:05 2019
@@ -27,6 +27,7 @@
  * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
+ * Copyright (c) 2019, Joyent, Inc.
  */
 
 /*
@@ -1509,7 +1510,7 @@
 
 		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);
@@ -1519,7 +1520,7 @@
 		    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))
--- old/usr/src/uts/common/io/cmlb.c	Tue Apr 16 05:23:06 2019
+++ new/usr/src/uts/common/io/cmlb.c	Tue Apr 16 05:23:06 2019
@@ -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 @@
 {
 	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);
--- old/usr/src/uts/common/sys/efi_partition.h	Tue Apr 16 05:23:08 2019
+++ new/usr/src/uts/common/sys/efi_partition.h	Tue Apr 16 05:23:08 2019
@@ -22,6 +22,7 @@
  * 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
@@ -28,6 +29,7 @@
 #define	_SYS_EFI_PARTITION_H
 
 #include <sys/uuid.h>
+#include <sys/stddef.h>
 
 #ifdef	__cplusplus
 extern "C" {
@@ -46,6 +48,16 @@
 
 #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 @@
 	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
--- old/usr/src/uts/sun4v/io/vds.c	Tue Apr 16 05:23:09 2019
+++ new/usr/src/uts/sun4v/io/vds.c	Tue Apr 16 05:23:09 2019
@@ -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 @@
 
 	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 @@
 	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);
