From nobody Sat Jul 25 00:18:33 2026 Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD502355819 for ; Wed, 22 Jul 2026 01:01:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682114; cv=none; b=bWleR1cwYD2ATyqoXFRFj0aKjWB6UYMhqWCwakkPdvwdQfa6QUkCU1ZnhheyhWaSYtBkg9kyR81NbBOLcjIrAgMbIM5R6IQf5J/Ygg3+rVuDWbmy5tEtqAcVt58c1Z6VtClUiE+LEjxwxsiRBNLjSLk/uouqh7dCE6g1hecUhbU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682114; c=relaxed/simple; bh=mvQzRuDTBJ6+ciorG8UImWjndciZ5rWLRK/3Uj4h794=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KwNV6RgTt/Q+fmBiZIIqmMXmKJbxwbQQLEcGU/9lrLY2dWznIKo9gouUYy5D+vCneCu3HPJO2Gg+fuHlTmnfNw8Fu1gk/fcx+0X2BgN9+vhfPDOu/wDLvvmm+zDN+Y48ld56qNm+VnpZd77sI4FuMEI8AEvFP13WK+qoEjvboDo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai; spf=pass smtp.mailfrom=nexthop.ai; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b=eWQ3smzo; arc=none smtp.client-ip=209.85.215.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b="eWQ3smzo" Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-cbb85186d43so816628a12.3 for ; Tue, 21 Jul 2026 18:01:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nexthop.ai; s=google; t=1784682111; x=1785286911; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=mB7RYWDgta8ixQNPzSsJsRPVpnbMTaTdGd52h3AbyCo=; b=eWQ3smzo5bg/qqWosHa192jhSaSIMLcq9wmf2iSk84KYt3eEuiPqKJxOdWrDOF+5Cu R9k1Oo+a0HautPnkA5DTZ/juiZ39hM+mXFdhq8BW7oxlGx+Y8c8od21yBAr+s86SIFn3 UtCwb5g2OgQO10ALZYoie8bqbckkORxJs/AHq8qcJzOvuZEYq5Lzhxze3f0sn3wto+vO e4hSkXyZC4qBhuFzVYp2zBZup7DphzKjS58XnFBtzXmhvUUkDtOVsuFfNIJd6+g79ZsO D6zPABbBJqNb9kyKLkYugRjiOiApWMY8Mvd6qjmhe7jaCKloa9EKIxHangP6nGBmH7TI Zw+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784682111; x=1785286911; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=mB7RYWDgta8ixQNPzSsJsRPVpnbMTaTdGd52h3AbyCo=; b=CX11hidXyNB7SjS0v4xD/XSPx6uQWMta8UhutE+Yok5CXFIvfO1f6YVUvP8MXErYk2 nWfOEr3bOQVz6ZHvBURhYF2rqA+bwU533eBSVQh87XyV0573pW3vXP2uSZC6bJA2hnDf iFmkXHyKXVa8W0api+nMITM09v1ZRA2MYldUlNTPhmdsCqxIbUJJxouvMTW79tjCcxPR awmri4vksBrmads3IPhnTbE0E09pwsmZGsIMZqBLbC8vYFynaD7YojyzGILFfhcme5up lW+E7zephVyR2Xqp6aowOkb/KPKGj6x7R6XcJBYshMi3GmvYnDX8J3XiBc1ykPU6X8G3 N7aw== X-Forwarded-Encrypted: i=1; AHgh+RoRniKWnK63frHJeK9JBLih6NEE7NZso6keIUuRpP1WhdB3QER3Bc7Za+JXbLLV0sfv2s2uJJin2tGVCJY=@vger.kernel.org X-Gm-Message-State: AOJu0Yx/cN9poZ2gLOq33y7/07er6PKLxn6PU0NDkP4KAJikCASdsSLU Q7UxTuvVonKgZKQOVcg4cEXcVVfXOZr6E3ACiKuYERaPC0pTio6vaMQ6NGEqJBPvO0Y= X-Gm-Gg: AR+sD10ELXwl5WQb733BJrTvqF1+1j7VGj6GvaX1Une9gM3jIuaWW3zT9he08TQcFH8 1GD8zd2PbGudyHI6Q8F80Wt4SKuahlVvPgzWYWW2e2mAfqrsq2Bdi4EnfsxaZIl2lJjpnrSQGOR o29cuYbY1MoicAChHHFWxQoMAvX1Zpe73TcZbGcQY4ivIBYRej43iKm1C0wQksGpURbbBollPiW kHAYs5C4tvBZwxX4dWsvBvfVAcu0oL5GB+Co/g9ftXy7YsHvuivoNnRE0PNX1c6J7OmZI79yf1d OoNbOUOBBfFVRjFwYVinu8D8N0gVR5GsUPjDmT+Jb/NSLN7hZufaWzJWA8LglqksGFAudrlWDY+ yKGk4mwfaAuFV9LoGIFoRJLDC5VJFzTTm1zwWOFOkoNtnVwN0dh+uGtnIkM6rGOnQs96jtWt8GZ Q8qcPl X-Received: by 2002:a05:6a21:7a45:b0:3c0:eeb7:28b with SMTP id adf61e73a8af0-3c3ad6681abmr24319552637.8.1784682111151; Tue, 21 Jul 2026 18:01:51 -0700 (PDT) Received: from [127.0.0.2] ([50.145.100.174]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3147dc1a689sm3141207eec.4.2026.07.21.18.01.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2026 18:01:50 -0700 (PDT) From: Abdurrahman Hussain Date: Tue, 21 Jul 2026 18:01:46 -0700 Subject: [PATCH v4 1/6] of: resolve alias-prefixed paths under devtree_lock Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-nh-of-alias-overlay-v4-1-8ad097e31e36@nexthop.ai> References: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> In-Reply-To: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> To: Rob Herring , Saravana Kannan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Abdurrahman Hussain X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784682109; l=4285; i=abdurrahman@nexthop.ai; s=20260510; h=from:subject:message-id; bh=mvQzRuDTBJ6+ciorG8UImWjndciZ5rWLRK/3Uj4h794=; b=OzzvHIxOPu4EDau/EvsGJu/uKjL5WgLPLHXetG+yEjzlxYClFWQVc4wBezu+R5zrhr0/FnOdz oBY6KgslNAzAW4KfWdlIUPhhsH7Gk7IhSZvFyoAB3re4zcxZgkcITZo X-Developer-Key: i=abdurrahman@nexthop.ai; a=ed25519; pk=omTm9cCAbO0ZhS32aKfJDKue0W3sQGpG9ub5eYHif8I= of_find_node_opts_by_path() resolves an alias-prefixed path by walking the property list of the of_aliases node with no lock held and no reference taken on the node. Property surgery on /aliases =E2=80=94 of_add_property(), of_remove_property(), changeset apply/revert =E2=80=94 mutates that list under devtree_lock, so the lockless walk can step into a property that is being unlinked. Nothing keeps the node itself alive across the walk either: detaching /aliases and dropping the last reference frees the node and its property list mid-iteration. The race has existed since the walk was introduced, but is hard to hit with a boot-FDT /aliases node that nothing ever detaches. The rest of this series makes /aliases dynamic =E2=80=94 overlays can add and remove properties, and create and destroy the node itself =E2=80=94 so close it first: find the matching property under devtree_lock with a reference held on of_aliases, and keep that reference across the of_find_node_by_path() call that resolves the value. The reference is what keeps the value string valid outside the lock: a concurrently removed property moves to the node's deadprops list and is only freed when the node itself is released. While here, validate the value's shape before handing it to of_find_node_by_path(): /aliases contents can now come from overlays and from raw changeset/of_add_property() callers, and only the overlay path validates at the producer. of_alias_value_ok() (shared with the alias tracking added later in this series) rejects values that are not non-empty C strings NUL-terminated within the property length, so the consumer no longer trusts any producer. This also covers the empty property (NULL value) that previously crashed in strchr(). The name match is folded into one bounded strncmp plus a check of the terminating NUL instead of strlen + strncmp, halving the string traversal now done with interrupts disabled. Assisted-by: Claude:claude-fable-5 [Claude Code] Signed-off-by: Abdurrahman Hussain --- drivers/of/base.c | 26 ++++++++++++++++++-------- drivers/of/of_private.h | 7 +++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 6e7a42dedad3..9c2770823889 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -995,6 +995,8 @@ struct device_node *of_find_node_opts_by_path(const cha= r *path, const char **opt =20 /* The path could begin with an alias */ if (*path !=3D '/') { + struct device_node *aliases; + const char *value =3D NULL; int len; const char *p =3D strchrnul(path, '/'); =20 @@ -1002,16 +1004,24 @@ struct device_node *of_find_node_opts_by_path(const= char *path, const char **opt p =3D separator; len =3D p - path; =20 - /* of_aliases must not be NULL */ - if (!of_aliases) - return NULL; - - for_each_property_of_node(of_aliases, pp) { - if (strlen(pp->name) =3D=3D len && !strncmp(pp->name, path, len)) { - np =3D of_find_node_by_path(pp->value); - break; + raw_spin_lock_irqsave(&devtree_lock, flags); + aliases =3D of_node_get(of_aliases); + if (aliases) { + for_each_property_of_node(aliases, pp) { + if (!strncmp(pp->name, path, len) && + !pp->name[len]) { + if (of_alias_value_ok(pp)) + value =3D pp->value; + break; + } } } + raw_spin_unlock_irqrestore(&devtree_lock, flags); + + /* the reference on @aliases keeps @value alive */ + if (value) + np =3D of_find_node_by_path(value); + of_node_put(aliases); if (!np) return NULL; path =3D p; diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 0ae16da066e2..792756389691 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -215,6 +215,13 @@ static inline bool is_pseudo_property(const char *prop= _name) !of_prop_cmp(prop_name, "linux,phandle"); } =20 +/* alias values are deref'd as C strings; they must terminate within lengt= h */ +static inline bool of_alias_value_ok(const struct property *pp) +{ + return pp->value && pp->length >=3D 2 && + strnlen(pp->value, pp->length) < pp->length; +} + #if IS_ENABLED(CONFIG_KUNIT) int __of_address_resource_bounds(struct resource *r, u64 start, u64 size); #endif --=20 2.54.0 From nobody Sat Jul 25 00:18:33 2026 Received: from mail-pg1-f172.google.com (mail-pg1-f172.google.com [209.85.215.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 578DE361657 for ; Wed, 22 Jul 2026 01:01:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682117; cv=none; b=jaK6wxiB9ppVCKkabIx9+qfzmV6nKtZSkhdr1HBLwwCYLa0wrLKk7PrXUtmBMKg+hK+YhFom04IzZ3w2TFABiE92LMKiaohdgK1c1h9JIyZH5JniewuwYjT8h/pJ19QquaeVKLWUd/XCbcrGiZHVkI20DOrDPO/y8uegkCOgFt0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682117; c=relaxed/simple; bh=NsciQdatXqeOPpuwIMMAyLF5F/k5idos/u5g0AxozaI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ezwQNgqnGWiMVS13v4oGEb3y0P5UtiDtbSf72cfRzVLDjoG3FJukr5mjr0aU4w6bT0myMhIOhM6Tr47UV+9eQoc19t5ym1EnWKRTNwwUWxmgdCs4iN18dYQFKJA7d++o3ak/v+c/5PNbFOBwhWQCrZi4V7XwnMSjilEZCwORYHc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai; spf=pass smtp.mailfrom=nexthop.ai; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b=Y3cmhnX+; arc=none smtp.client-ip=209.85.215.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b="Y3cmhnX+" Received: by mail-pg1-f172.google.com with SMTP id 41be03b00d2f7-ca913a601fbso8011070a12.3 for ; Tue, 21 Jul 2026 18:01:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nexthop.ai; s=google; t=1784682112; x=1785286912; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=FqKZ9pnnu0wAEnhjYKp829PY9NFFmDyTcpIAgN2Ex7I=; b=Y3cmhnX+vsdkESegwcDK7m0bjIBJhXG4BpWAckk6xgoHF8/DTPMCikxKCshkZLD2aU dss3wjVB6JRwE3LpQ5aPl+IXnFcWAfzfJVnb6v4F1++3qKlRpKTjpbsO6vG+pNVkw47P +E32iN4hQKsjS2CJSoRDuTe+dbwtX/t3R/4p2HQr81UXYc+jxM5havcIfFLItudmdtts yWSNXdXPReXt76MJAypoKJOMIlAx2X2TjI0tG4bMHke0MdSXQODmvveFddh4+2aQcs4U 4EyaUDm3eEBOJdQGyeov8ITs39KO/amRXLtfJYFcx1u03OYvB9Y2LTmKt6fazzbJeqkw B1Cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784682112; x=1785286912; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=FqKZ9pnnu0wAEnhjYKp829PY9NFFmDyTcpIAgN2Ex7I=; b=jX0NZEW+raQWnqebJ6Ri8qwTm4Iyh0puAfQMVEtp0XHc6Fc3a131AeLs8heT3IileJ 1ZTkREvW8ca7brAvioMcflPe5MEk888aEyaHsnEkweLxmu1iuUyI8QCLZ4w2PsE816WP O3M2CQC6jyvNRAsQ0/WtkmITHQD8WeSgzLzqX+mWEhVCwQNu/1yHgeLRxVFV2EYQ3keA VcM9JVl95MvGtbyl9rnJSa+zuoXbPHQFQqVRKOCRkrR2k3R7gOhJkyJq6wP+i5gPago2 h+6UxG3Umlq2i7GX9xWpo3eOWgbN0/WeHr9+i4yrNUMjrMEB35tnEHqBAf37PWxqDBrU nbtw== X-Forwarded-Encrypted: i=1; AHgh+RoREBeebCdUHWj2dSO7q7aYesRFuGoskOrxABBeBzB/RqvrU7fSyFqDSix+nLIqM7ACm0zFRNj2V4smuYQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwAzT70ccDXcCkleABHBRhENWDK6kkQD2cyCoFEDf0gqGVFtxeN x5I/uWAz76ssuHczefTb22sYeWQUSJrC0hDYAnpBkfbV2yaOux+KwhJPHlmedUt0PvA= X-Gm-Gg: AR+sD118A1XxB/aDCB3c1oo0U9raoE84X58pYhEY/ujXj7fKneTpFrf8eZauB3PkEwD AZdzyA2/epLvTwrWprO2pB6jjismUnPjiaMVdSXucwhYl6vG7BauZLKhrcXRC6ieEhsi8bZGfjV JcRAxf7fJpu7DkILoDUAciq5D6ulIz2mDpzoVgIIWZ2qGidG/iin83RbCWAuG7UhCBKE9r+tu8B RuS0RoQSTiTg98mWtnEIgnUDSH5QZzxdqRt1lLDoO7qtLzFhfx8TV3fHY5sxciD09SYhKR6YCze s/pXFMRQaeTYgkbFMozMGIC5R4JZOsCeF3yLncKbyvwGmcBUCGCdqhrtY7RZw0HyzoErON7v72E NOq/sObyIM4cF4R3MCNuGTr85/GK4uNUqB7IoEuA28cc9lvx/xRGRTwhXZ4el/0l7NjUIWHvJYY aYGd8EaU4mM5uMtTI= X-Received: by 2002:a05:6a21:103:b0:3bf:77d7:667d with SMTP id adf61e73a8af0-3c3ad677d8amr21968632637.28.1784682112093; Tue, 21 Jul 2026 18:01:52 -0700 (PDT) Received: from [127.0.0.2] ([50.145.100.174]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3147dc1a689sm3141207eec.4.2026.07.21.18.01.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2026 18:01:51 -0700 (PDT) From: Abdurrahman Hussain Date: Tue, 21 Jul 2026 18:01:47 -0700 Subject: [PATCH v4 2/6] of: incrementally update /aliases lookup on reconfig notifications Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-nh-of-alias-overlay-v4-2-8ad097e31e36@nexthop.ai> References: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> In-Reply-To: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> To: Rob Herring , Saravana Kannan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Abdurrahman Hussain X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784682109; l=16428; i=abdurrahman@nexthop.ai; s=20260510; h=from:subject:message-id; bh=NsciQdatXqeOPpuwIMMAyLF5F/k5idos/u5g0AxozaI=; b=fwbycA8K5x4SsHjbWNQV+b8/Wc2FFMlUo/OYNpG6n0QycG9yzGqXQISaXRyeKBfjmCY8PorMW nDm4VxzHZ+cBsmm69SNvjptwW5RYWoO3zqSWjdXywV+pdLDcmTHRn0j X-Developer-Key: i=abdurrahman@nexthop.ai; a=ed25519; pk=omTm9cCAbO0ZhS32aKfJDKue0W3sQGpG9ub5eYHif8I= /aliases entries added by a device-tree overlay are stored in the live tree but never enter the global aliases_lookup list that of_alias_scan() builds at boot. As a result, of_alias_get_id() returns -ENODEV for aliases declared inside overlays, and any driver that relies on alias-based numbering (i2c-xiic, spi, tty, mmc, ...) silently loses its pinned id and falls back to auto-assignment. Fix by registering an internal OF reconfig notifier that mirrors /aliases changes into aliases_lookup. Registration happens at core_initcall_sync time, safely after the boot-time of_alias_scan(), which runs pre-initcall from unflatten_device_tree() (or of_pdt_build_devicetree() on OF-real platforms): OF_RECONFIG_ADD_PROPERTY -> of_alias_create() OF_RECONFIG_REMOVE_PROPERTY -> of_alias_destroy() OF_RECONFIG_UPDATE_PROPERTY -> destroy + create OF_RECONFIG_ATTACH_NODE -> adopt the node as of_aliases OF_RECONFIG_DETACH_NODE -> drop every aliases_lookup entry The reconfig notifier chain fires from both direct changesets and overlay apply/revert, so the same code path covers runtime dt modifications and overlay-declared aliases without any overlay- specific hook in drivers/of/overlay.c. Grant Likely suggested this shape on Geert Uytterhoeven's 2015 RFC [1]; Geert's original hook was in dynamic.c directly. Match the /aliases target node structurally (exact name "aliases", parent =3D=3D root, via the shared of_node_is_aliases()) rather than by pointer against the of_aliases global. A system with no boot-time /aliases has of_aliases =3D=3D NULL, so an overlay that creates /aliases from scratch would otherwise be missed from the first ATTACH_NODE onward. The name compare is exact rather than of_node_name_eq(): the latter ignores unit addresses and would also match a root node named "aliases@1", which neither path lookup nor the DT spec treats as the aliases node. ATTACH publishes the adopted node in of_aliases with a reference held; DETACH clears the pointer and drops that reference again. Both pointer updates happen under devtree_lock, pairing with the locked reader in of_find_node_opts_by_path() from the previous patch =E2=80=94 a reader eith= er observes NULL or takes its own reference before the notifier's put can be the last one. Dropping the reference at DETACH also keeps the node at refcount 1 by the time an overlay changeset that created /aliases is destroyed, which __of_changeset_entry_destroy() insists on before it lets the node be freed. Only per-property notifications populate aliases_lookup =E2=80=94 the notifier does not walk the attached node's property list, which would race with devtree_lock-protected property mutations. A direct of_attach_node() caller that pre-populates /aliases is not tracked, matching pre-series behavior. DETACH_NODE conversely drops every aliases_lookup entry =E2=80=94 but only when the detached node is the tracked of_aliases. __of_attach_node() has no duplicate-name check, so a stray second root node named "aliases" can exist; detaching it must not wipe entries backed by the real node. Walking aliases_lookup itself (under aliases_mutex) avoids the same property-list race. Overlay revert additionally emits per- property REMOVE events beforehand; the sweep catches direct of_detach_node() callers that don't. The per-entry teardown is factored into __of_alias_del(), shared by the single-name destroy and the detach-time sweep. One ordering caveat is inherent to the notification architecture: within a single changeset, a device created by an earlier ATTACH entry can be probed by of_platform_notify() before a later /aliases ADD_PROPERTY entry reaches this notifier. Overlays that declare an alias for a node they also create should order the /aliases fragment first if the target bus is populated with a bound driver at apply time. The notifier machinery is built only for CONFIG_OF_DYNAMIC kernels: without it no reconfig notifications exist and of_reconfig_notifier_register() is a stub returning -EINVAL, so an unconditional registration would fail the initcall on every non-dynamic DT kernel. Factor the per-property loop body of of_alias_scan() into of_alias_create() so the boot-time scan and the runtime notifier share one code path. Owned (runtime) entries kstrdup the alias name so the alias_prop survives the property that spawned it =E2=80=94 required for the overlay revert path where the source property is freed. A one-bit @owned flag on struct alias_prop distinguishes kmalloc'd entries from memblock-backed ones so the destroy path kfree()s the right ones. Every entry, boot-time or runtime, holds the target-node reference that of_find_node_by_path() returned at create time; destroy drops it symmetrically. The destroy path unlinks matching entries regardless of ownership (freeing storage only for owned ones) so an overlay UPDATE against a boot-time alias leaves at most one entry per stem+id. This addresses the allocator-mismatch worry Grant flagged on the 2015 series [2] and the duplicate-mapping side effect that would otherwise leak through. Serialize aliases_lookup on a dedicated aliases_mutex: readers (of_alias_get_id, of_alias_get_highest_id, of_device_uevent) and the reconfig notifier hold it around every access. Boot-time of_alias_scan() runs single-threaded during init and stays lockless. This is preferable to piggy-backing on of_mutex because the reconfig notifier is called both under of_mutex (overlay apply path) and outside of it (direct of_add_property() path from dynamic.c), so a nested acquisition would deadlock on some callers. Validate the property value before feeding it to of_find_node_by_path(): pp->value must be non-empty and null-terminated within pp->length. An overlay that hasn't been through /aliases fixup can otherwise present a fragment-internal string that isn't a valid live-tree path or a malformed non-terminated value, and of_find_node_by_path() derefs it as a C string =E2=80=94 an OOB read on the malformed case. The refactor also fixes a pre-existing one-byte out-of-bounds read in the stem parser: the old loop tested isdigit(*(end - 1)) before checking end > start, reading one byte before the property name when the name is empty or all digits. of_alias_create() checks the bound first and rejects a zero-length stem. Naming builds on Geert's original series: - "of: Extract of_alias_create()" [3] - "of: Add of_alias_destroy()" [4] - "of/dynamic: Update list of aliases on aliases changes" [5] Link: https://lore.kernel.org/lkml/1435675876-2159-1-git-send-email-geert+r= enesas@glider.be/ [1] Link: https://lore.kernel.org/lkml/20150630172131.D4E6CC4041A@trevor.secret= lab.ca/ [2] Link: https://lore.kernel.org/lkml/1435675876-2159-2-git-send-email-geert+r= enesas@glider.be/ [3] Link: https://lore.kernel.org/lkml/1435675876-2159-3-git-send-email-geert+r= enesas@glider.be/ [4] Link: https://lore.kernel.org/lkml/1435675876-2159-4-git-send-email-geert+r= enesas@glider.be/ [5] Assisted-by: Claude:claude-fable-5 [Claude Code] Signed-off-by: Abdurrahman Hussain --- drivers/of/base.c | 210 +++++++++++++++++++++++++++++++++++++++-----= ---- drivers/of/device.c | 4 +- drivers/of/of_private.h | 14 ++++ 3 files changed, 186 insertions(+), 42 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 9c2770823889..669eed7d03cf 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1925,6 +1925,170 @@ static void of_alias_add(struct alias_prop *ap, str= uct device_node *np, ap->alias, ap->stem, ap->id, np); } =20 +/* + * Protects aliases_lookup and of_aliases. of_alias_scan() runs single- + * threaded at init and skips it; every other reader/writer must hold it. + */ +DEFINE_MUTEX(aliases_mutex); + +/* Callers other than of_alias_scan() must hold @aliases_mutex. */ +static void of_alias_create(const struct property *pp, + void *(*dt_alloc)(u64 size, u64 align), + bool owned) +{ + const char *start =3D pp->name; + const char *end; + struct device_node *np; + struct alias_prop *ap; + const char *dup; + int id, len; + + if (is_pseudo_property(pp->name)) + return; + + if (!of_alias_value_ok(pp)) + return; + + np =3D of_find_node_by_path(pp->value); + if (!np) + return; + + end =3D start + strlen(start); + while (end > start && isdigit(*(end - 1))) + end--; + len =3D end - start; + if (len =3D=3D 0) + goto out_put; + + if (kstrtoint(end, 10, &id) < 0) + goto out_put; + + ap =3D dt_alloc(sizeof(*ap) + len + 1, __alignof__(*ap)); + if (!ap) + goto out_put; + memset(ap, 0, sizeof(*ap) + len + 1); + + if (owned) { + dup =3D kstrdup(pp->name, GFP_KERNEL); + if (!dup) { + kfree(ap); + goto out_put; + } + } else { + dup =3D start; + } + ap->alias =3D dup; + ap->owned =3D owned; + of_alias_add(ap, np, id, start, len); + return; + +out_put: + of_node_put(np); +} + +#ifdef CONFIG_OF_DYNAMIC +/* Unlink @ap; free its storage if it was runtime-allocated. */ +static void __of_alias_del(struct alias_prop *ap) +{ + list_del(&ap->link); + of_node_put(ap->np); + if (ap->owned) { + kfree(ap->alias); + kfree(ap); + } +} + +/* Callers must hold @aliases_mutex. */ +static void of_alias_destroy(const char *name) +{ + struct alias_prop *ap, *tmp; + + list_for_each_entry_safe(ap, tmp, &aliases_lookup, link) { + if (strcmp(ap->alias, name) !=3D 0) + continue; + __of_alias_del(ap); + return; + } +} + +static void *alias_alloc(u64 size, u64 align) +{ + return kzalloc(size, GFP_KERNEL); +} + +/* Callers must hold @aliases_mutex. */ +static void of_aliases_forget_all(void) +{ + struct alias_prop *ap, *tmp; + + list_for_each_entry_safe(ap, tmp, &aliases_lookup, link) + __of_alias_del(ap); +} + +static int of_aliases_reconfig_notifier(struct notifier_block *nb, + unsigned long action, void *arg) +{ + struct of_reconfig_data *rd =3D arg; + struct device_node *put =3D NULL; + unsigned long flags; + + /* of_aliases may still be NULL when an overlay creates the node */ + if (!rd->dn || !of_node_is_aliases(rd->dn)) + return NOTIFY_DONE; + + mutex_lock(&aliases_mutex); + switch (action) { + case OF_RECONFIG_ATTACH_NODE: + /* of_aliases is read under devtree_lock by alias path lookup */ + raw_spin_lock_irqsave(&devtree_lock, flags); + if (!of_aliases) + of_aliases =3D of_node_get(rd->dn); + raw_spin_unlock_irqrestore(&devtree_lock, flags); + break; + case OF_RECONFIG_DETACH_NODE: + raw_spin_lock_irqsave(&devtree_lock, flags); + if (of_aliases =3D=3D rd->dn) { + of_aliases =3D NULL; + put =3D rd->dn; + } + raw_spin_unlock_irqrestore(&devtree_lock, flags); + if (put) { + of_aliases_forget_all(); + /* may free the node, so must sit outside devtree_lock */ + of_node_put(put); + } + break; + case OF_RECONFIG_ADD_PROPERTY: + of_alias_create(rd->prop, alias_alloc, true); + break; + case OF_RECONFIG_REMOVE_PROPERTY: + of_alias_destroy(rd->prop->name); + break; + case OF_RECONFIG_UPDATE_PROPERTY: + if (rd->old_prop) + of_alias_destroy(rd->old_prop->name); + of_alias_create(rd->prop, alias_alloc, true); + break; + default: + break; + } + mutex_unlock(&aliases_mutex); + return NOTIFY_OK; +} + +static struct notifier_block of_aliases_nb =3D { + .notifier_call =3D of_aliases_reconfig_notifier, +}; + +static int __init of_aliases_reconfig_init(void) +{ + return of_reconfig_notifier_register(&of_aliases_nb); +} + +/* of_alias_scan() runs pre-initcall, so the boot-time scan is complete */ +core_initcall_sync(of_aliases_reconfig_init); +#endif /* CONFIG_OF_DYNAMIC */ + /** * of_alias_scan - Scan all properties of the 'aliases' node * @dt_alloc: An allocator that provides a virtual address to memory @@ -1960,42 +2124,8 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 = align)) if (!of_aliases) return; =20 - for_each_property_of_node(of_aliases, pp) { - const char *start =3D pp->name; - const char *end =3D start + strlen(start); - struct device_node *np; - struct alias_prop *ap; - int id, len; - - /* Skip those we do not want to proceed */ - if (is_pseudo_property(pp->name)) - continue; - - np =3D of_find_node_by_path(pp->value); - if (!np) - continue; - - /* walk the alias backwards to extract the id and work out - * the 'stem' string */ - while (isdigit(*(end-1)) && end > start) - end--; - len =3D end - start; - - if (kstrtoint(end, 10, &id) < 0) { - of_node_put(np); - continue; - } - - /* Allocate an alias_prop with enough space for the stem */ - ap =3D dt_alloc(sizeof(*ap) + len + 1, __alignof__(*ap)); - if (!ap) { - of_node_put(np); - continue; - } - memset(ap, 0, sizeof(*ap) + len + 1); - ap->alias =3D start; - of_alias_add(ap, np, id, start, len); - } + for_each_property_of_node(of_aliases, pp) + of_alias_create(pp, dt_alloc, false); } =20 /** @@ -2013,7 +2143,7 @@ int of_alias_get_id(const struct device_node *np, con= st char *stem) struct alias_prop *app; int id =3D -ENODEV; =20 - mutex_lock(&of_mutex); + mutex_lock(&aliases_mutex); list_for_each_entry(app, &aliases_lookup, link) { if (strcmp(app->stem, stem) !=3D 0) continue; @@ -2023,7 +2153,7 @@ int of_alias_get_id(const struct device_node *np, con= st char *stem) break; } } - mutex_unlock(&of_mutex); + mutex_unlock(&aliases_mutex); =20 return id; } @@ -2041,7 +2171,7 @@ int of_alias_get_highest_id(const char *stem) struct alias_prop *app; int id =3D -ENODEV; =20 - mutex_lock(&of_mutex); + mutex_lock(&aliases_mutex); list_for_each_entry(app, &aliases_lookup, link) { if (strcmp(app->stem, stem) !=3D 0) continue; @@ -2049,7 +2179,7 @@ int of_alias_get_highest_id(const char *stem) if (app->id > id) id =3D app->id; } - mutex_unlock(&of_mutex); + mutex_unlock(&aliases_mutex); =20 return id; } diff --git a/drivers/of/device.c b/drivers/of/device.c index b3dc78f2fa3a..fa0cc8129ab0 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -237,7 +237,7 @@ void of_device_uevent(const struct device *dev, struct = kobj_uevent_env *env) add_uevent_var(env, "OF_COMPATIBLE_N=3D%d", seen); =20 seen =3D 0; - mutex_lock(&of_mutex); + mutex_lock(&aliases_mutex); list_for_each_entry(app, &aliases_lookup, link) { if (dev->of_node =3D=3D app->np) { add_uevent_var(env, "OF_ALIAS_%d=3D%s", seen, @@ -245,7 +245,7 @@ void of_device_uevent(const struct device *dev, struct = kobj_uevent_env *env) seen++; } } - mutex_unlock(&of_mutex); + mutex_unlock(&aliases_mutex); } EXPORT_SYMBOL_GPL(of_device_uevent); =20 diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 792756389691..604a0b0dfda8 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -17,6 +17,11 @@ * @alias: Alias property name * @np: Pointer to device_node that the alias stands for * @id: Index value from end of alias name + * @owned: True for runtime entries, where the struct and @alias are + * kmalloc'd/kstrdup'd and freed on removal. False for boot-time + * entries, which live in memblock (@alias points into the FDT) + * and are only unlinked. Every entry holds a reference on @np; + * removal drops it regardless of @owned. * @stem: Alias string without the index * * The structure represents one alias property of 'aliases' node as @@ -27,6 +32,7 @@ struct alias_prop { const char *alias; struct device_node *np; int id; + bool owned; char stem[]; }; =20 @@ -40,6 +46,7 @@ struct alias_prop { =20 extern struct mutex of_mutex; extern raw_spinlock_t devtree_lock; +extern struct mutex aliases_mutex; extern struct list_head aliases_lookup; extern struct kset *of_kset; =20 @@ -222,6 +229,13 @@ static inline bool of_alias_value_ok(const struct prop= erty *pp) strnlen(pp->value, pp->length) < pp->length; } =20 +/* the /aliases node: root child with the exact name "aliases" */ +static inline bool of_node_is_aliases(const struct device_node *np) +{ + return of_node_is_root(np->parent) && + !strcmp(kbasename(np->full_name), "aliases"); +} + #if IS_ENABLED(CONFIG_KUNIT) int __of_address_resource_bounds(struct resource *r, u64 start, u64 size); #endif --=20 2.54.0 From nobody Sat Jul 25 00:18:33 2026 Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EBF943624AE for ; Wed, 22 Jul 2026 01:01:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682116; cv=none; b=E0yEKmO2MMAKSeAZdK3KVeF9jGZEoYIHhejMWcnjXz4M+4947b/944DvSOYXd13QlzmP8/UayIrzOcBM7o/+rbN2JDEy5j63GJwrbXKxuB8WNhD3EuB3lavogBny5cPKtS4K663NiYsKQ0znCHusU8R7u1kuoQaVKgwgTODOKXk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682116; c=relaxed/simple; bh=kRpIeIkOBNbm/VqI0BkoZECW2QHfP+btpWk4Ns3ReaI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mzDaK4LwASdgQINlvd3VU1v6DccMYVkh1rJclNRMt+Yms8A1q62iALg83O2roSfan0JWxT7rMapRGkpedyMQRzJM4eJFO9H18f/H8IX+nyYd1cda+NwugARxlBj/M1HX0PFv4nzvDeDcc9EN26BA0bX0b+3YvykNybnZIXg54h8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai; spf=pass smtp.mailfrom=nexthop.ai; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b=eVI2nQ+w; arc=none smtp.client-ip=209.85.210.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b="eVI2nQ+w" Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-848743155bcso3362544b3a.0 for ; Tue, 21 Jul 2026 18:01:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nexthop.ai; s=google; t=1784682113; x=1785286913; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=1dw4LW8kSdGmcldnGWhnWc2M/cNC9RFM1UCRX4bcCtw=; b=eVI2nQ+wYGjbrpBk3TJuxBBdfKCKJhc/vKp1taPdF9OxyWbzy3WXkEHpd4Txlq2uZQ cBGLzlW5p2+4Rud4cu95Vyt70cDVHjGSP1yyvUNL2crHhSzknk5dcJmHkMm2mQP5gbtB FbzX06lP+ZSZFM5hdU7Nb0QsxmdAGMmqbmvU/WzYBbSXh6dJfKt2bTQns8cXr0iZUReF BUmwXcs/N+VvjR6jHkD0O6r60aV5Sw/W6HkWbx38p3/VZyFHj2j9Rx/LteXMyMiCLqVK kfM+71rEm1JD2h4QieMn0H767d2ry+y5nRzWbzlcRWwFnRP3BrQe8fdCwrCyV9Pk1mdZ KjHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784682113; x=1785286913; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=1dw4LW8kSdGmcldnGWhnWc2M/cNC9RFM1UCRX4bcCtw=; b=F34WLSVTzlIA3UMg3m5WgrkHaCE6erSbo6gl9ZaU/EsbngPNHe8GtR6u7lnajH9IXw S3cA3bqA5s9ihBbOGjjyoSrtL/tFXY5OZ7gz0DyEE10EfSYj9opJsXYH/qhsVh53dOMp WObT7lbTHytQcO7qqeOBmhAMzjxhOLsUkPd+y5gcz5BVWSgpnFT/d0Sb/HtaNNvL0QYU PtdMZUBnalNhKs7Q3RxzB7KtP4piwHbgaw/0b10OxmTCocQ99Z9BNU257KELpBTEGFun oKt7oTl7Q52KtbCbj63SJuvSGEG6Aj+VuiDQ/+KeHdZq0z1MtfGtrfQf7jlVPWidEGF/ CsJQ== X-Forwarded-Encrypted: i=1; AHgh+RqO03h9xsXWNsqVQRQm0Cy5yrImn6IZqlFB1WH9qoPQYysVQeNgNLVKSYnnj0J5K49iMhd8KsIS2n3BuEI=@vger.kernel.org X-Gm-Message-State: AOJu0YyX3OVvBs8KmufW0HzbfslhPpRHmQ1gNdepYIIq4vZFe856eEsz vvY4WOEj45GPX3AblD7hQE+VZrb5TjFBSXvpMittJbipz/2MkNL5o6G0vnHcVUhs9kr2rEQSJyw /FbGzWjc= X-Gm-Gg: AR+sD10ZoqsyVzO6umINaOGgmbGATc38UvTpZOz95BDfCNs/Y8D4fQQjK/0yKkc5el5 4bcdwwwV/bPoUYC5KoCpun2sA0O1WtK7vfIL9OjqvziQzmLwOBeXvqvA36OiteL1E9f9xTdRJft 2xQG5dLrkQrCUCH4F3MxAzhsjoeDe/Eghj4+WsCFhClGZ4g74n5k0jZabuxaZn8E8s7epsuvfbF 2SCh3C2F9vc/7v8Ps+7kWh0J4ic6EEf8U3gkI5Ll79fUWk2Nn8ySSXB1xb3xnww5MLzAQZioZgF QasYVn5LogWoqxn3p/pO5k84SJa2OvvuOwkNCTC4e2d9v6/CJ3+ga/fbsm4uJOATK5b3ORIw4JR dEC5/Lffwb9UCl9sQ3NWr76PyA9veTuq6RS3btcm7MFkbUmuLtPU3GQEkewicAk5eu/TVVE1Nl+ PIAnh2 X-Received: by 2002:a05:6300:141:b0:3bf:63af:85d with SMTP id adf61e73a8af0-3c3ad7f9c33mr22691710637.18.1784682113003; Tue, 21 Jul 2026 18:01:53 -0700 (PDT) Received: from [127.0.0.2] ([50.145.100.174]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3147dc1a689sm3141207eec.4.2026.07.21.18.01.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2026 18:01:52 -0700 (PDT) From: Abdurrahman Hussain Date: Tue, 21 Jul 2026 18:01:48 -0700 Subject: [PATCH v4 3/6] of/overlay: look up absolute target-paths absolutely Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-nh-of-alias-overlay-v4-3-8ad097e31e36@nexthop.ai> References: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> In-Reply-To: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> To: Rob Herring , Saravana Kannan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Abdurrahman Hussain X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784682109; l=4474; i=abdurrahman@nexthop.ai; s=20260510; h=from:subject:message-id; bh=kRpIeIkOBNbm/VqI0BkoZECW2QHfP+btpWk4Ns3ReaI=; b=5ijyVEp1xZ9Z3BnjZUvplK7hk36P7eSeU4T8wKCEQ6Ha3YFD5wzM5j6/yJXNsP2DmWQS1ki3F OgKVtSY32A9AsZCftxmvou9r9feTq4vrns9BFw0lIYbmXZunndo1YCc X-Developer-Key: i=abdurrahman@nexthop.ai; a=ed25519; pk=omTm9cCAbO0ZhS32aKfJDKue0W3sQGpG9ub5eYHif8I= When of_overlay_fdt_apply() is called with a non-NULL target base, find_target() currently concatenates the base's full path with every fragment's target-path via "%pOF%s" =E2=80=94 so target-path=3D"" resolves = to the base itself (the intended common case), but target-path=3D"/foo" resolves to "/foo" (never the DT root) and target-path=3D"/" to "/" (never a valid node at all). That makes it impossible for a two-fragment overlay to modify one subtree under the base and one node at the DT root =E2=80=94 a shape that arises naturally when a PCI-attached device wants to declare its peripherals under dev_of_node(&pdev->dev) AND add /aliases entries so alias-aware drivers (i2c-xiic, spi, tty, ...) can pin bus numbers. Treat target-path as absolute whenever it is non-empty. An empty target-path continues to mean "the target base itself", preserving the existing shape used by drivers/misc/lan966x_pci.c and its dtso (the only in-tree of_overlay_fdt_apply() caller today that passes a non-NULL base). Spell the new contract out in the kernel-doc for @base and @target_base and in find_target()'s strategy comment, so out-of-tree callers that modeled a base-relative target-path on the old concatenation behavior have a documented signal that the semantics changed. Assisted-by: Claude:claude-fable-5 [Claude Code] Signed-off-by: Abdurrahman Hussain --- drivers/of/overlay.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 08d5351746be..74aea704835a 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -688,12 +688,15 @@ static int build_changeset(struct overlay_changeset *= ovcs) * * 1) "target" property containing the phandle of the target * 2) "target-path" property containing the path of the target + * + * With a non-NULL @target_base, an empty "target-path" means + * @target_base itself; any non-empty "target-path" is resolved + * absolutely from the live-tree root. */ static struct device_node *find_target(const struct device_node *info_node, const struct device_node *target_base) { struct device_node *node; - char *target_path; const char *path; u32 val; int ret; @@ -709,23 +712,14 @@ static struct device_node *find_target(const struct d= evice_node *info_node, =20 ret =3D of_property_read_string(info_node, "target-path", &path); if (!ret) { - if (target_base) { - target_path =3D kasprintf(GFP_KERNEL, "%pOF%s", target_base, path); - if (!target_path) - return NULL; - node =3D of_find_node_by_path(target_path); - if (!node) { - pr_err("find target, node: %pOF, path '%s' not found\n", - info_node, target_path); - } - kfree(target_path); - } else { - node =3D of_find_node_by_path(path); - if (!node) { - pr_err("find target, node: %pOF, path '%s' not found\n", - info_node, path); - } - } + /* an empty target-path means the target base itself */ + if (target_base && path[0] =3D=3D '\0') + return of_node_get((struct device_node *)target_base); + + node =3D of_find_node_by_path(path); + if (!node) + pr_err("find target, node: %pOF, path '%s' not found\n", + info_node, path); return node; } =20 @@ -737,7 +731,9 @@ static struct device_node *find_target(const struct dev= ice_node *info_node, /** * init_overlay_changeset() - initialize overlay changeset from overlay tr= ee * @ovcs: Overlay changeset to build - * @target_base: Point to the target node to apply overlay + * @target_base: Target for fragments with an empty "target-path"; + * fragments with a non-empty "target-path" resolve + * absolutely and ignore @target_base * * Initialize @ovcs. Populate @ovcs->fragments with node information from * the top level of @overlay_root. The relevant top level nodes are the @@ -982,7 +978,9 @@ static int of_overlay_apply(struct overlay_changeset *o= vcs, * @overlay_fdt: pointer to overlay FDT * @overlay_fdt_size: number of bytes in @overlay_fdt * @ret_ovcs_id: pointer for returning created changeset id - * @base: pointer for the target node to apply overlay + * @base: target for fragments with an empty "target-path"; + * fragments with a non-empty "target-path" resolve + * absolutely and ignore @base * * Creates and applies an overlay changeset. * --=20 2.54.0 From nobody Sat Jul 25 00:18:33 2026 Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C7D3C35FF6E for ; Wed, 22 Jul 2026 01:01:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682118; cv=none; b=YtevmtQ2HUCIMAhQo2Xj6ZFAbG2LlKYHCfXSDkEKA1+Hp8ly43ias0EdTYup2onK4TIx5CQpvwoGStoySFaXXwHgdfSN1leiSYwjieuO4zebrG3olZMMO6Pxn2UYkg32Axxo1oQ7eJFxEBPZX7Oda96EhjOQl8hLwWMJ5cGiHsQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682118; c=relaxed/simple; bh=ruyEsUSk7dAWeLJgBxW2yqpOhr/A/9X7aodtMZGO2fU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=giOybB0d/eN7sSZRMb+IFsZUXBIAIm//2vW7x0Qaw6Dr7bqUTDXVnhIxYSfpNFxjSOIpdSfuUlmOYEJo6C6n/7x+uo4mzIR0ySMqFM6MZFQF+XQJV0F3lxJ0EcU6lU/U3cg5o2V8Ti08g525T5FDpBIMR24Ck08sFC/6YI71mx0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai; spf=pass smtp.mailfrom=nexthop.ai; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b=V6L+sp/0; arc=none smtp.client-ip=209.85.214.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b="V6L+sp/0" Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-2ca64c3ce5fso136503715ad.3 for ; Tue, 21 Jul 2026 18:01:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nexthop.ai; s=google; t=1784682114; x=1785286914; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Tp8AOE3uAFXZigZSnFMB1K5F/tkZ+Fy9Wupl/gvbYAk=; b=V6L+sp/0T/WD9g7vBXu4wRVC7uAVq4ZOF0RTuGk2vRKr6r0voodO9ASw3Jr+eutfo4 vCWeqHP0MfrPz8r+qpD0nKmeKoPbax7wadaZ52D/dmL0KOfYo7YMFhTtem9fuSOorQX1 Lh8Lut08h7PHgOCyGmsSBnG1PVreBTes3Gz65XGaFxKNbCfjBqBr2mtv9VG2vr0gEz75 KcvYb6mbFs/rc/gBA7ju4A+XQh/4qt+NhOvPpuqktAtWVXQQO0DiVxRtXNIiK8Q+0o1c bdqAf3qrgf2XucdG1HOZa8hhppByeg2pycN3aM/iVsgMQT+5MRiuTFu8MRPPUZVajKj+ fvsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784682114; x=1785286914; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Tp8AOE3uAFXZigZSnFMB1K5F/tkZ+Fy9Wupl/gvbYAk=; b=JNcH4U8q4qWZHo+2V9ji14h+vSO5YcgwduGHVmWG+I3SMO5S/078ElJ56jfFbDSPWT ZF0DJ2qIJkDLxuh0NprZh59KHPjNiPWoO8kmHEe6UrrkgP7FAQ3NkF9HaFRrvkYbpdes Ty7noRegwqN2DnvnwDrnGyZfzKxz8aYHp4OeDvFkP6XYXFSELYEupao0IsaQ6Zz47YG5 9bvMQ1NQADIKHHhCDy+GTsBGgpbgJDtiGhz888qrnMPMC2j5lhXhV2mpXgnHs1P3PmSa gZgKxH8xQkOAPNKrBEhiwiDARFyZcHzXfdoouwjK63SacZ0XC18MUiCqEkBbqJt9Y0d3 3yNA== X-Forwarded-Encrypted: i=1; AHgh+Rokui/N7mdnwO7b9VUr0OP0ZqJXb/npap1oB2gK2Jplr01B0cHgbJBOkT4c87wG2/hFwRNZu5iO4jCBsZQ=@vger.kernel.org X-Gm-Message-State: AOJu0YyLJ6/8uX+xsL6xZqXNPnqSK0dVjzbMr1rbsolifY09ypP7lAX/ KrHmfkGMsR/bwA3ZyLpa4QbpjJNTxkSa+aSZVV2rN69qDJij8aqNk72WHqtwjA/Mebsbs46CZt2 NYSs5eFs= X-Gm-Gg: AR+sD1035VCQELFdRcxm7zbVgd79J28elIKWZqidBC0ejuU0uzVsL3leltl8y42rXSN dJ9HInQqmhVWUw0ojJWgTptXAZiu5QgEGL2qWbKinDMRwjxmiuj35Y5k/CDsQvV6Fz10JneEI6t bu52sqRCvCpKdjPRPEcKP4gwA3nJ8ACyUnEOWun/iCK5c+jO+wZew0Yv5ki+12nd0FHd6ddISAe icwppv+QYSL/ZDqW3jKjy+XpVA/hhgBXIcWZcbyG9sQkn7JDrbaW/qfbviAnLi3IJ74QXeZvLb4 /LtEAoZw5BB6ILEACrtwNki7COQCjjCB/khSRLApiTL2CO9cCWbHZRdQgsKEqGWi0/7WiyS4scD ty56UHpoWbRNxik0gYl0CkDi/z1qYVLnKRdwuOdQxppL/EGKgppZbHTePmeDKAix7XWyPnYPraH VMYPZc X-Received: by 2002:a17:903:1210:b0:2c9:d298:6c06 with SMTP id d9443c01a7336-2cf34a0a6c0mr212343185ad.25.1784682113847; Tue, 21 Jul 2026 18:01:53 -0700 (PDT) Received: from [127.0.0.2] ([50.145.100.174]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3147dc1a689sm3141207eec.4.2026.07.21.18.01.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2026 18:01:53 -0700 (PDT) From: Abdurrahman Hussain Date: Tue, 21 Jul 2026 18:01:49 -0700 Subject: [PATCH v4 4/6] of/overlay: return ERR_PTR from dup_and_fixup_symbol_prop() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-nh-of-alias-overlay-v4-4-8ad097e31e36@nexthop.ai> References: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> In-Reply-To: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> To: Rob Herring , Saravana Kannan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Abdurrahman Hussain X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784682109; l=3699; i=abdurrahman@nexthop.ai; s=20260510; h=from:subject:message-id; bh=ruyEsUSk7dAWeLJgBxW2yqpOhr/A/9X7aodtMZGO2fU=; b=HJWATAYBeNlEyPwzlI1Xqfu0VK1VBCRpKGEAgPsD0xFwpREaCrfUj9YfFwHmmKR1HDvedi5D1 kSy8kTm1gWsBuSx5y2bslal13DRwAVC9EawOT7gkh1nmvGPPnIF1Gi6 X-Developer-Key: i=abdurrahman@nexthop.ai; a=ed25519; pk=omTm9cCAbO0ZhS32aKfJDKue0W3sQGpG9ub5eYHif8I= dup_and_fixup_symbol_prop() returns NULL for three very different reasons: the property value is not a valid non-empty C string (malformed input), the value does not resolve to a node inside one of the overlay's fragments (not an overlay-internal path), and memory allocation failure. Its only caller today reports every NULL as -ENOMEM, so structural problems in an overlay's /__symbols__ node are diagnosed as memory exhaustion. The next patch reuses the helper for /aliases values, where the distinction is load-bearing: a value that doesn't resolve inside the overlay is a legacy alias that must be copied verbatim, a malformed value must be admitted inertly with a warning, and only a real allocation failure may fail the overlay apply. Return ERR_PTR instead: -EINVAL for malformed values, -ENODEV when the value is not a path into one of the overlay's fragments, -ENOMEM for allocation failures. The /__symbols__ caller now propagates the distinct errno instead of collapsing everything to -ENOMEM. Assisted-by: Claude:claude-fable-5 [Claude Code] Signed-off-by: Abdurrahman Hussain --- drivers/of/overlay.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 74aea704835a..ad4e50482515 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -206,6 +206,10 @@ static void overlay_fw_devlink_refresh(struct overlay_= changeset *ovcs) * The duplicated property value will be modified by replacing the * "/fragment_name/__overlay/" portion of the value with the target * path from the fragment node. + * + * Return: the fixed-up property, or ERR_PTR: -EINVAL if @prop's value + * is not a valid non-empty C string, -ENODEV if it is not a path into + * one of @ovcs's fragments, -ENOMEM on allocation failure. */ static struct property *dup_and_fixup_symbol_prop( struct overlay_changeset *ovcs, const struct property *prop) @@ -224,14 +228,14 @@ static struct property *dup_and_fixup_symbol_prop( int target_path_len; =20 if (!prop->value) - return NULL; + return ERR_PTR(-EINVAL); if (strnlen(prop->value, prop->length) >=3D prop->length) - return NULL; + return ERR_PTR(-EINVAL); path =3D prop->value; path_len =3D strlen(path); =20 if (path_len < 1) - return NULL; + return ERR_PTR(-EINVAL); fragment_node =3D __of_find_node_by_path(ovcs->overlay_root, path + 1); overlay_node =3D __of_find_node_by_path(fragment_node, "__overlay__/"); of_node_put(fragment_node); @@ -243,18 +247,18 @@ static struct property *dup_and_fixup_symbol_prop( break; } if (k >=3D ovcs->count) - return NULL; + return ERR_PTR(-ENODEV); =20 overlay_name_len =3D snprintf(NULL, 0, "%pOF", fragment->overlay); =20 if (overlay_name_len > path_len) - return NULL; + return ERR_PTR(-EINVAL); path_tail =3D path + overlay_name_len; path_tail_len =3D strlen(path_tail); =20 target_path =3D kasprintf(GFP_KERNEL, "%pOF", fragment->target); if (!target_path) - return NULL; + return ERR_PTR(-ENOMEM); target_path_len =3D strlen(target_path); =20 new_prop =3D kzalloc_obj(*new_prop); @@ -281,7 +285,7 @@ static struct property *dup_and_fixup_symbol_prop( err_free_target_path: kfree(target_path); =20 - return NULL; + return ERR_PTR(-ENOMEM); } =20 /** @@ -350,6 +354,8 @@ static int add_changeset_property(struct overlay_change= set *ovcs, if (prop) return -EINVAL; new_prop =3D dup_and_fixup_symbol_prop(ovcs, overlay_prop); + if (IS_ERR(new_prop)) + return PTR_ERR(new_prop); } else { new_prop =3D __of_prop_dup(overlay_prop, GFP_KERNEL); } --=20 2.54.0 From nobody Sat Jul 25 00:18:33 2026 Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB7F935E1B5 for ; Wed, 22 Jul 2026 01:01:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682118; cv=none; b=cIrffQ8a3V8Gm+/sZSPuMUNWOyExEcv0WHw5dqI0ixy/X0nL4HqP8f6LgSgGIrPsDRNSlGNOC2NameF9CZuObtjXDTC2+zRzSxKbjARml+lzLjALj56OcRU/m0jDbMfPYf0h/G8yJuyOUJvcJrPuSsF1Vq5l03YVmgkNKd2zh+4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682118; c=relaxed/simple; bh=0ohr3ai49eqwG8m8my5lvmnqSRw5RzvE46mSA+j7yUo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Dvl6yUPbBuujJHqmaC8sO6jPZMn7/qDKSebb9zPdoVKeMXhC3zMpyFTmFTOVECxLf7KyjiIBluU0ij0SIRG54kInmwEHY5NQV8fLq5I6jp7U5Tlh37u6YzhweZ2d+KEqvFiBfZ2K/n2KnGuBeNz5MQW89EeY6bU0cTcNGFq9Ve8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai; spf=pass smtp.mailfrom=nexthop.ai; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b=EAnpasY/; arc=none smtp.client-ip=209.85.215.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b="EAnpasY/" Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-ca2fad0ae38so9297282a12.3 for ; Tue, 21 Jul 2026 18:01:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nexthop.ai; s=google; t=1784682115; x=1785286915; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=6hvLIlMFPJGt7jq/BkMyrua/J1s+njTaPVLS8zaead4=; b=EAnpasY/HXLB/XjGgBQ1HOPEqA5BqBSCeEEbrSTrsv9bFYjabJ1OIxvb+NszoJExTV 8CIdp3NlD7RdZxNd4/FzjPyz69KUNtuOGckrZ/f9JMgPnBdX30xhAy2nFUdkysf4917S NHPEZ4Bj9AVsu2lCpwrb+G3VCqYelUYpIo1D+ySxfSk7cGDnWWemRcW5vTkxQ7gdIOUe VPnpyHjHlmsBTuD/7NTkIA17HmnU52n0EIVrAbrkr8Sw3zf2r+eJqEe3oCvdlkMsSnGF syQssDEWlglAqJps4HiaFE50ioHo4RG86whHryVQYViQLcNpCon1aA2nS/GQpmvkOpcG sU6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784682115; x=1785286915; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=6hvLIlMFPJGt7jq/BkMyrua/J1s+njTaPVLS8zaead4=; b=CsloEP44WkcjDQ03sNyWEbRzWNkAhL/4OOtaYYcuuZrb5B4z1VCnpDi6FQfg+rZA/O WG9pabOtprvownmdJD8rkI4d8J6mDHpPYOrOSpR1KcStRy4h4PRoK55ROkUbpw2qDy3z p3xaetkLKLHNdhXZVYUJZ2sJzTCqhNm4/7RYHYNkl8GzkFTxEXmsuEb9jxEWHy9NtskF WB5VG8uYqrFReV1dkUE1f/WPxIe1q8QhYRm8G99C1C8BOystVyDkmkN3RnhljPTFfKsK FKaUeQgN4uDWqa8oQRmTQgYI0rsySX7z72qeoTOM6kmadjsMsClsrwDMn1YpGunx3KSm HR+w== X-Forwarded-Encrypted: i=1; AHgh+Rq2vvKyF5IPab6T/S7Up5crEOqfN3RZ73w2QEbMKMWItlAWm8WvNHQXdkIa/OG44xSkepEtnOnvRbT6abg=@vger.kernel.org X-Gm-Message-State: AOJu0YxCX+XdyOjkqwoFHLJA13WRvJ5LDaFTlIUQ/ZntDTznVv69kqwS 1L1fIIHImp16XR/Hh/ITxTYE0+K/5v6EeatVABZEF6o/tqmVOXQeldZpGD2jqvhfCFI= X-Gm-Gg: AR+sD10HfKhbXwx8P2wYZw1ujDnkxmlROYtIGtmTNBKUaUsTmPDDrW9Xm5UFuIdLHCE ik33iASRDt9l7M8ltkIu+wYkyNGZ1zDyqwsLUF+m01/bFOtq2GWvTl90tGDzemwjoTqic2t1Ptq pJXptTtMWuWY3kR44oVSmBpUymftC+9T0TyfC4xAYprpVd8QxG/x5vhuZ/yC5O+UfrsAZ+2ysOa Q5lO5wmsel07udu3CY6Mt2t371fwXejfu/PWGjr+KMcLb6a+EcShMsLL65PWjEtUNQZedEJzo5L CGCdsZMAfaky1AI752Hs5aS2X3Fx35VpeNfRs+9BGaH9UAtlfd+S9ElRWW7J+fuH4dI2MRjGIS3 GObfm02UKBEMzSS49P0cGtjtilW7SusIVev+X8PawmF7+x1Cq5+Lj/fW6WddghT9FtW/yOIay9H gsyFR8 X-Received: by 2002:a05:6a21:6110:b0:3b4:71a9:cd8f with SMTP id adf61e73a8af0-3c3ad947df1mr24250388637.41.1784682114646; Tue, 21 Jul 2026 18:01:54 -0700 (PDT) Received: from [127.0.0.2] ([50.145.100.174]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3147dc1a689sm3141207eec.4.2026.07.21.18.01.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2026 18:01:54 -0700 (PDT) From: Abdurrahman Hussain Date: Tue, 21 Jul 2026 18:01:50 -0700 Subject: [PATCH v4 5/6] of/overlay: rewrite /aliases path values to live-tree paths Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-nh-of-alias-overlay-v4-5-8ad097e31e36@nexthop.ai> References: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> In-Reply-To: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> To: Rob Herring , Saravana Kannan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Abdurrahman Hussain X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784682109; l=3894; i=abdurrahman@nexthop.ai; s=20260510; h=from:subject:message-id; bh=0ohr3ai49eqwG8m8my5lvmnqSRw5RzvE46mSA+j7yUo=; b=V0VzmeZWCl+Yn44Np+rub0/SOwtCbBsPHtb9r9b0aCzutB8DxqqCxMsQqqDCTyRMsr/RLczbF t0YLnxf7d/jCeWl6r/o845jewHyZDesPrMGe4q/DXZp7VQS6RWyKC2K X-Developer-Key: i=abdurrahman@nexthop.ai; a=ed25519; pk=omTm9cCAbO0ZhS32aKfJDKue0W3sQGpG9ub5eYHif8I= /aliases entries added by an overlay reference labeled nodes inside the overlay via '&label' in the .dtso. dtc renders those references as string paths at compile time, but the paths encode the overlay's internal fragment layout (e.g. "/fragment@1/__overlay__/fpga@0/i2c@40000") rather than the location where the node will live after apply. Currently only /__symbols__ has its property values rewritten from overlay-internal paths to live-tree paths by dup_and_fixup_symbol_prop(). /aliases values fall through the plain __of_prop_dup() path and are copied byte-for-byte, so of_find_node_by_path() on such a value returns NULL, of_alias_get_id() reports -ENODEV =E2=80=94 and the reconfig notifier added earlier in this series sees uninterpretable paths and can't populate aliases_lookup for overlay-declared aliases. The values in /aliases follow the same textual convention as /__symbols__, so we can reuse the existing rewriter. Detect the /aliases target node (of_node_is_aliases(), the same predicate the reconfig notifier uses) and offer every non-pseudo property to dup_and_fixup_symbol_prop(); the previous patch made its return value carry the distinction this needs. A value that resolves inside one of the overlay's fragments is stored rewritten. -ENODEV means the value is not a path into this overlay =E2=80=94 legacy string aliases like "ttyS0= ", or absolute live-tree paths =E2=80=94 and is copied verbatim, as before this series. -EINVAL means the value is not a valid non-empty C string; it is also copied verbatim, but with a warning: consumers (of_alias_create() and the alias path lookup) validate before dereferencing, so a malformed alias is inert rather than a reason to reject an otherwise-valid overlay that applied cleanly before this series. Only -ENOMEM fails the apply. Matching on where the value resolves rather than on a "/fragment@" name prefix matters: init_overlay_changeset() accepts fragments with any node name, and dtc emits the actual fragment name into the alias value, so a prefix test would silently leave a hand-named fragment's alias unrewritten (and misroute a live-tree path that happens to start with "/fragment@"). Pseudo-properties (name, phandle, linux,phandle) are exempt from the /aliases handling: the is_pseudo_property() skip at the top of add_changeset_property() only covers targets already in the live tree, so a phandle of a newly created /aliases node would otherwise reach the rewriter =E2=80=94 and a phandle value is a raw cell, not a C string. Such properties take the plain __of_prop_dup() path as before this patch; of_alias_create() skips them at notifier time. Assisted-by: Claude:claude-fable-5 [Claude Code] Signed-off-by: Abdurrahman Hussain --- drivers/of/overlay.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index ad4e50482515..2a37b5260ba7 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -356,6 +356,19 @@ static int add_changeset_property(struct overlay_chang= eset *ovcs, new_prop =3D dup_and_fixup_symbol_prop(ovcs, overlay_prop); if (IS_ERR(new_prop)) return PTR_ERR(new_prop); + } else if (!is_pseudo_property(overlay_prop->name) && + of_node_is_aliases(target->np)) { + /* rewrite overlay-internal alias values to live-tree paths */ + new_prop =3D dup_and_fixup_symbol_prop(ovcs, overlay_prop); + if (new_prop =3D=3D ERR_PTR(-ENOMEM)) + return -ENOMEM; + if (IS_ERR(new_prop)) { + if (new_prop =3D=3D ERR_PTR(-EINVAL)) + pr_warn("%pOF/%s is not a valid string; alias will be inert\n", + target->np, overlay_prop->name); + /* not overlay-internal: copy verbatim, consumers validate */ + new_prop =3D __of_prop_dup(overlay_prop, GFP_KERNEL); + } } else { new_prop =3D __of_prop_dup(overlay_prop, GFP_KERNEL); } --=20 2.54.0 From nobody Sat Jul 25 00:18:33 2026 Received: from mail-pj1-f43.google.com (mail-pj1-f43.google.com [209.85.216.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2081B361640 for ; Wed, 22 Jul 2026 01:01:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682120; cv=none; b=u3IhWQnu8um52bnwPOVkKWYmJcGvS08Lace/434x1fYqhq5iMkqwRYjX2Q6r5TOSyPnEaUwVyMkHmyBZhii55Y2+AYhfi/KSybTj98D4PBCbWj5GTsGDv3Qdaj0S8Hdep+U8OEwqfRALaUesBctTwdkH4xZpXnLhibDexyEe0ZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784682120; c=relaxed/simple; bh=GiQ8QmcT52eeZQ8hU0W7klQyaak1qO4zuG4S19GZ1Eo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iBksncDeTNLvYwgv+5eF8EoTOb+HSUo+cIB9uAPunuY+F0v1JejSUPDZF2i4UrhWuZDdXnSMY69/qzx6WMyT7sy0i6PxI0WDQxsrT7zvXD+iV0IdX+RbodBLERr8XOFtF0cdnr6+WMU4IvEiazLrwWUbEZqV4wCCBVKeujIczG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai; spf=pass smtp.mailfrom=nexthop.ai; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b=ScDy/Aws; arc=none smtp.client-ip=209.85.216.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b="ScDy/Aws" Received: by mail-pj1-f43.google.com with SMTP id 98e67ed59e1d1-383cb94f742so11130875a91.3 for ; Tue, 21 Jul 2026 18:01:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nexthop.ai; s=google; t=1784682116; x=1785286916; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=E3gS4IFrL1u/fKDkWRYURGH9FqMyDvXnOF4aO0ajrY4=; b=ScDy/AwsZXPd9BNS1XD98CA+oLHwjA/LLRJH1STD5qNo/jbJGoyGPxj02DSWVi03DQ CMUzxMSNnrbtIsUgpn8l0GBxSiFpLULT6LAejj2H+XMz4faVGO2DZQCdEAbjIHRIliaG XtXBTd9+L0v263rz758fUkkS4sLNn3I6/X5+vlbqy4IBsGpuDuZAG0//37ARdSGPjj/7 U4tHtfYxdcT7+uWtknoA7ro1LUDbLn9QERfhoVTgk1N88PPvBSzkQvE7+DuIWhWHPkNm d9btNJXpO8qFmgkh77Lbx4+vFYsLX30YMKqoEF17KkCvKkO+h5gVf1fbUZCSCXrnilMC zMrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784682116; x=1785286916; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=E3gS4IFrL1u/fKDkWRYURGH9FqMyDvXnOF4aO0ajrY4=; b=sgEqkvgE/8mZWXYNHFFuW+pTOgVMxD+F+sTj/833ZJ8ea4t51ZWPxOpr1lAD9PcVKC svcfu96MdOrl6taBTt2S2in2HWosLZJE0AgQycRUJhvGqqf1Vv5rRNxAT0ZcGSdgKokF YOkLscQExYKFmCe1HeSnei5og330subIvrSjKQG8g514eiQYCfhKJhXdIC7BU9eMvOhh UIJMWYONEQU4BswEoaCweQFWxSNmDsi1jWNK/Wa9vUOdruI6u5ZV5EuHL7yEVt+C3QnV 6ed2Mh5+X11+eRhVhfuR1PL9ZqkT+6g/nNW1VgVa1Kiupc2SAcwm/RHRlzEaABf+RiPx nxcQ== X-Forwarded-Encrypted: i=1; AHgh+RpnAazKInLupYJYHm7UcpSKg90KHEAlfugxC63DuOUzWYw1mdArejSiceRfto2gWSv1xgUoSQ3gKuTR4rs=@vger.kernel.org X-Gm-Message-State: AOJu0YzY1zYCHZ9QpMtEd/lZxSWD2LZF3mPm6KJhtlcoWM80LlVOr5T2 6jfxf8oKS/BEf9G9IagDHRPhk3FKTZ+vRG/x8H26Kj76ivzK+zJDRBvhRoSMawgtLxj4Q+KWFE2 9XEg5CCk= X-Gm-Gg: AR+sD11j8ZqcMtUhbG/6YzTJDhs27bITuieRwgztY7XuXaWXASsidQMIIurXLsPaJeH DjdM/NfFw9V2C9y5/4bK15iJbSEweCmSTx1lv/HKD0joNPX4bkxjJdvJ9D3PQbZexdbNZe1Bdri jvxtLkubjOYe7VoXgaBqFsq1jfOfWrg6mY2+dKG3f7/20AL7fTEKYB8jgGanjUR3oQI9Cvm2b2m 2OXhZDA1bBmyB9e5WWFB9EwLvUG/euBJkYB1XGbtVUZ/KL8fXOKIfiw11j1j2TQFitgsw7PfTOd j5eEKnl5SMk1/Cqst5tbqiJ2Rnm/C4D2sm8jEOS878EErb0QMDFnBEq5L/zBxK40EmiPA83rCb3 iVvIcglQ1SGMiYheE6GGoG6jKMVFcckyZTi7Le694DBIaRM6A9HHw/8H/TIPmADaKGcE1WzoRls a19th22Qupz8V5LfU= X-Received: by 2002:a05:6a20:244c:b0:3c3:7fff:ba77 with SMTP id adf61e73a8af0-3c3ad973f68mr21115284637.42.1784682115750; Tue, 21 Jul 2026 18:01:55 -0700 (PDT) Received: from [127.0.0.2] ([50.145.100.174]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3147dc1a689sm3141207eec.4.2026.07.21.18.01.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jul 2026 18:01:55 -0700 (PDT) From: Abdurrahman Hussain Date: Tue, 21 Jul 2026 18:01:51 -0700 Subject: [PATCH v4 6/6] of: unittest: cover /aliases updates from overlay apply/revert Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260721-nh-of-alias-overlay-v4-6-8ad097e31e36@nexthop.ai> References: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> In-Reply-To: <20260721-nh-of-alias-overlay-v4-0-8ad097e31e36@nexthop.ai> To: Rob Herring , Saravana Kannan Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Abdurrahman Hussain X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784682109; l=6951; i=abdurrahman@nexthop.ai; s=20260510; h=from:subject:message-id; bh=GiQ8QmcT52eeZQ8hU0W7klQyaak1qO4zuG4S19GZ1Eo=; b=kaF+TPamx+WeqjjMa9P8S8tKYPLbJ0Utab3dOA6LcHvy8dU4cDRuzD4OSnR75PDFH7krararu f+yU4NK0zFYB09h5b109mM6VZ0TbJSHCYKRlUkNj5bj/9g66J1GXcQC X-Developer-Key: i=abdurrahman@nexthop.ai; a=ed25519; pk=omTm9cCAbO0ZhS32aKfJDKue0W3sQGpG9ub5eYHif8I= Add overlay_alias.dtso plus of_unittest_overlay_alias() to cover the "aliases inside an overlay" flow end-to-end. The overlay has two fragments: fragment@0: target-path=3D"" grafts a labeled node under target_base. fragment@1: target-path=3D"/aliases" adds `testcase-alias99 =3D &