* Re: [PATCH 3/5] drivers: remoteproc: imx: add autoboot support for A-core remoteproc
From: Daniel Baluta @ 2026-04-28 13:49 UTC (permalink / raw)
To: Jiafei Pan, andersson, mathieu.poirier, peng.fan, Frank.Li,
s.hauer, kernel, festevam, imx, linux-arm-kernel, linux-kernel
Cc: Zhiqiang.Hou, mingkai.hu
In-Reply-To: <20260428090819.17761-4-Jiafei.Pan@nxp.com>
On 4/28/26 12:08, Jiafei Pan wrote:
> [You don't often get email from jiafei.pan@nxp.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> Add autoboot support for Cortex-A Core remoteproc.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
Please also add your Signed-off-by tag here.
See: https://developercertificate.org/
^ permalink raw reply
* Re: [PATCH v2 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 13:47 UTC (permalink / raw)
To: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Rob Clark, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten, Tian Tao,
Xinwei Kong, Sumit Semwal, John Stultz, Andrzej Hajda,
Neil Armstrong, Robert Foss, laurent.pinchart, Jonas Karlman,
Jernej Skrabec, tomi.valkeinen, Michal Simek
Cc: Hui Pu, Ian Ray, Thomas Petazzoni,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <TY3PR01MB11346E82D19FBE8544F51624286372@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hello,
On Tue Apr 28, 2026 at 3:31 PM CEST, Biju Das wrote:
>> >> > @@ -1251,10 +1251,9 @@ static int adv7511_probe(struct i2c_client
>> >> > *i2c)
>> >> >
>> >> > memset(&link_config, 0, sizeof(link_config));
>> >> >
>> >> > - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,
>> >> > - &adv7511->next_bridge);
>> >> > - if (ret && ret != -ENODEV)
>> >> > - return ret;
>> >> > + adv7511->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 1, -1);
>> >> > + if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) != -ENODEV)
>> >> > + return PTR_ERR(adv7511->bridge.next_bridge);
>> >>
>> >> Does it crash, if the error is -EPROBE_DEFER?
>> >
>> > I see a crash with patch [1], which is fixed by avoiding the direct assignment.
>>
>> Ah, dammit! Good catch, thanks for the quick testing and follow-up!
>>
>> Indeed this driver assumes next_bridge is either NULL or a valid pointer, but due to the 'if(IS_ERR()
>> && some_other_condition)' now it can also be -ENODEV (not -EPROBE_DEFER, but that's irrelevant).
>>
>> This affects the msm and zynqmp_dp patches equally.
>>
>> I'm sending a v3 soon with these fixed. I'm just not sure which approach to use to fix (same for all
>> the 3 patches). Alternatives are:
>>
>> 1. -ENODEV is accepted, set next_bridge to NULL when it happens:
>>
>> - if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) != -
>> ENODEV)
>> - return PTR_ERR(adv7511->bridge.next_bridge);
>> + if (IS_ERR(adv7511->bridge.next_bridge)) {
>> + if (PTR_ERR(adv7511->bridge.next_bridge) == -ENODEV)
>> + adv7511->bridge.next_bridge = NULL;
>> + else
>> + return PTR_ERR(adv7511->bridge.next_bridge);
>
> The point is you cannot return PTR_ERR as it will lead to crash, if it is
> direct assignment.
It would definitely crash when the next_bridge is dereferenced (which
happens in adv7511_bridge_attach()) but I don't see how it can crash
here. Here it _can_ be assigned -ENODEV, but it would be immediately be
cleared to NULL, or to enother error, but we'd immediately return. And in
case of return, when next_bridge is cleared by __drm_bridge_free ->
drm_bridge_put, the error value would be ignored thanks to patch 1.
>
> if (IS_ERR(adv7511->bridge.next_bridge)) {
> int err = PTR_ERR(adv7511->bridge.next_bridge);
> adv7511->bridge.next_bridge = NULL;
> return err;
> }
Is this if() condition wrong? The driver needs to accept the -ENODEV return
value, the next_bridge is conditional in the curent driver code.
>
> Cheers,
> Biju
>
>> 2. let nexxt_bridge hold -ENODEV but ignore it when it is used (only in
>> the attach op, for all 3 drivers):
>>
>> - if (adv->bridge.next_bridge) {
>> + if (!IS_ERR_OR_NULL(adv->bridge.next_bridge)) {
>>
>> While the latter approach involves less code, it might let errors sneak in in case new usages of
>> next_bridge are added with just a NULL check.
>>
>> Opinions about the two?
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v4 3/3] coco: guest: arm64: Query host IPA-change alignment via RHI
From: Marc Zyngier @ 2026-04-28 13:49 UTC (permalink / raw)
To: Aneesh Kumar K.V
Cc: linux-kernel, iommu, linux-coco, linux-arm-kernel, kvmarm,
Catalin Marinas, Jason Gunthorpe, Marek Szyprowski, Robin Murphy,
Steven Price, Suzuki K Poulose, Thomas Gleixner, Will Deacon
In-Reply-To: <yq5a4ikv1c7p.fsf@kernel.org>
On Tue, 28 Apr 2026 13:49:46 +0100,
Aneesh Kumar K.V <aneesh.kumar@kernel.org> wrote:
>
> Marc Zyngier <maz@kernel.org> writes:
>
> > On Mon, 27 Apr 2026 07:31:08 +0100,
> > "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel.org> wrote:
> >>
> >> Add the Realm Host Interface support needed to query host configuration
> >> from a Realm guest. Define the RHI hostconf SMCs, add rsi_host_call(), and
> >> use them during Realm initialization to retrieve the host IPA-change
> >> alignment size.
> >
> > I don't understand what "IPA-change" means. What you are after is the
> > host's sharing granule size.
> >
>
> This is part of the RHI specification, and the call is named
> RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT. The intent is to determine the
> alignment requirements for changing IPA attributes (protected vs.
> unprotected IPA
This really is a terrible name. Why the 'change' part? It doesn't
change, it is a constant.
Oh well...
[...]
> >> +static inline unsigned long rsi_host_call(struct rsi_host_call *rhi_call)
> >> +{
> >> + phys_addr_t addr = virt_to_phys(rhi_call);
> >> + struct arm_smccc_res res;
> >> +
> >> + arm_smccc_1_1_invoke(SMC_RSI_HOST_CALL, addr, &res);
> >
> > Errr... What guarantees that *rhi_call is *IPA contiguous*? This is
> > incredibly fragile. You should at the very least check that this isn't
> > vmalloc'd.
> >
>
>
> I didn’t quite follow that. We have other RSI calls (even RMI calls)
> that do similar things, and the caller understands that the address
> should be IPA-contiguous.
Does it? Where is it documented? All you get is a pointer, so all
bets are off.
> Are you suggesting that all RSI calls should
> add checks for this?. or are you suggesting to update the API to
>
> unsigned long rsi_host_call(unsigned long rhi_call_phys) ?
I'm suggesting that this API is subtly broken because it makes random
assumption about the physical contiguity of the VA space. It does so
without any check, without any documentation.
Simply changing the parameter to phys_addr_t could at the very least
capture some of the requirements, but I'd like something in big bold
letters.
>
> >> +
> >> + return res.a0;
> >> +}
> >> +
> >> #endif /* __ASM_RSI_CMDS_H */
> >> diff --git a/arch/arm64/include/asm/rsi_smc.h b/arch/arm64/include/asm/rsi_smc.h
> >> index e19253f96c94..9ee8b5c7612e 100644
> >> --- a/arch/arm64/include/asm/rsi_smc.h
> >> +++ b/arch/arm64/include/asm/rsi_smc.h
> >> @@ -182,6 +182,13 @@ struct realm_config {
> >> */
> >> #define SMC_RSI_IPA_STATE_GET SMC_RSI_FID(0x198)
> >>
> >> +struct rsi_host_call {
> >> + union {
> >> + u16 imm;
> >> + u64 padding0;
> >> + };
> >> + u64 gprs[31];
> >> +} __aligned(0x100);
> >> /*
> >> * Make a Host call.
> >> *
> >> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> >> index fe627100d199..3e72dd9584ed 100644
> >> --- a/arch/arm64/kernel/Makefile
> >> +++ b/arch/arm64/kernel/Makefile
> >> @@ -34,7 +34,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
> >> cpufeature.o alternative.o cacheinfo.o \
> >> smp.o smp_spin_table.o topology.o smccc-call.o \
> >> syscall.o proton-pack.o idle.o patching.o pi/ \
> >> - rsi.o jump_label.o
> >> + rsi.o jump_label.o rhi.o
> >>
> >> obj-$(CONFIG_COMPAT) += sys32.o signal32.o \
> >> sys_compat.o
> >> diff --git a/arch/arm64/kernel/rhi.c b/arch/arm64/kernel/rhi.c
> >> new file mode 100644
> >> index 000000000000..7cd6c5102464
> >> --- /dev/null
> >> +++ b/arch/arm64/kernel/rhi.c
> >> @@ -0,0 +1,54 @@
> >> +// SPDX-License-Identifier: GPL-2.0-only
> >> +/*
> >> + * Copyright (C) 2026 ARM Ltd.
> >> + */
> >> +
> >> +#include <linux/mm.h>
> >> +#include <asm/rsi.h>
> >> +#include <asm/rhi.h>
> >> +
> >> +/* we need an aligned rhicall for rsi_host_call. slab is not yet ready */
> >> +static struct rsi_host_call hyp_pagesize_rhicall;
> >
> > Why the "hyp_" prefix? This has absolutely nothing to with the
> > hypervisor.
> >
>
> Sure will update "hyp_" reference to host.
>
>
> >> +unsigned long rhi_get_ipa_change_alignment(void)
> >> +{
> >> + long ret;
> >> + unsigned long ipa_change_align;
> >> +
> >> + hyp_pagesize_rhicall.imm = 0;
> >> + hyp_pagesize_rhicall.gprs[0] = RHI_HOSTCONF_VERSION;
> >> + ret = rsi_host_call(lm_alias(&hyp_pagesize_rhicall));
> >> + if (ret != RSI_SUCCESS)
> >> + goto err_out;
> >> +
> >> + if (hyp_pagesize_rhicall.gprs[0] != RHI_HOSTCONF_VER_1_0)
> >> + goto err_out;
> >> +
> >> + hyp_pagesize_rhicall.imm = 0;
> >> + hyp_pagesize_rhicall.gprs[0] = RHI_HOSTCONF_FEATURES;
> >> + ret = rsi_host_call(lm_alias(&hyp_pagesize_rhicall));
> >> + if (ret != RSI_SUCCESS)
> >> + goto err_out;
> >> +
> >> + if (!(hyp_pagesize_rhicall.gprs[0] & __RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT))
> >> + goto err_out;
> >> +
> >> + hyp_pagesize_rhicall.imm = 0;
> >> + hyp_pagesize_rhicall.gprs[0] = RHI_HOSTCONF_GET_IPA_CHANGE_ALIGNMENT;
> >> + ret = rsi_host_call(lm_alias(&hyp_pagesize_rhicall));
> >> + if (ret != RSI_SUCCESS)
> >> + goto err_out;
> >> +
> >> + ipa_change_align = hyp_pagesize_rhicall.gprs[0];
> >> + /* This error needs special handling in the caller */
> >> + if (ipa_change_align & (SZ_4K - 1))
> >> + return 0;
> >> +
> >> + return ipa_change_align;
> >> +
> >> +err_out:
> >> + /*
> >> + * For failure condition assume host is built with 4K page size
> >> + * and hence ipa change alignment can be guest PAGE_SIZE.
> >> + */
> >> + return PAGE_SIZE;
> >> +}
> >
> > Why can't this be part of rsi.c? This is an RSI call, and it should be
> > part of the RSI initialisation.
> >
>
> This is an RHI call as per the specification, hence it has been added to
> rhi.c.
News flash: this is the Linux kernel, not an ARM spec. We organise
things based on the logical use, not on the TLA associated with it.
And RHI is implemented in terms of RSI. In rsi.c it goes. We don't
need this pointless proliferation of helper files that only result in
equally pointless global symbols.
>
> >> diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
> >> index 9e846ce4ef9c..ff735c04e236 100644
> >> --- a/arch/arm64/kernel/rsi.c
> >> +++ b/arch/arm64/kernel/rsi.c
> >> @@ -14,8 +14,10 @@
> >> #include <asm/mem_encrypt.h>
> >> #include <asm/pgtable.h>
> >> #include <asm/rsi.h>
> >> +#include <asm/rhi.h>
> >>
> >> static struct realm_config config;
> >> +static unsigned long ipa_change_alignment = PAGE_SIZE;
> >>
> >> unsigned long prot_ns_shared;
> >> EXPORT_SYMBOL(prot_ns_shared);
> >> @@ -139,6 +141,11 @@ static int realm_ioremap_hook(phys_addr_t phys, size_t size, pgprot_t *prot)
> >> return 0;
> >> }
> >>
> >> +unsigned long realm_get_hyp_pagesize(void)
> >> +{
> >> + return ipa_change_alignment;
> >> +}
> >
> > Again, this has nothing to do with the hypervisor, but the host. And
> > ipa_change_alignment is still a wording I can't wrap my small head
> > around.
> >
> >> +
> >> void __init arm64_rsi_init(void)
> >> {
> >> if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
> >> @@ -147,6 +154,12 @@ void __init arm64_rsi_init(void)
> >> return;
> >> if (WARN_ON(rsi_get_realm_config(&config)))
> >> return;
> >> +
> >> + ipa_change_alignment = rhi_get_ipa_change_alignment();
> >> + /* If we don't get a correct alignment response, don't enable realm */
> >> + if (!ipa_change_alignment)
> >> + return;
> >
> > But at the same time, you override a global value with an error, and
> > then paper over it in mem_decrypt_granule_size()...
> >
>
>
> I believe I received similar feedback on my previous version as well,
> which I didn’t quite follow.
And you didn't think of asking? Sometimes I wonder what these patch
reviews are for... Just to waste some more electrons, I guess :-/.
>
> rhi_get_ipa_change_alignment() only returns an error when the host
> returns a size that is not 4K-aligned. Otherwise, it returns the
> host-determined size, or defaults to guest PAGE_SIZE if the RHI call
> itself is not supported.
You encode the error as 0. You override ipa_change_alignment with 0.
Then...
> >> +size_t mem_decrypt_granule_size(void)
> >> +{
> >> + if (is_realm_world())
> >> + return max(PAGE_SIZE, realm_get_hyp_pagesize());
> >
> > If you didn't mess with ipa_change_alignment above, you shouldn't need
> > this max().
> >
>
> size_t mem_decrypt_granule_size(void)
> {
> if (is_realm_world())
> return max(PAGE_SIZE, realm_get_hyp_pagesize());
> return PAGE_SIZE;
> }
>
> That needs to use max(), because we should align to the guest PAGE_SIZE
> if it is larger than the host-specified alignment value.
... you need to correct that back to PAGE_SIZE because you have stored
something smaller than PAGE_SIZE.
Isn't the problem really obvious? ipa_change_alignment can *NEVER* go
down. It should never be allowed to reduce, because that's exactly
the property you are trying to enforce.
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH 2/8] KVM: arm64: Synchronise HCR_EL2 writes on the guest exit path
From: Will Deacon @ 2026-04-28 13:50 UTC (permalink / raw)
To: Fuad Tabba
Cc: maz, oliver.upton, james.morse, suzuki.poulose, yuzenghui,
qperret, vdonnefort, catalin.marinas, linux-arm-kernel, kvmarm,
linux-kernel, stable
In-Reply-To: <20260428103008.696141-3-tabba@google.com>
On Tue, Apr 28, 2026 at 11:30:02AM +0100, Fuad Tabba wrote:
> MSR HCR_EL2 is not self-synchronising. Per ARM DDI 0487 M.b K1.2.4
> (p.K1-16823) and B2.6.1 (p.B2-297), a Context Synchronisation Event
> is required between an HCR_EL2 write and any subsequent direct
> register access at the same EL that depends on the new value being
> in effect.
>
> On the entry path, the HCR_EL2 write in __activate_traps is followed
> by further EL2 sysreg work (MDCR_EL2, CPTR_EL2, VBAR_EL2, and on the
> speculative-AT errata path SCTLR_EL1/TCR_EL1) before ERET into the
> guest. None of those intervening accesses depend on the new HCR_EL2
> value, and ERET is a CSE per ARM DDI 0487 M.b D1.4.4.1 rule RBWCFK
> (p. D1-7209) conditional on SCTLR_EL2.EOS=1, which is set
> unconditionally by INIT_SCTLR_EL2_MMU_ON (see the prerequisite patch
> in this series). The requirement is therefore satisfied implicitly
> on the activate path.
>
> The deactivate path is different: after write_sysreg_hcr() in
> __deactivate_traps() further EL2 sysreg work runs before any natural
> CSE - on nVHE, __deactivate_cptr_traps and the VBAR_EL2 write; on
> VHE, the timer context save which reads CNTP_CVAL_EL0 under the new
> TGE/E2H, and the EL1 sysreg restore. Add an explicit isb() at each
> of the two deactivate sites.
>
> The practical impact today is bounded: HCR_EL2.E2H does not toggle
> in either path, and the trap bits being changed primarily affect
> EL1&0 behaviour. But the architectural rule should be honoured.
> Note that write_sysreg_hcr() itself already issues isb() on the
> Ampere errata path (sysreg.h), confirming the architectural
> expectation; the fast path optimises that away.
>
> The fix is at the call sites rather than inside write_sysreg_hcr()
> because the macro has many users (e.g. the activate path, at.c,
> hardirq.h, ptrauth alternatives) where the immediately-following
> code either reaches ERET or has another CSE; making the macro emit
> an unconditional ISB would impose unnecessary cost on those
> well-formed users.
>
> Fixes: 9404673293b0 ("KVM: arm64: timers: Correctly handle TGE flip with CNTPOFF_EL2")
> Signed-off-by: Fuad Tabba <tabba@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/switch.c | 11 +++++++++++
> arch/arm64/kvm/hyp/vhe/switch.c | 11 +++++++++++
> 2 files changed, 22 insertions(+)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index 8d1df3d33595..9d7ead5a5503 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -105,6 +105,17 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
> __deactivate_traps_common(vcpu);
>
> write_sysreg_hcr(this_cpu_ptr(&kvm_init_params)->hcr_el2);
> + /*
> + * MSR HCR_EL2 is not self-synchronising. Per ARM ARM K1.2.4 p.K1-16823
> + * and B2.6.1 p.B2-297, a Context Synchronisation Event is required
> + * between an HCR_EL2 write and any subsequent direct register access at
> + * the same EL that depends on the new value being in effect.
> + * The activate_traps path falls through to ERET (a CSE), but the
> + * deactivate path still executes further EL2 sysreg work (CPTR/VBAR
> + * writes below) before any natural CSE, so make the synchronisation
> + * explicit.
> + */
> + isb();
Sorry, but I don't understand this. Please can you explain why you think
that CPTR and VBAR have an ordering dependency on HCR_EL2? Preferably,
the comment would talk about the specific fields that are relevant.
Will
^ permalink raw reply
* Re: [PATCH v5 05/10] drm/bridge: dw-hdmi-qp: Add HDMI 2.0 SCDC scrambling and high TMDS clock ratio support
From: Cristian Ciocaltea @ 2026-04-28 13:51 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Heiko Stübner, Andy Yan, kernel, dri-devel, linux-kernel,
linux-arm-kernel, linux-rockchip, Diederik de Haas,
Maud Spierings
In-Reply-To: <m5fxlfktxtvki5yaxhkx4h3hsjj5266stwvfdykhqkgcjbz5bk@s5gggcd45abm>
Hi Dmitry,
Thanks for taking the time to review the series!
On 4/28/26 4:38 AM, Dmitry Baryshkov wrote:
> On Sun, Apr 26, 2026 at 03:20:17AM +0300, Cristian Ciocaltea wrote:
>> Enable HDMI 2.0 display modes (e.g. 4K@60Hz) by adding SCDC management
>> for the high TMDS clock ratio and scrambling, required when the TMDS
>> character rate exceeds the 340 MHz HDMI 1.4b limit.
>>
>> A periodic work item monitors the sink's scrambling status to recover
>> from sink-side resets. On hotplug detect, if SCDC scrambling state is
>> out of sync with the driver, trigger a CRTC reset to re-establish the
>> link.
>>
>> Reject modes requiring TMDS rates above 600 MHz, as those fall in the
>> HDMI 2.1 FRL domain which is not supported. In no_hpd configurations,
>> further restrict to 340 MHz since SCDC requires a connected sink.
>>
>> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
>> Tested-by: Maud Spierings <maud_spierings@hotmail.com>
>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
>> ---
>> drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 188 ++++++++++++++++++++++++---
>> 1 file changed, 172 insertions(+), 16 deletions(-)
>
> My main issue with this patch (sorry) is that this adds yet another copy
> of SCDC-related helpers into the driver which already OP_HDMI and other
> helpers.
>
>> @@ -39,7 +42,9 @@
>> #define DDC_SEGMENT_ADDR 0x30
>>
>> #define HDMI14_MAX_TMDSCLK 340000000
>> +#define HDMI20_MAX_TMDSRATE 600000000
>>
>> +#define SCDC_MAX_SOURCE_VERSION 0x1
>> #define SCRAMB_POLL_DELAY_MS 3000
>>
>> /*
>> @@ -164,6 +169,11 @@ struct dw_hdmi_qp {
>> } phy;
>>
>> unsigned long ref_clk_rate;
>> +
>> + struct drm_connector *curr_conn;
>> + struct delayed_work scramb_work;
>> + bool scramb_enabled;
>
> s/scramb/scrambler/
>
> Can we move those two to the drm_connector_hdmi
Sure, will do.
>> +
>> struct regmap *regm;
>> int main_irq;
>>
>> @@ -749,28 +759,124 @@ static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi)
>> return adap;
>> }
>>
>> +static bool dw_hdmi_qp_supports_scrambling(struct drm_display_info *display)
>> +{
>> + if (!display->is_hdmi)
>> + return false;
>> +
>> + return display->hdmi.scdc.supported &&
>> + display->hdmi.scdc.scrambling.supported;
>> +}
>> +
>> +static int dw_hdmi_qp_set_scramb(struct dw_hdmi_qp *hdmi)
>> +{
>> + bool done;
>> +
>> + dev_dbg(hdmi->dev, "set scrambling\n");
>> +
>> + done = drm_scdc_set_high_tmds_clock_ratio(hdmi->curr_conn, true);
>> + if (!done)
>> + return -EIO;
>> +
>> + done = drm_scdc_set_scrambling(hdmi->curr_conn, true);
>> + if (!done) {
>> + drm_scdc_set_high_tmds_clock_ratio(hdmi->curr_conn, false);
>> + return -EIO;
>> + }
>> +
>> + schedule_delayed_work(&hdmi->scramb_work,
>> + msecs_to_jiffies(SCRAMB_POLL_DELAY_MS));
>> + return 0;
>> +}
>> +
>> +static void dw_hdmi_qp_scramb_work(struct work_struct *work)
>> +{
>> + struct dw_hdmi_qp *hdmi = container_of(to_delayed_work(work),
>> + struct dw_hdmi_qp,
>> + scramb_work);
>> + if (READ_ONCE(hdmi->scramb_enabled) &&
>> + !drm_scdc_get_scrambling_status(hdmi->curr_conn))
>> + dw_hdmi_qp_set_scramb(hdmi);
>> +}
>> +
>> +static void dw_hdmi_qp_enable_scramb(struct dw_hdmi_qp *hdmi)
>> +{
>> + int ret;
>> + u8 ver;
>> +
>> + if (!dw_hdmi_qp_supports_scrambling(&hdmi->curr_conn->display_info))
>> + return;
>> +
>> + ret = drm_scdc_readb(hdmi->bridge.ddc, SCDC_SINK_VERSION, &ver);
>> + if (ret) {
>> + dev_err(hdmi->dev, "Failed to read SCDC_SINK_VERSION: %d\n", ret);
>> + return;
>> + }
>> +
>> + ret = drm_scdc_writeb(hdmi->bridge.ddc, SCDC_SOURCE_VERSION,
>> + min_t(u8, ver, SCDC_MAX_SOURCE_VERSION));
>> + if (ret) {
>> + dev_err(hdmi->dev, "Failed to write SCDC_SOURCE_VERSION: %d\n", ret);
>> + return;
>> + }
>> +
>> + WRITE_ONCE(hdmi->scramb_enabled, true);
>> +
>> + ret = dw_hdmi_qp_set_scramb(hdmi);
>> + if (ret) {
>> + hdmi->scramb_enabled = false;
>> + return;
>> + }
>> +
>> + dw_hdmi_qp_write(hdmi, 1, SCRAMB_CONFIG0);
>> +
>> + /* Wait at least 1 ms before resuming TMDS transmission */
>> + usleep_range(1000, 5000);
>> +}
>> +
>> +static void dw_hdmi_qp_disable_scramb(struct dw_hdmi_qp *hdmi)
>> +{
>> + if (!hdmi->scramb_enabled)
>> + return;
>> +
>> + dev_dbg(hdmi->dev, "disable scrambling\n");
>> +
>> + WRITE_ONCE(hdmi->scramb_enabled, false);
>> + cancel_delayed_work_sync(&hdmi->scramb_work);
>> +
>> + dw_hdmi_qp_write(hdmi, 0, SCRAMB_CONFIG0);
>> +
>> + if (hdmi->curr_conn->status == connector_status_connected) {
>> + drm_scdc_set_scrambling(hdmi->curr_conn, false);
>> + drm_scdc_set_high_tmds_clock_ratio(hdmi->curr_conn, false);
>> + }
>> +}
>
> All of these feel like generic helpers.
I'll factor these out.
>> +
>> static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
>> struct drm_atomic_state *state)
>> {
>> struct dw_hdmi_qp *hdmi = bridge->driver_private;
>> struct drm_connector_state *conn_state;
>> - struct drm_connector *connector;
>> unsigned int op_mode;
>>
>> - connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
>> - if (WARN_ON(!connector))
>> + hdmi->curr_conn = drm_atomic_get_new_connector_for_encoder(state,
>> + bridge->encoder);
>> + if (WARN_ON(!hdmi->curr_conn))
>> return;
>>
>> - conn_state = drm_atomic_get_new_connector_state(state, connector);
>> + conn_state = drm_atomic_get_new_connector_state(state, hdmi->curr_conn);
>> if (WARN_ON(!conn_state))
>> return;
>>
>> - if (connector->display_info.is_hdmi) {
>> + if (hdmi->curr_conn->display_info.is_hdmi) {
>> dev_dbg(hdmi->dev, "%s mode=HDMI %s rate=%llu bpc=%u\n", __func__,
>> drm_hdmi_connector_get_output_format_name(conn_state->hdmi.output_format),
>> conn_state->hdmi.tmds_char_rate, conn_state->hdmi.output_bpc);
>> op_mode = 0;
>> hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
>> +
>> + if (conn_state->hdmi.tmds_char_rate > HDMI14_MAX_TMDSCLK)
>> + dw_hdmi_qp_enable_scramb(hdmi);
>> } else {
>> dev_dbg(hdmi->dev, "%s mode=DVI\n", __func__);
>> op_mode = OPMODE_DVI;
>> @@ -781,7 +887,7 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
>> dw_hdmi_qp_mod(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0);
>> dw_hdmi_qp_mod(hdmi, op_mode, OPMODE_DVI, LINK_CONFIG0);
>>
>> - drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
>> + drm_atomic_helper_connector_hdmi_update_infoframes(hdmi->curr_conn, state);
>> }
>>
>> static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge,
>> @@ -791,14 +897,49 @@ static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge,
>>
>> hdmi->tmds_char_rate = 0;
>>
>> + dw_hdmi_qp_disable_scramb(hdmi);
>> +
>> + hdmi->curr_conn = NULL;
>> hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
>> }
>>
>> -static enum drm_connector_status
>> -dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector)
>> +static int dw_hdmi_qp_reset_crtc(struct dw_hdmi_qp *hdmi,
>> + struct drm_connector *connector,
>> + struct drm_modeset_acquire_ctx *ctx)
>> +{
>> + u8 config;
>> + int ret;
>> +
>> + ret = drm_scdc_readb(hdmi->bridge.ddc, SCDC_TMDS_CONFIG, &config);
>> + if (ret < 0) {
>> + dev_err(hdmi->dev, "Failed to read TMDS config: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + if (!!(config & SCDC_SCRAMBLING_ENABLE) == hdmi->scramb_enabled)
>> + return 0;
>
> Also please check the high TMDS clock ration bit.
Ack.
>> +
>> + drm_atomic_helper_connector_hdmi_hotplug(connector,
>> + connector_status_connected);
>
> I don't see a forced hotplug event in the existing drivers. Why is it
> necessary? This function is being called from the detect() path.
For some reason, without it, the connector seems to lose its state after reset:
[ 2142.982967] dwhdmiqp-rockchip fde80000.hdmi: resetting crtc
[ 2142.994132] rockchip-drm display-subsystem: [drm] HDMI Sink doesn't support RGB, something's wrong.
[ 2143.140827] dwhdmiqp-rockchip fde80000.hdmi: dw_hdmi_qp_bridge_atomic_enable mode=DVI
Will recheck if that's still the case after the HPD handling rework.
>
>> + /*
>> + * Conform to HDMI 2.0 spec by ensuring scrambled data is not sent
>> + * before configuring the sink scrambling, as well as suspending any
>> + * TMDS transmission while changing the TMDS clock rate in the sink.
>> + */
>> +
>> + dev_dbg(hdmi->dev, "resetting crtc\n");
>> +
>> + return drm_bridge_helper_reset_crtc(&hdmi->bridge, ctx);
>> +}
>> +
>> +static int dw_hdmi_qp_bridge_detect_ctx(struct drm_bridge *bridge,
>> + struct drm_connector *connector,
>> + struct drm_modeset_acquire_ctx *ctx)
>> {
>> struct dw_hdmi_qp *hdmi = bridge->driver_private;
>> + enum drm_connector_status status;
>> const struct drm_edid *drm_edid;
>> + int ret;
>>
>> if (hdmi->no_hpd) {
>> drm_edid = drm_edid_read_ddc(connector, bridge->ddc);
>> @@ -808,7 +949,20 @@ dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connec
>> return connector_status_disconnected;
>> }
>>
>> - return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
>> + status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
>> +
>> + dev_dbg(hdmi->dev, "%s status=%d scramb=%d\n", __func__,
>> + status, hdmi->scramb_enabled);
>> +
>> + if (status == connector_status_connected && hdmi->scramb_enabled) {
>> + ret = dw_hdmi_qp_reset_crtc(hdmi, connector, ctx);
>> + if (ret == -EDEADLK)
>> + return ret;
>> + if (ret < 0)
>> + status = connector_status_unknown;
>
> Ideally this should go to the drm_atomic_helper_connector_hdmi_update().
> And once it goes, I don't think we'd need the detect_ctx() callback for
> bridges.
Ok, I'll try that.
Regards,
Cristian
^ permalink raw reply
* Re: [PATCH v2 07/11] drm/bridge: lt9611: switch to of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-28 13:53 UTC (permalink / raw)
To: Gyeyoung Baek
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tian Tao, Xinwei Kong,
Sumit Semwal, John Stultz, Andrzej Hajda, Neil Armstrong,
Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
Tomi Valkeinen, Michal Simek, Hui Pu, Ian Ray, Thomas Petazzoni,
dri-devel, linux-kernel, linux-arm-msm, freedreno,
linux-arm-kernel
In-Reply-To: <CAKbEznt-PUvg48tegibw+0xYCCvK+1jwESnuHx9+MG0p3MD5gA@mail.gmail.com>
On Tue Apr 28, 2026 at 3:18 PM CEST, Gyeyoung Baek wrote:
>>
>> @@ -1058,7 +1057,11 @@ static int lt9611_parse_dt(struct device *dev,
>>
>> lt9611->ac_mode = of_property_read_bool(dev->of_node, "lt,ac-mode");
>>
>> - return drm_of_find_panel_or_bridge(dev->of_node, 2, -1, NULL, <9611->next_bridge);
>> + lt9611->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 2, -1);
>> + if (IS_ERR(lt9611->bridge.next_bridge))
>> + return PTR_ERR(lt9611->bridge.next_bridge);
>> +
>> + return 0;
>> }
>
> Hello Luca,
> Could you take a look at this alternative?
> ------
> struct drm_bridge *next_bridge =
> of_drm_get_bridge_by_endpoint(dev->of_node, 2, -1);
>
> if (IS_ERR(next_bridge))
> return PTR_ERR(next_bridge);
>
> lt9611->bridge.next_bridge = next_bridge;
> return 0;
> ------
>
> I think it reads a bit cleaner and avoids holding the ERR_PTR in the struct.
Yes, but more verbose.
Based on this and the patch 8 fallback reported by Biju, I started
wondering whether the v1 version of this function, while being a bit ugly,
was leading to cleaner code... An example: [0].
Dmitry, your opinion?
[0] https://lore.kernel.org/all/20260413-drm-bridge-alloc-getput-panel_or_bridge-v1-6-acd01cd79a1f@bootlin.com/
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v4 3/3] coco: guest: arm64: Query host IPA-change alignment via RHI
From: Will Deacon @ 2026-04-28 13:56 UTC (permalink / raw)
To: Aneesh Kumar K.V (Arm)
Cc: linux-kernel, iommu, linux-coco, linux-arm-kernel, kvmarm,
Catalin Marinas, Jason Gunthorpe, Marc Zyngier, Marek Szyprowski,
Robin Murphy, Steven Price, Suzuki K Poulose, Thomas Gleixner,
sebastianene
In-Reply-To: <20260427063108.909019-4-aneesh.kumar@kernel.org>
[+Seb for the ITS]
On Mon, Apr 27, 2026 at 12:01:08PM +0530, Aneesh Kumar K.V (Arm) wrote:
> Add the Realm Host Interface support needed to query host configuration
> from a Realm guest. Define the RHI hostconf SMCs, add rsi_host_call(), and
> use them during Realm initialization to retrieve the host IPA-change
> alignment size.
>
> Expose that alignment through realm_get_hyp_pagesize() and
> mem_decrypt_granule_size() so shared-buffer allocation and
> encryption/decryption paths can honor the ipa change page-size requirement.
>
> If the host reports an invalid alignment (when alginment value is not
> multiple of 4K), do not enable Realm support.
>
> This provides the host alignment information required by the shared buffer
> alignment changes.
>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
> arch/arm64/include/asm/mem_encrypt.h | 3 ++
> arch/arm64/include/asm/rhi.h | 24 +++++++++++++
> arch/arm64/include/asm/rsi.h | 2 ++
> arch/arm64/include/asm/rsi_cmds.h | 10 ++++++
> arch/arm64/include/asm/rsi_smc.h | 7 ++++
> arch/arm64/kernel/Makefile | 2 +-
> arch/arm64/kernel/rhi.c | 54 ++++++++++++++++++++++++++++
> arch/arm64/kernel/rsi.c | 13 +++++++
> arch/arm64/mm/mem_encrypt.c | 8 +++++
> 9 files changed, 122 insertions(+), 1 deletion(-)
> create mode 100644 arch/arm64/include/asm/rhi.h
> create mode 100644 arch/arm64/kernel/rhi.c
[...]
> diff --git a/arch/arm64/mm/mem_encrypt.c b/arch/arm64/mm/mem_encrypt.c
> index 38c62c9e4e74..f5d64bc29c20 100644
> --- a/arch/arm64/mm/mem_encrypt.c
> +++ b/arch/arm64/mm/mem_encrypt.c
> @@ -59,3 +59,11 @@ int set_memory_decrypted(unsigned long addr, int numpages)
> return crypt_ops->decrypt(addr, numpages);
> }
> EXPORT_SYMBOL_GPL(set_memory_decrypted);
> +
> +size_t mem_decrypt_granule_size(void)
> +{
> + if (is_realm_world())
> + return max(PAGE_SIZE, realm_get_hyp_pagesize());
> + return PAGE_SIZE;
No, this should be indirected via 'struct arm64_mem_crypt_ops' because
there's nothing particularly unique to realms here. For pKVM protected
guests using a smaller page-size than the host, we'd presumably need
something similar for the ITS (where restricted-dma isn't used).
Will
^ permalink raw reply
* [PATCH RESEND] firmware: imx: sm-misc: Make scmi_imx_misc_ctrl_nb variable static
From: Krzysztof Kozlowski @ 2026-04-28 13:57 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
imx, linux-arm-kernel, linux-kernel
Cc: Krzysztof Kozlowski, Daniel Baluta
File-scope 'scmi_imx_misc_ctrl_nb' is not used outside of this unit, so
make it static to silence sparse warning:
sm-misc.c:19:23: warning: symbol 'scmi_imx_misc_ctrl_nb' was not declared. Should it be static?
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
drivers/firmware/imx/sm-misc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c
index 16b5ff833d21..ac9af824c2d4 100644
--- a/drivers/firmware/imx/sm-misc.c
+++ b/drivers/firmware/imx/sm-misc.c
@@ -16,7 +16,7 @@
static const struct scmi_imx_misc_proto_ops *imx_misc_ctrl_ops;
static struct scmi_protocol_handle *ph;
-struct notifier_block scmi_imx_misc_ctrl_nb;
+static struct notifier_block scmi_imx_misc_ctrl_nb;
static const char * const rst_imx95[] = {
"cm33_lockup", "cm33_swreq", "cm7_lockup", "cm7_swreq", "fccu",
--
2.51.0
^ permalink raw reply related
* Re: [PATCH v5 09/10] drm/rockchip: dw_hdmi_qp: Register HPD IRQ after connector setup
From: Cristian Ciocaltea @ 2026-04-28 13:58 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Heiko Stübner, Andy Yan, kernel, dri-devel, linux-kernel,
linux-arm-kernel, linux-rockchip, Diederik de Haas,
Maud Spierings
In-Reply-To: <hnbecmgviu7jl4xrsksna63sa376gpcaa6ate2qp2o5lgg35ot@wdthrayons3k>
On 4/28/26 4:41 AM, Dmitry Baryshkov wrote:
> On Sun, Apr 26, 2026 at 03:20:21AM +0300, Cristian Ciocaltea wrote:
>> Move devm_request_threaded_irq() to the end of bind(), after
>> drm_bridge_connector_init() and drm_connector_attach_encoder(), to
>> ensure all DRM resources are ready before HPD interrupts can fire.
>>
>> While at it, add error handling for drm_connector_attach_encoder().
>>
>> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
>> Tested-by: Maud Spierings <maud_spierings@hotmail.com>
>> Reviewed-by: Heiko Stuebner <heiko@sntech.de>
>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
>> ---
>> drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 18 +++++++++---------
>> 1 file changed, 9 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
>> index 618d2aaa5c7d..fbbe26f8730c 100644
>> --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
>> +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
>> @@ -577,14 +577,6 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
>> if (irq < 0)
>> return irq;
>>
>> - ret = devm_request_threaded_irq(dev, irq,
>> - cfg->ctrl_ops->hardirq_callback,
>> - cfg->ctrl_ops->irq_callback,
>> - IRQF_SHARED, "dw-hdmi-qp-hpd",
>> - hdmi);
>> - if (ret)
>> - return ret;
>> -
>> drm_encoder_helper_add(encoder, &dw_hdmi_qp_rockchip_encoder_helper_funcs);
>> ret = drmm_encoder_init(drm, encoder, NULL, DRM_MODE_ENCODER_TMDS, NULL);
>> if (ret)
>> @@ -602,7 +594,15 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
>> return dev_err_probe(dev, PTR_ERR(connector),
>> "Failed to init bridge connector\n");
>>
>> - return drm_connector_attach_encoder(connector, encoder);
>> + ret = drm_connector_attach_encoder(connector, encoder);
>> + if (ret)
>> + return dev_err_probe(dev, ret, "Failed to attach connector\n");
>> +
>> + return devm_request_threaded_irq(dev, irq,
>> + cfg->ctrl_ops->hardirq_callback,
>> + cfg->ctrl_ops->irq_callback,
>> + IRQF_SHARED, "dw-hdmi-qp-hpd",
>> + hdmi);
>
> And if requesting of the IRQ fails, you have a lot to unwind. It might
> be better to request IRQ early enough with the IRQF_NO_AUTOEN flag and
> then enable_irq() here.
Indeed, that'd be a better approach.
Thanks,
Cristian
^ permalink raw reply
* RE: [PATCH v2 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
From: Biju Das @ 2026-04-28 14:02 UTC (permalink / raw)
To: Luca Ceresoli, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
Marijn Suijten, Tian Tao, Xinwei Kong, Sumit Semwal, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, laurent.pinchart,
Jonas Karlman, Jernej Skrabec, tomi.valkeinen, Michal Simek
Cc: Hui Pu, Ian Ray, Thomas Petazzoni,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <DI4U2DT3OBMR.23T3F7X8P75RU@bootlin.com>
Hi Luca,
> -----Original Message-----
> From: Luca Ceresoli <luca.ceresoli@bootlin.com>
> Sent: 28 April 2026 14:48
> Subject: Re: [PATCH v2 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
>
> Hello,
>
> On Tue Apr 28, 2026 at 3:31 PM CEST, Biju Das wrote:
> >> >> > @@ -1251,10 +1251,9 @@ static int adv7511_probe(struct
> >> >> > i2c_client
> >> >> > *i2c)
> >> >> >
> >> >> > memset(&link_config, 0, sizeof(link_config));
> >> >> >
> >> >> > - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,
> >> >> > - &adv7511->next_bridge);
> >> >> > - if (ret && ret != -ENODEV)
> >> >> > - return ret;
> >> >> > + adv7511->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 1, -1);
> >> >> > + if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) != -ENODEV)
> >> >> > + return PTR_ERR(adv7511->bridge.next_bridge);
> >> >>
> >> >> Does it crash, if the error is -EPROBE_DEFER?
> >> >
> >> > I see a crash with patch [1], which is fixed by avoiding the direct assignment.
> >>
> >> Ah, dammit! Good catch, thanks for the quick testing and follow-up!
> >>
> >> Indeed this driver assumes next_bridge is either NULL or a valid
> >> pointer, but due to the 'if(IS_ERR() && some_other_condition)' now it can also be -ENODEV (not -
> EPROBE_DEFER, but that's irrelevant).
> >>
> >> This affects the msm and zynqmp_dp patches equally.
> >>
> >> I'm sending a v3 soon with these fixed. I'm just not sure which
> >> approach to use to fix (same for all the 3 patches). Alternatives are:
> >>
> >> 1. -ENODEV is accepted, set next_bridge to NULL when it happens:
> >>
> >> - if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) != -
> >> ENODEV)
> >> - return PTR_ERR(adv7511->bridge.next_bridge);
> >> + if (IS_ERR(adv7511->bridge.next_bridge)) {
> >> + if (PTR_ERR(adv7511->bridge.next_bridge) == -ENODEV)
> >> + adv7511->bridge.next_bridge = NULL;
> >> + else
> >> + return PTR_ERR(adv7511->bridge.next_bridge);
> >
> > The point is you cannot return PTR_ERR as it will lead to crash, if it
> > is direct assignment.
>
> It would definitely crash when the next_bridge is dereferenced (which happens in
> adv7511_bridge_attach()) but I don't see how it can crash here. Here it _can_ be assigned -ENODEV, but
> it would be immediately be cleared to NULL, or to enother error, but we'd immediately return. And in
> case of return, when next_bridge is cleared by __drm_bridge_free -> drm_bridge_put, the error value
> would be ignored thanks to patch 1.
OK, I haven't noticed the newly introduced check in drm_bridge_put() in patch#1.
I guess, we should avoid putting error values in bridge.next_bridge.
It should be either NULL or Valid pointer, not PTR_ERR.
Cheers,
Biju
^ permalink raw reply
* Re: [GIT PULL 2/4] i.MX arm dts changes for v7.1
From: Sébastien Szymanski @ 2026-04-28 14:03 UTC (permalink / raw)
To: Frank Li, soc, arm
Cc: Shawn Guo, Fabio Estevam, kernel, imx, linux-arm-kernel
In-Reply-To: <20260330141444.3789193-3-Frank.Li@nxp.com>
Hello,
On 3/30/26 4:14 PM, Frank Li wrote:
> ARM: dts: imx: remove redundant intermediate node in pinmux hierarchy
This commit breaks Linux 7.1-rc1 boot on my APF27Dev board. I see the
following errors with earlyprintk enabled:
[ 0.346162] imx27-pinctrl 10015000.pinmux: unable to find group for
node i2c1grp
[ 0.354438] imx27-pinctrl 10015000.pinmux: unable to find group for
node i2c2grp
...
[ 0.636217] imx27-pinctrl 10015000.pinmux: unable to find group for
node pwmgrp
[ 0.644346] imx27-pinctrl 10015000.pinmux: unable to find group for
node gpioledsgrp
[ 0.657247] imx27-pinctrl 10015000.pinmux: unable to find group for
node uart1grp
...
[ 0.868102] imx27-pinctrl 10015000.pinmux: unable to find group for
node cspi1grp
[ 0.876513] imx27-pinctrl 10015000.pinmux: unable to find group for
node cspi2grp
[ 0.888903] imx27-pinctrl 10015000.pinmux: unable to find group for
node fec1grp
...
[ 2.413181] imx27-pinctrl 10015000.pinmux: unable to find group for
node gpiokeysgrp
Reverting the commit makes the errors disappear and the board boot again.
Should I send a patch reverting this commit ?
Regards,
--
Sébastien Szymanski, Armadeus Systems
Software engineer
^ permalink raw reply
* [PATCH net v4] net: dsa: mt7530: fix .get_stats64 sleeping in atomic context
From: Daniel Golle @ 2026-04-28 14:10 UTC (permalink / raw)
To: Chester A. Unal, Daniel Golle, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Matthias Brugger, AngeloGioacchino Del Regno, Russell King,
Christian Marangi, netdev, linux-kernel, linux-arm-kernel,
linux-mediatek
The .get_stats64 callback runs in atomic context, but on
MDIO-connected switches every register read acquires the MDIO bus
mutex, which can sleep:
[ 12.645973] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:609
[ 12.654442] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 759, name: grep
[ 12.663377] preempt_count: 0, expected: 0
[ 12.667410] RCU nest depth: 1, expected: 0
[ 12.671511] INFO: lockdep is turned off.
[ 12.675441] CPU: 0 UID: 0 PID: 759 Comm: grep Tainted: G S W 7.0.0+ #0 PREEMPT
[ 12.675453] Tainted: [S]=CPU_OUT_OF_SPEC, [W]=WARN
[ 12.675456] Hardware name: Bananapi BPI-R64 (DT)
[ 12.675459] Call trace:
[ 12.675462] show_stack+0x14/0x1c (C)
[ 12.675477] dump_stack_lvl+0x68/0x8c
[ 12.675487] dump_stack+0x14/0x1c
[ 12.675495] __might_resched+0x14c/0x220
[ 12.675504] __might_sleep+0x44/0x80
[ 12.675511] __mutex_lock+0x50/0xb10
[ 12.675523] mutex_lock_nested+0x20/0x30
[ 12.675532] mt7530_get_stats64+0x40/0x2ac
[ 12.675542] dsa_user_get_stats64+0x2c/0x40
[ 12.675553] dev_get_stats+0x44/0x1e0
[ 12.675564] dev_seq_printf_stats+0x24/0xe0
[ 12.675575] dev_seq_show+0x14/0x3c
[ 12.675583] seq_read_iter+0x37c/0x480
[ 12.675595] seq_read+0xd0/0xec
[ 12.675605] proc_reg_read+0x94/0xe4
[ 12.675615] vfs_read+0x98/0x29c
[ 12.675625] ksys_read+0x54/0xdc
[ 12.675633] __arm64_sys_read+0x18/0x20
[ 12.675642] invoke_syscall.constprop.0+0x54/0xec
[ 12.675653] do_el0_svc+0x3c/0xb4
[ 12.675662] el0_svc+0x38/0x200
[ 12.675670] el0t_64_sync_handler+0x98/0xdc
[ 12.675679] el0t_64_sync+0x158/0x15c
For MDIO-connected switches, poll MIB counters asynchronously using a
delayed workqueue every second and let .get_stats64 return the cached
values under a spinlock. A mod_delayed_work() call on each read
triggers an immediate refresh so counters stay responsive when queried
more frequently.
MMIO-connected switches (MT7988, EN7581, AN7583) are not affected
because their regmap does not sleep, so they continue to read MIB
counters directly in .get_stats64.
Fixes: 88c810f35ed5 ("net: dsa: mt7530: implement .get_stats64")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Acked-by: Chester A. Unal <chester.a.unal@arinc9.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
v4:
* extract mt7530_stats_refresh() helper from mt7530_stats_poll()
-> mt7530_stats_poll() now just refreshes and re-arms
* call helper synchronously in mt753x_setup() to seed the cache
* avoid zeroed counters during the first poll interval
* avoid INITIAL_JIFFIES vs stats_last==0 wraparound on 32-bit
* swap deprecated system_wq for system_percpu_wq in get_stats64
* keeps on-demand refresh on the same queue as schedule_*_work
v3:
* move `stats_last` access under the spinlock to avoid potential race
v2:
* use spin_lock_bh()/spin_unlock_bh() to prevent potential deadlock
* rate-limit mod_delayed_work() refresh to at most once per 100ms
* move cancel_delayed_work_sync() after dsa_unregister_switch()
* add mt753x_teardown() callback to cancel the stats work
* fix commit message
drivers/net/dsa/mt7530.c | 76 ++++++++++++++++++++++++++++++++++++++--
drivers/net/dsa/mt7530.h | 8 +++++
2 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index b9423389c2ef..66bff861a921 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -25,6 +25,9 @@
#include "mt7530.h"
+#define MT7530_STATS_POLL_INTERVAL (1 * HZ)
+#define MT7530_STATS_RATE_LIMIT (HZ / 10)
+
static struct mt753x_pcs *pcs_to_mt753x_pcs(struct phylink_pcs *pcs)
{
return container_of(pcs, struct mt753x_pcs, pcs);
@@ -906,10 +909,9 @@ static void mt7530_get_rmon_stats(struct dsa_switch *ds, int port,
*ranges = mt7530_rmon_ranges;
}
-static void mt7530_get_stats64(struct dsa_switch *ds, int port,
- struct rtnl_link_stats64 *storage)
+static void mt7530_read_port_stats64(struct mt7530_priv *priv, int port,
+ struct rtnl_link_stats64 *storage)
{
- struct mt7530_priv *priv = ds->priv;
uint64_t data;
/* MIB counter doesn't provide a FramesTransmittedOK but instead
@@ -951,6 +953,54 @@ static void mt7530_get_stats64(struct dsa_switch *ds, int port,
&storage->rx_crc_errors);
}
+static void mt7530_stats_refresh(struct mt7530_priv *priv)
+{
+ struct rtnl_link_stats64 stats = {};
+ struct dsa_port *dp;
+ int port;
+
+ dsa_switch_for_each_user_port(dp, priv->ds) {
+ port = dp->index;
+
+ mt7530_read_port_stats64(priv, port, &stats);
+
+ spin_lock_bh(&priv->stats_lock);
+ priv->ports[port].stats = stats;
+ priv->stats_last = jiffies;
+ spin_unlock_bh(&priv->stats_lock);
+ }
+}
+
+static void mt7530_stats_poll(struct work_struct *work)
+{
+ struct mt7530_priv *priv = container_of(work, struct mt7530_priv,
+ stats_work.work);
+
+ mt7530_stats_refresh(priv);
+ schedule_delayed_work(&priv->stats_work,
+ MT7530_STATS_POLL_INTERVAL);
+}
+
+static void mt7530_get_stats64(struct dsa_switch *ds, int port,
+ struct rtnl_link_stats64 *storage)
+{
+ struct mt7530_priv *priv = ds->priv;
+ bool refresh;
+
+ if (priv->bus) {
+ spin_lock_bh(&priv->stats_lock);
+ *storage = priv->ports[port].stats;
+ refresh = time_after(jiffies, priv->stats_last +
+ MT7530_STATS_RATE_LIMIT);
+ spin_unlock_bh(&priv->stats_lock);
+ if (refresh)
+ mod_delayed_work(system_percpu_wq,
+ &priv->stats_work, 0);
+ } else {
+ mt7530_read_port_stats64(priv, port, storage);
+ }
+}
+
static void mt7530_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
struct ethtool_eth_ctrl_stats *ctrl_stats)
{
@@ -3137,9 +3187,25 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq_domain)
mt7530_free_mdio_irq(priv);
+ if (!ret && priv->bus) {
+ spin_lock_init(&priv->stats_lock);
+ INIT_DELAYED_WORK(&priv->stats_work, mt7530_stats_poll);
+ mt7530_stats_refresh(priv);
+ schedule_delayed_work(&priv->stats_work,
+ MT7530_STATS_POLL_INTERVAL);
+ }
+
return ret;
}
+static void mt753x_teardown(struct dsa_switch *ds)
+{
+ struct mt7530_priv *priv = ds->priv;
+
+ if (priv->bus)
+ cancel_delayed_work_sync(&priv->stats_work);
+}
+
static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
struct ethtool_keee *e)
{
@@ -3257,6 +3323,7 @@ static int mt7988_setup(struct dsa_switch *ds)
static const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
+ .teardown = mt753x_teardown,
.preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,
.get_strings = mt7530_get_strings,
.get_ethtool_stats = mt7530_get_ethtool_stats,
@@ -3409,6 +3476,9 @@ mt7530_remove_common(struct mt7530_priv *priv)
dsa_unregister_switch(priv->ds);
+ if (priv->bus)
+ cancel_delayed_work_sync(&priv->stats_work);
+
mutex_destroy(&priv->reg_mutex);
}
EXPORT_SYMBOL_GPL(mt7530_remove_common);
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 3e0090bed298..dd33b0df3419 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -796,6 +796,7 @@ struct mt7530_fdb {
* @pvid: The VLAN specified is to be considered a PVID at ingress. Any
* untagged frames will be assigned to the related VLAN.
* @sgmii_pcs: Pointer to PCS instance for SerDes ports
+ * @stats: Cached port statistics for MDIO-connected switches
*/
struct mt7530_port {
bool enable;
@@ -803,6 +804,7 @@ struct mt7530_port {
u32 pm;
u16 pvid;
struct phylink_pcs *sgmii_pcs;
+ struct rtnl_link_stats64 stats;
};
/* Port 5 mode definitions of the MT7530 switch */
@@ -875,6 +877,9 @@ struct mt753x_info {
* @create_sgmii: Pointer to function creating SGMII PCS instance(s)
* @active_cpu_ports: Holding the active CPU ports
* @mdiodev: The pointer to the MDIO device structure
+ * @stats_lock: Protects cached per-port stats from concurrent access
+ * @stats_work: Delayed work for polling MIB counters on MDIO switches
+ * @stats_last: Jiffies timestamp of last MIB counter poll
*/
struct mt7530_priv {
struct device *dev;
@@ -900,6 +905,9 @@ struct mt7530_priv {
int (*create_sgmii)(struct mt7530_priv *priv);
u8 active_cpu_ports;
struct mdio_device *mdiodev;
+ spinlock_t stats_lock; /* protects cached stats counters */
+ struct delayed_work stats_work;
+ unsigned long stats_last;
};
struct mt7530_hw_vlan_entry {
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v5 10/10] drm/rockchip: dw_hdmi_qp: Restrict HPD event to the affected connector
From: Cristian Ciocaltea @ 2026-04-28 14:10 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Sandy Huang,
Heiko Stübner, Andy Yan, kernel, dri-devel, linux-kernel,
linux-arm-kernel, linux-rockchip, Diederik de Haas,
Maud Spierings
In-Reply-To: <xwsnwqk2bqixswue7ajy5tfzxn6u7sfuqlpquywsrdj3bs6nmb@pv6szzdjjuzu>
On 4/28/26 4:53 AM, Dmitry Baryshkov wrote:
> On Sun, Apr 26, 2026 at 03:20:22AM +0300, Cristian Ciocaltea wrote:
>> Switch from drm_helper_hpd_irq_event(), which polls all connectors, to
>> drm_connector_helper_hpd_irq_event(), which runs the detect cycle only
>> on the affected connector.
>>
>> This avoids unnecessary work and redundant detect calls on unrelated
>> connectors.
>
> This also doesn't feel correct. The dw_hdmi_qp is a bridge. As such it
> should be using drm_bridge_hpd_notify() rather than any of the mentioned
> functions. Would it be better to add the a corresponding wrapper to the
> dw_hdmi_qp API and call one there?
Let me try that.
> Also consider implementing the
> .hpd_enable() and .hpd_disable() callbacks for the bridge, which would
> remove the necessity to call enable the IRQ in the bind function.
Ack.
Thanks,
Cristian
^ permalink raw reply
* Re: [PATCH v4 01/15] arm64: mm: Map the linear alias of text/rodata as tagged
From: Kevin Brodsky @ 2026-04-28 14:16 UTC (permalink / raw)
To: Ard Biesheuvel, linux-arm-kernel
Cc: linux-kernel, will, catalin.marinas, mark.rutland, Ard Biesheuvel,
Ryan Roberts, Anshuman Khandual, Liz Prucka, Seth Jenkins,
Kees Cook, Mike Rapoport, David Hildenbrand, Andrew Morton,
linux-mm, linux-hardening
In-Reply-To: <20260427153416.2103979-18-ardb+git@google.com>
On 27/04/2026 17:34, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
>
> Before moving the empty_zero_page into the __ro_after_init section, make
> sure it has the memory-tagged type. This is needed to ensure that
> cpu_enable_mte() will be able to initialize the tags correctly.
mark_linear_text_alias_ro() is called after all features have been
detected and enabled, so do we actually need this?
AFAICT the lines that matter for cpu_enable_mte() are those, in map_mem():
__map_memblock(pgdp, kernel_start, kernel_end,
PAGE_KERNEL, NO_CONT_MAPPINGS);
It is probably this call that needs to be changed to use
pgprot_tagged(PAGE_KERNEL).
- Kevin
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> arch/arm64/mm/mmu.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index dd85e093ffdb..f084993024ab 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -1049,7 +1049,7 @@ void __init mark_linear_text_alias_ro(void)
> */
> update_mapping_prot(__pa_symbol(_text), (unsigned long)lm_alias(_text),
> (unsigned long)__init_begin - (unsigned long)_text,
> - PAGE_KERNEL_RO);
> + pgprot_tagged(PAGE_KERNEL_RO));
> }
>
> #ifdef CONFIG_KFENCE
^ permalink raw reply
* Re: [PATCH v4 02/15] mm: Make empty_zero_page __ro_after_init
From: Kevin Brodsky @ 2026-04-28 14:16 UTC (permalink / raw)
To: Ard Biesheuvel, linux-arm-kernel
Cc: linux-kernel, will, catalin.marinas, mark.rutland, Ard Biesheuvel,
Ryan Roberts, Anshuman Khandual, Liz Prucka, Seth Jenkins,
Kees Cook, Mike Rapoport, David Hildenbrand, Andrew Morton,
linux-mm, linux-hardening
In-Reply-To: <20260427153416.2103979-19-ardb+git@google.com>
On 27/04/2026 17:34, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
>
> The empty zero page is used to back any kernel or user space mapping
> that is supposed to remain cleared, and so the page itself is never
> supposed to be modified.
>
> So make it __ro_after_init rather than __page_aligned_bss: on most
> architectures, this ensures that both the kernel's mapping of it and any
> aliases that are accessible via the kernel direct (linear) map are
> mapped read-only, and cannot be used (inadvertently or maliciously) to
> corrupt the contents of the zero page.
>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> mm/mm_init.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mm/mm_init.c b/mm/mm_init.c
> index f9f8e1af921c..6ca01ed2a5a4 100644
> --- a/mm/mm_init.c
> +++ b/mm/mm_init.c
> @@ -57,7 +57,7 @@ unsigned long zero_page_pfn __ro_after_init;
> EXPORT_SYMBOL(zero_page_pfn);
>
> #ifndef __HAVE_COLOR_ZERO_PAGE
> -uint8_t empty_zero_page[PAGE_SIZE] __page_aligned_bss;
> +uint8_t empty_zero_page[PAGE_SIZE] __ro_after_init __aligned(PAGE_SIZE);
> EXPORT_SYMBOL(empty_zero_page);
>
> struct page *__zero_page __ro_after_init;
^ permalink raw reply
* Re: [PATCH 2/8] KVM: arm64: Synchronise HCR_EL2 writes on the guest exit path
From: Fuad Tabba @ 2026-04-28 14:21 UTC (permalink / raw)
To: Will Deacon
Cc: maz, oliver.upton, james.morse, suzuki.poulose, yuzenghui,
qperret, vdonnefort, catalin.marinas, linux-arm-kernel, kvmarm,
linux-kernel, stable
In-Reply-To: <afC7H1fu4vFzTRTt@willie-the-truck>
Hi Will,
On Tue, 28 Apr 2026 at 14:50, Will Deacon <will@kernel.org> wrote:
>
> On Tue, Apr 28, 2026 at 11:30:02AM +0100, Fuad Tabba wrote:
> > MSR HCR_EL2 is not self-synchronising. Per ARM DDI 0487 M.b K1.2.4
> > (p.K1-16823) and B2.6.1 (p.B2-297), a Context Synchronisation Event
> > is required between an HCR_EL2 write and any subsequent direct
> > register access at the same EL that depends on the new value being
> > in effect.
> >
> > On the entry path, the HCR_EL2 write in __activate_traps is followed
> > by further EL2 sysreg work (MDCR_EL2, CPTR_EL2, VBAR_EL2, and on the
> > speculative-AT errata path SCTLR_EL1/TCR_EL1) before ERET into the
> > guest. None of those intervening accesses depend on the new HCR_EL2
> > value, and ERET is a CSE per ARM DDI 0487 M.b D1.4.4.1 rule RBWCFK
> > (p. D1-7209) conditional on SCTLR_EL2.EOS=1, which is set
> > unconditionally by INIT_SCTLR_EL2_MMU_ON (see the prerequisite patch
> > in this series). The requirement is therefore satisfied implicitly
> > on the activate path.
> >
> > The deactivate path is different: after write_sysreg_hcr() in
> > __deactivate_traps() further EL2 sysreg work runs before any natural
> > CSE - on nVHE, __deactivate_cptr_traps and the VBAR_EL2 write; on
> > VHE, the timer context save which reads CNTP_CVAL_EL0 under the new
> > TGE/E2H, and the EL1 sysreg restore. Add an explicit isb() at each
> > of the two deactivate sites.
> >
> > The practical impact today is bounded: HCR_EL2.E2H does not toggle
> > in either path, and the trap bits being changed primarily affect
> > EL1&0 behaviour. But the architectural rule should be honoured.
> > Note that write_sysreg_hcr() itself already issues isb() on the
> > Ampere errata path (sysreg.h), confirming the architectural
> > expectation; the fast path optimises that away.
> >
> > The fix is at the call sites rather than inside write_sysreg_hcr()
> > because the macro has many users (e.g. the activate path, at.c,
> > hardirq.h, ptrauth alternatives) where the immediately-following
> > code either reaches ERET or has another CSE; making the macro emit
> > an unconditional ISB would impose unnecessary cost on those
> > well-formed users.
> >
> > Fixes: 9404673293b0 ("KVM: arm64: timers: Correctly handle TGE flip with CNTPOFF_EL2")
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> > arch/arm64/kvm/hyp/nvhe/switch.c | 11 +++++++++++
> > arch/arm64/kvm/hyp/vhe/switch.c | 11 +++++++++++
> > 2 files changed, 22 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> > index 8d1df3d33595..9d7ead5a5503 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> > @@ -105,6 +105,17 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
> > __deactivate_traps_common(vcpu);
> >
> > write_sysreg_hcr(this_cpu_ptr(&kvm_init_params)->hcr_el2);
> > + /*
> > + * MSR HCR_EL2 is not self-synchronising. Per ARM ARM K1.2.4 p.K1-16823
> > + * and B2.6.1 p.B2-297, a Context Synchronisation Event is required
> > + * between an HCR_EL2 write and any subsequent direct register access at
> > + * the same EL that depends on the new value being in effect.
> > + * The activate_traps path falls through to ERET (a CSE), but the
> > + * deactivate path still executes further EL2 sysreg work (CPTR/VBAR
> > + * writes below) before any natural CSE, so make the synchronisation
> > + * explicit.
> > + */
> > + isb();
>
> Sorry, but I don't understand this. Please can you explain why you think
> that CPTR and VBAR have an ordering dependency on HCR_EL2? Preferably,
> the comment would talk about the specific fields that are relevant.
You're right, I misread the spec in my excitement to fix an issue
raised by my new and improved prompts. I went back to the access
pseudocode for the registers being written after write_sysreg_hcr():
- CPTR_EL2/VBAR_EL2 (nVHE) are direct EL2-only registers; their write
semantics at EL2 don't consult HCR_EL2.
- CPACR_EL1/VBAR_EL1/CNTP_CVAL_EL0 (VHE) redirect to their EL2
counterparts on ELIsInHost(EL2) — i.e., HCR_EL2.E2H — and E2H doesn't
toggle here. TGE isn't a condition for these EL2-level accesses.
So the whole "depends on the new value being in effect" doesn't
actually bite for any of the accesses I cited. I'll drop this patch.
The natural CSEs cover whatever real synchronisation is needed.
Cheers,
/fuad
>
> Will
^ permalink raw reply
* Re: [PATCH net] net: airoha: Move entries to queue head in case of DMA mapping failure in airoha_dev_xmit()
From: Lorenzo Bianconi @ 2026-04-28 14:27 UTC (permalink / raw)
To: Paolo Abeni
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Jacob Keller, Simon Horman, linux-arm-kernel, linux-mediatek,
netdev
In-Reply-To: <679ebe0a-5889-4a84-afd6-3da50a07bced@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 1475 bytes --]
> On 4/28/26 10:44 AM, Lorenzo Bianconi wrote:
> > In order to respect the original descriptor order and avoid any
> > potential IOMMU fault or memory corruption, move pending queue entries
> > to the head of hw queue tx_list if the DMA mapping of current inflight
> > packet fails in airoha_dev_xmit routine.
> >
> > Fixes: 3f47e67dff1f7 ("net: airoha: Add the capability to consume out-of-order DMA tx descriptors")
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> > drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> > index 5effb4a4ae84..82018a085e46 100644
> > --- a/drivers/net/ethernet/airoha/airoha_eth.c
> > +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> > @@ -2123,14 +2123,14 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
> > return NETDEV_TX_OK;
> >
> > error_unmap:
> > - while (!list_empty(&tx_list)) {
> > + list_for_each_entry(e, &tx_list, list) {
> > e = list_first_entry(&tx_list, struct airoha_queue_entry,
> > list);
>
> Coccinelle says:
>
> +/srv/nipa-builds-contest/testing/wt-cocci/drivers/net/ethernet/airoha/airoha_eth.c:2123:1-20:
> iterator with update on line 2124
>
> I guess you should additionally drop the statement above.
ack, sorry. I will fix it in v2.
Regards,
Lorenzo
>
> /P
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 03/43] KVM: arm64: gic-v5: Add resident/non-resident hyp calls
From: Marc Zyngier @ 2026-04-28 14:28 UTC (permalink / raw)
To: Sascha Bischoff
Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
kvm@vger.kernel.org, nd, oliver.upton@linux.dev, Joey Gouly,
Suzuki Poulose, yuzenghui@huawei.com, peter.maydell@linaro.org,
lpieralisi@kernel.org, Timothy Hayes
In-Reply-To: <20260427160547.3129448-4-sascha.bischoff@arm.com>
On Mon, 27 Apr 2026 17:07:03 +0100,
Sascha Bischoff <Sascha.Bischoff@arm.com> wrote:
>
> So far the KVM GICv5 support has been limited to PPIs. These only go
> as far out as the CPU interface, and have no interaction with the
> host's IRS. Therefore, PPIs can be directly used for guests without
> host IRS involvement. However, in order to support both SPIs and LPIs
> IRS involvement is required.
Please keep this in the cover letter. It isn't required to understand
this patch.
>
> GICv5 introduces the concept of VPE residency - a VPE can be either
> resident or non-resident. When the VPE is resident, the IRS is allowed
> to select interrupts that target that VPE (or the VM) as the HPPI
> (Highest Priority Pending Interrupt). As the IRS handles both SPIs and
> LPIs, these will only be picked as the IRS's HPPI when a VPE is
> resident.
>
> A GICv5 VPE is made resident by writing to the ICH_CONTEXTR_EL2 with a
> valid VM and VPE ID, and marking it valid in the process. This informs
> the IRS that a specific VPE is running, and that it can begin HPPI
> selection for that VPE. Making a VPE non-resident (by making the
> ICH_CONTEXTR_EL2 invalid) informs the IRS that the VPE is no longer
> running, and it stops HPPI selection for it.
>
> This change introduces two new hyp calls - one to make a VPE resident
> and its counterpart to make a VPE non-resident. As part of making a
> VPE resident, the ICH_CONTEXTR_EL2.F bit is checked in order to catch
> faults, at which point the kernel will WARN. If everything is
> configured correctly, this should not happen.
>
> Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
> ---
> arch/arm64/include/asm/kvm_asm.h | 2 ++
> arch/arm64/include/asm/kvm_hyp.h | 2 ++
> arch/arm64/kvm/hyp/nvhe/hyp-main.c | 15 +++++++++++++++
> arch/arm64/kvm/hyp/vgic-v5-sr.c | 25 +++++++++++++++++++++++++
> include/kvm/arm_vgic.h | 3 +++
> 5 files changed, 47 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index fa033be6141ad..8c69f1f4de534 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -79,6 +79,8 @@ enum __kvm_host_smccc_func {
> __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff,
> __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs,
> __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
> + __KVM_HOST_SMCCC_FUNC___vgic_v5_make_resident,
> + __KVM_HOST_SMCCC_FUNC___vgic_v5_make_non_resident,
> __KVM_HOST_SMCCC_FUNC___vgic_v5_save_apr,
> __KVM_HOST_SMCCC_FUNC___vgic_v5_restore_vmcr_apr,
>
> diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
> index 8d06b62e7188c..5f9184276b04e 100644
> --- a/arch/arm64/include/asm/kvm_hyp.h
> +++ b/arch/arm64/include/asm/kvm_hyp.h
> @@ -88,6 +88,8 @@ void __vgic_v3_restore_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if);
> int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu);
>
> /* GICv5 */
> +void __vgic_v5_make_resident(struct vgic_v5_cpu_if *cpu_if);
> +void __vgic_v5_make_non_resident(struct vgic_v5_cpu_if *cpu_if);
> void __vgic_v5_save_apr(struct vgic_v5_cpu_if *cpu_if);
> void __vgic_v5_restore_vmcr_apr(struct vgic_v5_cpu_if *cpu_if);
> /* No hypercalls for the following */
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 9e44c05cf780e..804a9ffdc8594 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -672,6 +672,19 @@ static void handle___tracing_write_event(struct kvm_cpu_context *host_ctxt)
> trace_selftest(id);
> }
>
> +static void handle___vgic_v5_make_resident(struct kvm_cpu_context *host_ctxt)
> +{
> + DECLARE_REG(struct vgic_v5_cpu_if *, cpu_if, host_ctxt, 1);
> +
> + __vgic_v5_make_resident(kern_hyp_va(cpu_if));
> +}
> +static void handle___vgic_v5_make_non_resident(struct kvm_cpu_context *host_ctxt)
> +{
> + DECLARE_REG(struct vgic_v5_cpu_if *, cpu_if, host_ctxt, 1);
> +
> + __vgic_v5_make_non_resident(kern_hyp_va(cpu_if));
> +}
> +
> static void handle___vgic_v5_save_apr(struct kvm_cpu_context *host_ctxt)
> {
> DECLARE_REG(struct vgic_v5_cpu_if *, cpu_if, host_ctxt, 1);
> @@ -711,6 +724,8 @@ static const hcall_t host_hcall[] = {
> HANDLE_FUNC(__kvm_timer_set_cntvoff),
> HANDLE_FUNC(__vgic_v3_save_aprs),
> HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
> + HANDLE_FUNC(__vgic_v5_make_resident),
> + HANDLE_FUNC(__vgic_v5_make_non_resident),
> HANDLE_FUNC(__vgic_v5_save_apr),
> HANDLE_FUNC(__vgic_v5_restore_vmcr_apr),
>
> diff --git a/arch/arm64/kvm/hyp/vgic-v5-sr.c b/arch/arm64/kvm/hyp/vgic-v5-sr.c
> index 6d69dfe89a96c..04c5846b9abac 100644
> --- a/arch/arm64/kvm/hyp/vgic-v5-sr.c
> +++ b/arch/arm64/kvm/hyp/vgic-v5-sr.c
> @@ -7,6 +7,31 @@
>
> #include <asm/kvm_hyp.h>
>
> +void __vgic_v5_make_resident(struct vgic_v5_cpu_if *cpu_if)
> +{
> + write_sysreg_s(cpu_if->vgic_contextr, SYS_ICH_CONTEXTR_EL2);
> + isb();
> +
> + /* Catch any faults */
> + cpu_if->vgic_contextr = read_sysreg_s(SYS_ICH_CONTEXTR_EL2);
> + if (WARN_ON(FIELD_GET(ICH_CONTEXTR_EL2_F, cpu_if->vgic_contextr)))
> + return;
I don't think this is particularly useful here. With non-VHE, this
results in a panic. If there is a problem, you need to fail the vcpu
entry early, and let the caller find out.
> +
> + cpu_if->gicv5_vpe.resident = true;
> +}
> +
> +void __vgic_v5_make_non_resident(struct vgic_v5_cpu_if *cpu_if)
> +{
> + /*
> + * Make as non-resident before actually making non-resident. Avoids race
> + * with doorbell arriving.
> + */
> + cpu_if->gicv5_vpe.resident = false;
Stores and sysreg accesses are not ordered without a DSB ST in between.
> +
> + write_sysreg_s(cpu_if->vgic_contextr, SYS_ICH_CONTEXTR_EL2);
Is this really making anything non-resident? Who clears the V bit?
> + isb();
> +}
> +
> void __vgic_v5_save_apr(struct vgic_v5_cpu_if *cpu_if)
> {
> cpu_if->vgic_apr = read_sysreg_s(SYS_ICH_APR_EL2);
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index fe49fb56dc3c9..d14cf4771d606 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -495,6 +495,9 @@ struct vgic_v5_cpu_if {
> */
> u64 vgic_icsr;
>
> + /* The contextr used to make VPEs resident and non-resident */
> + u64 vgic_contextr;
> +
> struct gicv5_vpe gicv5_vpe;
> };
>
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: remoteproc: xlnx: add auto boot feature
From: Mathieu Poirier @ 2026-04-28 14:30 UTC (permalink / raw)
To: tanmay.shah
Cc: Krzysztof Kozlowski, andersson, robh, krzk+dt, conor+dt,
michal.simek, ben.levinsky, linux-remoteproc, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <09928c66-f041-479d-954f-56dcfcfa1c13@amd.com>
On Fri, Apr 24, 2026 at 12:52:40PM -0500, Shah, Tanmay wrote:
>
>
> On 4/24/2026 11:53 AM, Krzysztof Kozlowski wrote:
> > On 23/04/2026 19:59, Shah, Tanmay wrote:
> >> Ack, I will rename it to xlnx,auto-boot.
> >>
> >>>>
> >>>>>> + type: boolean
> >>>>>> + description: remote core is either already running or ready to boot
> >>>>>
> >>>>> And why is this property of a board?
> >>>>>
> >>>>
> >>>> Not sure what indicates it is? The property is under remoteproc child
> >>>> device that is SOC level property. Remote core is on same SOC wher linux
> >>>> core is running.
> >>>
> >>> So it is implied by SoC compatible? Please provide some arguments why it
> >>> cannot be implied by the SoC compatible. I gave you one way out, but if
> >>> you disagree then no problem.
> >>>
> >>
> >> So on some SoC, the bootloader supports loading and starting of the
> >> remote processor. But it is totally user's choice. User can choose to
> >> load & start one core of a cluster via bootloader and leave another core
> >> powered-off.
> >> That is why it is not possible to decide based on SoC compatible.
> >
> > OK. The problem is that "user" is a bit vague and usually user choice
> > goes to user-space.
> >
> > The property will be set or unset for ALL of given boards. So all of the
> > DTS->DTB. That's why it should be clear why all such boards should
> > behave like you described. If this is truly user, as in user-space,
> > choice, then DT is not the way.
> >
>
> Okay 'user' may not be the right choice of word. I should say 'hardware
> configuration'. On same SoC, some cores can be configured to boot
> automatically before Linux boots, and some won't. So if device-tree is
> about hardware configuration, then we need a way to show which core is
> configured to boot before linux. This configuration is board agnostic.
> So I think auto-boot in device-tree makes sense.
>
> The only advantage on this platform is, it has a way to detect if the
> core is running or not runtime and don't have to rely on device-tree.
>
> >
> >>
> >> If we don't want to make it a device-tree property then I can implement
> >> in a different way. New way will detect if the remote is running or not
> >> via EMMI/SCMI call to the firmware, and take a decision based on that.
> >> If this new way works, then I don't think we need auto-boot property at all.
> >>
> >> Let me know your thoughts.
> >
> > This works for me and solves my questions from DT point of view, but I
> > cannot judge whether this makes sense for you.
> >
>
> I say I will keep it open ended for now. I will avoid introducing
> auto-boot in the device-tree for now, and send a patch without it. In
> future if for some other reason this property is needed, will send new
> patch later.
>
In light of this conversation, should I still review this patchset or it was
made obsolete by "[PATCH] remoteproc: xlnx: check remote node state" ?
> Thanks,
> Tanmay
>
> >
> > Best regards,
> > Krzysztof
>
^ permalink raw reply
* Re: [PATCH v4 05/15] arm64: mm: Remove bogus stop condition from map_mem() loop
From: Kevin Brodsky @ 2026-04-28 14:33 UTC (permalink / raw)
To: Ard Biesheuvel, linux-arm-kernel
Cc: linux-kernel, will, catalin.marinas, mark.rutland, Ard Biesheuvel,
Ryan Roberts, Anshuman Khandual, Liz Prucka, Seth Jenkins,
Kees Cook, Mike Rapoport, David Hildenbrand, Andrew Morton,
linux-mm, linux-hardening
In-Reply-To: <20260427153416.2103979-22-ardb+git@google.com>
On 27/04/2026 17:34, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
>
> The memblock API guarantees that start is not greater than or equal to
> end, so there is no need to test it. And if it were, it is doubtful that
> breaking out of the loop would be a reasonable course of action here
> (rather than attempting to map the remaining regions)
>
> So let's drop this check.
>
> Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> arch/arm64/mm/mmu.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 005844e521bd..bfbf3fe0d1be 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -1177,8 +1177,6 @@ static void __init map_mem(pgd_t *pgdp)
>
> /* map all the memory banks */
> for_each_mem_range(i, &start, &end) {
> - if (start >= end)
> - break;
> /*
> * The linear map must allow allocation tags reading/writing
> * if MTE is present. Otherwise, it has the same attributes as
^ permalink raw reply
* Re: [PATCH v4 06/15] arm64: mm: Drop redundant pgd_t* argument from map_mem()
From: Kevin Brodsky @ 2026-04-28 14:33 UTC (permalink / raw)
To: Ard Biesheuvel, linux-arm-kernel
Cc: linux-kernel, will, catalin.marinas, mark.rutland, Ard Biesheuvel,
Ryan Roberts, Anshuman Khandual, Liz Prucka, Seth Jenkins,
Kees Cook, Mike Rapoport, David Hildenbrand, Andrew Morton,
linux-mm, linux-hardening
In-Reply-To: <20260427153416.2103979-23-ardb+git@google.com>
On 27/04/2026 17:34, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
>
> __map_memblock() and map_mem() always operate on swapper_pg_dir, so
> there is no need to pass around a pgd_t pointer between them.
>
> Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> arch/arm64/mm/mmu.c | 25 ++++++++++----------
> 1 file changed, 12 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index bfbf3fe0d1be..9610dd2d7bd9 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -1039,11 +1039,11 @@ static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
> flush_tlb_kernel_range(virt, virt + size);
> }
>
> -static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start,
> - phys_addr_t end, pgprot_t prot, int flags)
> +static void __init __map_memblock(phys_addr_t start, phys_addr_t end,
> + pgprot_t prot, int flags)
> {
> - early_create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start,
> - prot, early_pgtable_alloc, flags);
> + early_create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
> + end - start, prot, early_pgtable_alloc, flags);
> }
>
> void __init mark_linear_text_alias_ro(void)
> @@ -1091,13 +1091,13 @@ static phys_addr_t __init arm64_kfence_alloc_pool(void)
> return kfence_pool;
> }
>
> -static void __init arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp)
> +static void __init arm64_kfence_map_pool(phys_addr_t kfence_pool)
> {
> if (!kfence_pool)
> return;
>
> /* KFENCE pool needs page-level mapping. */
> - __map_memblock(pgdp, kfence_pool, kfence_pool + KFENCE_POOL_SIZE,
> + __map_memblock(kfence_pool, kfence_pool + KFENCE_POOL_SIZE,
> pgprot_tagged(PAGE_KERNEL),
> NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
> memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
> @@ -1133,11 +1133,11 @@ bool arch_kfence_init_pool(void)
> #else /* CONFIG_KFENCE */
>
> static inline phys_addr_t arm64_kfence_alloc_pool(void) { return 0; }
> -static inline void arm64_kfence_map_pool(phys_addr_t kfence_pool, pgd_t *pgdp) { }
> +static inline void arm64_kfence_map_pool(phys_addr_t kfence_pool) { }
>
> #endif /* CONFIG_KFENCE */
>
> -static void __init map_mem(pgd_t *pgdp)
> +static void __init map_mem(void)
> {
> static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN);
> phys_addr_t kernel_start = __pa_symbol(_text);
> @@ -1182,7 +1182,7 @@ static void __init map_mem(pgd_t *pgdp)
> * if MTE is present. Otherwise, it has the same attributes as
> * PAGE_KERNEL.
> */
> - __map_memblock(pgdp, start, end, pgprot_tagged(PAGE_KERNEL),
> + __map_memblock(start, end, pgprot_tagged(PAGE_KERNEL),
> flags);
> }
>
> @@ -1196,10 +1196,9 @@ static void __init map_mem(pgd_t *pgdp)
> * Note that contiguous mappings cannot be remapped in this way,
> * so we should avoid them here.
> */
> - __map_memblock(pgdp, kernel_start, kernel_end,
> - PAGE_KERNEL, NO_CONT_MAPPINGS);
> + __map_memblock(kernel_start, kernel_end, PAGE_KERNEL, NO_CONT_MAPPINGS);
> memblock_clear_nomap(kernel_start, kernel_end - kernel_start);
> - arm64_kfence_map_pool(early_kfence_pool, pgdp);
> + arm64_kfence_map_pool(early_kfence_pool);
> }
>
> void mark_rodata_ro(void)
> @@ -1421,7 +1420,7 @@ static void __init create_idmap(void)
>
> void __init paging_init(void)
> {
> - map_mem(swapper_pg_dir);
> + map_mem();
>
> memblock_allow_resize();
>
^ permalink raw reply
* Re: [PATCH 6/8] KVM: arm64: Propagate stage-2 map failure on host->guest donation
From: Fuad Tabba @ 2026-04-28 14:36 UTC (permalink / raw)
To: Will Deacon
Cc: maz, oliver.upton, james.morse, suzuki.poulose, yuzenghui,
qperret, vdonnefort, catalin.marinas, linux-arm-kernel, kvmarm,
linux-kernel, stable
In-Reply-To: <afC5_jrTEVRfJ77x@willie-the-truck>
Hi Will,
On Tue, 28 Apr 2026 at 14:45, Will Deacon <will@kernel.org> wrote:
>
> On Tue, Apr 28, 2026 at 11:30:06AM +0100, Fuad Tabba wrote:
> > __pkvm_host_donate_guest() flips the host stage-2 PTE for the donated
> > page to a non-valid annotation (KVM_HOST_INVALID_PTE_TYPE_DONATION,
> > owner = PKVM_ID_GUEST) via host_stage2_set_owner_metadata_locked()
> > and then calls kvm_pgtable_stage2_map() to install the matching guest
> > stage-2 mapping. The map's return value was wrapped in WARN_ON() and
> > otherwise discarded.
> >
> > At EL2 in nVHE/pKVM, WARN_ON() is not warn-and-continue: it expands
> > to a BRK that enters the invalid-host-el2 vector and branches to
> > hyp_panic(), declared __noreturn. WARN_ON of a reachable failure at
> > EL2 is a panic primitive, not a debug aid.
> >
> > kvm_pgtable_stage2_map() can fail in reachable ways even at PAGE_SIZE
> > granularity: __pkvm_host_donate_guest() verifies PKVM_NOPAGE for the
> > guest IPA before the map, meaning no valid stage-2 entry exists. The
> > walker must allocate new page-table pages from the vcpu memcache to
> > install the mapping, returning -ENOMEM if exhausted. The host
> > controls the vcpu memcache via the topup interface, so an
> > under-provisioned donation request converts a recoverable error into
> > a fatal hyp panic.
> >
> > Capture the stage-2 map return value and propagate it. The walker
> > may have installed partial leaf entries for the IPA before failing,
> > so unmap the range to clear them; otherwise the guest would retain
> > stage-2 access to a page the host is about to reclaim as
> > PKVM_PAGE_OWNED. Then roll back the host stage-2 mutation: the only
> > forward mutation is host_stage2_set_owner_metadata_locked() flipping
> > the host vmemmap from PKVM_PAGE_OWNED to PKVM_NOPAGE and the host
> > stage-2 PTE from idmap to invalid+annotation.
> > host_stage2_set_owner_locked(_, _, PKVM_ID_HOST) restores both.
> >
> > The rollback calls host_stage2_set_owner_locked() under WARN_ON.
> > This is the correct use: host_stage2_set_owner_metadata_locked()
> > just wrote the host leaf PTE as an invalid+annotation entry, so the
> > reverse idmap rewrite cannot require new page-table allocation — it
> > rewrites the leaf in-place. The WARN_ON asserts an impossible state
> > under correct EL2 execution, semantically distinct from the misuse
> > being fixed.
> >
> > Fixes: 1e579adca177 ("KVM: arm64: Introduce __pkvm_host_donate_guest()")
> > Signed-off-by: Fuad Tabba <tabba@google.com>
> > ---
> > arch/arm64/kvm/hyp/nvhe/mem_protect.c | 27 ++++++++++++++++++++++++---
> > 1 file changed, 24 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > index 7044913a0758..b8c57a95e9bf 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > @@ -1391,9 +1391,30 @@ int __pkvm_host_donate_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu)
> > meta = host_stage2_encode_gfn_meta(vm, gfn);
> > WARN_ON(host_stage2_set_owner_metadata_locked(phys, PAGE_SIZE,
> > PKVM_ID_GUEST, meta));
> > - WARN_ON(kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys,
> > - pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_OWNED),
> > - &vcpu->vcpu.arch.pkvm_memcache, 0));
> > + ret = kvm_pgtable_stage2_map(&vm->pgt, ipa, PAGE_SIZE, phys,
> > + pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_OWNED),
> > + &vcpu->vcpu.arch.pkvm_memcache, 0);
> > + if (ret) {
> > + /*
> > + * Stage-2 map can fail mid-walk (e.g. -ENOMEM from the
> > + * memcache), leaving partial leaf entries installed in the
> > + * guest stage-2. Tear them down before rolling back the host
> > + * stage-2; otherwise the guest would retain access to a page
> > + * the host is about to reclaim as PKVM_PAGE_OWNED.
> > + */
> > + kvm_pgtable_stage2_unmap(&vm->pgt, ipa, PAGE_SIZE);
>
> Whoa, whoa, whoa.
>
> First of all, this is mapping a single page, so the comment talking about
> "leaf entries" (plural) is bogus. If an operation to map a single page
> fails, then it makes no sense to try unmapping the mapping which we
> failed to create. What do you expect it to do?
>
> On the other hand, if we extend this to handle ranges in future (which
> presumably we'll want as part of the THP support) then wouldn't this
> mean that a concurrent vCPU could have transiently written to the pages
> that _did_ get mapped, and now we're going to give those back to the
> host? That's really not ok! We're relying on these WARN_ON()s being
> fatal and they shouldn't fail because we perform all the permission
> checks first, in a separate pass.
>
> If you want to improve this, then I think the options are either:
>
> 1. Check that the the memcache is topped up first
> 2. Poison the page (similar to the forced-reclaim path)
> 3. Tell the host about the pages it's lost and maybe it can leak them
>
> (I vote for (1))
>
> But we absolutely cannot do the simple rollback for the ownership
> changes; that's why the code is written to do the checks up-front. Your
> other patches at the end of this series have different flavours of the
> same issue.
>
> If it's just about keeping the LLM happy, then either fix the LLM or
> make these BUG_ON() (in conjunction with (1) above).
You're right, and no, it's not just about keeping em happy :D
The "leaf entries" comment on the single-page donate path is wrong, and
more importantly the rollback model is unsound. The right fix is to tighten
the precondition, not to handle a failure that shouldn't be reachable.
V2 will drop two patches (in addition to the HCR_EL2 one), and will be
as follows:
1. host->guest share and host->guest donate (kept, rewritten): add a
memcache-sufficiency check during the existing pre-check pass
(option 1) and return -ENOMEM cleanly without touching any state.
Restore the WARN_ON() on the subsequent kvm_pgtable_stage2_map() —
with the topup precheck it asserts an established invariant rather
than ignoring a reachable error.
For the single-page donate, "topped up" is
KVM_PGTABLE_LAST_LEVEL - vm->pgt.start_level (mirroring host EL1's
kvm_mmu_cache_min_pages). For multi-page share I plan to use the
conservative nr_pages * (LAST_LEVEL - start_level) bound and flag it
as conservative in the commit message; happy to compute a tighter
alignment-aware bound if you'd prefer.
2. guest->host share and guest->host unshare (dropped): on reflection
these shouldn't have been in V1 at all. As I did note in the commit
message, failure path is not reachable. Again, too eager to make
use of the new prompts.
I'll repost this as V2 if you agree.
Cheers,
/fuad
>
> Will
^ permalink raw reply
* RE: [PATCH v2 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
From: Biju Das @ 2026-04-28 14:38 UTC (permalink / raw)
To: Luca Ceresoli, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Clark,
Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang, Sean Paul,
Marijn Suijten, Tian Tao, Xinwei Kong, Sumit Semwal, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, laurent.pinchart,
Jonas Karlman, Jernej Skrabec, tomi.valkeinen, Michal Simek
Cc: Hui Pu, Ian Ray, Thomas Petazzoni,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <TY3PR01MB113465B0308DE16ACC48D1E8186372@TY3PR01MB11346.jpnprd01.prod.outlook.com>
> -----Original Message-----
> From: Biju Das
> Sent: 28 April 2026 15:02
> Subject: RE: [PATCH v2 08/11] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
>
> Hi Luca,
>
> > -----Original Message-----
> > From: Luca Ceresoli <luca.ceresoli@bootlin.com>
> > Sent: 28 April 2026 14:48
> > Subject: Re: [PATCH v2 08/11] drm/bridge: adv7511: switch to
> > of_drm_get_bridge_by_endpoint()
> >
> > Hello,
> >
> > On Tue Apr 28, 2026 at 3:31 PM CEST, Biju Das wrote:
> > >> >> > @@ -1251,10 +1251,9 @@ static int adv7511_probe(struct
> > >> >> > i2c_client
> > >> >> > *i2c)
> > >> >> >
> > >> >> > memset(&link_config, 0, sizeof(link_config));
> > >> >> >
> > >> >> > - ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL,
> > >> >> > - &adv7511->next_bridge);
> > >> >> > - if (ret && ret != -ENODEV)
> > >> >> > - return ret;
> > >> >> > + adv7511->bridge.next_bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 1, -1);
> > >> >> > + if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) != -ENODEV)
> > >> >> > + return PTR_ERR(adv7511->bridge.next_bridge);
> > >> >>
> > >> >> Does it crash, if the error is -EPROBE_DEFER?
> > >> >
> > >> > I see a crash with patch [1], which is fixed by avoiding the direct assignment.
> > >>
> > >> Ah, dammit! Good catch, thanks for the quick testing and follow-up!
> > >>
> > >> Indeed this driver assumes next_bridge is either NULL or a valid
> > >> pointer, but due to the 'if(IS_ERR() && some_other_condition)' now
> > >> it can also be -ENODEV (not -
> > EPROBE_DEFER, but that's irrelevant).
> > >>
> > >> This affects the msm and zynqmp_dp patches equally.
> > >>
> > >> I'm sending a v3 soon with these fixed. I'm just not sure which
> > >> approach to use to fix (same for all the 3 patches). Alternatives are:
> > >>
> > >> 1. -ENODEV is accepted, set next_bridge to NULL when it happens:
> > >>
> > >> - if (IS_ERR(adv7511->bridge.next_bridge) && PTR_ERR(adv7511->bridge.next_bridge) != -
> > >> ENODEV)
> > >> - return PTR_ERR(adv7511->bridge.next_bridge);
> > >> + if (IS_ERR(adv7511->bridge.next_bridge)) {
> > >> + if (PTR_ERR(adv7511->bridge.next_bridge) == -ENODEV)
> > >> + adv7511->bridge.next_bridge = NULL;
> > >> + else
> > >> + return PTR_ERR(adv7511->bridge.next_bridge);
> > >
> > > The point is you cannot return PTR_ERR as it will lead to crash, if
> > > it is direct assignment.
> >
> > It would definitely crash when the next_bridge is dereferenced (which
> > happens in
> > adv7511_bridge_attach()) but I don't see how it can crash here. Here
> > it _can_ be assigned -ENODEV, but it would be immediately be cleared
> > to NULL, or to enother error, but we'd immediately return. And in case
> > of return, when next_bridge is cleared by __drm_bridge_free -> drm_bridge_put, the error value would
> be ignored thanks to patch 1.
>
> OK, I haven't noticed the newly introduced check in drm_bridge_put() in patch#1.
>
> I guess, we should avoid putting error values in bridge.next_bridge.
> It should be either NULL or Valid pointer, not PTR_ERR.
FTR, I get a crash in attach. I will apply the suggested changes and will let you know the result.
[ 18.957324] pc : drm_bridge_attach+0x34/0x210 [drm]
[ 18.969425] lr : adv7511_bridge_attach+0x38/0xb8 [adv7511]
[ 18.969610] drm_bridge_attach+0x34/0x210 [drm] (P)
[ 18.969845] adv7511_bridge_attach+0x38/0xb8 [adv7511]
[ 18.969867] drm_bridge_attach+0xf0/0x210 [drm]
[ 18.970042] rzg2l_mipi_dsi_attach+0x24/0x3c [rzg2l_mipi_dsi]
[ 18.970064] drm_bridge_attach+0xf0/0x210 [drm]
[ 18.970262] rzg2l_du_encoder_init+0x9c/0x250 [rzg2l_du_drm]
[ 18.970293] rzg2l_du_modeset_init+0x30c/0x4d0 [rzg2l_du_drm]
[ 18.970307] rzg2l_du_probe+0xc8/0x174 [rzg2l_du_drm]
[ 18.970321] platform_probe+0x5c/0xa4
[ 18.970336] really_probe+0xbc/0x2c0
[ 18.970348] __driver_probe_device+0x80/0x14c
[ 18.970359] driver_probe_device+0x3c/0x164
[ 18.970369] __driver_attach+0x90/0x1a4
[ 18.970379] bus_for_each_dev+0x7c/0xdc
[ 18.970388] driver_attach+0x24/0x30
[ 18.970397] bus_add_driver+0xe4/0x208
[ 18.970406] driver_register+0x68/0x130
[ 18.970416] __platform_driver_register+0x24/0x30
Cheers,
Biju
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: remoteproc: xlnx: add auto boot feature
From: Shah, Tanmay @ 2026-04-28 14:38 UTC (permalink / raw)
To: Mathieu Poirier, tanmay.shah
Cc: Krzysztof Kozlowski, andersson, robh, krzk+dt, conor+dt,
michal.simek, ben.levinsky, linux-remoteproc, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <afDEgHUN8fWatC_u@p14s>
On 4/28/2026 9:30 AM, Mathieu Poirier wrote:
> On Fri, Apr 24, 2026 at 12:52:40PM -0500, Shah, Tanmay wrote:
>>
>>
>> On 4/24/2026 11:53 AM, Krzysztof Kozlowski wrote:
>>> On 23/04/2026 19:59, Shah, Tanmay wrote:
>>>> Ack, I will rename it to xlnx,auto-boot.
>>>>
>>>>>>
>>>>>>>> + type: boolean
>>>>>>>> + description: remote core is either already running or ready to boot
>>>>>>>
>>>>>>> And why is this property of a board?
>>>>>>>
>>>>>>
>>>>>> Not sure what indicates it is? The property is under remoteproc child
>>>>>> device that is SOC level property. Remote core is on same SOC wher linux
>>>>>> core is running.
>>>>>
>>>>> So it is implied by SoC compatible? Please provide some arguments why it
>>>>> cannot be implied by the SoC compatible. I gave you one way out, but if
>>>>> you disagree then no problem.
>>>>>
>>>>
>>>> So on some SoC, the bootloader supports loading and starting of the
>>>> remote processor. But it is totally user's choice. User can choose to
>>>> load & start one core of a cluster via bootloader and leave another core
>>>> powered-off.
>>>> That is why it is not possible to decide based on SoC compatible.
>>>
>>> OK. The problem is that "user" is a bit vague and usually user choice
>>> goes to user-space.
>>>
>>> The property will be set or unset for ALL of given boards. So all of the
>>> DTS->DTB. That's why it should be clear why all such boards should
>>> behave like you described. If this is truly user, as in user-space,
>>> choice, then DT is not the way.
>>>
>>
>> Okay 'user' may not be the right choice of word. I should say 'hardware
>> configuration'. On same SoC, some cores can be configured to boot
>> automatically before Linux boots, and some won't. So if device-tree is
>> about hardware configuration, then we need a way to show which core is
>> configured to boot before linux. This configuration is board agnostic.
>> So I think auto-boot in device-tree makes sense.
>>
>> The only advantage on this platform is, it has a way to detect if the
>> core is running or not runtime and don't have to rely on device-tree.
>>
>>>
>>>>
>>>> If we don't want to make it a device-tree property then I can implement
>>>> in a different way. New way will detect if the remote is running or not
>>>> via EMMI/SCMI call to the firmware, and take a decision based on that.
>>>> If this new way works, then I don't think we need auto-boot property at all.
>>>>
>>>> Let me know your thoughts.
>>>
>>> This works for me and solves my questions from DT point of view, but I
>>> cannot judge whether this makes sense for you.
>>>
>>
>> I say I will keep it open ended for now. I will avoid introducing
>> auto-boot in the device-tree for now, and send a patch without it. In
>> future if for some other reason this property is needed, will send new
>> patch later.
>>
>
> In light of this conversation, should I still review this patchset or it was
> made obsolete by "[PATCH] remoteproc: xlnx: check remote node state" ?
>
>
Hi,
Yes it was made obsolete by the mentioned patch.
Please wait for v2, which depends on the mentioned patch and removes
need of the auto-boot property from the device-tree.
Thanks,
Tanmay
>> Thanks,
>> Tanmay
>>
>>>
>>> Best regards,
>>> Krzysztof
>>
^ permalink raw reply
* RE: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
From: Shenwei Wang @ 2026-04-28 14:43 UTC (permalink / raw)
To: Beleswar Prasad Padhi, Linus Walleij, Bartosz Golaszewski,
Jonathan Corbet, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Mathieu Poirier, Frank Li, Sascha Hauer
Cc: Shuah Khan, linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, Pengutronix Kernel Team,
Fabio Estevam, Peng Fan, devicetree@vger.kernel.org,
linux-remoteproc@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, dl-linux-imx,
Bartosz Golaszewski, Andrew Lunn
In-Reply-To: <29485742-6e49-482e-b73d-228295daaeec@ti.com>
> -----Original Message-----
> From: Beleswar Prasad Padhi <b-padhi@ti.com>
> Sent: Tuesday, April 28, 2026 2:25 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; Linus Walleij
> <linusw@kernel.org>; Bartosz Golaszewski <brgl@kernel.org>; Jonathan Corbet
> <corbet@lwn.net>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Bjorn Andersson
> <andersson@kernel.org>; Mathieu Poirier <mathieu.poirier@linaro.org>; Frank Li
> <frank.li@nxp.com>; Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Shuah Khan <skhan@linuxfoundation.org>; linux-gpio@vger.kernel.org; linux-
> doc@vger.kernel.org; linux-kernel@vger.kernel.org; Pengutronix Kernel Team
> <kernel@pengutronix.de>; Fabio Estevam <festevam@gmail.com>; Peng Fan
> <peng.fan@nxp.com>; devicetree@vger.kernel.org; linux-
> remoteproc@vger.kernel.org; imx@lists.linux.dev; linux-arm-
> kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>; Bartosz
> Golaszewski <brgl@bgdev.pl>; Andrew Lunn <andrew@lunn.ch>
> Subject: [EXT] Re: [PATCH v13 3/4] gpio: rpmsg: add generic rpmsg GPIO driver
> On 28/04/26 00:53, Shenwei Wang wrote:
> [...]
>
> >
> >>> + void *channel_devices[MAX_PORT_PER_CHANNEL];
> >>
> >> So this is technically a rpmsg endpoint (struct rpmsg_endpoint)
> >> without naming it "endpoint". Every rpmsg endpoint has a reference to
> >> its parent rpmsg channel (struct rpmsg_device) which represents the
> >> same information here. So we should use the framework standard here.
> >>
> > Yes, agree to use "endpoint_devices".
>
>
> I did not mean to say to just change the variable name from "channel_devices" to
> "endpoint_devices". Infact you would not need to have this field & struct
> anymore.
>
> Pseudo-code:
> 1. Add a 'struct rpmsg_endpoint *ept' field to struct rpmsg_gpio_port
> to maintain the ept to port idx map.
>
> 2. Call port->ept = rpmsg_create_ept(rpdev,
> rpmsg_gpio_channel_callback,
> port, {rpdev.id.name,
> RPMSG_ADDR_ANY,
> RPMSG_ADDR_ANY})
> from rpmsg_gpiochip_register().
>
On the Linux side, we invoke rpmsg_create_ept. What is expected from the remote system in this case?
If the remote side does not need any extra support, this would be an excellent solution.
Thanks,
Shenwei
> 3. Send msgs from local ept in rpmsg_gpio_send_message() by:
> rpmsg_send(port->ept, msg, sizeof(*msg));
>
> 4. Get the port info in rpmsg_gpio_channel_callback() by:
> struct rpmsg_gpio_port *port = priv;
>
> Which also eliminates the need for struct rpdev_drvdata as you can just do
> rpmsg_get_rproc_node_name(rpdev) from rpmsg_gpiochip_register().
>
^ permalink raw reply
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