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