* Re: [PATCH v2 2/2] arm64: dts: qcom: kaanapali: fix traceNoC probe issue
From: Jie Gan @ 2026-06-30 8:42 UTC (permalink / raw)
To: Leo Yan, Suzuki K Poulose, Mike Leach, James Clark
Cc: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang, Jingyi Wang,
Abel Vesa, Yuanfang Zhang, linux-arm-msm, devicetree,
linux-kernel, coresight, linux-arm-kernel
In-Reply-To: <20260630081021.GD1812158@e132581.arm.com>
Hi Leo,
On 6/30/2026 4:10 PM, Leo Yan wrote:
> Hi Jie,
>
> On Tue, Jun 30, 2026 at 09:03:52AM +0800, Jie Gan wrote:
>
> [...]
>
>>> - How can you guarantee that a interconnect TraceNoC will never
>>> require ATID in the future?
>
>> From a hardware perspective, there is no fundamental difference between an
>> itnoc and an AG TraceNoC. They use the same TraceNoC hardware implementation
>> and share the same AMBA bus type. The distinction is purely functional: an
>> itnoc is used for local trace aggregation within a subsystem, whereas an AG
>> TraceNoC serves as the top-level aggregation point for the SoC.
>
> I'm still not convinced that adding "arm,primecell-periphid" is the
> right approach.
>
I agree we shouldn't need to add arm,primecell-periphid for the AMBA
bus, as the hardware provides the necessary registers to read the
peripheral ID. I used it as a temporary workaround to resolve the issue,
but I believe that solution is not correct.
> From the description above, I'd expect either the hardware to expose
> bits in a register to distinguish these two module types, or as I
> suggested earlier, to use a DT property to indicate the module type (or
> whether ATID is required).
>
I wanna distinguish the aggregator traceNoC and interconnect traceNoC,
even probe with platform driver, but the existing compatible is too
specific to the interconnect traceNoC device(coresight-itnoc), that's
why I didnt try the DT property proposal.
> Or have you tried to detect the last tnoc on a path and allocate ID for
> it? (You can retrieve csdev->path).
As Suzuki mentioned in the other thread, I think it would be better to
add separate compatibles in the of_match_table to distinguish between
Aggregator TraceNoC and Interconnect TraceNoC when probing with the
platform driver. This would allow us to allocate an ATID only for
Aggregator TraceNoC during probe, which is consistent with our original
design.
Thanks,
Jie
>
> Thanks,
> Leo
^ permalink raw reply
* Re: [PATCH RFC v5 11/12] reset: zte: Add a zx297520v3 reset driver
From: Philipp Zabel @ 2026-06-30 8:45 UTC (permalink / raw)
To: Stefan Dösinger, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Brian Masney
Cc: linux-clk, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <20260628-zx29clk-v5-11-79ff044e4192@gmail.com>
On So, 2026-06-28 at 22:59 +0300, Stefan Dösinger wrote:
> This drives the MFD child devices created by the zx297520v3-crm driver
> as well as the aux device created by the zx297520v3-lspclk driver.
>
> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
>
> ---
>
> v5:
> Make top and matrix MFD children instead of aux devices
Why? What is the difference between top/matrix and lsp here?
Couldn't you just keep all three as aux devices and remove the
platform_device boilerplate half of the driver?
[...]
> diff --git a/drivers/reset/reset-zte-zx297520v3.c b/drivers/reset/reset-zte-zx297520v3.c
> new file mode 100644
> index 000000000000..8ef434904230
> --- /dev/null
> +++ b/drivers/reset/reset-zte-zx297520v3.c
> @@ -0,0 +1,274 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2026 Stefan Dösinger
> + */
> +#include <dt-bindings/reset/zte,zx297520v3-reset.h>
> +#include <linux/reset-controller.h>
> +#include <linux/platform_device.h>
> +#include <linux/auxiliary_bus.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
> +#include <linux/iopoll.h>
Looks like this is not needed anymore.
> +/* Most devices on the zx297520v3 SoC have one reset bit per clock line. As a rule of thumb, the
> + * lower bit disconnects the device from the bus, similarly to turning off PCLK - registers read 0
> + * or hang indefinitely. Unlike PCLK, this reset may have a lingering effect after deasserting.
> + * E.g. timers will be disabled, but retain their counter value.
> + *
> + * The other bit resets the actual device registers.
> + *
> + * For some devices, e.g. GMAC, the reset bits behave in the same way: They disconnect the device
> + * and registers will have their default state after deasserting. For devices that have both reset
> + * bits, both need to be deasserted for the device to function.
> + */
> +struct zte_reset_reg {
> + u32 mask;
> + u16 reg;
> +};
> +
> +struct zte_reset_info {
> + const struct zte_reset_reg *resets;
> + unsigned int num;
> +};
> +
> +struct zte_reset {
> + struct reset_controller_dev rcdev;
> + struct regmap *map;
> + const struct zte_reset_reg *resets;
> +};
> +
> +static inline struct zte_reset *to_zte_reset(struct reset_controller_dev *rcdev)
> +{
> + return container_of(rcdev, struct zte_reset, rcdev);
> +}
> +
> +static int zx29_rst_assert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + struct zte_reset *rst = to_zte_reset(rcdev);
> +
> + return regmap_clear_bits(rst->map, rst->resets[id].reg, rst->resets[id].mask);
> +}
> +
> +static int zx29_rst_deassert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + struct zte_reset *rst = to_zte_reset(rcdev);
> +
> + return regmap_set_bits(rst->map, rst->resets[id].reg, rst->resets[id].mask);
> +}
> +
> +static int zx29_rst_status(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> + struct zte_reset *rst = to_zte_reset(rcdev);
> + int res;
> +
> + res = regmap_test_bits(rst->map, rst->resets[id].reg, rst->resets[id].mask);
The correct thing to do here would be to only check the reset bit.
This happens to work anyway because we always set reset and isolation
bits together, but maybe this warrants a comment.
I assume the registers just read back the value that was set.
> + if (res < 0)
> + return res;
> +
> + return !res;
> +}
> +
[...]
> +static int reset_zx297520v3_common_probe(struct device *dev,
> + struct device_node *of_node,
> + const struct zte_reset_info *drv_info)
> +{
> + struct zte_reset *rst;
> +
> + rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL);
> + if (!rst)
> + return -ENOMEM;
> +
> + rst->resets = drv_info->resets;
> + rst->rcdev.owner = THIS_MODULE;
> + rst->rcdev.nr_resets = drv_info->num;
> + rst->rcdev.ops = &zx29_rst_ops;
> + rst->rcdev.of_node = of_node;
> + rst->rcdev.dev = dev;
> +
> + rst->map = device_node_to_regmap(of_node);
> + if (IS_ERR(rst->map))
> + return dev_err_probe(dev, PTR_ERR(rst->map), "Cannot get parent syscon regmap\n");
> +
> + return devm_reset_controller_register(dev, &rst->rcdev);
> +
Unnecessary blank line.
> +}
> +
> +static int reset_zx297520v3_aux_probe(struct auxiliary_device *adev,
> + const struct auxiliary_device_id *id)
> +{
> + return reset_zx297520v3_common_probe(&adev->dev, adev->dev.of_node,
> + (const struct zte_reset_info *)id->driver_data);
> +}
> +
> +static int reset_zx297520v3_top_probe(struct platform_device *pdev)
> +{
> + return reset_zx297520v3_common_probe(&pdev->dev, pdev->dev.parent->of_node,
> + &zx297520v3_top_info);
> +}
> +
> +static struct platform_driver reset_zx297520v3_top = {
> + .probe = reset_zx297520v3_top_probe,
> + .driver = {
> + .name = "zx297520v3-toprst",
> + },
> +};
> +
> +static int reset_zx297520v3_matrix_probe(struct platform_device *pdev)
> +{
> + return reset_zx297520v3_common_probe(&pdev->dev, pdev->dev.parent->of_node,
> + &zx297520v3_matrix_info);
> +}
> +
> +static struct platform_driver reset_zx297520v3_matrix = {
> + .probe = reset_zx297520v3_matrix_probe,
> + .driver = {
> + .name = "zx297520v3-matrixrst",
> + },
> +};
> +
> +static const struct auxiliary_device_id reset_zx297520v3_ids[] = {
> + {
> + .name = "clk_zte.zx297520v3_lsprst",
> + .driver_data = (kernel_ulong_t)&zx297520v3_lsp_info,
> + },
> + { },
> +};
> +MODULE_DEVICE_TABLE(auxiliary, reset_zx297520v3_ids);
> +
> +static struct auxiliary_driver reset_zx297520v3_auxdrv = {
> + .name = "zx297520v3_lsp_reset",
> + .id_table = reset_zx297520v3_ids,
> + .probe = reset_zx297520v3_aux_probe,
> +};
> +
> +static struct platform_driver * const reset_zx297520v3_mfddrv[] = {
> + &reset_zx297520v3_top,
> + &reset_zx297520v3_matrix,
> +};
> +
> +static int __init reset_zx297520v3_init(void)
> +{
> + int res;
> +
> + res = auxiliary_driver_register(&reset_zx297520v3_auxdrv);
> + if (res)
> + return res;
> +
> + res = platform_register_drivers(reset_zx297520v3_mfddrv,
> + ARRAY_SIZE(reset_zx297520v3_mfddrv));
> + if (res)
> + auxiliary_driver_unregister(&reset_zx297520v3_auxdrv);
> +
> + return res;
> +}
> +
> +static void __exit reset_zx297520v3_exit(void)
> +{
> + platform_unregister_drivers(reset_zx297520v3_mfddrv,
> + ARRAY_SIZE(reset_zx297520v3_mfddrv));
> + auxiliary_driver_unregister(&reset_zx297520v3_auxdrv);
> +}
> +
> +module_init(reset_zx297520v3_init);
> +module_exit(reset_zx297520v3_exit);
That's too much boilerplate given I don't understand the benefit of
using platform_device for top/matrix resets yet.
regards
Philipp
^ permalink raw reply
* Re: [PATCH v2 0/5] netfilter: nf_flow_table_path: L2 bridge offload
From: Pablo Neira Ayuso @ 2026-06-30 8:45 UTC (permalink / raw)
To: Daniel Pawlik
Cc: netfilter-devel, netdev, fw, phil, davem, edumazet, kuba, pabeni,
horms, andrew+netdev, razor, idosch, matthias.bgg,
angelogioacchino.delregno, bridge, coreteam, linux-mediatek,
linux-arm-kernel, rchen14b, lorenzo
In-Reply-To: <20260630065735.3341614-1-pawlik.dan@gmail.com>
Hi,
On Tue, Jun 30, 2026 at 08:57:30AM +0200, Daniel Pawlik wrote:
> This series adds L2 bridge offload support to nft_flow_offload, allowing
> bridged IPv4/IPv6 flows to be accelerated by the flowtable fast path
> without requiring L3 routing.
>
> Background
> ----------
> Hardware flow offload engines (e.g. MediaTek PPE) can accelerate bridged
> traffic but require that nft_flow_offload detect and handle bridged flows
> differently from routed ones: no routing table lookup, MAC addresses from
> the Ethernet header, and VLAN context pre-populated from the bridge port.
>
> v2: Fix missing Returns: tags in kernel-doc comments for the three new
> bridge helpers (br_fdb_has_forwarding_entry_rcu,
> br_vlan_get_offload_info_rcu, br_vlan_is_enabled_rcu).
>
> Patches
> -------
> 1/5 net: export __dev_fill_forward_path
> Refactors dev_fill_forward_path() to expose __dev_fill_forward_path()
> which accepts a caller-supplied net_device_path_ctx, needed to
> pre-populate VLAN state before the forward path walk.
>
> 2/5 net: bridge: add flow offload helpers
> Adds br_fdb_has_forwarding_entry_rcu(), br_vlan_get_offload_info_rcu()
> and br_vlan_is_enabled_rcu() to expose bridge state to nft_flow_offload
> without requiring inclusion of net/bridge/br_private.h.
>
> 3/5 netfilter: nf_flow_table_path: add L2 bridge offload
> Core of the series. Adds nft_flow_offload_is_bridging() detection,
> nft_flow_route_bridging() which avoids nf_route() (fails for
> bridged-only subnets), MAC/VLAN pre-population for bridged flows,
> and a dst leak fix. nft_flow_route() becomes a thin dispatcher.
>
> 4/5 netfilter: nf_flow_table_path: handle DEV_PATH_MTK_WDMA in path info
> Fixes zero-source-MAC in PPE entries when a bridged flow traverses
> MT7996/MT7915 WiFi WDMA hardware.
>
> 5/5 netfilter: nf_flow_table_path: add VLAN passthrough support
> Records VLAN encap info for passthrough-mode bridge ports so hardware
> offload entries include the correct VLAN tag.
>
> Rebase note
> -----------
> Originally developed against OpenWrt pending-6.18 patches by Ryan Chen
> <rchen14b@gmail.com> and Bo-Cun Chen <bc-bocun.chen@mediatek.com>.
> Rebased to current upstream: path discovery infrastructure moved to
> nf_flow_table_path.c in commit 93d7a7ed0734 ("netfilter: flowtable: move
> path discovery infrastructure to its own file"), so all netfilter changes
> now land in that file rather than nft_flow_offload.c.
>
> How to enable bridge offload
> -----------------------------
> 1. Load kmod-br-netfilter so that bridged IP traffic traverses the
> netfilter forward chain.
>
> 2. Enable netfilter hooks on the bridge:
> echo 1 > /sys/class/net/<br>/bridge/nf_call_iptables
> echo 1 > /sys/class/net/<br>/bridge/nf_call_ip6tables
This requires br_netfilter which is a no go.
Sorry, but we should really target at the native nf_conntrack_bridge
support.
> 3. Register bridge member interfaces in the nft flowtable:
> table inet filter {
> flowtable f {
> hook ingress priority filter
> devices = { eth0, wlan0 }
> }
> chain forward {
> type filter hook forward priority filter
> meta l4proto { tcp, udp } flow add @f
> }
> }
Yes, but br_netfilter makes no sense for nftables.
br_netfilter was made to fill gap at the time ebtables was lagging a
lot behind iptables in terms of features. And getting ebtables on pair
with iptables in functionality was not feasible either, because it
required many new extensions that were specific of the bridge family,
which probably was not a big deal, but it also required to get
the ebtables command line tool on pair with iptables userspace, which
has received more development attention/effort that the bridge tool.
All of this does not stand true anymore with nftables, where the
bridge family capabilities are at pair with the inet families.
I am looking now at the native flowtable bridge support, I will get
back to you with updates.
^ permalink raw reply
* Re: [PATCH RFC v5 05/12] clk: zte: Add Clock registration infrastructure.
From: Stefan Dösinger @ 2026-06-30 8:53 UTC (permalink / raw)
To: Philipp Zabel
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Brian Masney, linux-clk, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <c59fab242716c80250a66707d7ccaaf243a85aac.camel@pengutronix.de>
[-- Attachment #1: Type: text/plain, Size: 754 bytes --]
Hi Philipp,
> Am 30.06.2026 um 11:27 schrieb Philipp Zabel <p.zabel@pengutronix.de>:
>
> I think the MFD driver is unnecessary overhead. Can't you just keep the
> reset controllers as auxdev and use of_platform_populate() to create
> devices for clock-controller child nodes such as syscon-reboot?
MFD for top and matrix was the suggestion of Conor:
https://lore.kernel.org/linux-arm-kernel/20260618-fantasy-estimate-6c52edbc6890@spud/
To quote:
> I think aux bus makes perfect sense when you have a clock/reset
> controller, but once you start expanding past that and you have reboot
> or hwmon or hwspinlock then mfd starts to make sense.
I can go either way. To me aux vs mfd seems like a distinction without a difference.
[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH v3] iommu/arm-smmu: Use pm_runtime in fault handlers
From: Prakash Gupta @ 2026-06-30 9:02 UTC (permalink / raw)
To: Will Deacon, Robin Murphy, Joerg Roedel, Rob Clark, Connor Abbott
Cc: linux-arm-msm, linux-arm-kernel, iommu, linux-kernel,
Akhil P Oommen, Pranjal Shrivastava, Pratyush Brahma,
Prakash Gupta
Commit d4a44f0750bb ("iommu/arm-smmu: Invoke pm_runtime across the driver")
enabled pm_runtime for the arm-smmu device. On systems where the SMMU
sits in a power domain, all register accesses must be done while the
device is runtime active to avoid unclocked register reads and
potential NoC errors.
So far, this has not been an issue for most SMMU clients because
stall-on-fault is enabled by default. While a translation fault is
being handled, the SMMU stalls further translations for that context
bank, so the fault handler would not race with a powered-down SMMU.
Adreno SMMU now disables stall-on-fault in the presence of fault
storms to avoid saturating SMMU resources and hanging the GMU. With
stall-on-fault disabled, the SMMU can generate faults while its power
domain may no longer be enabled, which makes unclocked accesses to
fault-status registers in the SMMU fault handlers possible.
Guard the context and global fault handlers with
arm_smmu_rpm_get_if_active() and arm_smmu_rpm_put() so that all SMMU
fault register accesses are done with the SMMU powered. If the SMMU is
not runtime active, the fault can be safely ignored as
arm_smmu_device_reset() clears fault registers on resume.
Additionally, disable fault reporting in arm_smmu_runtime_suspend()
before powering down. pm_runtime_get_if_active() returns 0 during
RPM_SUSPENDING, so without this, level-triggered fault interrupts would
cause an interrupt storm while the device is being suspended.
arm_smmu_device_reset() re-enables fault reporting on resume.
Fixes: b13044092c1e ("drm/msm: Temporarily disable stall-on-fault after a page fault")
Co-developed-by: Pratyush Brahma <pratyush.brahma@oss.qualcomm.com>
Signed-off-by: Pratyush Brahma <pratyush.brahma@oss.qualcomm.com>
Signed-off-by: Prakash Gupta <prakash.gupta@oss.qualcomm.com>
---
Changes in v3:
- Add arm_smmu_rpm_get_if_active() wrapper that returns 1 when pm_runtime
is disabled, ensuring fault handlers work on non-pm_runtime systems
- Disable fault reporting in arm_smmu_runtime_suspend() before powering
down to prevent interrupt storms during RPM_SUSPENDING state
- Use pm_runtime_put_autosuspend() in arm_smmu_rpm_put() instead of
private __pm_runtime_put_autosuspend()
- Link to v2: https://patch.msgid.link/20260313-smmu-rpm-v2-1-8c2236b402b0@oss.qualcomm.com
Changes in v2:
- Switched from arm_smmu_rpm_get()/arm_smmu_rpm_put() wrappers to
pm_runtime_get_if_active()/pm_runtime_put_autosuspend() APIs
- Added support for smmu->impl->global_fault callback in global fault handler
- Remove threaded irq context fault restriction to allow modifying stall
mode for adreno smmu
- Link to v1: https://patch.msgid.link/20260127-smmu-rpm-v1-1-2ef2f4c85305@oss.qualcomm.com
---
drivers/iommu/arm/arm-smmu/arm-smmu.c | 92 +++++++++++++++++++++++++----------
1 file changed, 67 insertions(+), 25 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 0bd21d206eb3..045389e89484 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -79,11 +79,16 @@ static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
{
- if (pm_runtime_enabled(smmu->dev)) {
- pm_runtime_mark_last_busy(smmu->dev);
- __pm_runtime_put_autosuspend(smmu->dev);
+ if (pm_runtime_enabled(smmu->dev))
+ pm_runtime_put_autosuspend(smmu->dev);
+}
- }
+static inline int arm_smmu_rpm_get_if_active(struct arm_smmu_device *smmu)
+{
+ if (!pm_runtime_enabled(smmu->dev))
+ return 1;
+
+ return pm_runtime_get_if_active(smmu->dev);
}
static void arm_smmu_rpm_use_autosuspend(struct arm_smmu_device *smmu)
@@ -462,10 +467,20 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
int idx = smmu_domain->cfg.cbndx;
int ret;
+ if (!arm_smmu_rpm_get_if_active(smmu))
+ return IRQ_NONE;
+
+ if (smmu->impl && smmu->impl->context_fault) {
+ ret = smmu->impl->context_fault(irq, dev);
+ goto out_power_off;
+ }
+
arm_smmu_read_context_fault_info(smmu, idx, &cfi);
- if (!(cfi.fsr & ARM_SMMU_CB_FSR_FAULT))
- return IRQ_NONE;
+ if (!(cfi.fsr & ARM_SMMU_CB_FSR_FAULT)) {
+ ret = IRQ_NONE;
+ goto out_power_off;
+ }
ret = report_iommu_fault(&smmu_domain->domain, NULL, cfi.iova,
cfi.fsynr & ARM_SMMU_CB_FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ);
@@ -480,7 +495,12 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
ret == -EAGAIN ? 0 : ARM_SMMU_RESUME_TERMINATE);
}
- return IRQ_HANDLED;
+ ret = IRQ_HANDLED;
+
+out_power_off:
+ arm_smmu_rpm_put(smmu);
+
+ return ret;
}
static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
@@ -489,14 +509,25 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
struct arm_smmu_device *smmu = dev;
static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
+ int ret;
+
+ if (!arm_smmu_rpm_get_if_active(smmu))
+ return IRQ_NONE;
+
+ if (smmu->impl && smmu->impl->global_fault) {
+ ret = smmu->impl->global_fault(irq, dev);
+ goto out_power_off;
+ }
gfsr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSR);
gfsynr0 = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSYNR0);
gfsynr1 = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSYNR1);
gfsynr2 = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSYNR2);
- if (!gfsr)
- return IRQ_NONE;
+ if (!gfsr) {
+ ret = IRQ_NONE;
+ goto out_power_off;
+ }
if (__ratelimit(&rs)) {
if (IS_ENABLED(CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT) &&
@@ -513,7 +544,11 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
}
arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sGFSR, gfsr);
- return IRQ_HANDLED;
+ ret = IRQ_HANDLED;
+
+out_power_off:
+ arm_smmu_rpm_put(smmu);
+ return ret;
}
static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
@@ -683,7 +718,6 @@ static int arm_smmu_init_domain_context(struct arm_smmu_domain *smmu_domain,
enum io_pgtable_fmt fmt;
struct iommu_domain *domain = &smmu_domain->domain;
struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
- irqreturn_t (*context_fault)(int irq, void *dev);
mutex_lock(&smmu_domain->init_mutex);
if (smmu_domain->smmu)
@@ -850,19 +884,14 @@ static int arm_smmu_init_domain_context(struct arm_smmu_domain *smmu_domain,
*/
irq = smmu->irqs[cfg->irptndx];
- if (smmu->impl && smmu->impl->context_fault)
- context_fault = smmu->impl->context_fault;
- else
- context_fault = arm_smmu_context_fault;
-
if (smmu->impl && smmu->impl->context_fault_needs_threaded_irq)
ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
- context_fault,
+ arm_smmu_context_fault,
IRQF_ONESHOT | IRQF_SHARED,
"arm-smmu-context-fault",
smmu_domain);
else
- ret = devm_request_irq(smmu->dev, irq, context_fault, IRQF_SHARED,
+ ret = devm_request_irq(smmu->dev, irq, arm_smmu_context_fault, IRQF_SHARED,
"arm-smmu-context-fault", smmu_domain);
if (ret < 0) {
@@ -2125,7 +2154,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
int num_irqs, i, err;
u32 global_irqs, pmu_irqs;
- irqreturn_t (*global_fault)(int irq, void *dev);
smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
if (!smmu) {
@@ -2205,18 +2233,13 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
smmu->num_context_irqs = smmu->num_context_banks;
}
- if (smmu->impl && smmu->impl->global_fault)
- global_fault = smmu->impl->global_fault;
- else
- global_fault = arm_smmu_global_fault;
-
for (i = 0; i < global_irqs; i++) {
int irq = platform_get_irq(pdev, i);
if (irq < 0)
return irq;
- err = devm_request_irq(dev, irq, global_fault, IRQF_SHARED,
+ err = devm_request_irq(dev, irq, arm_smmu_global_fault, IRQF_SHARED,
"arm-smmu global fault", smmu);
if (err)
return dev_err_probe(dev, err,
@@ -2306,6 +2329,25 @@ static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
{
struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+ int i;
+ u32 reg;
+
+ /*
+ * Disable fault reporting before powering down to prevent unclocked
+ * register accesses in the fault handlers if an interrupt races with
+ * the suspend callback (e.g. device in RPM_SUSPENDING state).
+ * arm_smmu_device_reset() re-enables fault reporting on resume.
+ */
+ reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sCR0);
+ reg &= ~(ARM_SMMU_sCR0_GFRE | ARM_SMMU_sCR0_GFIE |
+ ARM_SMMU_sCR0_GCFGFRE | ARM_SMMU_sCR0_GCFGFIE);
+ arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sCR0, reg);
+
+ for (i = 0; i < smmu->num_context_banks; i++) {
+ reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_SCTLR);
+ reg &= ~(ARM_SMMU_SCTLR_CFIE | ARM_SMMU_SCTLR_CFRE);
+ arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_SCTLR, reg);
+ }
clk_bulk_disable(smmu->num_clks, smmu->clks);
---
base-commit: ba3e43a9e601636f5edb54e259a74f96ca3b8fd8
change-id: 20251208-smmu-rpm-8bd67db93dca
Best regards,
--
Prakash Gupta <prakash.gupta@oss.qualcomm.com>
^ permalink raw reply related
* [PATCH 0/9] firmware: arm_scmi: Fix SCMI core cleanup paths
From: Sudeep Holla @ 2026-06-30 9:05 UTC (permalink / raw)
To: arm-scmi, linux-arm-kernel
Cc: Cristian Marussi, Sudeep Holla, Sudeep Holla, Sashiko
This series fixes a set of SCMI core and mailbox transport lifetime issues
found around device creation, channel setup failure and teardown paths.
They were mostly found by Sashiko[1] when reviewing some other series.
Posting these separately as the issues or the fixes are not related to [2]
Here is the attempt to fix them, some of them can be dropped if it is too
theoretical. I have addressed all the issues that made sense to me at the
time of reading the report.
The fixes tighten ownership of OF node references, make transport devices
reachable by explicit teardown without exposing them to normal SCMI driver
binding, and ensure partially initialized channels are unwound consistently on
probe/setup failures. The series also fixes races around requested-device
notifier teardown and RCU-protected protocol lookups.
The mailbox transport fixes are split by the feature that introduced the
leaking channel: one for unidirectional mailbox channels and one for P2A
completion channels.
Summary:
- Fix OF node reference ownership for generated SCMI devices.
- Allow explicit teardown lookup of internal transport devices.
- Clean up TX/RX channels when SCMI channel setup fails midway.
- Fix SCMI device lifetime handling around child lookup and bus ID reuse.
- Free transport resources when IDR insertion fails after channel setup.
- Unregister requested-device notifier before active protocol IDR teardown.
- Unwind mailbox channels on TX receiver and P2A receiver setup failures.
- Protect requested-device protocol lookup with RCU.
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
[1] https://sashiko.dev/#/patchset/20260525-acpi_scmi_pcc-v2-0-4f38938d08d8@arm.com
[2] https://patch.msgid.link/20260525-acpi_scmi_pcc-v2-0-4f38938d08d8@arm.com
---
Sudeep Holla (9):
firmware: arm_scmi: Fix OF node reference handling
firmware: arm_scmi: Fix transport device teardown lookup
firmware: arm_scmi: Clean up channels on setup failure
firmware: arm_scmi: Fix SCMI device destroy lifetimes
firmware: arm_scmi: Free transport channel on IDR failure
firmware: arm_scmi: Unregister device notifier before IDR teardown
firmware: arm_scmi: Unwind TX receiver mailbox setup failure
firmware: arm_scmi: Unwind P2A receiver mailbox setup failure
firmware: arm_scmi: Protect device request lookup with RCU
drivers/firmware/arm_scmi/bus.c | 50 +++++++++++++++++---------
drivers/firmware/arm_scmi/common.h | 2 ++
drivers/firmware/arm_scmi/driver.c | 21 ++++++-----
drivers/firmware/arm_scmi/transports/mailbox.c | 12 +++++--
4 files changed, 57 insertions(+), 28 deletions(-)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260629-scmi_core_fixes-da3cd753b4ea
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH 1/9] firmware: arm_scmi: Fix OF node reference handling
From: Sudeep Holla @ 2026-06-30 9:05 UTC (permalink / raw)
To: arm-scmi, linux-arm-kernel; +Cc: Cristian Marussi, Sudeep Holla, Sudeep Holla
In-Reply-To: <20260630-scmi_core_fixes-v1-0-f932c1e51992@kernel.org>
SCMI devices store the DT node in dev.of_node through
device_set_node(), but that helper only assigns the fwnode and
of_node pointers without taking an OF node reference.
Take a reference when assigning the node and release it from the
SCMI device release path. With the device owning that reference,
remove the separate channel-side get/put pair from the core driver.
Fixes: 96da4a99ce50 ("firmware: arm_scmi: Set fwnode for the scmi_device")
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
---
drivers/firmware/arm_scmi/bus.c | 3 ++-
drivers/firmware/arm_scmi/driver.c | 4 ----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 793be9eabaed..f643a1f0e282 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -395,6 +395,7 @@ static void scmi_device_release(struct device *dev)
{
struct scmi_device *scmi_dev = to_scmi_dev(dev);
+ of_node_put(dev->of_node);
kfree_const(scmi_dev->name);
kfree(scmi_dev);
}
@@ -465,7 +466,7 @@ __scmi_device_create(struct device_node *np, struct device *parent,
scmi_dev->id = id;
scmi_dev->protocol_id = protocol;
scmi_dev->dev.parent = parent;
- device_set_node(&scmi_dev->dev, of_fwnode_handle(np));
+ device_set_node(&scmi_dev->dev, of_fwnode_handle(of_node_get(np)));
scmi_dev->dev.bus = &scmi_bus_type;
scmi_dev->dev.release = scmi_device_release;
dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3e0d975ec94c..b9245238e293 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2778,13 +2778,11 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
devm_kfree(info->dev, cinfo);
return -EINVAL;
}
- of_node_get(of_node);
cinfo->id = prot_id;
cinfo->dev = &tdev->dev;
ret = info->desc->ops->chan_setup(cinfo, info->dev, tx);
if (ret) {
- of_node_put(of_node);
scmi_device_destroy(info->dev, prot_id, name);
devm_kfree(info->dev, cinfo);
return ret;
@@ -2807,7 +2805,6 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
"unable to allocate SCMI idr slot err %d\n", ret);
/* Destroy channel and device only if created by this call. */
if (tdev) {
- of_node_put(of_node);
scmi_device_destroy(info->dev, prot_id, name);
devm_kfree(info->dev, cinfo);
}
@@ -2892,7 +2889,6 @@ static int scmi_chan_destroy(int id, void *p, void *idr)
struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
struct scmi_device *sdev = to_scmi_dev(cinfo->dev);
- of_node_put(cinfo->dev->of_node);
scmi_device_destroy(info->dev, id, sdev->name);
cinfo->dev = NULL;
}
--
2.43.0
^ permalink raw reply related
* [PATCH 6/9] firmware: arm_scmi: Unregister device notifier before IDR teardown
From: Sudeep Holla @ 2026-06-30 9:06 UTC (permalink / raw)
To: arm-scmi, linux-arm-kernel
Cc: Cristian Marussi, Sudeep Holla, Sashiko, Sudeep Holla
In-Reply-To: <20260630-scmi_core_fixes-v1-0-f932c1e51992@kernel.org>
The requested-devices notifier looks up protocol fwnodes from the
active_protocols IDR. During remove, unregister the notifier before
releasing and destroying active_protocols so no notifier callback can race
with the IDR teardown.
Keep the bus notifier registered until after the protocol state is torn
down, matching the existing remove ordering for SCMI bus users.
Fixes: 53b8c25df708 ("firmware: arm_scmi: Add common notifier helpers")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
---
drivers/firmware/arm_scmi/driver.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 4b369b003003..6df0fe055d64 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -3402,6 +3402,9 @@ static void scmi_remove(struct platform_device *pdev)
scmi_notification_exit(&info->handle);
+ blocking_notifier_chain_unregister(&scmi_requested_devices_nh,
+ &info->dev_req_nb);
+
mutex_lock(&info->protocols_mtx);
idr_destroy(&info->protocols);
mutex_unlock(&info->protocols_mtx);
@@ -3410,8 +3413,6 @@ static void scmi_remove(struct platform_device *pdev)
of_node_put(child);
idr_destroy(&info->active_protocols);
- blocking_notifier_chain_unregister(&scmi_requested_devices_nh,
- &info->dev_req_nb);
bus_unregister_notifier(&scmi_bus_type, &info->bus_nb);
/* Safe to free channels since no more users */
--
2.43.0
^ permalink raw reply related
* [PATCH 7/9] firmware: arm_scmi: Unwind TX receiver mailbox setup failure
From: Sudeep Holla @ 2026-06-30 9:06 UTC (permalink / raw)
To: arm-scmi, linux-arm-kernel
Cc: Cristian Marussi, Sudeep Holla, Sashiko, Sudeep Holla
In-Reply-To: <20260630-scmi_core_fixes-v1-0-f932c1e51992@kernel.org>
mailbox_chan_setup() can request an additional unidirectional TX
receiver channel after successfully acquiring the primary channel. If
that second request fails, the function returns immediately and leaves
the primary channel allocated.
Unwind the primary mailbox channel before returning the error so probe
deferral or other setup failures do not leave the channel busy for later
probe attempts.
Fixes: 9f68ff79ec2c ("firmware: arm_scmi: Add support for unidirectional mailbox channels")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
---
drivers/firmware/arm_scmi/transports/mailbox.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/arm_scmi/transports/mailbox.c b/drivers/firmware/arm_scmi/transports/mailbox.c
index ae0f67e6cc45..44d45ce838e5 100644
--- a/drivers/firmware/arm_scmi/transports/mailbox.c
+++ b/drivers/firmware/arm_scmi/transports/mailbox.c
@@ -225,9 +225,10 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
smbox->chan_receiver = mbox_request_channel(cl, a2p_rx_chan);
if (IS_ERR(smbox->chan_receiver)) {
ret = PTR_ERR(smbox->chan_receiver);
+ smbox->chan_receiver = NULL;
if (ret != -EPROBE_DEFER)
dev_err(cdev, "failed to request SCMI Tx Receiver mailbox\n");
- return ret;
+ goto err_free_chan;
}
}
@@ -246,6 +247,10 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
mutex_init(&smbox->chan_lock);
return 0;
+
+err_free_chan:
+ mbox_free_channel(smbox->chan);
+ return ret;
}
static int mailbox_chan_free(int id, void *p, void *data)
--
2.43.0
^ permalink raw reply related
* [PATCH 9/9] firmware: arm_scmi: Protect device request lookup with RCU
From: Sudeep Holla @ 2026-06-30 9:06 UTC (permalink / raw)
To: arm-scmi, linux-arm-kernel
Cc: Cristian Marussi, Sudeep Holla, Sashiko, Sudeep Holla
In-Reply-To: <20260630-scmi_core_fixes-v1-0-f932c1e51992@kernel.org>
The SCMI device request notifier looks up protocol OF nodes from the
active_protocols IDR. The IDR lookup can run concurrently with protocol
activation while probe is still registering protocols and creating their
SCMI devices.
Wrap the lookup in an RCU read-side critical section as required by the
IDR API for lockless readers.
Fixes: 53b8c25df708 ("firmware: arm_scmi: Add common notifier helpers")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
---
drivers/firmware/arm_scmi/driver.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 6df0fe055d64..a575e661f1e2 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -33,6 +33,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/processor.h>
+#include <linux/rcupdate.h>
#include <linux/refcount.h>
#include <linux/slab.h>
#include <linux/xarray.h>
@@ -2957,7 +2958,9 @@ static int scmi_device_request_notifier(struct notifier_block *nb,
struct scmi_device_id *id_table = data;
struct scmi_info *info = req_nb_to_scmi_info(nb);
+ rcu_read_lock();
np = idr_find(&info->active_protocols, id_table->protocol_id);
+ rcu_read_unlock();
if (!np)
return NOTIFY_DONE;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH RFC v8 01/24] mm: Introduce kpkeys
From: Kevin Brodsky @ 2026-06-30 9:11 UTC (permalink / raw)
To: David Hildenbrand (Arm), Linus Walleij
Cc: linux-hardening, Andrew Morton, Andy Lutomirski, Catalin Marinas,
Dave Hansen, Ira Weiny, Jann Horn, Jeff Xu, Joey Gouly, Kees Cook,
Marc Zyngier, Mark Brown, Matthew Wilcox, Maxwell Bland,
Mike Rapoport (IBM), Peter Zijlstra, Pierre Langlois,
Quentin Perret, Rick Edgecombe, Ryan Roberts, Vlastimil Babka,
Will Deacon, Yang Shi, Yeoreum Yun, linux-arm-kernel, linux-mm,
x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <9b11b0c0-dfc7-45ba-934e-19cd053e5635@kernel.org>
On 22/06/2026 20:38, David Hildenbrand (Arm) wrote:
> On 6/18/26 15:22, Linus Walleij wrote:
>> On Tue, Jun 16, 2026 at 5:19 PM David Hildenbrand (Arm)
>> <david@kernel.org> wrote:
>>
>>> Looking at this, and wondering about "why do we get registers involved in this
>>> API" I would probably have an interface like:
>>>
>>> arch_kpkeys_enter_context()
>>> arch_kpkeys_leave_context()
>>>
>>> Whereby you return a "struct kpkeys_state" or sth like that.
>> This is close to what I was looking for as well.
> Cool :)
That's probably what I was looking for too, without knowing it!
>> enter/leave makes the code look more like generic entry.
>>
>> Passing some kind of state cookie around is inevitable in
>> this design and IIUC Kevin argued that it would be inefficient
>> (another level of abstraction) as opposed to just hammering
>> in the context we want, where we want it.
I must have misunderstood what you meant in your previous comments, I
don't have a concern with performance here.
>>
>> But I think the compiler will optimize that out by constant
>> propagation if the backing architecture implementation is
>> simple.
> Yes, it should be wrapped somehow. I don't think this will be a problem
> performance-wise that cannot be solved differently.
>
> Returning an u64 ("register") here is really arm64-sepcific and should be
> abstracted.
Agreed. All this looks very much like the new lazy MMU API, and doing
something along the same lines seems perfectly reasonable.
- Kevin
^ permalink raw reply
* [RESEND PATCH v3] coresight: etm-perf: Fix reference count leak in etm_setup_aux
From: Ma Ke @ 2026-06-30 9:11 UTC (permalink / raw)
To: suzuki.poulose, mike.leach, james.clark, leo.yan,
alexander.shishkin, mathieu.poirier
Cc: coresight, linux-arm-kernel, linux-kernel, akpm, Ma Ke, stable
bus_find_device() returns a device with its reference count
incremented. When a user-selected sink is obtained through
coresight_get_sink_by_id(), etm_setup_aux() keeps using the returned
sink while building the path and allocating the sink buffer.
Therefore the lookup reference must remain valid while etm_setup_aux()
is still using the sink, otherwise the sink could be removed under the
caller. Drop the lookup reference on the common exit path, after
etm_setup_aux() no longer directly uses the user-selected sink.
The CoreSight path code takes the references it needs for built paths,
so the initial lookup reference from coresight_get_sink_by_id() is no
longer needed after setup_aux finishes.
Found by code review.
Signed-off-by: Ma Ke <make_ruc2021@163.com>
Cc: stable@vger.kernel.org
Fixes: 0e6c20517596 ("coresight: etm-perf: Allow an event to use different sinks")
---
Changes in v3:
- do not drop the lookup reference in coresight_get_sink_by_id(), as
that would return a sink pointer without keeping the device reference
while etm_setup_aux() is still using it.
- dropped the lookup reference in etm_setup_aux on the common exit path,
as suggested by Suzuki.
- updated the commit message to describe why the reference is kept
until etm_setup_aux() finishes using the sink.
Changes in v2:
- modified the patch as suggestions.
---
drivers/hwtracing/coresight/coresight-etm-perf.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 09b21a711a87..a25985743b7f 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -509,6 +509,11 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
goto err;
out:
+ if (user_sink) {
+ put_device(&user_sink->dev);
+ user_sink = NULL;
+ }
+
return event_data;
err:
--
2.43.0
^ permalink raw reply related
* Re: [PATCH RFC v8 01/24] mm: Introduce kpkeys
From: Kevin Brodsky @ 2026-06-30 9:13 UTC (permalink / raw)
To: David Hildenbrand (Arm), linux-hardening
Cc: Andrew Morton, Andy Lutomirski, Catalin Marinas, Dave Hansen,
Ira Weiny, Jann Horn, Jeff Xu, Joey Gouly, Kees Cook,
Linus Walleij, Marc Zyngier, Mark Brown, Matthew Wilcox,
Maxwell Bland, Mike Rapoport (IBM), Peter Zijlstra,
Pierre Langlois, Quentin Perret, Rick Edgecombe, Ryan Roberts,
Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <70f4dcdf-c45f-47d3-91df-a7897bd86ff4@kernel.org>
On 16/06/2026 17:19, David Hildenbrand (Arm) wrote:
> On 5/26/26 13:15, Kevin Brodsky wrote:
>> kpkeys is a simple framework to enable the use of protection keys
>> (pkeys) to harden the kernel itself. This patch introduces the basic
>> API in <linux/kpkeys.h>: a couple of functions to set and restore
>> the pkey register and macros to define guard objects.
>>
>> kpkeys introduces a new concept on top of pkeys: the kpkeys context.
>> Each context is associated to a set of permissions for the pkeys
>> managed by the kpkeys framework. kpkeys_set_context(ctx) sets those
>> permissions according to ctx, and returns the original pkey
>> register, to be later restored by kpkeys_restore_pkey_reg(). To
>> start with, only KPKEYS_CTX_DEFAULT is available, which is meant to
>> grant RW access to KPKEYS_PKEY_DEFAULT (i.e. all memory since this
>> is the only available pkey for now).
>>
>> Because each architecture implementing pkeys uses a different
>> representation for the pkey register, and may reserve certain pkeys
>> for specific uses, support for kpkeys must be explicitly indicated
>> by selecting ARCH_HAS_KPKEYS and defining the following functions in
>> <asm/kpkeys.h>, in addition to the macros provided in
>> <asm-generic/kpkeys.h>:
>>
>> - arch_kpkeys_set_context()
>> - arch_kpkeys_restore_pkey_reg()
> Looking at this, and wondering about "why do we get registers involved in this
> API" I would probably have an interface like:
>
> arch_kpkeys_enter_context()
> arch_kpkeys_leave_context()
>
> Whereby you return a "struct kpkeys_state" or sth like that.
>
> You could either let the architecture define what's in the state, or
> alternatively store some generic data in there as well.
>
> struct kpkeys_state {
> bool entered_context;
> struct arch_pkey_state arch;
> };
>
> Maybe the "entered_context" or however you would want to call it could avoid the
> KPKEYS_PKEY_REG_INVAL (which confuses me ;) )?
Yep that would do the trick. And would make Sashiko happier too, using a
magic register value isn't great ;)
> But the KPKEYS_PKEY_REG_INVAL usage confuses me. I understand the
> KPKEYS_GUARD_COND + kpkeys_restore_pkey_reg() one, but not the one where
> arch_kpkeys_set_context() would return that value.
Right, that's used in a follow-up series to protect struct cred, so that
unnecessary switches are avoided in case of nesting [1]. I wonder if I
shouldn't fold that patch into this one. I don't think nesting is likely
to occur in this series, but the extra branch probably doesn't add much
cost either (it's easily predicted).
[1]
https://lore.kernel.org/linux-mm/20250815090000.2182450-2-kevin.brodsky@arm.com/
>> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
>> ---
>> include/asm-generic/kpkeys.h | 17 ++++++
>> include/linux/kpkeys.h | 122 +++++++++++++++++++++++++++++++++++++++++++
>> mm/Kconfig | 2 +
>> 3 files changed, 141 insertions(+)
>>
>> diff --git a/include/asm-generic/kpkeys.h b/include/asm-generic/kpkeys.h
>> new file mode 100644
>> index 000000000000..ab819f157d6a
>> --- /dev/null
>> +++ b/include/asm-generic/kpkeys.h
>> @@ -0,0 +1,17 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +#ifndef __ASM_GENERIC_KPKEYS_H
>> +#define __ASM_GENERIC_KPKEYS_H
>> +
>> +#ifndef KPKEYS_PKEY_DEFAULT
>> +#define KPKEYS_PKEY_DEFAULT 0
>> +#endif
> Do we currently expect an architecture to overwrite this? How does this interact
> with KPKEYS_CTX_DEFAULT?
That's a fair point, pkey 0 being the default is pretty much hardcoded
and I don't see that ever changing.
The value isn't coupled to that of KPKEYS_CTX_DEFAULT, which is purely
symbolic.
> Nobody in this patch uses it, so maybe it should be added where actually needed.
Agreed, the ifdefery can be removed.
>> [...]
>>
>> +/**
>> + * kpkeys_set_context() - switch kpkeys context
>> + * @ctx: the context to switch to
>> + *
>> + * Switches to specified kpkeys context. @ctx must be a compile-time
>> + * constant. The arch-specific pkey register will be updated accordingly, and
>> + * the original value returned.
> Are these arch details and registers relevant? Ideally, we'd keep it very simple
> here ...
>
>> + *
>> + * Return: the original pkey register value if the register was written to, or
>> + * KPKEYS_PKEY_REG_INVAL otherwise (no write to the register was
>> + * required).
> ... and here. Not sure if any caller cares about these details. Again, with some
> abstract state we could maybe handle that internally.
>
> "Return: the pkey state to pass to kpkeys_restore_pkey_reg" (or however that
> function will be called)
Yep agreed.
>> + */
>> +static __always_inline u64 kpkeys_set_context(int ctx)
>> +{
>> + BUILD_BUG_ON_MSG(!__builtin_constant_p(ctx),
>> + "kpkeys_set_context() only takes constant values");
>> + BUILD_BUG_ON_MSG(ctx < KPKEYS_CTX_MIN || ctx > KPKEYS_CTX_MAX,
>> + "Invalid value passed to kpkeys_set_context()");
>> +
>> + return arch_kpkeys_set_context(ctx);
>> +}
>> +
>> +/**
>> + * kpkeys_restore_pkey_reg() - restores a pkey register value
>> + * @pkey_reg: the pkey register value to restore
>> + *
>> + * This function is meant to be passed the value returned by
>> + * kpkeys_set_context(), in order to restore the pkey register to its original
>> + * value (thus restoring the original kpkeys context).
>> + */
>> +static __always_inline void kpkeys_restore_pkey_reg(u64 pkey_reg)
>> +{
>> + if (pkey_reg != KPKEYS_PKEY_REG_INVAL)
>> + arch_kpkeys_restore_pkey_reg(pkey_reg);
>> +}
>> +
>> +static inline bool kpkeys_enabled(void)
> Is the enabled vs. supported intentional?
That's a fair point. It is intentional for
kpkeys_hardened_pgtables*_enabled() in patch 11: on arm64,
arch_supports_kpkeys*() always return true if POE is detected, while
kpkeys_hardened_pgtables*_enabled() also require
CONFIG_KPKEYS_HARDENED_PGTABLES=y.
For kpkeys_enabled() the condition is CONFIG_ARCH_HAS_KPKEYS=y, which is
always true if we support POE. So it would be reasonable to rename it to
kpkeys_supported() (and maybe more intuitive, since it doesn't imply any
functional change).
Thanks for the very useful suggestions and sorry for the late replies!
- Kevin
>> +{
>> + return arch_supports_kpkeys();
>> +}
>> +
>
>
^ permalink raw reply
* Re: [PATCH RFC v8 02/24] set_memory: Introduce set_memory_pkey() stub
From: Kevin Brodsky @ 2026-06-30 9:14 UTC (permalink / raw)
To: David Hildenbrand (Arm), linux-hardening
Cc: Andrew Morton, Andy Lutomirski, Catalin Marinas, Dave Hansen,
Ira Weiny, Jann Horn, Jeff Xu, Joey Gouly, Kees Cook,
Linus Walleij, Marc Zyngier, Mark Brown, Matthew Wilcox,
Maxwell Bland, Mike Rapoport (IBM), Peter Zijlstra,
Pierre Langlois, Quentin Perret, Rick Edgecombe, Ryan Roberts,
Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <e026ab6b-aee2-48e7-9bb5-1735d7a23859@kernel.org>
On 16/06/2026 17:41, David Hildenbrand (Arm) wrote:
> On 5/26/26 13:15, Kevin Brodsky wrote:
>> Introduce a new function, set_memory_pkey(), which sets the
>> protection key (pkey) of pages in the specified linear mapping
>> range. Architectures implementing kernel pkeys (kpkeys) must
>> provide a suitable implementation; an empty stub is added as
>> fallback.
>>
>> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
>> ---
>> include/linux/set_memory.h | 7 +++++++
>> 1 file changed, 7 insertions(+)
>>
>> diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
>> index 3030d9245f5a..7b3a8bfde3c6 100644
>> --- a/include/linux/set_memory.h
>> +++ b/include/linux/set_memory.h
>> @@ -84,4 +84,11 @@ static inline int set_memory_decrypted(unsigned long addr, int numpages)
>> }
>> #endif /* CONFIG_ARCH_HAS_MEM_ENCRYPT */
>>
>> +#ifndef CONFIG_ARCH_HAS_KPKEYS
>> +static inline int set_memory_pkey(unsigned long addr, int numpages, int pkey)
>> +{
>> + return 0;
>> +}
>> +#endif
>> +
>> #endif /* _LINUX_SET_MEMORY_H_ */
>>
> This patch looks rather odd, given that this is just a stub that won't be used
> before patch #20.
>
> And there, it's only used from arm64 code? So why do we need the common-code stub?
It is primarily used in patch 12, the generic kpkeys page table
allocator, so we do need a stub.
The ordering might be a little confusing indeed, but I tried to follow
the following order: 1. kpkeys/generic, 2. kpkeys/arm64, 3.
kpkeys_hardened_pgtables/generic, 4. kpkeys_hardened_pgtables/arm64.
Happy to reorder if you have other preferences.
- Kevin
^ permalink raw reply
* Re: [PATCH 09/27] ASoC: codecs: idt821034: Use guard() for mutex locks
From: Bui Duc Phuc @ 2026-06-30 9:14 UTC (permalink / raw)
To: Herve Codina
Cc: Mark Brown, Takashi Iwai, Nick Li, Support Opensource,
Liam Girdwood, Jaroslav Kysela, Srinivas Kandagatla,
Charles Keepax, Richard Fitzgerald, Matthias Brugger,
AngeloGioacchino Del Regno, Shenghao Ding, Kevin Lu, Baojun Xu,
Sen Wang, Oder Chiou, Linus Walleij, Kuninori Morimoto,
u.kleine-koenig, Zhang Yi, Marco Crivellari, Kees Cook,
HyeongJun An, Arnd Bergmann, Qianfeng Rong, linux-sound,
linux-kernel, patches, linux-mediatek, linux-arm-msm,
linux-arm-kernel
In-Reply-To: <20260630092821.650c30ec@bootlin.com>
On Tue, Jun 30, 2026 at 2:28 PM Herve Codina <herve.codina@bootlin.com> wrote:
>
> Hi,
>
> On Tue, 30 Jun 2026 13:34:31 +0700
> phucduc.bui@gmail.com wrote:
>
> > From: bui duc phuc <phucduc.bui@gmail.com>
> >
> > Clean up the code using guard() for mutex locks.
> > Merely code refactoring, and no behavior change.
> >
> > Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
> > ---
> > sound/soc/codecs/idt821034.c | 121 +++++++++++++++--------------------
> > 1 file changed, 51 insertions(+), 70 deletions(-)
> >
> > diff --git a/sound/soc/codecs/idt821034.c b/sound/soc/codecs/idt821034.c
> > index 084090ccef77..078de6c9c395 100644
> > --- a/sound/soc/codecs/idt821034.c
> > +++ b/sound/soc/codecs/idt821034.c
> > @@ -6,6 +6,7 @@
> > //
> > // Author: Herve Codina <herve.codina@bootlin.com>
> >
> > +#include <linux/cleanup.h>
> > #include <linux/bitrev.h>
> > #include <linux/gpio/driver.h>
> > #include <linux/module.h>
>
> Alphabetic order. Move <linux/cleanup.h> after <linux/bitrev.h>.
>
> ...
>
> > @@ -456,7 +457,7 @@ static int idt821034_kctrl_gain_put(struct snd_kcontrol *kcontrol,
> >
> > ch = IDT821034_ID_GET_CHAN(mc->reg);
> >
> > - mutex_lock(&idt821034->mutex);
> > + guard(mutex)(&idt821034->mutex);
> >
> > if (IDT821034_ID_IS_OUT(mc->reg)) {
> > amp = &idt821034->amps.ch[ch].amp_out;
> > @@ -466,21 +467,18 @@ static int idt821034_kctrl_gain_put(struct snd_kcontrol *kcontrol,
> > gain_type = IDT821034_GAIN_TX;
> > }
> >
> > - if (amp->gain == val) {
> > - ret = 0;
> > - goto end;
> > - }
> > + if (amp->gain == val)
> > + return 0;
> >
> > if (!amp->is_muted) {
> > ret = idt821034_set_gain_channel(idt821034, ch, gain_type, val);
> > if (ret)
> > - goto end;
> > + return ret;
> > }
> >
> > amp->gain = val;
> > ret = 1; /* The value changed */
> > -end:
> > - mutex_unlock(&idt821034->mutex);
> > +
> > return ret;
>
> Instead of
> ret = 1; /* The value changed */
> return ret;
>
> Call directly
> return 1; /* The value changed */
>
> > }
>
> ...
> > @@ -521,7 +519,7 @@ static int idt821034_kctrl_mute_put(struct snd_kcontrol *kcontrol,
> > ch = IDT821034_ID_GET_CHAN(id);
> > is_mute = !ucontrol->value.integer.value[0];
> >
> > - mutex_lock(&idt821034->mutex);
> > + guard(mutex)(&idt821034->mutex);
> >
> > if (IDT821034_ID_IS_OUT(id)) {
> > amp = &idt821034->amps.ch[ch].amp_out;
> > @@ -531,20 +529,17 @@ static int idt821034_kctrl_mute_put(struct snd_kcontrol *kcontrol,
> > gain_type = IDT821034_GAIN_TX;
> > }
> >
> > - if (amp->is_muted == is_mute) {
> > - ret = 0;
> > - goto end;
> > - }
> > + if (amp->is_muted == is_mute)
> > + return 0;
> >
> > ret = idt821034_set_gain_channel(idt821034, ch, gain_type,
> > is_mute ? 0 : amp->gain);
> > if (ret)
> > - goto end;
> > + return ret;
> >
> > amp->is_muted = is_mute;
> > ret = 1; /* The value changed */
> > -end:
> > - mutex_unlock(&idt821034->mutex);
> > +
> > return ret;
>
> Instead of
> ret = 1; /* The value changed */
> return ret;
>
> Call directly
> return 1; /* The value changed */
>
> > }
> >
> > @@ -629,7 +624,7 @@ static int idt821034_power_event(struct snd_soc_dapm_widget *w,
> > ch = IDT821034_ID_GET_CHAN(id);
> > mask = IDT821034_ID_IS_OUT(id) ? IDT821034_CONF_PWRUP_RX : IDT821034_CONF_PWRUP_TX;
> >
> > - mutex_lock(&idt821034->mutex);
> > + guard(mutex)(&idt821034->mutex);
> >
> > power = idt821034_get_channel_power(idt821034, ch);
> > if (SND_SOC_DAPM_EVENT_ON(event))
> > @@ -638,8 +633,6 @@ static int idt821034_power_event(struct snd_soc_dapm_widget *w,
> > power &= ~mask;
> > ret = idt821034_set_channel_power(idt821034, ch, power);
> >
> > - mutex_unlock(&idt821034->mutex);
> > -
> > return ret;
>
> Instead of
> ret = idt821034_set_channel_power(idt821034, ch, power);
> return ret;
>
> return directly:
>
> return idt821034_set_channel_power(idt821034, ch, power);
>
> and remove the 'ret' variable (no more used)
>
> > }
> >
>
> ...
> > @@ -771,7 +764,7 @@ static int idt821034_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> > u8 conf;
> > int ret;
> >
> > - mutex_lock(&idt821034->mutex);
> > + guard(mutex)(&idt821034->mutex);
> >
> > conf = idt821034_get_codec_conf(idt821034);
> >
> > @@ -785,12 +778,10 @@ static int idt821034_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> > default:
> > dev_err(dai->dev, "Unsupported DAI format 0x%x\n",
> > fmt & SND_SOC_DAIFMT_FORMAT_MASK);
> > - ret = -EINVAL;
> > - goto end;
> > + return -EINVAL;
> > }
> > ret = idt821034_set_codec_conf(idt821034, conf);
> > -end:
> > - mutex_unlock(&idt821034->mutex);
> > +
> > return ret;
>
> Instead of
> ret = idt821034_set_codec_conf(idt821034, conf);
> return ret;
>
> return directly:
> return idt821034_set_codec_conf(idt821034, conf);
>
> and remove the 'ret' variable.
>
> > }
> >
> > @@ -802,7 +793,7 @@ static int idt821034_dai_hw_params(struct snd_pcm_substream *substream,
> > u8 conf;
> > int ret;
> >
> > - mutex_lock(&idt821034->mutex);
> > + guard(mutex)(&idt821034->mutex);
> >
> > conf = idt821034_get_codec_conf(idt821034);
> >
> > @@ -816,12 +807,10 @@ static int idt821034_dai_hw_params(struct snd_pcm_substream *substream,
> > default:
> > dev_err(dai->dev, "Unsupported PCM format 0x%x\n",
> > params_format(params));
> > - ret = -EINVAL;
> > - goto end;
> > + return -EINVAL;
> > }
> > ret = idt821034_set_codec_conf(idt821034, conf);
> > -end:
> > - mutex_unlock(&idt821034->mutex);
> > +
> > return ret;
>
> Idem here:
> return idt821034_set_codec_conf(idt821034, conf);
>
> and remove 'ret'.
>
>
> > }
> >
> > @@ -897,11 +886,11 @@ static int idt821034_reset_audio(struct idt821034 *idt821034)
> > int ret;
> > u8 i;
> >
> > - mutex_lock(&idt821034->mutex);
> > + guard(mutex)(&idt821034->mutex);
> >
> > ret = idt821034_set_codec_conf(idt821034, 0);
> > if (ret)
> > - goto end;
> > + return ret;
> >
> > for (i = 0; i < IDT821034_NB_CHANNEL; i++) {
> > idt821034->amps.ch[i].amp_out.gain = IDT821034_GAIN_OUT_INIT_RAW;
> > @@ -909,23 +898,22 @@ static int idt821034_reset_audio(struct idt821034 *idt821034)
> > ret = idt821034_set_gain_channel(idt821034, i, IDT821034_GAIN_RX,
> > idt821034->amps.ch[i].amp_out.gain);
> > if (ret)
> > - goto end;
> > + return ret;
> >
> > idt821034->amps.ch[i].amp_in.gain = IDT821034_GAIN_IN_INIT_RAW;
> > idt821034->amps.ch[i].amp_in.is_muted = false;
> > ret = idt821034_set_gain_channel(idt821034, i, IDT821034_GAIN_TX,
> > idt821034->amps.ch[i].amp_in.gain);
> > if (ret)
> > - goto end;
> > + return ret;
> >
> > ret = idt821034_set_channel_power(idt821034, i, 0);
> > if (ret)
> > - goto end;
> > + return ret;
> > }
> >
> > ret = 0;
> > -end:
> > - mutex_unlock(&idt821034->mutex);
> > +
> > return ret;
>
> Instead of
> ret = 0;
> return ret;
>
> return directly
> return 0;
>
> > }
> >
> ...
>
> >
> > @@ -1079,23 +1061,22 @@ static int idt821034_reset_gpio(struct idt821034 *idt821034)
> > int ret;
> > u8 i;
> >
> > - mutex_lock(&idt821034->mutex);
> > + guard(mutex)(&idt821034->mutex);
> >
> > /* IO0 and IO1 as input for all channels and output IO set to 0 */
> > for (i = 0; i < IDT821034_NB_CHANNEL; i++) {
> > ret = idt821034_set_slic_conf(idt821034, i,
> > IDT821034_SLIC_IO1_IN | IDT821034_SLIC_IO0_IN);
> > if (ret)
> > - goto end;
> > + return ret;
> >
> > ret = idt821034_write_slic_raw(idt821034, i, 0);
> > if (ret)
> > - goto end;
> > + return ret;
> >
> > }
> > ret = 0;
> > -end:
> > - mutex_unlock(&idt821034->mutex);
> > +
> > return ret;
>
> return 0;
>
> > }
> >
>
> Best regards,
> Hervé
>
Hi Hervé,
Thank you for the very detailed review.
I hadn't realized I had missed so many issues.
I'll fix them all and include the updates in v2.
Best regards,
Phuc
^ permalink raw reply
* Re: [PATCH RFC v8 04/24] arm64: Introduce por_elx_set_pkey_perms() helper
From: Kevin Brodsky @ 2026-06-30 9:15 UTC (permalink / raw)
To: David Hildenbrand (Arm), linux-hardening
Cc: Andrew Morton, Andy Lutomirski, Catalin Marinas, Dave Hansen,
Ira Weiny, Jann Horn, Jeff Xu, Joey Gouly, Kees Cook,
Linus Walleij, Marc Zyngier, Mark Brown, Matthew Wilcox,
Maxwell Bland, Mike Rapoport (IBM), Peter Zijlstra,
Pierre Langlois, Quentin Perret, Rick Edgecombe, Ryan Roberts,
Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <e334c595-92ab-4eb9-a096-35602d57ae6d@kernel.org>
On 22/06/2026 15:16, David Hildenbrand (Arm) wrote:
> On 5/26/26 13:15, Kevin Brodsky wrote:
>> Introduce a helper that sets the permissions of a given pkey
>> (POIndex) in the POR_ELx format, and make use of it in
>> arch_set_user_pkey_access().
>>
>> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
>> ---
>> arch/arm64/include/asm/por.h | 7 +++++++
>> arch/arm64/mm/mmu.c | 26 ++++++++++----------------
>> 2 files changed, 17 insertions(+), 16 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/por.h b/arch/arm64/include/asm/por.h
>> index d913d5b529e4..bffb4d2b1246 100644
>> --- a/arch/arm64/include/asm/por.h
>> +++ b/arch/arm64/include/asm/por.h
>> @@ -31,4 +31,11 @@ static inline bool por_elx_allows_exec(u64 por, u8 pkey)
>> return perm & POE_X;
>> }
>>
>> +static inline u64 por_elx_set_pkey_perms(u64 por, u8 pkey, u64 perms)
>> +{
>> + u64 shift = POR_ELx_PERM_SHIFT(pkey);
>> +
>> + return (por & ~(POE_MASK << shift)) | (perms << shift);
>> +}
>> +
>> #endif /* _ASM_ARM64_POR_H */
>> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
>> index dd85e093ffdb..493310cf0486 100644
>> --- a/arch/arm64/mm/mmu.c
>> +++ b/arch/arm64/mm/mmu.c
>> @@ -2339,8 +2339,8 @@ void __cpu_replace_ttbr1(pgd_t *pgdp, bool cnp)
>> #ifdef CONFIG_ARCH_HAS_PKEYS
>> int arch_set_user_pkey_access(int pkey, unsigned long init_val)
>> {
>> - u64 new_por;
>> - u64 old_por;
>> + u64 new_perms;
> You should spell out the renaming of the variable.
Sure, will do.
> Given that perms is 4bit per key, should we use a u8 for it instead?
We could, in fact I'm just noticing that this all very inconsistent
right now: the POE_* constants are defined as UL, but por_elx_allows_*
and other functions use u8. I'll clean that up in a separate patch and
use u8 here.
>> + u64 por;
>>
>> if (!system_supports_poe())
>> return -ENOSPC;
>> @@ -2354,25 +2354,19 @@ int arch_set_user_pkey_access(int pkey, unsigned long init_val)
>> return -EINVAL;
>>
>> /* Set the bits we need in POR: */
>> - new_por = POE_RWX;
>> + new_perms = POE_RWX;
>> if (init_val & PKEY_DISABLE_WRITE)
>> - new_por &= ~POE_W;
>> + new_perms &= ~POE_W;
>> if (init_val & PKEY_DISABLE_ACCESS)
>> - new_por &= ~POE_RW;
>> + new_perms &= ~POE_RW;
>> if (init_val & PKEY_DISABLE_READ)
>> - new_por &= ~POE_R;
>> + new_perms &= ~POE_R;
>> if (init_val & PKEY_DISABLE_EXECUTE)
>> - new_por &= ~POE_X;
>> + new_perms &= ~POE_X;
>>
>> - /* Shift the bits in to the correct place in POR for pkey: */
>> - new_por = POR_ELx_PERM_PREP(pkey, new_por);
>> -
>> - /* Get old POR and mask off any old bits in place: */
>> - old_por = read_sysreg_s(SYS_POR_EL0);
>> - old_por &= ~(POE_MASK << POR_ELx_PERM_SHIFT(pkey));
>> -
>> - /* Write old part along with new part: */
>> - write_sysreg_s(old_por | new_por, SYS_POR_EL0);
>> + por = read_sysreg_s(SYS_POR_EL0);
>> + por = por_elx_set_pkey_perms(por, pkey, new_perms);
>> + write_sysreg_s(por, SYS_POR_EL0);
> Was wondering whether to move reading+writing of the register into the same
> helper, but you cannot reuse this exactly the same way for SYS_POR_EL1 as it seems.
It wouldn't be useful because the new user of the helper,
por_set_kpkeys_context(), doesn't itself read or write the register.
> Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Thanks!
- Kevin
^ permalink raw reply
* [PATCH v4 09/10] riscv: kdump: exclude non-dumpable reserved memory regions from vmcore
From: Wandun Chen @ 2026-06-30 7:47 UTC (permalink / raw)
To: chenhuacai, kernel, pjw, palmer, aou, robh, saravanak, bhe, rppt,
linux-arm-kernel, linux-kernel, loongarch, linux-riscv,
devicetree, kexec, iommu, zhaomeijing
Cc: catalin.marinas, will, alex, akpm, pasha.tatashin, pratyush,
ruirui.yang, m.szyprowski, robin.murphy
In-Reply-To: <20260630074715.4126796-1-chenwandun1@gmail.com>
From: Wandun Chen <chenwandun@lixiang.com>
Apply the same non-dumpable reserved memory filtering to RISC-V kdump
as was done for arm64. Use of_reserved_mem_kdump_exclude() to drop
flagged regions from the elfcorehdr PT_LOAD segments, and
of_reserved_mem_kdump_nr_ranges() to pre-size the crash_mem array.
Signed-off-by: Wandun Chen <chenwandun@lixiang.com>
---
arch/riscv/kernel/machine_kexec_file.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/riscv/kernel/machine_kexec_file.c b/arch/riscv/kernel/machine_kexec_file.c
index 59d4bbc848a8..25359d583bc3 100644
--- a/arch/riscv/kernel/machine_kexec_file.c
+++ b/arch/riscv/kernel/machine_kexec_file.c
@@ -10,6 +10,7 @@
#include <linux/elf.h>
#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/of_reserved_mem.h>
#include <linux/libfdt.h>
#include <linux/types.h>
#include <linux/memblock.h>
@@ -64,6 +65,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
nr_ranges = 1; /* For exclusion of crashkernel region */
walk_system_ram_res(0, -1, &nr_ranges, get_nr_ram_ranges_callback);
+ nr_ranges += of_reserved_mem_kdump_nr_ranges();
cmem = kmalloc_flex(*cmem, ranges, nr_ranges);
if (!cmem)
@@ -77,6 +79,8 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
/* Exclude crashkernel region */
ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
+ if (!ret)
+ ret = of_reserved_mem_kdump_exclude(cmem);
if (!ret)
ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH RFC v8 05/24] arm64: Implement asm/kpkeys.h using POE
From: Kevin Brodsky @ 2026-06-30 9:16 UTC (permalink / raw)
To: David Hildenbrand (Arm), linux-hardening
Cc: Andrew Morton, Andy Lutomirski, Catalin Marinas, Dave Hansen,
Ira Weiny, Jann Horn, Jeff Xu, Joey Gouly, Kees Cook,
Linus Walleij, Marc Zyngier, Mark Brown, Matthew Wilcox,
Maxwell Bland, Mike Rapoport (IBM), Peter Zijlstra,
Pierre Langlois, Quentin Perret, Rick Edgecombe, Ryan Roberts,
Vlastimil Babka, Will Deacon, Yang Shi, Yeoreum Yun,
linux-arm-kernel, linux-mm, x86, Lorenzo Stoakes, Thomas Gleixner
In-Reply-To: <f8507ad6-761c-4073-85ae-bddb2a07d660@kernel.org>
On 22/06/2026 15:35, David Hildenbrand (Arm) wrote:
> On 5/26/26 13:15, Kevin Brodsky wrote:
>> Implement the kpkeys interface if CONFIG_ARM64_POE is enabled.
>> The permissions for KPKEYS_PKEY_DEFAULT (pkey 0) are set to RWX as
>> this pkey is also used for code mappings.
>>
>> To allow <asm/kpkeys.h> to be included from assembly, also add
>> appropriate #ifdef's to <asm/por.h>.
>>
>> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
>> ---
>> arch/arm64/include/asm/kpkeys.h | 59 +++++++++++++++++++++++++++++++++++++++++
>> arch/arm64/include/asm/por.h | 4 +++
>> 2 files changed, 63 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/kpkeys.h b/arch/arm64/include/asm/kpkeys.h
>> new file mode 100644
>> index 000000000000..4dbfeb3dfcfe
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/kpkeys.h
>> @@ -0,0 +1,59 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +#ifndef __ASM_KPKEYS_H
>> +#define __ASM_KPKEYS_H
>> +
>> +#include <asm/barrier.h>
>> +#include <asm/cpufeature.h>
>> +#include <asm/por.h>
>> +
>> +#include <asm-generic/kpkeys.h>
>> +
>> +/*
>> + * Equivalent to por_set_kpkeys_context(0, KPKEYS_CTX_DEFAULT), but can also be
>> + * used in assembly.
>> + */
>> +#define POR_EL1_INIT POR_ELx_PERM_PREP(KPKEYS_PKEY_DEFAULT, POE_RWX)
> Okay, this matches
>
> #define POR_EL0_INIT POR_ELx_PERM_PREP(0, POE_RWX)
>
> Is there a good reason we need KPKEYS_PKEY_DEFAULT at all (and not similarly
> just hardcode it to 0)?
I did wonder about that. As per the discussion on patch 1 I don't see
that value ever changing, so I'm fine with hardcoding 0 if that feels
more consistent/intuitive.
> Just wondering, because apparently we didn't care about adding an indicator for
> user space pkey 0.
It's never too late to add a constant for userspace as well, but of
course since it's been ABI for so long the value isn't going to change.
>> +
>> +#ifndef __ASSEMBLY__
>> +
>> +static inline bool arch_supports_kpkeys(void)
>> +{
>> + return system_supports_poe();
>> +}
>> +
>> +#ifdef CONFIG_ARM64_POE
>> +
>> +static inline u64 por_set_kpkeys_context(u64 por, int ctx)
>> +{
>> + por = por_elx_set_pkey_perms(por, KPKEYS_PKEY_DEFAULT, POE_RWX);
>> +
>> + return por;
> Why not
>
> return por_elx_set_pkey_perms(por, KPKEYS_PKEY_DEFAULT, POE_RWX);
>
> ?
Because of patch 17, I wanted to minimise the diff. Happy to change it
if that feels less surprising.
> In light of API discussions, it would be nicer if arch_kpkeys_set_context()
> would just return the old context. But that would mean that restoring the
> context would require another read_sysreg_s(SYS_POR_EL1);
Correct, that's what I wanted to avoid.
> So instead of returning magic register values, that should be wrapped in some
> arch state struct as mentioned as reply to a previous patch.
Agreed.
>> +}
>> +
>> +static __always_inline void __kpkeys_set_pkey_reg_nosync(u64 pkey_reg)
>> +{
>> + write_sysreg_s(pkey_reg, SYS_POR_EL1);
>> +}
>> +
>> +static __always_inline u64 arch_kpkeys_set_context(int ctx)
>> +{
>> + u64 prev_por = read_sysreg_s(SYS_POR_EL1);
>> + u64 new_por = por_set_kpkeys_context(prev_por, ctx);
> Both can be const.
Sure.
> But maybe you just use a single "por" variable.
Not sure how? prev_por is returned and new_por is based on its value.
>> +
>> + __kpkeys_set_pkey_reg_nosync(new_por);
>> + isb();
>> +
>> + return prev_por;
>> +}
>> +
>> +static __always_inline void arch_kpkeys_restore_pkey_reg(u64 pkey_reg)
>> +{
>> + __kpkeys_set_pkey_reg_nosync(pkey_reg);
>> + isb();
> Why is that isb() for both callers outside of the function? Do you expect
> another user that doesn't need the isb?
Outside of __kpkeys_set_pkey_reg_nosync() that is? That function is also
used by patch 22, which doesn't want the ISB because we already have an
ISB somewhere else. The naming follows that of __set_pte_nosync().
- Kevin
^ permalink raw reply
* [PATCH 2/9] firmware: arm_scmi: Fix transport device teardown lookup
From: Sudeep Holla @ 2026-06-30 9:05 UTC (permalink / raw)
To: arm-scmi, linux-arm-kernel
Cc: Cristian Marussi, Sudeep Holla, Sashiko, Sudeep Holla
In-Reply-To: <20260630-scmi_core_fixes-v1-0-f932c1e51992@kernel.org>
SCMI transport devices are deliberately excluded from normal SCMI bus
matching so protocol drivers cannot bind to the internal transport
children. However, scmi_device_destroy() uses the same protocol/name
lookup to find devices that must be unregistered during channel teardown.
Split the match helper so driver matching still skips transport devices,
while explicit child lookup can find them for teardown. Use a shared
transport-device name prefix macro for both matching and name generation.
Since transport-device names are derived from direction and protocol ID,
reject duplicate protocol channel setup before creating or finding a
transport device. This prevents malformed firmware with duplicate
protocol child nodes from reusing an existing transport device and then
destroying it when the duplicate IDR insertion fails.
Fixes: 9593804c44c2 ("firmware: arm_scmi: Exclude transport devices from bus matching")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
---
drivers/firmware/arm_scmi/bus.c | 22 +++++++++++++++++-----
drivers/firmware/arm_scmi/common.h | 2 ++
drivers/firmware/arm_scmi/driver.c | 5 ++++-
3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index f643a1f0e282..d4beefa4234f 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -201,21 +201,33 @@ scmi_protocol_table_unregister(const struct scmi_device_id *id_table)
scmi_protocol_device_unrequest(entry);
}
-static int scmi_dev_match_by_id_table(struct scmi_device *scmi_dev,
- const struct scmi_device_id *id_table)
+static bool scmi_device_is_transport(const struct scmi_device *scmi_dev)
+{
+ return !strncmp(scmi_dev->name, SCMI_TRANSPORT_DEVNAME_PREFIX,
+ strlen(SCMI_TRANSPORT_DEVNAME_PREFIX));
+}
+
+static int __scmi_dev_match_by_id_table(struct scmi_device *scmi_dev,
+ const struct scmi_device_id *id_table,
+ bool skip_transport)
{
if (!id_table || !id_table->name)
return 0;
- /* Always skip transport devices from matching */
for (; id_table->protocol_id && id_table->name; id_table++)
if (id_table->protocol_id == scmi_dev->protocol_id &&
- strncmp(scmi_dev->name, "__scmi_transport_device", 23) &&
+ !(skip_transport && scmi_device_is_transport(scmi_dev)) &&
!strcmp(id_table->name, scmi_dev->name))
return 1;
return 0;
}
+static int scmi_dev_match_by_id_table(struct scmi_device *scmi_dev,
+ const struct scmi_device_id *id_table)
+{
+ return __scmi_dev_match_by_id_table(scmi_dev, id_table, true);
+}
+
static int scmi_dev_match_id(struct scmi_device *scmi_dev,
const struct scmi_driver *scmi_drv)
{
@@ -235,7 +247,7 @@ static int scmi_match_by_id_table(struct device *dev, const void *data)
struct scmi_device *scmi_dev = to_scmi_dev(dev);
const struct scmi_device_id *id_table = data;
- return scmi_dev_match_by_id_table(scmi_dev, id_table);
+ return __scmi_dev_match_by_id_table(scmi_dev, id_table, false);
}
static struct scmi_device *scmi_child_dev_find(struct device *parent,
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index b9723c105fc1..fe8c22cfb9f7 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -34,6 +34,8 @@
#define SCMI_SHMEM_MAX_PAYLOAD_SIZE 104
+#define SCMI_TRANSPORT_DEVNAME_PREFIX "__scmi_transport_device"
+
enum scmi_error_codes {
SCMI_SUCCESS = 0, /* Success */
SCMI_ERR_SUPPORT = -1, /* Not supported */
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index b9245238e293..b9ba566fc759 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2751,6 +2751,9 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
idx = tx ? 0 : 1;
idr = tx ? &info->tx_idr : &info->rx_idr;
+ if (idr_find(idr, prot_id))
+ return -EEXIST;
+
if (!info->desc->ops->chan_available(of_node, idx)) {
cinfo = idr_find(idr, SCMI_PROTOCOL_BASE);
if (unlikely(!cinfo)) /* Possible only if platform has no Rx */
@@ -2768,7 +2771,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
cinfo->no_completion_irq = info->desc->no_completion_irq;
/* Create a unique name for this transport device */
- snprintf(name, 32, "__scmi_transport_device_%s_%02X",
+ snprintf(name, sizeof(name), SCMI_TRANSPORT_DEVNAME_PREFIX "_%s_%02X",
idx ? "rx" : "tx", prot_id);
/* Create a uniquely named, dedicated transport device for this chan */
tdev = scmi_device_create(of_node, info->dev, prot_id, name);
--
2.43.0
^ permalink raw reply related
* [PATCH 4/9] firmware: arm_scmi: Fix SCMI device destroy lifetimes
From: Sudeep Holla @ 2026-06-30 9:06 UTC (permalink / raw)
To: arm-scmi, linux-arm-kernel
Cc: Cristian Marussi, Sudeep Holla, Sashiko, Sudeep Holla
In-Reply-To: <20260630-scmi_core_fixes-v1-0-f932c1e51992@kernel.org>
scmi_child_dev_find() drops the reference returned by
device_find_child() before returning the scmi_device pointer. A
concurrent unregister can then release the device while the destroy path
is still using the returned pointer.
Make the lookup helper return the device_find_child() reference and keep
it until scmi_device_destroy() has finished unregistering the child.
Also split device_unregister() in __scmi_device_destroy() so the SCMI bus
ID is not made reusable until after device_del() has removed the old
scmi_dev.N name from sysfs. This avoids a new SCMI device reusing the
same ID while the old device is still registered.
Fixes: 46edb8d1322c ("firmware: arm_scmi: provide the mandatory device release callback")
Fixes: 9ca67840c0dd ("firmware: arm_scmi: Balance device refcount when destroying devices")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
---
drivers/firmware/arm_scmi/bus.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index d4beefa4234f..e1deb1b3011d 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -250,8 +250,9 @@ static int scmi_match_by_id_table(struct device *dev, const void *data)
return __scmi_dev_match_by_id_table(scmi_dev, id_table, false);
}
-static struct scmi_device *scmi_child_dev_find(struct device *parent,
- int prot_id, const char *name)
+/* Returns a device_find_child() reference which must be dropped by caller. */
+static struct scmi_device *
+scmi_child_dev_find_get(struct device *parent, int prot_id, const char *name)
{
struct scmi_device_id id_table[2] = { 0 };
struct device *dev;
@@ -263,9 +264,6 @@ static struct scmi_device *scmi_child_dev_find(struct device *parent,
if (!dev)
return NULL;
- /* Drop the refcnt bumped implicitly by device_find_child */
- put_device(dev);
-
return to_scmi_dev(dev);
}
@@ -422,8 +420,9 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
atomic_set(&scmi_syspower_registered, 0);
+ device_del(&scmi_dev->dev);
ida_free(&scmi_bus_id, scmi_dev->id);
- device_unregister(&scmi_dev->dev);
+ put_device(&scmi_dev->dev);
}
static struct scmi_device *
@@ -440,9 +439,11 @@ __scmi_device_create(struct device_node *np, struct device *parent,
* each DT defined protocol at probe time, and the concurrent
* registration of SCMI drivers.
*/
- scmi_dev = scmi_child_dev_find(parent, protocol, name);
- if (scmi_dev)
+ scmi_dev = scmi_child_dev_find_get(parent, protocol, name);
+ if (scmi_dev) {
+ put_device(&scmi_dev->dev);
return scmi_dev;
+ }
/*
* Ignore any possible subsequent failures while creating the device
@@ -492,8 +493,8 @@ __scmi_device_create(struct device_node *np, struct device *parent,
return scmi_dev;
put_dev:
+ ida_free(&scmi_bus_id, scmi_dev->id);
put_device(&scmi_dev->dev);
- ida_free(&scmi_bus_id, id);
return NULL;
}
@@ -574,9 +575,11 @@ void scmi_device_destroy(struct device *parent, int protocol, const char *name)
{
struct scmi_device *scmi_dev;
- scmi_dev = scmi_child_dev_find(parent, protocol, name);
- if (scmi_dev)
+ scmi_dev = scmi_child_dev_find_get(parent, protocol, name);
+ if (scmi_dev) {
__scmi_device_destroy(scmi_dev);
+ put_device(&scmi_dev->dev);
+ }
}
EXPORT_SYMBOL_GPL(scmi_device_destroy);
--
2.43.0
^ permalink raw reply related
* [PATCH 5/9] firmware: arm_scmi: Free transport channel on IDR failure
From: Sudeep Holla @ 2026-06-30 9:06 UTC (permalink / raw)
To: arm-scmi, linux-arm-kernel
Cc: Cristian Marussi, Sudeep Holla, Sashiko, Sudeep Holla
In-Reply-To: <20260630-scmi_core_fixes-v1-0-f932c1e51992@kernel.org>
If transport channel setup succeeds but the following IDR insertion fails,
the error path destroys the transport device and frees the channel info
without invoking the transport cleanup callback.
Call chan_free() before destroying the device so transport specific
resources such as IRQs, mailbox channels and mapped shared memory are
released consistently with the normal teardown path.
Fixes: 05a2801d8b90 ("firmware: arm_scmi: Use dedicated devices to initialize channels")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
---
drivers/firmware/arm_scmi/driver.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 861087b2920e..4b369b003003 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2808,6 +2808,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
"unable to allocate SCMI idr slot err %d\n", ret);
/* Destroy channel and device only if created by this call. */
if (tdev) {
+ info->desc->ops->chan_free(prot_id, cinfo, idr);
scmi_device_destroy(info->dev, prot_id, name);
devm_kfree(info->dev, cinfo);
}
--
2.43.0
^ permalink raw reply related
* [PATCH 3/9] firmware: arm_scmi: Clean up channels on setup failure
From: Sudeep Holla @ 2026-06-30 9:05 UTC (permalink / raw)
To: arm-scmi, linux-arm-kernel
Cc: Cristian Marussi, Sudeep Holla, Sashiko, Sudeep Holla
In-Reply-To: <20260630-scmi_core_fixes-v1-0-f932c1e51992@kernel.org>
scmi_channels_setup() can fail after the common BASE channel or earlier
protocol channels have already been registered in the TX/RX IDRs.
Route this failure through the existing channel cleanup label so the
transport channels, transport devices and IDR state created before the
failure are released before the probe error path frees the SCMI instance
ID.
Fixes: 05a2801d8b90 ("firmware: arm_scmi: Use dedicated devices to initialize channels")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
---
drivers/firmware/arm_scmi/driver.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index b9ba566fc759..861087b2920e 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -3262,7 +3262,7 @@ static int scmi_probe(struct platform_device *pdev)
ret = scmi_channels_setup(info);
if (ret) {
err_str = "failed to setup channels\n";
- goto clear_ida;
+ goto clear_txrx_setup;
}
ret = bus_register_notifier(&scmi_bus_type, &info->bus_nb);
@@ -3377,7 +3377,6 @@ static int scmi_probe(struct platform_device *pdev)
bus_unregister_notifier(&scmi_bus_type, &info->bus_nb);
clear_txrx_setup:
scmi_cleanup_txrx_channels(info);
-clear_ida:
ida_free(&scmi_id, info->id);
out_err:
--
2.43.0
^ permalink raw reply related
* [PATCH v4 0/7] Read MAC address from SST vendor specific SFDP region
From: Manikandan Muralidharan @ 2026-06-30 9:23 UTC (permalink / raw)
To: pratyush, mwalle, takahiro.kuwano, miquel.raynal, richard,
vigneshr, robh, krzk+dt, conor+dt, srini, nicolas.ferre,
alexandre.belloni, claudiu.beznea, linux, richardcochran, linusw,
arnd, michael, linux-mtd, devicetree, linux-kernel,
linux-arm-kernel, netdev
Cc: Manikandan Muralidharan
Some Microchip/SST QSPI flashes (e.g. the SST26VF064BEUI) are factory
programmed with globally unique, write-protected EUI-48 and EUI-64
identifiers stored in a vendor-specific SFDP parameter table. On boards
that have no on-board EEPROM (sama5d27_wlsom1, sama5d29 curiosity,
sam9x75 curiosity) this is a reliable source for an Ethernet MAC address,
instead of relying on a U-Boot-provided or random address.
This v4 reworks the approach into a generic NVMEM framework with no vendor
code in the SPI NOR core:
- The SPI NOR core now exposes the entire SFDP as a generic read-only
NVMEM device, rooted at a new "sfdp" child node of the flash.
- A new NVMEM layout driver (drivers/nvmem/layouts/) locates the
Microchip vendor parameter table at runtime and presents the EUI-48 as
a "mac-address" cell.
- Arbitrary parameters can be read with a standard fixed-layout
(known offset) or with an nvmem-layout parser (location discovered at runtime).
Changes in v4:
- Rework per v3 review: remove the vendor-specific SFDP handling from the
SPI NOR core; expose the whole SFDP as a generic read-only NVMEM device
and move the EUI extraction into an nvmem-layout driver.
- Introduce a new nvmem-layout driver to discover the vendor-table location
at runtime; no offset hardcoded in the device tree.
- Describe the SFDP via a dedicated "sfdp" subnode (compatible
"jedec,sfdp"), which also resolves the v3 dtbs_check "Unevaluated
properties ('nvmem-layout')" warning.
- Reverse the stored EUI bytes into canonical MAC order.
- Enable the layout in sama5_defconfig.
Changes in v3:
- 2/3 - add support to update the QSPI partition into 'fixed-partition'
binding in sama5d27_wlsom1
- 3/3 - add nvmem-layout in qspi node for EUI48 MAC Address and nvmem cell
properties for macb node in sama5d27_wlsom1
Changes in v2:
- 1/3 - parse the SST vendor table, read and store the addresses
into a resource - managed space. Register the addresses
into NVMEM framework
- 2/3 - add support to update the QSPI partition into 'fixed-partition'
binding
v3: https://lore.kernel.org/linux-arm-kernel/20250521070336.402202-1-manikandan.m@microchip.com/
Manikandan Muralidharan (7):
dt-bindings: mtd: jedec,spi-nor: allow the SFDP to be exposed via
NVMEM
dt-bindings: nvmem: layouts: add Microchip/SST SFDP EUI layout
mtd: spi-nor: sfdp: expose the SFDP as a read-only NVMEM device
nvmem: layouts: add Microchip/SST SFDP EUI layout driver
ARM: dts: microchip: sama5d27_wlsom1: use fixed-partitions for QSPI
flash
ARM: dts: microchip: sama5d27_wlsom1: read MAC address from QSPI SFDP
ARM: configs: sama5: enable Microchip/SST SFDP EUI NVMEM layout
.../bindings/mtd/jedec,spi-nor.yaml | 18 ++
.../layouts/microchip,sst26vf-sfdp-eui.yaml | 60 ++++++
.../bindings/nvmem/layouts/nvmem-layout.yaml | 1 +
MAINTAINERS | 6 +
.../dts/microchip/at91-sama5d27_wlsom1.dtsi | 61 +++---
.../dts/microchip/at91-sama5d27_wlsom1_ek.dts | 2 +
arch/arm/configs/sama5_defconfig | 1 +
drivers/mtd/spi-nor/core.c | 5 +
drivers/mtd/spi-nor/core.h | 1 +
drivers/mtd/spi-nor/sfdp.c | 83 ++++++++
drivers/nvmem/layouts/Kconfig | 10 +
drivers/nvmem/layouts/Makefile | 1 +
drivers/nvmem/layouts/sst26vf-sfdp-eui.c | 182 ++++++++++++++++++
13 files changed, 409 insertions(+), 22 deletions(-)
create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/microchip,sst26vf-sfdp-eui.yaml
create mode 100644 drivers/nvmem/layouts/sst26vf-sfdp-eui.c
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
--
2.43.0
^ permalink raw reply
* Re: [PATCH v2] firmware: arm_ffa: Handle maximum RX/TX buffer size
From: Sudeep Holla @ 2026-06-30 9:24 UTC (permalink / raw)
To: Sebastian Ene, Seth Forshee; +Cc: Sudeep Holla, linux-arm-kernel, linux-kernel
In-Reply-To: <20260602-b4-ffa-rxtx-map-fixes-v2-1-7cb06508da84@nvidia.com>
On Tue, 02 Jun 2026 21:54:06 +0000, Seth Forshee wrote:
> A partition manager may reject unsupported RX/TX buffer sizes by
> returning INVALID_PARAMETERS. Commit 83210251fd70 ("firmware: arm_ffa:
> Use the correct buffer size during RXTX_MAP") has the effect of rounding
> up the buffer size from FFA_FEATURES to be PAGE_SIZE-aligned, which may
> be larger than what the partition manager supports. This caused RXTX_MAP
> to fail for some FF-A implementations on kernels with PAGE_SIZE > 4K.
>
> [...]
Applied to sudeep.holla/linux (for-next/ffa/fixes), thanks!
[1/1] firmware: arm_ffa: Handle maximum RX/TX buffer size
https://git.kernel.org/sudeep.holla/c/53716a4d745f
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH v4 1/7] dt-bindings: mtd: jedec,spi-nor: allow the SFDP to be exposed via NVMEM
From: Manikandan Muralidharan @ 2026-06-30 9:24 UTC (permalink / raw)
To: pratyush, mwalle, takahiro.kuwano, miquel.raynal, richard,
vigneshr, robh, krzk+dt, conor+dt, srini, nicolas.ferre,
alexandre.belloni, claudiu.beznea, linux, richardcochran, linusw,
arnd, michael, linux-mtd, devicetree, linux-kernel,
linux-arm-kernel, netdev
Cc: Manikandan Muralidharan
In-Reply-To: <20260630092406.150587-1-manikandan.m@microchip.com>
Add an optional "sfdp" child node (compatible "jedec,sfdp") that
describes the SFDP as a read-only NVMEM provider via nvmem.yaml, so its
contents (e.g. a vendor EUI-48/EUI-64) can be read through NVMEM cells.
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
.../devicetree/bindings/mtd/jedec,spi-nor.yaml | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
index 587af4968255..98fd954598ab 100644
--- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
+++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
@@ -103,6 +103,20 @@ properties:
spi-cpol: true
spi-cpha: true
+ sfdp:
+ $ref: /schemas/nvmem/nvmem.yaml#
+ unevaluatedProperties: false
+ description:
+ The Serial Flash Discoverable Parameters (SFDP) tables exposed as a
+ read-only NVMEM device. This allows standard or vendor-specific SFDP
+ data (for example a factory-programmed EUI-48/EUI-64 identifier) to be
+ consumed through NVMEM cells.
+ properties:
+ compatible:
+ const: jedec,sfdp
+ required:
+ - compatible
+
dependencies:
spi-cpol: [ spi-cpha ]
spi-cpha: [ spi-cpol ]
@@ -122,6 +136,10 @@ examples:
spi-max-frequency = <40000000>;
m25p,fast-read;
reset-gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+
+ sfdp {
+ compatible = "jedec,sfdp";
+ };
};
};
...
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox