* [PATCH 1/2] gpio: mxc: fix irq_high handling
From: Alexander Stein @ 2026-05-22 7:01 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: Alexander Stein, linux-gpio, imx, linux-arm-kernel, linux-kernel
If port->irq_high is -1 (fsl,imx21-gpio compatible) and gpio_idx is >= 16
enable_irq_wake() is called with -1 which is wrong.
Fixes: 5f6d1998adeb ("gpio: mxc: release the parent IRQ in runtime suspend")
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
I don't have hardware to test. I just noticed this by code review.
drivers/gpio/gpio-mxc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 647b6f4861b74..12f11a6c96653 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -469,7 +469,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
* the handler is needed only once, but doing it for every port
* is more robust and easier.
*/
- port->irq_high = -1;
+ port->irq_high = 0;
port->mx_irq_handler = mx2_gpio_irq_handler;
} else
port->mx_irq_handler = mx3_gpio_irq_handler;
--
2.43.0
^ permalink raw reply related
* [PATCH] media: rockchip: rkcif: Fix error handling for media_entity_remote_source_pad_unique()
From: Chen Ni @ 2026-05-22 6:55 UTC (permalink / raw)
To: mehdi.djait, michael.riesch
Cc: mchehab, heiko, hverkuil+cisco, gerald.loacker, bryan.odonoghue,
linux-media, linux-arm-kernel, linux-rockchip, linux-kernel,
Chen Ni
The media_entity_remote_source_pad_unique() function returns an error
pointer on failure, not NULL. Fix the check to use IS_ERR() and return
PTR_ERR() to correctly handle allocation failures.
Fixes: 501802e2ad51 ("media: rockchip: rkcif: add abstraction for dma blocks")
Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
---
drivers/media/platform/rockchip/rkcif/rkcif-stream.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-stream.c b/drivers/media/platform/rockchip/rkcif/rkcif-stream.c
index 3130d420ad55..542aa877919d 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-stream.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-stream.c
@@ -466,7 +466,7 @@ static int rkcif_stream_link_validate(struct media_link *link)
struct rkcif_stream *stream = to_rkcif_stream(vdev);
int ret = -EINVAL;
- if (!media_entity_remote_source_pad_unique(link->sink->entity))
+ if (IS_ERR(media_entity_remote_source_pad_unique(link->sink->entity)))
return -ENOTCONN;
sd = media_entity_to_v4l2_subdev(link->source->entity);
--
2.25.1
^ permalink raw reply related
* Re: [PATCH v1 13/15] dt-bindings: display: panel-lvds: Add dual-channel LVDS support
From: Krzysztof Kozlowski @ 2026-05-22 6:55 UTC (permalink / raw)
To: Vitor Soares
Cc: Laurent Pinchart, Neil Armstrong, Jessica Zhang,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Nishanth Menon, Vignesh Raghavendra, Tero Kristo, Lad Prabhakar,
Thierry Reding, Sam Ravnborg, Vitor Soares, dri-devel, devicetree,
linux-kernel, linux-arm-kernel
In-Reply-To: <20260521150038.103538-30-ivitro@gmail.com>
On Thu, May 21, 2026 at 04:00:49PM +0100, Vitor Soares wrote:
> From: Vitor Soares <vitor.soares@toradex.com>
>
> The panel-lvds binding only supports single-channel panels.
On purpose, no?
> Extend it to support dual-channel LVDS panels by referencing the
> lvds-dual-ports schema when a ports container is present.
You now changed existing panels to dual channel.
>
> Assisted-by: Claude:claude-sonnet-4.6
Using assisted by is not permission to send us unreviewed code.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2] net: stmmac: mmc: Remove duplicate mmc_rx crc
From: Abid Ali @ 2026-05-22 6:54 UTC (permalink / raw)
To: andrew
Cc: alexandre.torgue, andrew+netdev, davem, dev.taqnialabs, edumazet,
kuba, linux-arm-kernel, linux-kernel, linux-stm32,
mcoquelin.stm32, netdev, pabeni
In-Reply-To: <2d702678-5b2b-451e-b692-228efcbbefc4@lunn.ch>
On Thu, May 21, 2026 at 20:44:53 +0200, Andrew Lunn wrote:
> Thanks for the updated commit message.
>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Much appreciated.
Should I send a v3 with the Reviewed-by trailer added ?
- Abid
^ permalink raw reply
* Re: [RESEND v3 1/3] KVM: arm64: Reset page order in pKVM hyp_pool
From: Fuad Tabba @ 2026-05-22 6:53 UTC (permalink / raw)
To: Vincent Donnefort
Cc: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, linux-arm-kernel, kvmarm, kernel-team,
qperret, Sashiko
In-Reply-To: <20260521143626.1005660-2-vdonnefort@google.com>
On Thu, 21 May 2026 at 15:36, Vincent Donnefort <vdonnefort@google.com> wrote:
>
> When a VM fails to initialise after its stage-2 hyp_pool has been
> initialised, that stage-2 must be torn down entirely. This requires
> resetting both the refcount and the order of its pages back to 0.
>
> Currently, reclaim_pgtable_pages() implicitly resets the page order by
> allocating the entire pool with order-0 granularity. However, in the VM
> initialisation error path, the addresses of the donated memory (the PGD)
> are already known, making it unnecessary to iterate over all pages in
> the pool.
>
> Since the vmemmap page order is a hyp_pool-specific field, leaving a
> non-zero order on hyp_pool destruction is harmless until another pool
> attempts to admit the page. Instead of resetting this field during
> destruction, reset it during pool initialization in hyp_pool_init().
>
> For 'external' pages, we can't trust the order either as they bypass
> hyp_pool_init(). Since we never coalesce them, enforce order-0 to ensure
> safe insertion into the pool.
>
> This leaves no vmemmap order users outside of hyp_pool.
>
> Fixes: 256b4668cd89 ("KVM: arm64: Introduce separate hypercalls for pKVM VM reservation and initialization")
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Reviewed-by: Fuad Tabba <tabba@google.com>
Tested-by: Fuad Tabba <tabba@google.com>
Cheers,
/fuad
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 25f04629014e..fa447d400b71 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -217,7 +217,6 @@ static void *guest_s2_zalloc_page(void *mc)
> memset(addr, 0, PAGE_SIZE);
> p = hyp_virt_to_page(addr);
> p->refcount = 1;
> - p->order = 0;
>
> return addr;
> }
> @@ -322,7 +321,6 @@ void reclaim_pgtable_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
> while (addr) {
> page = hyp_virt_to_page(addr);
> page->refcount = 0;
> - page->order = 0;
> push_hyp_memcache(mc, addr, hyp_virt_to_phys);
> WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1));
> addr = hyp_alloc_pages(&vm->pool, 0);
> diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
> index a1eb27a1a747..57f86aa0f82f 100644
> --- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
> +++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
> @@ -94,13 +94,22 @@ static void __hyp_attach_page(struct hyp_pool *pool,
> struct hyp_page *p)
> {
> phys_addr_t phys = hyp_page_to_phys(p);
> - u8 order = p->order;
> struct hyp_page *buddy;
> + bool coalesce = true;
> + u8 order = p->order;
>
> - memset(hyp_page_to_virt(p), 0, PAGE_SIZE << p->order);
> + /*
> + * 'external' pages are never coalesced and their ->order field
> + * untrusted as they bypass hyp_pool_init(). Enforce order-0.
> + */
> + if (phys < pool->range_start || phys >= pool->range_end) {
> + order = 0;
> + coalesce = false;
> + }
> +
> + memset(hyp_page_to_virt(p), 0, PAGE_SIZE << order);
>
> - /* Skip coalescing for 'external' pages being freed into the pool. */
> - if (phys < pool->range_start || phys >= pool->range_end)
> + if (!coalesce)
> goto insert;
>
> /*
> @@ -237,8 +246,10 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
>
> /* Init the vmemmap portion */
> p = hyp_phys_to_page(phys);
> - for (i = 0; i < nr_pages; i++)
> + for (i = 0; i < nr_pages; i++) {
> hyp_set_page_refcounted(&p[i]);
> + p[i].order = 0;
> + }
>
> /* Attach the unused pages to the buddy tree */
> for (i = reserved_pages; i < nr_pages; i++)
> --
> 2.54.0.746.g67dd491aae-goog
>
^ permalink raw reply
* Re: [PATCH v1 14/15] dt-bindings: display: panel-lvds: Add LG LP156WF1
From: Krzysztof Kozlowski @ 2026-05-22 6:53 UTC (permalink / raw)
To: Vitor Soares
Cc: Laurent Pinchart, Neil Armstrong, Jessica Zhang,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Nishanth Menon, Vignesh Raghavendra, Tero Kristo, Lad Prabhakar,
Thierry Reding, Sam Ravnborg, Vitor Soares, dri-devel, devicetree,
linux-kernel, linux-arm-kernel
In-Reply-To: <20260521150038.103538-31-ivitro@gmail.com>
On Thu, May 21, 2026 at 04:00:50PM +0100, Vitor Soares wrote:
> From: Vitor Soares <vitor.soares@toradex.com>
>
> Add the compatible string for the LG LP156WF1 15.6" FHD (1920x1080)
> dual-channel TFT LCD LVDS panel.
>
> Assisted-by: Claude:claude-sonnet-4.6
Really - oneliner for trivial binding needs AI tools to help writing it?
> Signed-off-by: Vitor Soares <vitor.soares@toradex.com>
> ---
> Documentation/devicetree/bindings/display/panel/panel-lvds.yaml | 2 ++
> 1 file changed, 2 insertions(+)
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v6 01/10] dt-bindings: display: rockchip: analogix-dp: Fix hclk as third clock for RK3588
From: Damon Ding @ 2026-05-22 6:29 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss, Laurent.pinchart, jonas, jernej.skrabec,
nicolas.frattaroli, cristian.ciocaltea, sebastian.reichel,
dmitry.baryshkov, luca.ceresoli, dianders, m.szyprowski,
dri-devel, devicetree, linux-arm-kernel, linux-rockchip,
linux-kernel
In-Reply-To: <20260522-demonic-shaggy-wasp-a3f261@quoll>
Hi Krzysztof,
On 5/22/2026 2:11 PM, Krzysztof Kozlowski wrote:
> On Thu, May 21, 2026 at 04:08:26PM +0800, Damon Ding wrote:
>> RK3588 eDP controller requires HCLK_VO1 to access the VO1 GRF
>> registers and enable the video datapath.
>>
>> Previously, the clock was enabled implicitly via the 'rockchip,vo-grf'
>> phandle reference, which allowed the eDP to work without explicitly
>> managing the hclk_vo1 clock. However, this is not safe or explicit.
>>
>> To make the clock dependency explicit, enforce per-SoC clock-names
>> requirements:
>> - RK3288: 2 clocks (dp, pclk)
>> - RK3399: 3 clocks (dp, pclk, grf)
>> - RK3588: 3 clocks (dp, pclk, hclk)
>>
>> Do not reuse the 'grf' clock name for RK3588 because it represents
>> a different clock with distinct control logic:
>> - The 'grf' clock is only for GRF register access and is toggled
>> dynamically during register access.
>> - The 'hclk' clock controls both GRF access and video datapath
>> gating, and must remain enabled during probe.
>>
>> Fixes: f855146263b1 ("dt-bindings: display: rockchip: analogix-dp: Add support for RK3588")
>> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
>>
>> ---
>>
>> Changes in v4:
>> - Modify the commit msg.
>>
>> Changes in v5:
>> - Enforce the correct third clock name on a per-compatible basis.
>> - Modify the commit msg simultaneously.
>>
>> Changes in v6:
>> - Expand more detail commit msg about using hclk instead of grf clock.
>> ---
>> .../rockchip/rockchip,analogix-dp.yaml | 37 +++++++++++++++++--
>> 1 file changed, 33 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> index d99b23b88cc5..8001c1facf98 100644
>> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
>> @@ -23,10 +23,7 @@ properties:
>>
>> clock-names:
>> minItems: 2
>> - items:
>> - - const: dp
>> - - const: pclk
>> - - const: grf
>> + maxItems: 3
>>
>> power-domains:
>> maxItems: 1
>> @@ -60,6 +57,33 @@ required:
>> allOf:
>> - $ref: /schemas/display/bridge/analogix,dp.yaml#
>>
>> + - if:
>> + properties:
>> + compatible:
>> + contains:
>> + enum:
>> + - rockchip,rk3288-dp
>> + then:
>> + properties:
>> + clock-names:
>> + items:
>> + - const: dp
>> + - const: pclk
>
> Why aren't there constraints for clocks? They always must come together.
>
> Please open any other binding and look how it is done there.
>
>
Yes, as Conor's suggestion, the right way is to keep all valid clock
names at the top level, and use only minItems/maxItems in allOf to
differentiate clocks and clock-names of platforms.
I will update this in next version.
Best regards,
Damon
^ permalink raw reply
* Re: [PATCH] irqchip/exynos-combiner: remove useless spinlock
From: Sebastian Andrzej Siewior @ 2026-05-22 6:27 UTC (permalink / raw)
To: Marek Szyprowski
Cc: linux-arm-kernel, linux-samsung-soc, linux-rt-devel,
Thomas Gleixner, Krzysztof Kozlowski, Alim Akhtar, Clark Williams,
Steven Rostedt
In-Reply-To: <20260522061012.2687122-1-m.szyprowski@samsung.com>
On 2026-05-22 08:10:12 [+0200], Marek Szyprowski wrote:
> irq_controller_lock doesn't protect anything, it must be some leftover
> from early development or copy/paste. Remove it completely.
>
> Suggested-by: Thomas Gleixner <tglx@kernel.org>
> Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Link: https://lore.kernel.org/all/20260520220422.3522908-1-m.szyprowski@samsung.com/
> Fixes: 96031b31a4b3 ("irqchip/exynos-combiner: Switch to raw_spinlock")
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
There is a bit of reserch in 20260521090453.bbUZ00tS@linutronix.de why
it is a leftover.
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Sebastian
^ permalink raw reply
* Re: [PATCH 02/10] dt-bindings: clock: Add Amlogic A9 PLL clock controller
From: Jian Hu @ 2026-05-22 6:20 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Neil Armstrong, Jerome Brunet, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl, linux-kernel, linux-clk,
devicetree, linux-amlogic, linux-arm-kernel
In-Reply-To: <20260515-subtle-sepia-tuatara-cfee3d@quoll>
Hi Krzysztof,
Thanks for your review.
On 5/15/2026 4:09 PM, Krzysztof Kozlowski wrote:
> [ EXTERNAL EMAIL ]
>
> On Mon, May 11, 2026 at 08:47:24PM +0800, Jian Hu wrote:
>> Add the PLL clock controller dt-bindings for the Amlogic A9 SoC family.
>>
>> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
>> ---
>> .../bindings/clock/amlogic,a9-pll-clkc.yaml | 110 +++++++++++++++++++++
>> include/dt-bindings/clock/amlogic,a9-pll-clkc.h | 55 +++++++++++
>> 2 files changed, 165 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-pll-clkc.yaml
>> new file mode 100644
>> index 000000000000..4ee6013ba1a1
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/amlogic,a9-pll-clkc.yaml
>> @@ -0,0 +1,110 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +# Copyright (C) 2026 Amlogic, Inc. All rights reserved
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/amlogic,a9-pll-clkc.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Amlogic A9 Series PLL Clock Controller
>> +
>> +maintainers:
>> + - Neil Armstrong <neil.armstrong@linaro.org>
>> + - Jerome Brunet <jbrunet@baylibre.com>
>> + - Jian Hu <jian.hu@amlogic.com>
>> + - Xianwei Zhao <xianwei.zhao@amlogic.com>
>> +
>> +properties:
>> + compatible:
>> + enum:
>> + - amlogic,a9-gp0-pll
>> + - amlogic,a9-hifi0-pll
>> + - amlogic,a9-hifi1-pll
>> + - amlogic,a9-mclk0-pll
>> + - amlogic,a9-mclk1-pll
>> +
>> + reg:
>> + maxItems: 1
>> +
>> + '#clock-cells':
>> + const: 1
>> +
>> + clocks:
>> + items:
>> + - description: pll input oscillator gate
>> + - description: fixed input clock source for mclk_sel_0
>> + - description: u3p2pll input clock source for mclk_sel_0 (optional)
> Second clock is also optional. Drop "(optional)" comment, just
> confusing.
GP0 has only one parent clock, while MCLK has three.
The second and third parent entries of GP0 are vacant,
so they need to be marked optional.
I will add the optional property for the second clock in the next revision.
>> + minItems: 1
>> +
>> + clock-names:
>> + items:
>> + - const: in0
>> + - const: in1
>> + - const: in2
> Pretty pointless names, drop property.
Ok, I will drop them.
clock-names:
- items:
- - const: in0
- - const: in1
- - const: in2
minItems: 1
>> + minItems: 1
>> +
>> +required:
>> + - compatible
>> + - '#clock-cells'
>> + - reg
>> + - clocks
>> + - clock-names
>> +
>> +allOf:
>> + - if:
>> + properties:
>> + compatible:
>> + contains:
>> + enum:
>> + - amlogic,a9-mclk0-pll
>> + - amlogic,a9-mclk1-pll
>> +
>> + then:
>> + properties:
>> + clocks:
>> + maxItems: 3
> No, minItems instead. maxItems is already 3, so what is the point of
> redefining it?
Ok, I will use minItems instead.
>> +
>> + clock-names:
>> + maxItems: 3
>> +
>> + - if:
>> + properties:
>> + compatible:
>> + contains:
>> + enum:
>> + - amlogic,a9-gp0-pll
>> + - amlogic,a9-hifi0-pll
>> + - amlogic,a9-hifi1-pll
>> +
>> + then:
>> + properties:
>> + clocks:
>> + maxItems: 1
>> +
>> + clock-names:
>> + maxItems: 1
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> + - |
>> + apb4 {
> soc
Ok, I will rename it to soc.
>> + #address-cells = <2>;
>> + #size-cells = <2>;
>> +
>> + clock-controller@8200 {
>> + compatible = "amlogic,a9-gp0-pll";
>> + reg = <0x0 0x8200 0x0 0x20>;
>> + #clock-cells = <1>;
>> + clocks = <&scmi_clk 0>;
>> + clock-names = "in0";
>> + };
>> +
>> + clock-controller@8330 {
>> + compatible = "amlogic,a9-mclk0-pll";
>> + reg = <0x0 0x8330 0x0 0x14>;
>> + #clock-cells = <1>;
>> + clocks = <&scmi_clk 4>,
>> + <&scmi_clk 8>;
>> + clock-names = "in0", "in1";
> One example is enough, you have exactly the same properties.
Ok, I will drop the second clock node.
>
> Best regards,
> Krzysztof
>
Best regards,
Jian
^ permalink raw reply
* RE: [PATCH 1/2] PCI: host-generic: Simplify return value handling in pci_host_common_parse_port(s)
From: Sherry Sun @ 2026-05-22 6:20 UTC (permalink / raw)
To: Hongxing Zhu, Sherry Sun (OSS), l.stach@pengutronix.de, Frank Li,
bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com,
will@kernel.org
Cc: imx@lists.linux.dev, linux-pci@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <GV2PR04MB12019D8D1854A947AA7DDE1208C0F2@GV2PR04MB12019.eurprd04.prod.outlook.com>
> > Subject: [PATCH 1/2] PCI: host-generic: Simplify return value handling
> > in
> > pci_host_common_parse_port(s)
> >
> > From: Sherry Sun <sherry.sun@nxp.com>
> >
> > The pci_host_common_parse_port() shouldn't check the RC-level binding.
> > That's a policy decision that belongs to the caller, not this common helper.
> >
> > Simplify pci_host_common_parse_port() to only parses properties from
> > the Root
> "to only parses"/s/"to only parse"
>
> > Port(and its children) without checking the RC node. Also change
> Missing space after "Port".
>
> > pci_host_common_parse_ports() to return 0 when no ports are found,
> > since it is not an error.
> >
> > So now both functions won't return failure for "property not found" or
> > "port not found", they purely returns 0 on success and a negative
> > error code on real
> returns/s/return
Thanks, will fix these issues.
Best Regards
Sherry Sun
>
> Best Regards
> Richard Zhu
>
> > failures.
> >
> > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > ---
> > drivers/pci/controller/pci-host-common.c | 29
> > ++++--------------------
> > 1 file changed, 5 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/pci/controller/pci-host-common.c
> > b/drivers/pci/controller/pci- host-common.c index
> > 67455caaf9e6..7ce5a939e3d9 100644
> > --- a/drivers/pci/controller/pci-host-common.c
> > +++ b/drivers/pci/controller/pci-host-common.c
> > @@ -108,8 +108,7 @@ static int pci_host_common_parse_perst(struct
> > device *dev,
> > * dependencies and the driver may fail to operate if required resources
> > * are missing.
> > *
> > - * Return: 0 on success, -ENODEV if PERST# found in RC node (legacy
> > binding
> > - * should be used), Other negative error codes on failure.
> > + * Return: 0 on success, negative error codes on failure.
> > */
> > static int pci_host_common_parse_port(struct device *dev,
> > struct pci_host_bridge *bridge, @@ -
> 128,22
> > +127,6 @@ static int pci_host_common_parse_port(struct device *dev,
> > if (ret)
> > return ret;
> >
> > - /*
> > - * 1. PERST# found in RP or its child nodes - list is not empty,
> > - * continue
> > - *
> > - * 2. PERST# not found in RP/children, but found in RC node -
> > - * return -ENODEV to fallback legacy binding
> > - *
> > - * 3. PERST# not found anywhere - list is empty, continue (optional
> > - * PERST#)
> > - */
> > - if (list_empty(&port->perst)) {
> > - if (of_property_present(dev->of_node, "reset-gpios") ||
> > - of_property_present(dev->of_node, "reset-gpio"))
> > - return -ENODEV;
> > - }
> > -
> > INIT_LIST_HEAD(&port->list);
> > list_add_tail(&port->list, &bridge->ports);
> >
> > @@ -158,13 +141,11 @@ static int pci_host_common_parse_port(struct
> > device *dev,
> > * Iterate through child nodes of the host bridge and parse Root Port
> > * properties (currently only reset GPIOs).
> > *
> > - * Return: 0 on success, -ENODEV if no ports found or PERST# found in
> > RC
> > - * node (legacy binding should be used), Other negative error codes
> > on
> > - * failure.
> > + * Return: 0 on success, negative error codes on failure.
> > */
> > int pci_host_common_parse_ports(struct device *dev, struct
> > pci_host_bridge
> > *bridge) {
> > - int ret = -ENODEV;
> > + int ret = 0;
> >
> > for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> > if (!of_node_is_type(of_port, "pci")) @@ -174,8 +155,8 @@
> int
> > pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge
> *brid
> > goto err_cleanup;
> > }
> >
> > - if (ret)
> > - return ret;
> > + if (list_empty(&bridge->ports))
> > + return 0;
> >
> > return devm_add_action_or_reset(dev,
> pci_host_common_delete_ports,
> > &bridge->ports);
> > --
> > 2.37.1
^ permalink raw reply
* Re: [PATCH v6 01/10] dt-bindings: display: rockchip: analogix-dp: Fix hclk as third clock for RK3588
From: Krzysztof Kozlowski @ 2026-05-22 6:11 UTC (permalink / raw)
To: Damon Ding
Cc: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss, Laurent.pinchart, jonas, jernej.skrabec,
nicolas.frattaroli, cristian.ciocaltea, sebastian.reichel,
dmitry.baryshkov, luca.ceresoli, dianders, m.szyprowski,
dri-devel, devicetree, linux-arm-kernel, linux-rockchip,
linux-kernel
In-Reply-To: <20260521080835.1362416-2-damon.ding@rock-chips.com>
On Thu, May 21, 2026 at 04:08:26PM +0800, Damon Ding wrote:
> RK3588 eDP controller requires HCLK_VO1 to access the VO1 GRF
> registers and enable the video datapath.
>
> Previously, the clock was enabled implicitly via the 'rockchip,vo-grf'
> phandle reference, which allowed the eDP to work without explicitly
> managing the hclk_vo1 clock. However, this is not safe or explicit.
>
> To make the clock dependency explicit, enforce per-SoC clock-names
> requirements:
> - RK3288: 2 clocks (dp, pclk)
> - RK3399: 3 clocks (dp, pclk, grf)
> - RK3588: 3 clocks (dp, pclk, hclk)
>
> Do not reuse the 'grf' clock name for RK3588 because it represents
> a different clock with distinct control logic:
> - The 'grf' clock is only for GRF register access and is toggled
> dynamically during register access.
> - The 'hclk' clock controls both GRF access and video datapath
> gating, and must remain enabled during probe.
>
> Fixes: f855146263b1 ("dt-bindings: display: rockchip: analogix-dp: Add support for RK3588")
> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
>
> ---
>
> Changes in v4:
> - Modify the commit msg.
>
> Changes in v5:
> - Enforce the correct third clock name on a per-compatible basis.
> - Modify the commit msg simultaneously.
>
> Changes in v6:
> - Expand more detail commit msg about using hclk instead of grf clock.
> ---
> .../rockchip/rockchip,analogix-dp.yaml | 37 +++++++++++++++++--
> 1 file changed, 33 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> index d99b23b88cc5..8001c1facf98 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
> @@ -23,10 +23,7 @@ properties:
>
> clock-names:
> minItems: 2
> - items:
> - - const: dp
> - - const: pclk
> - - const: grf
> + maxItems: 3
>
> power-domains:
> maxItems: 1
> @@ -60,6 +57,33 @@ required:
> allOf:
> - $ref: /schemas/display/bridge/analogix,dp.yaml#
>
> + - if:
> + properties:
> + compatible:
> + contains:
> + enum:
> + - rockchip,rk3288-dp
> + then:
> + properties:
> + clock-names:
> + items:
> + - const: dp
> + - const: pclk
Why aren't there constraints for clocks? They always must come together.
Please open any other binding and look how it is done there.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH] irqchip/exynos-combiner: remove useless spinlock
From: Marek Szyprowski @ 2026-05-22 6:10 UTC (permalink / raw)
To: linux-arm-kernel, linux-samsung-soc, linux-rt-devel
Cc: Marek Szyprowski, Thomas Gleixner, Krzysztof Kozlowski,
Alim Akhtar, Sebastian Andrzej Siewior, Clark Williams,
Steven Rostedt
In-Reply-To: <CGME20260522061030eucas1p15f61b7bc01f77a3d34d41472210ea662@eucas1p1.samsung.com>
irq_controller_lock doesn't protect anything, it must be some leftover
from early development or copy/paste. Remove it completely.
Suggested-by: Thomas Gleixner <tglx@kernel.org>
Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lore.kernel.org/all/20260520220422.3522908-1-m.szyprowski@samsung.com/
Fixes: 96031b31a4b3 ("irqchip/exynos-combiner: Switch to raw_spinlock")
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
drivers/irqchip/exynos-combiner.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index 03cafcc5c835..d9d408cb4711 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -24,8 +24,6 @@
#define IRQ_IN_COMBINER 8
-static DEFINE_RAW_SPINLOCK(irq_controller_lock);
-
struct combiner_chip_data {
unsigned int hwirq_offset;
unsigned int irq_mask;
@@ -72,9 +70,7 @@ static void combiner_handle_cascade_irq(struct irq_desc *desc)
chained_irq_enter(chip, desc);
- raw_spin_lock(&irq_controller_lock);
status = readl_relaxed(chip_data->base + COMBINER_INT_STATUS);
- raw_spin_unlock(&irq_controller_lock);
status &= chip_data->irq_mask;
if (status == 0)
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v9 2/5] dt-bindings: phy: Add documentation for Airoha AN7581 USB PHY
From: Krzysztof Kozlowski @ 2026-05-22 6:06 UTC (permalink / raw)
To: Christian Marangi
Cc: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul, Neil Armstrong,
Lorenzo Bianconi, Felix Fietkau, linux-clk, devicetree,
linux-kernel, linux-arm-kernel, linux-phy
In-Reply-To: <20260521153645.7028-3-ansuelsmth@gmail.com>
On Thu, May 21, 2026 at 05:35:53PM +0200, Christian Marangi wrote:
> Add documentation for Airoha AN7581 USB PHY that describe the USB PHY
> for the USB controller.
>
> Airoha AN7581 SoC support a maximum of 2 USB port. The USB 2.0 mode is
> always supported. The USB 3.0 mode is optional and depends on the Serdes
> mode currently configured on the system for the relevant USB port.
>
> To correctly calibrate, the USB 2.0 port require correct value in
> "airoha,usb2-monitor-clk-sel" property. Both the 2 USB 2.0 port permit
> selecting one of the 4 monitor clock for calibration (internal clock not
> exposed to the system) but each port have only one of the 4 actually
> connected in HW hence the correct value needs to be specified in DT
> based on board and the physical port. Normally it's monitor clock 1 for
> USB1 and monitor clock 2 for USB2.
>
> To correctly setup the Serdes mode attached to the USB 3.0 mode, a phys
> property is required with the phandle pointing to the correct Serdes port
> provided by the SCU node. Providing the phys property is optional if USB
> 3.0 is not used.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
> .../bindings/phy/airoha,an7581-usb-phy.yaml | 62 +++++++++++++++++++
> MAINTAINERS | 6 ++
> 2 files changed, 68 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/airoha,an7581-usb-phy.yaml
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* RE: [PATCH 1/2] PCI: host-generic: Simplify return value handling in pci_host_common_parse_port(s)
From: Hongxing Zhu @ 2026-05-22 6:05 UTC (permalink / raw)
To: Sherry Sun (OSS), l.stach@pengutronix.de, Frank Li,
bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com,
will@kernel.org
Cc: imx@lists.linux.dev, linux-pci@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Sherry Sun
In-Reply-To: <20260522034344.1147775-2-sherry.sun@oss.nxp.com>
> -----Original Message-----
> From: Sherry Sun (OSS) <sherry.sun@oss.nxp.com>
> Sent: Friday, May 22, 2026 11:44 AM
> To: Hongxing Zhu <hongxing.zhu@nxp.com>; l.stach@pengutronix.de; Frank Li
> <frank.li@nxp.com>; bhelgaas@google.com; lpieralisi@kernel.org;
> kwilczynski@kernel.org; mani@kernel.org; robh@kernel.org;
> s.hauer@pengutronix.de; kernel@pengutronix.de; festevam@gmail.com;
> will@kernel.org
> Cc: imx@lists.linux.dev; linux-pci@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org; Sherry Sun
> <sherry.sun@nxp.com>
> Subject: [PATCH 1/2] PCI: host-generic: Simplify return value handling in
> pci_host_common_parse_port(s)
>
> From: Sherry Sun <sherry.sun@nxp.com>
>
> The pci_host_common_parse_port() shouldn't check the RC-level binding.
> That's a policy decision that belongs to the caller, not this common helper.
>
> Simplify pci_host_common_parse_port() to only parses properties from the Root
"to only parses"/s/"to only parse"
> Port(and its children) without checking the RC node. Also change
Missing space after "Port".
> pci_host_common_parse_ports() to return 0 when no ports are found, since it is
> not an error.
>
> So now both functions won't return failure for "property not found" or "port not
> found", they purely returns 0 on success and a negative error code on real
returns/s/return
Best Regards
Richard Zhu
> failures.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> ---
> drivers/pci/controller/pci-host-common.c | 29 ++++--------------------
> 1 file changed, 5 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-
> host-common.c
> index 67455caaf9e6..7ce5a939e3d9 100644
> --- a/drivers/pci/controller/pci-host-common.c
> +++ b/drivers/pci/controller/pci-host-common.c
> @@ -108,8 +108,7 @@ static int pci_host_common_parse_perst(struct device
> *dev,
> * dependencies and the driver may fail to operate if required resources
> * are missing.
> *
> - * Return: 0 on success, -ENODEV if PERST# found in RC node (legacy binding
> - * should be used), Other negative error codes on failure.
> + * Return: 0 on success, negative error codes on failure.
> */
> static int pci_host_common_parse_port(struct device *dev,
> struct pci_host_bridge *bridge, @@ -128,22
> +127,6 @@ static int pci_host_common_parse_port(struct device *dev,
> if (ret)
> return ret;
>
> - /*
> - * 1. PERST# found in RP or its child nodes - list is not empty,
> - * continue
> - *
> - * 2. PERST# not found in RP/children, but found in RC node -
> - * return -ENODEV to fallback legacy binding
> - *
> - * 3. PERST# not found anywhere - list is empty, continue (optional
> - * PERST#)
> - */
> - if (list_empty(&port->perst)) {
> - if (of_property_present(dev->of_node, "reset-gpios") ||
> - of_property_present(dev->of_node, "reset-gpio"))
> - return -ENODEV;
> - }
> -
> INIT_LIST_HEAD(&port->list);
> list_add_tail(&port->list, &bridge->ports);
>
> @@ -158,13 +141,11 @@ static int pci_host_common_parse_port(struct device
> *dev,
> * Iterate through child nodes of the host bridge and parse Root Port
> * properties (currently only reset GPIOs).
> *
> - * Return: 0 on success, -ENODEV if no ports found or PERST# found in RC
> - * node (legacy binding should be used), Other negative error codes on
> - * failure.
> + * Return: 0 on success, negative error codes on failure.
> */
> int pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge
> *bridge) {
> - int ret = -ENODEV;
> + int ret = 0;
>
> for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> if (!of_node_is_type(of_port, "pci")) @@ -174,8 +155,8 @@ int
> pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge *brid
> goto err_cleanup;
> }
>
> - if (ret)
> - return ret;
> + if (list_empty(&bridge->ports))
> + return 0;
>
> return devm_add_action_or_reset(dev, pci_host_common_delete_ports,
> &bridge->ports);
> --
> 2.37.1
^ permalink raw reply
* RE: [PATCH 2/2] PCI: imx6: Add imx_pcie_perst_found() to inspect the parsed result
From: Hongxing Zhu @ 2026-05-22 6:05 UTC (permalink / raw)
To: Sherry Sun (OSS), l.stach@pengutronix.de, Frank Li,
bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com,
will@kernel.org
Cc: imx@lists.linux.dev, linux-pci@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Sherry Sun
In-Reply-To: <20260522034344.1147775-3-sherry.sun@oss.nxp.com>
> -----Original Message-----
> From: Sherry Sun (OSS) <sherry.sun@oss.nxp.com>
> Sent: Friday, May 22, 2026 11:44 AM
> To: Hongxing Zhu <hongxing.zhu@nxp.com>; l.stach@pengutronix.de; Frank Li
> <frank.li@nxp.com>; bhelgaas@google.com; lpieralisi@kernel.org;
> kwilczynski@kernel.org; mani@kernel.org; robh@kernel.org;
> s.hauer@pengutronix.de; kernel@pengutronix.de; festevam@gmail.com;
> will@kernel.org
> Cc: imx@lists.linux.dev; linux-pci@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org; Sherry Sun
> <sherry.sun@nxp.com>
> Subject: [PATCH 2/2] PCI: imx6: Add imx_pcie_perst_found() to inspect the
> parsed result
>
> From: Sherry Sun <sherry.sun@nxp.com>
>
> Since pci_host_common_parse_port() doesn't return failure for "property not
> found"(-ENODEV), the caller should inspect the parsed result and decide whether
One space should be placed before (-ENODEV).
> to fall back to the legacy binding.
> Add imx_pcie_perst_found() to inspect the parsed result.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Reviewed-by: Richard Zhu <hongxing.zhu@nxp.com>
Best Regards
Richard Zhu
> ---
> drivers/pci/controller/dwc/pci-imx6.c | 25 +++++++++++++++++--------
> 1 file changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> b/drivers/pci/controller/dwc/pci-imx6.c
> index b137551871fc..34756f28fcc6 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -1287,6 +1287,18 @@ static void imx_pcie_assert_perst(struct imx_pcie
> *imx_pcie, bool assert)
> }
> }
>
> +static bool imx_pcie_perst_found(struct pci_host_bridge *bridge) {
> + struct pci_host_port *port;
> +
> + list_for_each_entry(port, &bridge->ports, list) {
> + if (!list_empty(&port->perst))
> + return true;
> + }
> +
> + return false;
> +}
> +
> static int imx_pcie_host_init(struct dw_pcie_rp *pp) {
> struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -1299,15 +1311,12
> @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
> /* Parse Root Port nodes if present */
> ret = pci_host_common_parse_ports(dev, bridge);
> if (ret) {
> - if (ret != -ENODEV) {
> - dev_err(dev, "Failed to parse Root Port
> nodes: %d\n", ret);
> - return ret;
> - }
> + dev_err(dev, "Failed to parse Root Port nodes: %d\n",
> ret);
> + return ret;
> + }
>
> - /*
> - * Fall back to legacy binding for DT backwards
> - * compatibility
> - */
> + /* Fallback to legacy binding for DT backwards compatibility. */
> + if (!imx_pcie_perst_found(bridge)) {
> ret = imx_pcie_parse_legacy_binding(imx_pcie);
> if (ret)
> return ret;
> --
> 2.37.1
^ permalink raw reply
* Re: [PATCH v10 19/30] KVM: arm64: Provide assembly for SME register access
From: Marc Zyngier @ 2026-05-22 5:52 UTC (permalink / raw)
To: Mark Rutland
Cc: Mark Brown, Oliver Upton, Joey Gouly, Catalin Marinas,
Suzuki K Poulose, Will Deacon, Paolo Bonzini, Jonathan Corbet,
Shuah Khan, Dave Martin, Fuad Tabba, Ben Horgan, linux-arm-kernel,
kvmarm, linux-kernel, kvm, linux-doc, linux-kselftest,
Peter Maydell, Eric Auger
In-Reply-To: <ag8b7oq4SFpdmlP_@J2N7QTR9R3>
On Thu, 21 May 2026 15:51:26 +0100,
Mark Rutland <mark.rutland@arm.com> wrote:
>
> On Fri, Mar 06, 2026 at 05:01:11PM +0000, Mark Brown wrote:
> > Provide versions of the SME state save and restore functions for the
> > hypervisor to allow it to restore ZA and ZT for guests.
> >
> > Signed-off-by: Mark Brown <broonie@kernel.org>
> > ---
> > arch/arm64/include/asm/kvm_hyp.h | 2 ++
> > arch/arm64/kvm/hyp/fpsimd.S | 23 +++++++++++++++++++++++
> > 2 files changed, 25 insertions(+)
>
> While this specific instance is simple enough, I don't think we should
> continue to duplicate the low level save/restore routines between the
> main kernel and KVM hyp code.
>
> I've sent a series that avoids the need for this, and cleans up some
> other bits):
>
> https://lore.kernel.org/linux-arm-kernel/20260521132556.584676-1-mark.rutland@arm.com/
>
> Assuming Marc and Oliver are on board, I'd prefer that we do that
> cleanup first, and build the KVM SME support atop.
Absolutely. The whole FP/SVE is still way too complicated, full of
esoteric constructs, hard to audit, and I would really like to see it
cleaned-up before stacking another layer on top.
I've quickly eyeballed the KVM-specific patches yesterday, and nothing
seem outlandish, so there is a good chance some of that could make it
into 7.2. I plan to look at it again shortly.
Thanks,
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply
* Re: [PATCH] arm64: tlb: Flush walk cache when unsharing PMD tables
From: Zeng Heng @ 2026-05-22 5:32 UTC (permalink / raw)
To: Catalin Marinas
Cc: yezhenyu2, zhurui3, will, akpm, npiggin, aneesh.kumar, peterz,
linux-kernel, wangkefeng.wang, linux-arm-kernel, linux-mm,
linux-arch, David Hildenbrand, zengheng4
In-Reply-To: <ag8hmZ3kjtJINyIT@arm.com>
On 2026/5/21 23:15, Catalin Marinas wrote:
> On Thu, May 21, 2026 at 04:05:07PM +0100, Catalin Marinas wrote:
>> + David H.
>>
>> On Thu, May 21, 2026 at 03:30:11PM +0800, Zeng Heng wrote:
>>> From: Zeng Heng <zengheng4@huawei.com>
>>>
>>> When huge_pmd_unshare() is called to unshare a PMD table, the
>>> tlb_unshare_pmd_ptdesc() function sets tlb->unshared_tables=true
>>> but the aarch64 tlb_flush() only checked tlb->freed_tables to
>>> determine whether to use TLBF_NONE (vae1is, invalidates walk
>>> cache) or TLBF_NOWALKCACHE (vale1is, leaf-only).
>>>
>>> This caused the stale PMD page table entry to remain in the walk cache
>>> after unshare, potentially leading to incorrect page table walks.
>>>
>>> Fix by including unshared_tables in the check, so that when
>>> unsharing tables, TLBF_NONE is used and the walk cache is properly
>>> invalidated.
>>>
>>> Here is the detailed distinction between vae1is and vale1is:
>>>
>>> | Instruction Combination | Actual Invalidation Scope |
>>> | ------------------------ | --------------------------------------------------|
>>> | `VAE1IS` + TTL=`0` | All entries at all levels (full invalidation) |
>>> | `VAE1IS` + TTL=`2` (L2) | Non-leaf at Level 0/1 + leaf at Level 2 |
>>> | `VALE1IS` + TTL=`0` | Leaf entries at all levels (non-leaf not cleared) |
>>> | `VALE1IS` + TTL=`2` (L2) | Leaf entry at Level 2 only |
>>>
>>> Signed-off-by: Zeng Heng <zengheng4@huawei.com>
>> The fix looks fine but does it need:
>>
>> Fixes: 8ce720d5bd91 ("mm/hugetlb: fix excessive IPI broadcasts when unsharing PMD tables using mmu_gather")
>> Cc: <stable@vger.kernel.org>
>>
>>> ---
>>> arch/arm64/include/asm/tlb.h | 3 ++-
>>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
>>> index 10869d7731b8..751bd57bc3ba 100644
>>> --- a/arch/arm64/include/asm/tlb.h
>>> +++ b/arch/arm64/include/asm/tlb.h
>>> @@ -53,7 +53,8 @@ static inline int tlb_get_level(struct mmu_gather *tlb)
>>> static inline void tlb_flush(struct mmu_gather *tlb)
>>> {
>>> struct vm_area_struct vma = TLB_FLUSH_VMA(tlb->mm, 0);
>>> - tlbf_t flags = tlb->freed_tables ? TLBF_NONE : TLBF_NOWALKCACHE;
>>> + tlbf_t flags = (tlb->freed_tables || tlb->unshared_tables) ?
>>> + TLBF_NONE : TLBF_NOWALKCACHE;
>>> unsigned long stride = tlb_get_unmap_size(tlb);
>>> int tlb_level = tlb_get_level(tlb);
> Do we need this as well?
The proposed fix has been validated against the issue scenarios and
works as expected.
Per the ARM Architecture Reference Manual, whether only the last-level
page table entry is invalidated is determined by the instruction used
(vale1is for leaf entry only, vae1is for walk cache including leaf entry
and
non-leaf entry), rather than the TTL field. The TTL field merely specifies
which level the leaf entry belongs to.
Setting TTL to 0 always works fine, however, hardware must assume that
the entry can be from any level.[1][2]
[1]: vae1is instruction introduction by ARM spec,
https://developer.arm.com/documentation/ddi0601/2026-03/AArch64-Instructions/TLBI-VAE1IS--TLBI-VAE1ISNXS--TLB-Invalidate-by-VA--EL1--Inner-Shareable
[2]: rvae1is instruction introduction by ARM spec,
https://developer.arm.com/documentation/ddi0601/2026-03/AArch64-Instructions/TLBI-RVAE1IS--TLBI-RVAE1ISNXS--TLB-Range-Invalidate-by-VA--EL1--Inner-Shareable?lang=en
Best regards,
Zeng Heng
>
> diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
> index 10869d7731b8..3f4ab38cfd6e 100644
> --- a/arch/arm64/include/asm/tlb.h
> +++ b/arch/arm64/include/asm/tlb.h
> @@ -24,7 +24,7 @@ static void tlb_flush(struct mmu_gather *tlb);
> static inline int tlb_get_level(struct mmu_gather *tlb)
> {
> /* The TTL field is only valid for the leaf entry. */
> - if (tlb->freed_tables)
> + if (tlb->freed_tables || tlb->unshared_tables)
> return TLBI_TTL_UNKNOWN;
>
> if (tlb->cleared_ptes && !(tlb->cleared_pmds ||
^ permalink raw reply
* [PATCH v3 6/6] mm/vmalloc: align vm_area so vmap() can batch mappings
From: Wen Jiang @ 2026-05-22 5:31 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, will, akpm, urezki
Cc: baohua, Xueyuan.chen21, dev.jain, rppt, david, ryan.roberts,
anshuman.khandual, ajd, linux-kernel, jiangwen6
In-Reply-To: <20260522053146.83209-1-jiangwenxiaomi@gmail.com>
From: "Barry Song (Xiaomi)" <baohua@kernel.org>
Try to align the vmap virtual address to PMD_SHIFT or a
larger PTE mapping size hinted by the architecture, so
contiguous pages can be batch-mapped when setting PMD or
PTE entries.
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
Signed-off-by: Wen Jiang <jiangwen6@xiaomi.com>
Tested-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
---
mm/vmalloc.c | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 50642246f4d40..040d400928aab 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3620,6 +3620,37 @@ static int vmap_batched(unsigned long addr, unsigned long end,
return err;
}
+static struct vm_struct *get_aligned_vm_area(unsigned long size,
+ unsigned long flags, const void *caller)
+{
+ struct vm_struct *vm_area;
+ unsigned int shift;
+
+ /* Try PMD alignment for large sizes */
+ if (size >= PMD_SIZE) {
+ vm_area = __get_vm_area_node(size, PMD_SIZE, PAGE_SHIFT, flags,
+ VMALLOC_START, VMALLOC_END,
+ NUMA_NO_NODE, GFP_KERNEL, caller);
+ if (vm_area)
+ return vm_area;
+ }
+
+ /* Try CONT_PTE alignment */
+ shift = arch_vmap_pte_supported_shift(size);
+ if (shift > PAGE_SHIFT) {
+ vm_area = __get_vm_area_node(size, 1UL << shift, PAGE_SHIFT, flags,
+ VMALLOC_START, VMALLOC_END,
+ NUMA_NO_NODE, GFP_KERNEL, caller);
+ if (vm_area)
+ return vm_area;
+ }
+
+ /* Fall back to page alignment */
+ return __get_vm_area_node(size, PAGE_SIZE, PAGE_SHIFT, flags,
+ VMALLOC_START, VMALLOC_END,
+ NUMA_NO_NODE, GFP_KERNEL, caller);
+}
+
/**
* vmap - map an array of pages into virtually contiguous space
* @pages: array of page pointers
@@ -3658,7 +3689,7 @@ void *vmap(struct page **pages, unsigned int count,
return NULL;
size = (unsigned long)count << PAGE_SHIFT;
- area = get_vm_area_caller(size, flags, __builtin_return_address(0));
+ area = get_aligned_vm_area(size, flags, __builtin_return_address(0));
if (!area)
return NULL;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 5/6] mm/vmalloc: map contiguous pages in batches for vmap() if possible
From: Wen Jiang @ 2026-05-22 5:31 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, will, akpm, urezki
Cc: baohua, Xueyuan.chen21, dev.jain, rppt, david, ryan.roberts,
anshuman.khandual, ajd, linux-kernel, jiangwen6
In-Reply-To: <20260522053146.83209-1-jiangwenxiaomi@gmail.com>
From: "Barry Song (Xiaomi)" <baohua@kernel.org>
In many cases, the pages passed to vmap() may include high-order
pages. For example, the systemheap often allocates pages in descending
order: order 8, then 4, then 0. Currently, vmap() iterates over every
page individually—even pages inside a high-order block are handled
one by one.
This patch detects physically contiguous pages (regardless of whether
they are compound or non-compound) by scanning with
num_pages_contiguous(), and maps them as a single contiguous block
whenever possible. The first page's pfn must be aligned to the
mapping order for the batched mapping to be used.
Pages with the same page_shift are coalesced and mapped via
vmap_pages_range_noflush_walk() to avoid page table rewalk.
As users typically allocate memory in descending orders (e.g.
8 → 4 → 0), once an order-0 page is encountered, we stop scanning
for contiguous pages since subsequent pages are likely order-0 as well.
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
Co-developed-by: Dev Jain <dev.jain@arm.com>
Signed-off-by: Dev Jain <dev.jain@arm.com>
Signed-off-by: Wen Jiang <jiangwen6@xiaomi.com>
Tested-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
---
mm/vmalloc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 80 insertions(+), 2 deletions(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index deb764abc0571..50642246f4d40 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3542,6 +3542,84 @@ void vunmap(const void *addr)
}
EXPORT_SYMBOL(vunmap);
+static inline int get_vmap_batch_order(struct page **pages,
+ unsigned int max_steps, unsigned int idx)
+{
+ unsigned int nr_contig;
+ int order;
+
+ if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP) ||
+ ioremap_max_page_shift == PAGE_SHIFT)
+ return 0;
+
+ nr_contig = num_pages_contiguous(&pages[idx], max_steps);
+ if (nr_contig < 2)
+ return 0;
+
+ order = fls(nr_contig) - 1;
+
+ if (arch_vmap_pte_supported_shift(PAGE_SIZE << order) == PAGE_SHIFT)
+ return 0;
+
+ /* Ensure the first page's pfn is aligned to the order */
+ if (!IS_ALIGNED(page_to_pfn(pages[idx]), 1 << order))
+ return 0;
+
+ return order;
+}
+
+static int vmap_batched(unsigned long addr, unsigned long end,
+ pgprot_t prot, struct page **pages)
+{
+ unsigned int count = (end - addr) >> PAGE_SHIFT;
+ unsigned int prev_shift = 0, idx = 0;
+ unsigned long start = addr, map_addr = addr;
+ int err;
+
+ err = kmsan_vmap_pages_range_noflush(addr, end, prot, pages,
+ PAGE_SHIFT, GFP_KERNEL);
+ if (err)
+ goto out;
+
+ for (unsigned int i = 0; i < count; ) {
+ unsigned int shift = PAGE_SHIFT +
+ get_vmap_batch_order(pages, count - i, i);
+
+ if (!i)
+ prev_shift = shift;
+
+ if (shift != prev_shift) {
+ err = vmap_pages_range_noflush_walk(map_addr, addr,
+ prot, pages + idx,
+ min(prev_shift, PMD_SHIFT));
+ if (err)
+ goto out;
+ prev_shift = shift;
+ map_addr = addr;
+ idx = i;
+ }
+
+ /*
+ * Once small pages are encountered, the remaining pages
+ * are likely small as well.
+ */
+ if (shift == PAGE_SHIFT)
+ break;
+
+ addr += 1UL << shift;
+ i += 1U << (shift - PAGE_SHIFT);
+ }
+
+ /* Remaining */
+ if (map_addr < end)
+ err = vmap_pages_range_noflush_walk(map_addr, end,
+ prot, pages + idx, min(prev_shift, PMD_SHIFT));
+
+out:
+ flush_cache_vmap(start, end);
+ return err;
+}
+
/**
* vmap - map an array of pages into virtually contiguous space
* @pages: array of page pointers
@@ -3585,8 +3663,8 @@ void *vmap(struct page **pages, unsigned int count,
return NULL;
addr = (unsigned long)area->addr;
- if (vmap_pages_range(addr, addr + size, pgprot_nx(prot),
- pages, PAGE_SHIFT) < 0) {
+ if (vmap_batched(addr, addr + size, pgprot_nx(prot),
+ pages) < 0) {
vunmap(area->addr);
return NULL;
}
--
2.34.1
^ permalink raw reply related
* [PATCH v3 4/6] mm/vmalloc: Extend page table walk to support larger page_shift sizes and eliminate page table rewalk
From: Wen Jiang @ 2026-05-22 5:31 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, will, akpm, urezki
Cc: baohua, Xueyuan.chen21, dev.jain, rppt, david, ryan.roberts,
anshuman.khandual, ajd, linux-kernel, jiangwen6
In-Reply-To: <20260522053146.83209-1-jiangwenxiaomi@gmail.com>
From: "Barry Song (Xiaomi)" <baohua@kernel.org>
vmap_pages_range_noflush_walk() (formerly vmap_small_pages_range_noflush())
provides a clean interface by taking struct page **pages and mapping them
via direct PTE iteration. This avoids the page table rewalk seen when
using vmap_range_noflush() for page_shift values other than PAGE_SHIFT.
Extend it to support larger page_shift values, and add PMD- and
contiguous-PTE mappings as well. Rename it to vmap_pages_range_noflush_walk()
since it now handles more than just small pages.
For vmalloc() allocations with VM_ALLOW_HUGE_VMAP, we no longer need to
iterate over pages one by one via vmap_range_noflush(), which would
otherwise lead to page table rewalk. The code is now unified with the
PAGE_SHIFT case by simply calling vmap_pages_range_noflush_walk().
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
Signed-off-by: Wen Jiang <jiangwen6@xiaomi.com>
Tested-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
---
mm/vmalloc.c | 71 +++++++++++++++++++++++++++++-----------------------
1 file changed, 40 insertions(+), 31 deletions(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 53fd4ee460ea4..deb764abc0571 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -543,8 +543,10 @@ void vunmap_range(unsigned long addr, unsigned long end)
static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
unsigned long end, pgprot_t prot, struct page **pages, int *nr,
- pgtbl_mod_mask *mask)
+ pgtbl_mod_mask *mask, unsigned int shift)
{
+ unsigned long pfn, size;
+ unsigned int steps;
int err = 0;
pte_t *pte;
@@ -575,9 +577,10 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
break;
}
- set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
- (*nr)++;
- } while (pte++, addr += PAGE_SIZE, addr != end);
+ pfn = page_to_pfn(page);
+ size = vmap_set_ptes(pte, addr, end, pfn, prot, shift);
+ steps = PFN_DOWN(size);
+ } while (pte += steps, *nr += steps, addr += size, addr != end);
lazy_mmu_mode_disable();
*mask |= PGTBL_PTE_MODIFIED;
@@ -587,7 +590,7 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
static int vmap_pages_pmd_range(pud_t *pud, unsigned long addr,
unsigned long end, pgprot_t prot, struct page **pages, int *nr,
- pgtbl_mod_mask *mask)
+ pgtbl_mod_mask *mask, unsigned int shift)
{
pmd_t *pmd;
unsigned long next;
@@ -597,7 +600,27 @@ static int vmap_pages_pmd_range(pud_t *pud, unsigned long addr,
return -ENOMEM;
do {
next = pmd_addr_end(addr, end);
- if (vmap_pages_pte_range(pmd, addr, next, prot, pages, nr, mask))
+
+ if (shift == PMD_SHIFT) {
+ struct page *page = pages[*nr];
+ phys_addr_t phys_addr;
+
+ if (WARN_ON(!page))
+ return -ENOMEM;
+ if (WARN_ON(!pfn_valid(page_to_pfn(page))))
+ return -EINVAL;
+
+ phys_addr = page_to_phys(page);
+
+ if (vmap_try_huge_pmd(pmd, addr, next, phys_addr, prot,
+ shift)) {
+ *mask |= PGTBL_PMD_MODIFIED;
+ *nr += 1 << (shift - PAGE_SHIFT);
+ continue;
+ }
+ }
+
+ if (vmap_pages_pte_range(pmd, addr, next, prot, pages, nr, mask, shift))
return -ENOMEM;
} while (pmd++, addr = next, addr != end);
return 0;
@@ -605,7 +628,7 @@ static int vmap_pages_pmd_range(pud_t *pud, unsigned long addr,
static int vmap_pages_pud_range(p4d_t *p4d, unsigned long addr,
unsigned long end, pgprot_t prot, struct page **pages, int *nr,
- pgtbl_mod_mask *mask)
+ pgtbl_mod_mask *mask, unsigned int shift)
{
pud_t *pud;
unsigned long next;
@@ -615,7 +638,7 @@ static int vmap_pages_pud_range(p4d_t *p4d, unsigned long addr,
return -ENOMEM;
do {
next = pud_addr_end(addr, end);
- if (vmap_pages_pmd_range(pud, addr, next, prot, pages, nr, mask))
+ if (vmap_pages_pmd_range(pud, addr, next, prot, pages, nr, mask, shift))
return -ENOMEM;
} while (pud++, addr = next, addr != end);
return 0;
@@ -623,7 +646,7 @@ static int vmap_pages_pud_range(p4d_t *p4d, unsigned long addr,
static int vmap_pages_p4d_range(pgd_t *pgd, unsigned long addr,
unsigned long end, pgprot_t prot, struct page **pages, int *nr,
- pgtbl_mod_mask *mask)
+ pgtbl_mod_mask *mask, unsigned int shift)
{
p4d_t *p4d;
unsigned long next;
@@ -633,14 +656,14 @@ static int vmap_pages_p4d_range(pgd_t *pgd, unsigned long addr,
return -ENOMEM;
do {
next = p4d_addr_end(addr, end);
- if (vmap_pages_pud_range(p4d, addr, next, prot, pages, nr, mask))
+ if (vmap_pages_pud_range(p4d, addr, next, prot, pages, nr, mask, shift))
return -ENOMEM;
} while (p4d++, addr = next, addr != end);
return 0;
}
-static int vmap_small_pages_range_noflush(unsigned long addr, unsigned long end,
- pgprot_t prot, struct page **pages)
+static int vmap_pages_range_noflush_walk(unsigned long addr, unsigned long end,
+ pgprot_t prot, struct page **pages, unsigned int shift)
{
unsigned long start = addr;
pgd_t *pgd;
@@ -655,7 +678,7 @@ static int vmap_small_pages_range_noflush(unsigned long addr, unsigned long end,
next = pgd_addr_end(addr, end);
if (pgd_bad(*pgd))
mask |= PGTBL_PGD_MODIFIED;
- err = vmap_pages_p4d_range(pgd, addr, next, prot, pages, &nr, &mask);
+ err = vmap_pages_p4d_range(pgd, addr, next, prot, pages, &nr, &mask, shift);
if (err)
break;
} while (pgd++, addr = next, addr != end);
@@ -678,27 +701,13 @@ static int vmap_small_pages_range_noflush(unsigned long addr, unsigned long end,
int __vmap_pages_range_noflush(unsigned long addr, unsigned long end,
pgprot_t prot, struct page **pages, unsigned int page_shift)
{
- unsigned int i, nr = (end - addr) >> PAGE_SHIFT;
-
WARN_ON(page_shift < PAGE_SHIFT);
- if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMALLOC) ||
- page_shift == PAGE_SHIFT)
- return vmap_small_pages_range_noflush(addr, end, prot, pages);
+ if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMALLOC))
+ page_shift = PAGE_SHIFT;
- for (i = 0; i < nr; i += 1U << (page_shift - PAGE_SHIFT)) {
- int err;
-
- err = vmap_range_noflush(addr, addr + (1UL << page_shift),
- page_to_phys(pages[i]), prot,
- page_shift);
- if (err)
- return err;
-
- addr += 1UL << page_shift;
- }
-
- return 0;
+ return vmap_pages_range_noflush_walk(addr, end, prot, pages,
+ min(page_shift, PMD_SHIFT));
}
int vmap_pages_range_noflush(unsigned long addr, unsigned long end,
--
2.34.1
^ permalink raw reply related
* [PATCH v3 3/6] mm/vmalloc: Extract vmap_set_ptes() to consolidate PTE mapping logic
From: Wen Jiang @ 2026-05-22 5:31 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, will, akpm, urezki
Cc: baohua, Xueyuan.chen21, dev.jain, rppt, david, ryan.roberts,
anshuman.khandual, ajd, linux-kernel, jiangwen6
In-Reply-To: <20260522053146.83209-1-jiangwenxiaomi@gmail.com>
Extract the common PTE mapping logic from vmap_pte_range() into a
shared helper vmap_set_ptes(). This handles both CONT_PTE and regular
PTE mappings in a single function, preparing for the next patch which
will extend vmap_pages_pte_range() to also use this helper.
The #ifdef CONFIG_HUGETLB_PAGE guard is moved inside vmap_set_ptes(),
so callers no longer need to handle the conditional compilation.
Signed-off-by: Wen Jiang <jiangwen6@xiaomi.com>
Tested-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
---
mm/vmalloc.c | 49 ++++++++++++++++++++++++++++++++++---------------
1 file changed, 34 insertions(+), 15 deletions(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 2c2f74a07f396..53fd4ee460ea4 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -91,6 +91,35 @@ struct vfree_deferred {
static DEFINE_PER_CPU(struct vfree_deferred, vfree_deferred);
/*** Page table manipulation functions ***/
+
+/*
+ * Set PTE mappings for the given PFN. Try CONT_PTE mappings first when
+ * supported, otherwise fall back to PAGE_SIZE mappings.
+ *
+ * Return: mapping size.
+ */
+static __always_inline unsigned long vmap_set_ptes(pte_t *pte,
+ unsigned long addr, unsigned long end, u64 pfn,
+ pgprot_t prot, unsigned int max_page_shift)
+{
+#ifdef CONFIG_HUGETLB_PAGE
+ if (max_page_shift > PAGE_SHIFT) {
+ unsigned long size;
+
+ size = arch_vmap_pte_range_map_size(addr, end, pfn, max_page_shift);
+ if (size != PAGE_SIZE) {
+ pte_t entry = pfn_pte(pfn, prot);
+
+ entry = arch_make_huge_pte(entry, ilog2(size), 0);
+ set_huge_pte_at(&init_mm, addr, pte, entry, size);
+ return size;
+ }
+ }
+#endif
+ set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
+ return PAGE_SIZE;
+}
+
static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
phys_addr_t phys_addr, pgprot_t prot,
unsigned int max_page_shift, pgtbl_mod_mask *mask)
@@ -98,7 +127,8 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
pte_t *pte;
u64 pfn;
struct page *page;
- unsigned long size = PAGE_SIZE;
+ unsigned long size;
+ unsigned int steps;
if (WARN_ON_ONCE(!PAGE_ALIGNED(end - addr)))
return -EINVAL;
@@ -119,20 +149,9 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
BUG();
}
-#ifdef CONFIG_HUGETLB_PAGE
- size = arch_vmap_pte_range_map_size(addr, end, pfn, max_page_shift);
- if (size != PAGE_SIZE) {
- pte_t entry = pfn_pte(pfn, prot);
-
- entry = arch_make_huge_pte(entry, ilog2(size), 0);
- set_huge_pte_at(&init_mm, addr, pte, entry, size);
- pfn += PFN_DOWN(size);
- continue;
- }
-#endif
- set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
- pfn++;
- } while (pte += PFN_DOWN(size), addr += size, addr != end);
+ size = vmap_set_ptes(pte, addr, end, pfn, prot, max_page_shift);
+ steps = PFN_DOWN(size);
+ } while (pte += steps, pfn += steps, addr += size, addr != end);
lazy_mmu_mode_disable();
*mask |= PGTBL_PTE_MODIFIED;
--
2.34.1
^ permalink raw reply related
* [PATCH v3 2/6] arm64/vmalloc: Allow arch_vmap_pte_range_map_size to batch multiple CONT_PTE
From: Wen Jiang @ 2026-05-22 5:31 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, will, akpm, urezki
Cc: baohua, Xueyuan.chen21, dev.jain, rppt, david, ryan.roberts,
anshuman.khandual, ajd, linux-kernel, jiangwen6
In-Reply-To: <20260522053146.83209-1-jiangwenxiaomi@gmail.com>
From: "Barry Song (Xiaomi)" <baohua@kernel.org>
Allow arch_vmap_pte_range_map_size to batch multiple CONT_PTE hugepages,
reducing both PTE setup and TLB flush iterations.
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
Signed-off-by: Wen Jiang <jiangwen6@xiaomi.com>
Tested-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
---
arch/arm64/include/asm/vmalloc.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/vmalloc.h b/arch/arm64/include/asm/vmalloc.h
index 4ec1acd3c1b34..787fd17b48e2c 100644
--- a/arch/arm64/include/asm/vmalloc.h
+++ b/arch/arm64/include/asm/vmalloc.h
@@ -23,6 +23,8 @@ static inline unsigned long arch_vmap_pte_range_map_size(unsigned long addr,
unsigned long end, u64 pfn,
unsigned int max_page_shift)
{
+ unsigned long size;
+
/*
* If the block is at least CONT_PTE_SIZE in size, and is naturally
* aligned in both virtual and physical space, then we can pte-map the
@@ -40,7 +42,9 @@ static inline unsigned long arch_vmap_pte_range_map_size(unsigned long addr,
if (!IS_ALIGNED(PFN_PHYS(pfn), CONT_PTE_SIZE))
return PAGE_SIZE;
- return CONT_PTE_SIZE;
+ size = min3(end - addr, 1UL << max_page_shift, PMD_SIZE >> 1);
+ size = 1UL << __fls(size);
+ return size;
}
#define arch_vmap_pte_range_unmap_size arch_vmap_pte_range_unmap_size
--
2.34.1
^ permalink raw reply related
* [PATCH v3 1/6] arm64/hugetlb: Extend batching of multiple CONT_PTE in a single PTE setup
From: Wen Jiang @ 2026-05-22 5:31 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, will, akpm, urezki
Cc: baohua, Xueyuan.chen21, dev.jain, rppt, david, ryan.roberts,
anshuman.khandual, ajd, linux-kernel, jiangwen6
In-Reply-To: <20260522053146.83209-1-jiangwenxiaomi@gmail.com>
From: "Barry Song (Xiaomi)" <baohua@kernel.org>
For sizes aligned to CONT_PTE_SIZE and smaller than PMD_SIZE,
we can batch CONT_PTE settings instead of handling them individually.
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
Signed-off-by: Wen Jiang <jiangwen6@xiaomi.com>
Tested-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
---
arch/arm64/mm/hugetlbpage.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index a42c05cf56408..c4d8b226126cb 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -110,6 +110,12 @@ static inline int num_contig_ptes(unsigned long size, size_t *pgsize)
contig_ptes = CONT_PTES;
break;
default:
+ if (size > 0 && size < PMD_SIZE &&
+ IS_ALIGNED(size, CONT_PTE_SIZE)) {
+ contig_ptes = size >> PAGE_SHIFT;
+ *pgsize = PAGE_SIZE;
+ break;
+ }
WARN_ON(!__hugetlb_valid_size(size));
}
@@ -359,6 +365,10 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
case CONT_PTE_SIZE:
return pte_mkcont(entry);
default:
+ if (pagesize > 0 && pagesize < PMD_SIZE &&
+ IS_ALIGNED(pagesize, CONT_PTE_SIZE))
+ return pte_mkcont(entry);
+
break;
}
pr_warn("%s: unrecognized huge page size 0x%lx\n",
--
2.34.1
^ permalink raw reply related
* [PATCH v3 0/6] mm/vmalloc: Speed up ioremap, vmalloc and vmap with contiguous memory
From: Wen Jiang @ 2026-05-22 5:31 UTC (permalink / raw)
To: linux-mm, linux-arm-kernel, catalin.marinas, will, akpm, urezki
Cc: baohua, Xueyuan.chen21, dev.jain, rppt, david, ryan.roberts,
anshuman.khandual, ajd, linux-kernel, jiangwen6
From: jiangwen6 <jiangwen6@xiaomi.com>
This patchset accelerates ioremap, vmalloc, and vmap when the memory
is physically fully or partially contiguous. Two techniques are used:
1. Avoid page table rewalk when setting PTEs/PMDs for multiple memory
segments
2. Use batched mappings wherever possible in both vmalloc and ARM64
layers
Besides accelerating the mapping path, this also enables large
mappings (PMD and cont-PTE) for vmap, which are currently not
supported.
Patches 1-2 extend ARM64 vmalloc CONT-PTE mapping to support multiple
CONT-PTE regions instead of just one.
Patch 3 extracts a common helper vmap_set_ptes() that consolidates PTE
mapping logic between the ioremap and vmalloc/vmap paths, handling both
CONT_PTE and regular PTE mappings. This prepares for the next patch.
Patch 4 extends the page table walk path to support page shifts other
than PAGE_SHIFT and eliminates the page table rewalk for huge vmalloc
mappings. The function is renamed from vmap_small_pages_range_noflush()
to vmap_pages_range_noflush_walk().
Patches 5-6 add huge vmap support for contiguous pages, including
support for non-compound pages with pfn alignment verification.
On the RK3588 8-core ARM64 SoC, with tasks pinned to a little core and
the performance CPUfreq policy enabled, benchmark results:
* ioremap(1 MB): 1.35x faster (3407 ns -> 2526 ns)
* vmalloc(1 MB) mapping time (excluding allocation) with
VM_ALLOW_HUGE_VMAP: 1.42x faster (5.00 us -> 3.53us)
* vmap(100MB) with order-8 pages: 8.3x faster (1235 us -> 149 us)
Many thanks to Xueyuan Chen for his testing efforts on RK3588 boards.
Changes since v2:
- Use __fls instead of fls in arch_vmap_pte_range_map_size (patch 2)
- Add WARN_ON checks in vmap_pages_pmd_range (patch 4)
- Fix flush_cache_vmap to use saved start address instead of the
already-advanced addr (patch 5)
- Rename __vmap_huge() to vmap_batched() (patch 5)
- Add caller parameter and unroll while(1) loop (patch 5)
- Squash patch 7 into patch 5 (stop scanning for compound pages after
encountering small pages)
Changes since v1:
- Fix condition order and use PMD_SIZE instead of CONT_PMD_SIZE in
patch 1 (Dev Jain)
- Squash patch 3+4 and patch 5+7 (Dev Jain)
- Replace "zigzag" with "page table rewalk" in commit messages
(Dev Jain)
- Rename vmap_small_pages_range_noflush() to
vmap_pages_range_noflush_walk() (Dev Jain)
- Extract vmap_set_ptes() as a new patch to consolidate PTE mapping
logic between vmap_pte_range() and vmap_pages_pte_range(), handling
both CONT_PTE and regular mappings (Mike Rapoport)
- Support non-compound pages in get_vmap_batch_order() by falling
back to physical contiguity scanning with pfn alignment check
(Dev Jain, Uladzislau Rezki)
- In get_vmap_batch_order(), filter out orders that the architecture
cannot batch by checking arch_vmap_pte_supported_shift() directly.
This avoids overhead for orders 1-3 on ARM64 CONT_PTE with 4K
pages. (patch 5)
Barry Song (Xiaomi) (5):
arm64/hugetlb: Extend batching of multiple CONT_PTE in a single PTE
setup
arm64/vmalloc: Allow arch_vmap_pte_range_map_size to batch multiple
CONT_PTE
mm/vmalloc: Extend page table walk to support larger page_shift sizes
and eliminate page table rewalk
mm/vmalloc: map contiguous pages in batches for vmap() if possible
mm/vmalloc: align vm_area so vmap() can batch mappings
Wen Jiang (1):
mm/vmalloc: Extract vmap_set_ptes() to consolidate PTE mapping logic
arch/arm64/include/asm/vmalloc.h | 6 +-
arch/arm64/mm/hugetlbpage.c | 10 ++
mm/vmalloc.c | 235 ++++++++++++++++++++++++-------
3 files changed, 201 insertions(+), 50 deletions(-)
--
2.34.1
^ permalink raw reply
* [PATCH v4 4/4] Documentation: PCI: Add documentation for DOE endpoint support
From: Aksh Garg @ 2026-05-22 5:24 UTC (permalink / raw)
To: linux-pci, linux-doc, mani, kwilczynski, bhelgaas, corbet, kishon,
skhan, lukas, cassel, alistair
Cc: linux-arm-kernel, linux-kernel, s-vadapalli, danishanwar, srk,
a-garg7
In-Reply-To: <20260522052434.802034-1-a-garg7@ti.com>
Document the architecture and implementation details for the Data Object
Exchange (DOE) framework for PCIe Endpoint devices.
Co-developed-by: Siddharth Vadapalli <s-vadapalli@ti.com>
Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
Signed-off-by: Aksh Garg <a-garg7@ti.com>
---
Changes from v3 to v4:
- Updated the maximum size of the DOE object from 256KB to 1MB,
as per PCIe spec.
- Updated the DOE setup and cleanup sections.
Changes from v2 to v3:
- Rebased on 7.1-rc1.
Changes since v1:
- Squashed the patches [1] and [2], and moved the documentation file
to Documentation/PCI/endpoint/pci-endpoint-doe.rst to match the existing
naming scheme, as suggested by Niklas Cassel
- Updated the documentation as per the design and implementaion changes
made to previous patches in this series:
* Updated for static protocol array instead of dynamic registration
* Documented asynchronous callback model
* Updated request/response flow with new callback signature
* Updated memory ownership: DOE core frees request, driver frees response
* Updated initialization and cleanup sections for new APIs
v3: https://lore.kernel.org/all/20260427051725.223704-5-a-garg7@ti.com/
v2: https://lore.kernel.org/all/20260401073022.215805-5-a-garg7@ti.com/
v1: [1] https://lore.kernel.org/all/20260213123603.420941-2-a-garg7@ti.com/
[2] https://lore.kernel.org/all/20260213123603.420941-5-a-garg7@ti.com/
Documentation/PCI/endpoint/index.rst | 1 +
.../PCI/endpoint/pci-endpoint-doe.rst | 329 ++++++++++++++++++
2 files changed, 330 insertions(+)
create mode 100644 Documentation/PCI/endpoint/pci-endpoint-doe.rst
diff --git a/Documentation/PCI/endpoint/index.rst b/Documentation/PCI/endpoint/index.rst
index dd1f62e731c9..7c03d5abd2ef 100644
--- a/Documentation/PCI/endpoint/index.rst
+++ b/Documentation/PCI/endpoint/index.rst
@@ -9,6 +9,7 @@ PCI Endpoint Framework
pci-endpoint
pci-endpoint-cfs
+ pci-endpoint-doe
pci-test-function
pci-test-howto
pci-ntb-function
diff --git a/Documentation/PCI/endpoint/pci-endpoint-doe.rst b/Documentation/PCI/endpoint/pci-endpoint-doe.rst
new file mode 100644
index 000000000000..a424a0a3add6
--- /dev/null
+++ b/Documentation/PCI/endpoint/pci-endpoint-doe.rst
@@ -0,0 +1,329 @@
+.. SPDX-License-Identifier: GPL-2.0-only OR MIT
+
+.. include:: <isonum.txt>
+
+=============================================
+Data Object Exchange (DOE) for PCIe Endpoint
+=============================================
+
+:Copyright: |copy| 2026 Texas Instruments Incorporated
+:Author: Aksh Garg <a-garg7@ti.com>
+:Co-Author: Siddharth Vadapalli <s-vadapalli@ti.com>
+
+Overview
+========
+
+DOE (Data Object Exchange) is a standard PCIe extended capability feature
+introduced in the Data Object Exchange (DOE) ECN for PCIe r5.0. It is an optional
+mechanism for system firmware/software running on root complex (host) to perform
+:ref:`data object <data-object-term>` exchanges with an endpoint function. Each
+data object is uniquely identified by the Vendor ID of the vendor publishing the
+data object definition and a Data Object Type value assigned by that vendor.
+
+Think of DOE as a sophisticated mailbox system built into PCIe. The root complex
+can send structured requests to the endpoint device through DOE mailboxes, and
+the endpoint device responds with appropriate data. DOE mailboxes are implemented
+as PCIe Extended Capabilities in endpoint devices, allowing multiple mailboxes
+per function, each potentially supporting different data object protocols.
+
+The DOE support for root complex devices has already been implemented in
+``drivers/pci/doe.c``.
+
+How DOE Works
+=============
+
+The DOE mailbox operates through a simple request-response model:
+
+1. **Host sends request**: The root complex writes a data object (vendor ID, type,
+ and payload) to the DOE write mailbox register (one DWORD at a time) of the
+ endpoint function's config space and sets the GO bit in the DOE Control register
+ to indicate that a request is ready for processing.
+2. **Endpoint processes**: The endpoint function reads the request from DOE write
+ mailbox register, sets the BUSY bit in the DOE Status register, identifies the
+ protocol of the data object, and executes the appropriate handler.
+3. **Endpoint responds**: The endpoint function writes the response data object to the
+ DOE read mailbox register (one DWORD at a time), and sets the READY bit in the DOE
+ Status register to indicate that the response is ready. If an error occurs during
+ request processing (such as unsupported protocol or handler failure), the endpoint
+ sets the ERROR bit in the DOE Status register instead of the READY bit.
+4. **Host reads response**: The root complex retrieves the response data from the DOE read
+ mailbox register once the READY bit is set in the DOE Status register, and then writes
+ any value to this register to indicate a successful read. If the ERROR bit was set,
+ the root complex discards the response and performs error handling as needed.
+
+Each mailbox operates independently and can handle one transaction at a time. The
+DOE specification supports data objects of size up to 1MB (2\ :sup:`18` dwords).
+
+For complete DOE capability details, refer to `PCI Express Base Specification Revision 7.0,
+Section 6.30 - Data Object Exchange (DOE)`.
+
+Key Terminologies
+=================
+
+.. _data-object-term:
+
+**Data Object**
+ A structured, vendor-defined, or standard-defined message exchanged between
+ root complex and endpoint function via DOE capability registers in configuration
+ space of the function.
+
+**Mailbox**
+ A DOE capability on the endpoint device, where each physical function can have
+ multiple mailboxes.
+
+**Protocol**
+ A specific type of DOE communication data object identified by a Vendor ID and Type.
+
+**Handler**
+ A function that processes DOE requests of a specific protocol and generates responses.
+
+Architecture of DOE Implementation for Endpoint
+===============================================
+
+.. code-block:: text
+
+ +------------------+
+ | |
+ | Root Complex |
+ | |
+ +--------^---------+
+ |
+ | Config space access
+ | over PCIe link
+ |
+ +----------v-----------+
+ | |
+ | PCIe Controller |
+ | as Endpoint |
+ | |
+ | +-----------------+ |
+ | | DOE Mailbox | |
+ | +-------^---------+ |
+ +----------|-----------+
+ +-----------|---------------------------------------------------------------+
+ | | +--------------------+ |
+ | +---------v--------+ Allocate | +--------------+ | |
+ | | |-------------------------------->| Request | | |
+ | | EP Controller | +--->| Buffer | | |
+ | | Driver | Free | | +--------------+ | |
+ | | |--------------------------+ | | | |
+ | +--------^---------+ | | | | |
+ | | | | | | |
+ | | | | | | |
+ | | pci_ep_doe_process_request() | | | | |
+ | | | | | | |
+ | +--------v---------+ Free | | | | |
+ | | |----------------------------+ | DDR | |
+ | | DOE EP Core |<----+ | | | |
+ | | (doe-ep.c) | | Discovery | | | |
+ | | |-----+ Protocol Handler | | | |
+ | +--------^---------+ | | | |
+ | | | | | |
+ | | protocol_handler() | | | |
+ | | | | | |
+ | +--------v---------+ | | | |
+ | | | | | +--------------+ | |
+ | | Protocol Handler | +----->| Response | | |
+ | | Module |-------------------------------->| Buffer | | |
+ | | (CMA/SPDM/Other) | Allocate | +--------------+ | |
+ | | | | | |
+ | +------------------+ | | |
+ | +--------------------+ |
+ +---------------------------------------------------------------------------+
+
+Initialization and Cleanup
+--------------------------
+
+**Framework Initialization and DOE Setup**
+
+The EPC core automatically initializes and sets up DOE mailboxes through the
+``pci_epc_init_capabilities()`` internal function, which is invoked during
+``pci_epc_init_notify()`` when the controller driver calls this API.
+Controller drivers do not need to explicitly handle DOE initialization,
+rather the EPC core manages this transparently.
+
+DOE initialization only occurs when the EPC driver reports DOE capability
+through the ``doe_capable`` flag in its ``pci_epc_features``.
+
+This internal function performs the following steps:
+
+1. Calls ``pci_ep_doe_init(epc)`` to initialize the xarray data structure
+ (a resizable array data structure defined in linux) named ``doe_mbs`` that
+ stores metadata of DOE mailboxes for the controller in ``struct pci_epc``.
+2. Calls ``pci_epc_doe_setup(epc)`` to discover all DOE capabilities in the
+ endpoint function's configuration space for each function. For each
+ discovered DOE capability, calls ``pci_ep_doe_add_mailbox(epc, func_no,
+ cap_offset)`` to register the mailbox.
+
+Each DOE mailbox structure created by ``pci_ep_doe_add_mailbox()`` gets an
+ordered workqueue allocated for processing DOE requests sequentially for that
+mailbox, enabling concurrent request handling across different mailboxes. Each
+mailbox is uniquely identified by the combination of physical function number
+and capability offset for that controller.
+
+**Cleanup**
+
+The EPC core automatically cleans up DOE mailboxes through the
+``pci_epc_deinit_capabilities()`` internal function, which is invoked during
+``pci_epc_deinit_notify()`` when the controller driver calls this API.
+Controller drivers do not need to explicitly handle DOE cleanup, rather
+the EPC core manages this transparently.
+
+DOE cleanup only occurs when the EPC device reported DOE capability
+through the ``doe_capable`` flag in its ``pci_epc_features``.
+
+This internal function calls ``pci_ep_doe_destroy(epc)``, which destroys all
+registered mailboxes, cancels any pending tasks, flushes and destroys the
+workqueues, and frees all memory allocated to the mailboxes.
+
+Protocol Handler Support
+------------------------
+
+Protocol implementations (such as CMA, SPDM, or vendor-specific protocols) are
+supported through a static array of protocol handlers.
+
+When a new DOE protocol library is introduced, its handler function is added to
+the static ``pci_doe_protocols`` array in ``drivers/pci/endpoint/pci-ep-doe.c``.
+The discovery protocol (VID = 0x0001 (PCI-SIG vendor ID), Type = 0x00 (discovery
+protocol)) is included in this static array and handled internally by the
+DOE EP core.
+
+Request Handling
+----------------
+
+The complete flow of a DOE request from the root complex to the response:
+
+**Step 1: Root Complex → EP Controller Driver**
+
+The root complex writes a DOE request (Vendor ID, Type, and Payload) to the
+DOE write mailbox register in the endpoint function's configuration space and sets
+the GO bit in the DOE Control register, indicating that the request is ready for
+processing.
+
+**Step 2: EP Controller Driver → DOE EP Core**
+
+The controller driver reads the request header to determine the data object
+length. Based on this length field, it allocates a request buffer in memory
+(DDR) of the appropriate size. The driver then reads the complete request
+payload from the DOE write mailbox register and converts the data from
+little-endian format (the format followed in the PCIe transactions over the
+link) to CPU-native format using ``le32_to_cpu()``. The driver defines a
+completion callback function with signature ``void (*complete)(struct pci_epc *epc,
+u8 func_no, u16 cap_offset, int status, u16 vendor, u8 type, void *response_pl,
+size_t response_pl_sz)`` to be invoked when the request processing completes.
+The driver then calls ``pci_ep_doe_process_request(epc, func_no, cap_offset,
+vendor, type, request, request_sz, complete)`` to hand off the request to the
+DOE EP core. This function returns immediately after queuing the work
+(without blocking), and the driver sets the BUSY bit in the DOE Status register.
+
+**Step 3: DOE EP Core Processing**
+
+The DOE EP core creates a task structure and submits it to the mailbox's ordered
+workqueue. This ensures that requests for each mailbox are processed
+sequentially, one at a time, as required by the DOE specification. It looks up
+the protocol handler based on the Vendor ID and Type from the request header,
+and executes the handler function.
+
+**Step 4: Protocol Handler Execution**
+
+The workqueue executes the task by calling the registered protocol handler:
+``handler(request, request_sz, &response, &response_sz)``. The handler processes
+the request, allocates a response buffer in memory (DDR), builds the response
+data, and returns the response pointer and size. For the discovery protocol,
+the DOE EP core handles this directly without invoking an external handler.
+
+**Step 5: DOE EP Core → EP Controller Driver**
+
+After the protocol handler completes, the DOE EP core frees the request buffer,
+and invokes the completion callback provided by the controller driver asynchronously.
+The callback receives the struct pci_epc, function number, capability offset (to
+identify the mailbox), status code indicating the result of request processing,
+vendor ID and type of the data object, the response buffer, and its size.
+
+**Step 6: EP Controller Driver → Root Complex**
+
+The controller driver converts the response from CPU-native format to
+little-endian format using ``cpu_to_le32()``, writes the response to DOE read
+mailbox register, and sets the READY bit in the DOE Status register. The root
+complex then reads the response from the read mailbox register. Finally, the controller
+driver frees the response buffer (which the handler allocated).
+
+Asynchronous Request Processing
+-------------------------------
+
+The DOE-EP framework implements asynchronous request processing because an
+endpoint function can have multiple instances of DOE mailboxes, and requests may
+be interleaved across these mailboxes. Request processing of one mailbox should
+not result in blocking request processing of other mailboxes. Hence, requests
+on each mailbox need to be handled in parallel for optimization.
+
+For the EP controller driver to handle requests on multiple mailboxes in
+parallel, ``pci_ep_doe_process_request()`` must be asynchronous. The function
+returns immediately after submitting the request to the mailbox's workqueue,
+without waiting for the request to complete. A completion callback provided by
+the controller driver is invoked asynchronously when request processing
+finishes. This asynchronous design enables concurrent processing of requests
+across different mailboxes.
+
+Abort Handling
+--------------
+
+The DOE specification allows the root complex to abort ongoing DOE operations
+by setting the ABORT bit in the DOE Control register.
+
+**Trigger**
+
+When the root complex sets the ABORT bit, the EP controller driver detects this
+condition (typically in an interrupt handler or register polling routine). The
+action taken depends on the timing of the abort:
+
+- **ABORT during request transfer**: If the ABORT bit is set while the root complex
+ is still transferring the request to the mailbox registers, the controller driver
+ discards the request and no call to ``pci_ep_doe_abort()`` is needed.
+
+- **ABORT after request submission**: If the ABORT bit is set after the request
+ has been fully received and submitted to the DOE EP core via
+ ``pci_ep_doe_process_request()``, the controller driver must call
+ ``pci_ep_doe_abort(epc, func_no, cap_offset)`` for the affected mailbox to
+ perform abort sequence in the DOE EP core.
+
+**Abort Sequence**
+
+The abort function performs the following actions:
+
+1. Sets the CANCEL flag on the mailbox to prevent queued requests from starting
+2. Flushes the workqueue to wait for any currently executing handler to complete
+ (handlers cannot be interrupted mid-execution)
+3. Clears the CANCEL flag to allow the mailbox to accept new requests
+
+Queued requests that have not started execution will be aborted with an error
+status. The currently executing request will complete normally, and the controller
+will reject the response if it arrives after the abort sequence has been triggered.
+
+.. note::
+ Independent of when the ABORT bit is triggered, the controller driver must
+ clear the ERROR, BUSY, and READY bits in the DOE Status register after
+ completing the abort operation to reset the mailbox to an idle state.
+
+Error Handling
+--------------
+
+Errors can occur during DOE request processing for various reasons, such as
+unsupported protocols, handler failures, or memory allocation failures.
+
+**Error Detection**
+
+When an error occurs during DOE request processing, the DOE EP core propagates this error
+back to the controller driver either through the ``pci_ep_doe_process_request()`` return value,
+or the status code passed to the completion callback.
+
+**Error Response**
+
+When the controller driver receives an error code, it sets the ERROR bit in the DOE Status
+register instead of writing a response to the read mailbox register, and frees the buffers.
+
+API Reference
+=============
+
+.. kernel-doc:: drivers/pci/endpoint/pci-ep-doe.c
+ :export:
--
2.34.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox