From 332096ebb6380ae65829018b4e1d611cd68dcc33 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 10 Dec 2025 05:36:56 -0700 Subject: [PATCH] kboot: Explicitly use host:/proc When looking for the boot_params symbol we need to get the UEFI memory map, use host: prefix. The short-circuit we have for this only works when we have a filesystem. During the earliest parts of boot, we can sometimes not have this yet, so making this explicit allows these environments to function. It's always in the host path. Print better error messages, and add newlines in two palces. Sponsored by: Netflix --- stand/kboot/libkboot/dfk.c | 13 ++++++++++--- sys/dev/mpr/mpr_sas.c | 31 +++++++++++++++++++++++++++++-- sys/dev/mpr/mpr_sas.h | 3 +++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/stand/kboot/libkboot/dfk.c b/stand/kboot/libkboot/dfk.c index 09f4512f5c9..18a3ad8eada 100644 --- a/stand/kboot/libkboot/dfk.c +++ b/stand/kboot/libkboot/dfk.c @@ -39,8 +39,13 @@ #define ELF_TARG_DATA ELFDATA2LSB #endif +#ifndef _STANDALONE #define KCORE_PATH "/proc/kcore" #define KALLSYMS_PATH "/proc/kallsyms" +#else +#define KCORE_PATH "host:/proc/kcore" +#define KALLSYMS_PATH "host:/proc/kallsyms" +#endif struct elf_file { @@ -135,8 +140,10 @@ symbol_addr(const char *symbol) unsigned long addr; char line[256]; - if (!lb_init(&lb, KALLSYMS_PATH)) + if (!lb_init(&lb, KALLSYMS_PATH)) { + printf("Cannot open symbol file %s\n", KALLSYMS_PATH); return (0); + } while (lb_1line(&lb, line, sizeof(line))) { char *val, *name, *x, t; @@ -259,11 +266,11 @@ data_from_kernel(const char *sym, void *buf, size_t len) addr = symbol_addr(sym); if (addr == 0) { - fprintf(stderr, "Can't find symbol %s", sym); + fprintf(stderr, "Can't find symbol %s\n", sym); return (false); } if (!read_at_address(addr, buf, len)) { - fprintf(stderr, "Can't read from kernel"); + fprintf(stderr, "Can't read from kernel\n"); return (false); } return (true); diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c index 5f3a27a468b..a48593b1e6e 100644 --- a/sys/dev/mpr/mpr_sas.c +++ b/sys/dev/mpr/mpr_sas.c @@ -152,6 +152,25 @@ mprsas_find_target_by_handle(struct mprsas_softc *sassc, int start, return (NULL); } +static void +mprsas_startup_timeout(void *_sassc) +{ + struct mprsas_softc *sassc = _sassc; + + /* + * Things have taken far too long. We have to get on with it. However, + * we're still processing events. We'll release the boot here only. + * We're called with the mpr lock held, which the rest of these + * functions take. This may cause mountroot to fail, but we'll at least + * proceed with the boot if this isn't holding up the system disk. + */ + callout_stop(&sassc->startup_timeout); + sassc->flags &= ~MPRSAS_STARTUP_ARMED; + xpt_release_boot(); + printf("Gave up all the devices...\n"); +}; + + /* we need to freeze the simq during attach and diag reset, to avoid failing * commands before device handles have been found by discovery. Since * discovery involves reading config pages and possibly sending commands, @@ -171,6 +190,10 @@ mprsas_startup_increment(struct mprsas_softc *sassc) "%s freezing simq\n", __func__); xpt_hold_boot(); xpt_freeze_simq(sassc->sim, 1); + callout_init_mtx(&sassc->startup_timeout, + &sassc->sc->mpr_mtx, 0); + callout_reset(&sassc->startup_timeout, 60 * hz, + mprsas_startup_timeout, sassc); } mpr_dprint(sassc->sc, MPR_INIT, "%s refcount %u\n", __func__, sassc->startup_refcount); @@ -197,11 +220,15 @@ mprsas_startup_decrement(struct mprsas_softc *sassc) /* finished all discovery-related actions, release * the simq and rescan for the latest topology. */ + bool need_release = sassc->flags & MPRSAS_STARTUP_ARMED; mpr_dprint(sassc->sc, MPR_INIT, "%s releasing simq\n", __func__); - sassc->flags &= ~MPRSAS_IN_STARTUP; + if (need_release) /* stop to prevent deadlock */ + callout_stop(&sassc->startup_timeout); + sassc->flags &= ~(MPRSAS_IN_STARTUP | MPRSAS_STARTUP_ARMED); xpt_release_simq(sassc->sim, 1); - xpt_release_boot(); + if (need_release) + xpt_release_boot(); } mpr_dprint(sassc->sc, MPR_INIT, "%s refcount %u\n", __func__, sassc->startup_refcount); diff --git a/sys/dev/mpr/mpr_sas.h b/sys/dev/mpr/mpr_sas.h index 4f1be3cd421..24250cf50d1 100644 --- a/sys/dev/mpr/mpr_sas.h +++ b/sys/dev/mpr/mpr_sas.h @@ -91,6 +91,7 @@ struct mprsas_softc { #define MPRSAS_IN_STARTUP (1 << 1) #define MPRSAS_QUEUE_FROZEN (1 << 3) #define MPRSAS_TOREMOVE (1 << 5) +#define MPRSAS_STARTUP_ARMED (1 << 6) u_int maxtargets; struct mprsas_target *targets; struct cam_devq *devq; @@ -102,6 +103,8 @@ struct mprsas_softc { u_int startup_refcount; struct proc *sysctl_proc; + struct callout startup_timeout; + struct taskqueue *ev_tq; struct task ev_task; TAILQ_HEAD(, mpr_fw_event_work) ev_queue;