summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-05-25 15:32:00 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-05-25 15:32:00 +0000
commitbc8712ab4fd641aadc8101b3230acb05ff47cb86 (patch)
tree14350b8aa1e3d967e7018d6ac7546d0689e7eb83 /sys
parent823a36f62cf40f28f4f10ac1921f14c72e3cf151 (diff)
Pass boothowto from bootloader to kernel using .openbsd.bootdata. To make
sure that an old bootloader can boot a new kernel and a new bootloader can still boot an old kernel some hackery is needed as old kernels check for an exact size of the openbsd_bootdata struct. tested (with softraid) by kn@ ok stsp@, deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/include/boot_flag.h5
-rw-r--r--sys/arch/sparc64/sparc64/autoconf.c15
-rw-r--r--sys/arch/sparc64/stand/ofwboot/elf64_exec.c20
-rw-r--r--sys/arch/sparc64/stand/ofwboot/vers.c2
4 files changed, 34 insertions, 8 deletions
diff --git a/sys/arch/sparc64/include/boot_flag.h b/sys/arch/sparc64/include/boot_flag.h
index 782e87748ec..e4c3fa4acd8 100644
--- a/sys/arch/sparc64/include/boot_flag.h
+++ b/sys/arch/sparc64/include/boot_flag.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: boot_flag.h,v 1.6 2020/01/04 18:32:15 kettenis Exp $ */
+/* $OpenBSD: boot_flag.h,v 1.7 2020/05/25 15:31:59 kettenis Exp $ */
/* $NetBSD: boot_flag.h,v 1.3 2001/07/01 02:56:21 gmcgarry Exp $ */
/*-
@@ -41,8 +41,11 @@ struct openbsd_bootdata {
u_int8_t sr_uuid[BOOTSR_UUID_MAX];
u_int8_t sr_maskkey[BOOTSR_CRYPTO_MAXKEYBYTES];
+ u_int32_t boothowto;
} __packed;
#define BOOTDATA_VERSION 1
+#define BOOTDATA_LEN_SOFTRAID 64
+#define BOOTDATA_LEN_BOOTHOWTO 68
#endif /* _MACHINE_BOOT_FLAG_H_ */
diff --git a/sys/arch/sparc64/sparc64/autoconf.c b/sys/arch/sparc64/sparc64/autoconf.c
index c98aa201221..2ee25767870 100644
--- a/sys/arch/sparc64/sparc64/autoconf.c
+++ b/sys/arch/sparc64/sparc64/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.134 2020/01/04 23:43:54 kn Exp $ */
+/* $OpenBSD: autoconf.c,v 1.135 2020/05/25 15:31:59 kettenis Exp $ */
/* $NetBSD: autoconf.c,v 1.51 2001/07/24 19:32:11 eeh Exp $ */
/*
@@ -435,6 +435,15 @@ bootstrap(int nctx)
ncpus = get_ncpus();
pmap_bootstrap(KERNBASE, (u_long)&end, nctx, ncpus);
+ /*
+ * This length check deliberately checks BOOTDATA_LEN_SOFTRAID
+ * instead of BOOTDATA_LEN_BOOTHOWTO. See the ofwboot code
+ * for an explanation.
+ */
+ if (obd.version == BOOTDATA_VERSION &&
+ obd.len >= BOOTDATA_LEN_SOFTRAID)
+ boothowto = obd.boothowto;
+
#ifdef SUN4V
if (CPU_ISSUN4V) {
sun4v_soft_state_init();
@@ -539,7 +548,7 @@ bootpath_build(void)
bp->name[0] = 0;
bootpath_nodes(bootpath, nbootpath);
-
+
/* Setup pointer to boot flags */
OF_getprop(chosen, "bootargs", buf, sizeof(buf));
cp = buf;
@@ -691,7 +700,7 @@ cpu_configure(void)
#endif
if (obd.version == BOOTDATA_VERSION &&
- obd.len == sizeof(struct openbsd_bootdata)) {
+ obd.len >= BOOTDATA_LEN_SOFTRAID) {
#if NSOFTRAID > 0
memcpy(sr_bootuuid.sui_id, obd.sr_uuid,
sizeof(sr_bootuuid.sui_id));
diff --git a/sys/arch/sparc64/stand/ofwboot/elf64_exec.c b/sys/arch/sparc64/stand/ofwboot/elf64_exec.c
index f50d2d23d49..887aa57453d 100644
--- a/sys/arch/sparc64/stand/ofwboot/elf64_exec.c
+++ b/sys/arch/sparc64/stand/ofwboot/elf64_exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: elf64_exec.c,v 1.10 2019/10/29 02:55:52 deraadt Exp $ */
+/* $OpenBSD: elf64_exec.c,v 1.11 2020/05/25 15:31:59 kettenis Exp $ */
/* $NetBSD: elfXX_exec.c,v 1.2 2001/08/15 20:08:15 eeh Exp $ */
/*
@@ -71,6 +71,8 @@
#include "openfirm.h"
+extern int boothowto;
+
void syncicache(void *, int);
int
@@ -103,12 +105,19 @@ elf64_exec(int fd, Elf_Ehdr *elf, u_int64_t *entryp, void **ssymp, void **esymp)
if (phdr.p_type == PT_OPENBSD_BOOTDATA) {
memset((void *) (long)phdr.p_paddr, 0, phdr.p_filesz);
- if (phdr.p_filesz < sizeof(struct openbsd_bootdata))
+ if (phdr.p_filesz < BOOTDATA_LEN_SOFTRAID)
continue;
+ /*
+ * Kernels up to and including OpenBSD 6.7
+ * check for an exact match if the length.
+ * Lie here to make sure we can still boot
+ * older kernels with softraid.
+ */
obd = (struct openbsd_bootdata *)(long)phdr.p_paddr;
obd->version = BOOTDATA_VERSION;
- obd->len = sizeof(struct openbsd_bootdata);
+ obd->len = BOOTDATA_LEN_SOFTRAID;
+
#ifdef SOFTRAID
/*
* If booting from softraid we must pass additional
@@ -126,6 +135,11 @@ elf64_exec(int fd, Elf_Ehdr *elf, u_int64_t *entryp, void **ssymp, void **esymp)
}
#endif
+
+ if (phdr.p_filesz < BOOTDATA_LEN_BOOTHOWTO)
+ continue;
+
+ obd->boothowto = boothowto;
continue;
}
diff --git a/sys/arch/sparc64/stand/ofwboot/vers.c b/sys/arch/sparc64/stand/ofwboot/vers.c
index 4193339e082..1809042a243 100644
--- a/sys/arch/sparc64/stand/ofwboot/vers.c
+++ b/sys/arch/sparc64/stand/ofwboot/vers.c
@@ -1 +1 @@
-const char version[] = "1.17";
+const char version[] = "1.18";