git: ac9de183f370 - main - ofw_cpu: check for "disabled" status during probe
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 10 Jan 2025 19:18:31 UTC
The branch main has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=ac9de183f37006fc2089757779d6d5065a530d5b commit ac9de183f37006fc2089757779d6d5065a530d5b Author: Mitchell Horne <mhorne@FreeBSD.org> AuthorDate: 2025-01-10 18:46:56 +0000 Commit: Mitchell Horne <mhorne@FreeBSD.org> CommitDate: 2025-01-10 18:59:08 +0000 ofw_cpu: check for "disabled" status during probe Some RISC-V CPUs contain a "monitor core" with limited functionality (no MMU). These cores appear in some device trees, but we don't run the kernel on them; in early CPU start-up code we skip them, and they have no impact on mp_ncpu. It seems the new trend is to mark these monitor cores with a 'status' property of 'disabled'. However, we still instantiate an ofw_cpu pseudo device for the disabled core. This is generally harmless, but there is an impact when attempting to attach the cpufreq_dt driver. It counts more OFW CPU devices (unit number) than logical CPUs (mp_ncpus), and therefore fails to attach for the last logical CPU. The solution is to check the status property in ofw_cpu_probe(), and fail if the core is marked "disabled". This is subject to the same exception already in ofw_cpu_early_foreach(); that is, if a disabled CPU has an 'enable-method' property, it can be used by the kernel. Reviewed by: andrew, jrtc27 MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D48123 --- sys/dev/ofw/ofw_cpu.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/sys/dev/ofw/ofw_cpu.c b/sys/dev/ofw/ofw_cpu.c index 339716a946ff..888af0440746 100644 --- a/sys/dev/ofw/ofw_cpu.c +++ b/sys/dev/ofw/ofw_cpu.c @@ -182,6 +182,24 @@ static driver_t ofw_cpu_driver = { DRIVER_MODULE(ofw_cpu, cpulist, ofw_cpu_driver, 0, 0); +static bool +ofw_cpu_is_runnable(phandle_t node) +{ + /* + * Per the DeviceTree Specification, a cpu node (under /cpus) that + * has 'status = disabled' indicates that "the CPU is in a quiescent + * state." + * + * A quiescent CPU that specifies an "enable-method", such as + * "spin-table", can still be used by the kernel. + * + * Lacking this, any CPU marked "disabled" or other non-okay status + * should be excluded from the kernel's view. + */ + return (ofw_bus_node_status_okay(node) || + OF_hasprop(node, "enable-method")); +} + static int ofw_cpu_probe(device_t dev) { @@ -190,6 +208,9 @@ ofw_cpu_probe(device_t dev) if (type == NULL || strcmp(type, "cpu") != 0) return (ENXIO); + if (!ofw_cpu_is_runnable(ofw_bus_get_node(dev))) + return (ENXIO); + device_set_desc(dev, "Open Firmware CPU"); if (!bootverbose && device_get_unit(dev) != 0) { device_quiet(dev); @@ -352,7 +373,6 @@ ofw_cpu_early_foreach(ofw_cpu_foreach_cb callback, bool only_runnable) { phandle_t node, child; pcell_t addr_cells, reg[2]; - char status[16]; char device_type[16]; u_int id, next_id; int count, rv; @@ -389,14 +409,8 @@ ofw_cpu_early_foreach(ofw_cpu_foreach_cb callback, bool only_runnable) * those that have been enabled, or do provide a method * to enable them. */ - if (only_runnable) { - status[0] = '\0'; - OF_getprop(child, "status", status, sizeof(status)); - if (status[0] != '\0' && strcmp(status, "okay") != 0 && - strcmp(status, "ok") != 0 && - !OF_hasprop(child, "enable-method")) - continue; - } + if (only_runnable && !ofw_cpu_is_runnable(child)) + continue; /* * Check we have a register to identify the cpu