diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-05-25 15:32:00 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-05-25 15:32:00 +0000 |
commit | bc8712ab4fd641aadc8101b3230acb05ff47cb86 (patch) | |
tree | 14350b8aa1e3d967e7018d6ac7546d0689e7eb83 /sys | |
parent | 823a36f62cf40f28f4f10ac1921f14c72e3cf151 (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.h | 5 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/autoconf.c | 15 | ||||
-rw-r--r-- | sys/arch/sparc64/stand/ofwboot/elf64_exec.c | 20 | ||||
-rw-r--r-- | sys/arch/sparc64/stand/ofwboot/vers.c | 2 |
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"; |