* Re: [PATCH 00/30] KVM: arm64: Add support for protected guest memory with pKVM
From: Pavan Kondeti @ 2026-04-20 11:26 UTC (permalink / raw)
To: Will Deacon
Cc: Pavan Kondeti, kvmarm, linux-arm-kernel, Marc Zyngier,
Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Catalin Marinas, Quentin Perret, Fuad Tabba, Vincent Donnefort,
Mostafa Saleh
In-Reply-To: <aeX5Q7QNxmBCmsqM@willie-the-truck>
On Mon, Apr 20, 2026 at 11:00:35AM +0100, Will Deacon wrote:
> On Mon, Apr 20, 2026 at 01:32:03PM +0530, Pavan Kondeti wrote:
> > Hi Will,
> >
> > On Mon, Jan 05, 2026 at 03:49:08PM +0000, Will Deacon wrote:
> > > Hi folks,
> > >
> > > Although pKVM has been shipping in Android kernels for a while now,
> > > protected guest (pVM) support has been somewhat languishing upstream.
> > > This has partly been because we've been waiting for guest_memfd() but
> > > also because it hasn't been clear how to expose pVMs to userspace (which
> > > is necessary for testing) without getting everything in place beforehand.
> > > This has led to frustration on both sides of the fence [1] and so this
> > > patch series attempts to get things moving again by exposing pVM
> > > features in an incremental fashion based on top of anonymous memory,
> > > which is what we have been using in Android. The big difference between
> > > this series and the Android implementation is the graceful handling of
> > > host stage-2 faults arising from accesses made using kernel mappings.
> > > The hope is that this will unblock pKVM upstreaming efforts while the
> > > guest_memfd() work continues to evolve.
> > >
> > > Specifically, this patch series implements support for protected guest
> > > memory with pKVM, where pages are unmapped from the host as they are
> > > faulted into the guest and can be shared back from the guest using pKVM
> > > hypercalls. Protected guests are created using a new machine type
> > > identifier and can be booted to a shell using the kvmtool patches
> > > available at [2], which finally means that we are able to test the pVM
> > > logic in pKVM. Since this is an incremental step towards full isolation
> > > from the host (for example, the CPU register state and DMA accesses are
> > > not yet isolated), creating a pVM requires a developer Kconfig option to
> > > be enabled in addition to booting with 'kvm-arm.mode=protected' and
> > > results in a kernel taint.
> > >
> >
> > Good to see Protected VM support in upstream w/ pKVM.
> >
> > We (Qualcomm) have been trying to resume Gunyah upstreaming [1] efforts
> > for some time but the path to re-use guest_memfd is not straight forward as
> > guest_memfd is tightly coupled with KVM. While the efforts to use it for
> > pKVM is pending and refactoring to make it use outside KVM is not
> > happening anytime soon, we plan to send Gunyah series similar to how
> > this series is dealt with pages lent/donated to the Guest. Please let us
> > know if you have any suggestions/comments for us.
>
> The major problem I see with this is that the host/hyp interface for
> handling stage-2 faults is internal to pKVM. The exception is injected
> back into the host using a funky ESR encoding and the hypercall used
> to forcefully reclaim the page is not ABI. I have no appetite for
> standardising these mechanisms (the flexibility is one of pKVM's big
> advantages) but I also do not want to complicate EL1 fault handling path
> with hypervisor-specific crap that we have to maintain forever.
Thanks Will for the feedback. Agree that we don't want to sprinkle Gunyah
specific checks in fault handling code. Do we need to handle anything
apart from
(a) user space access a memory that is lent to the guest. Gunyah will
inject Synchronous External Abort and the offending process will be killed.
(b) For kernel access, we need to unmap the memory at S1 while lending
it to the guest. Earlier, Elliot attempted this with [1]. I am thinking
we can leverage from Direct map removal work done for guest_memfd w/o
really using it :-) . I am hoping [2] can be made available for Gunyah
module as well.
For the (b) problem above, pKVM takes a different route in upstream i.e
pkvm_force_reclaim_guest_page(). I believe this avoids kernel panic at
the expense of memory corruption in the guest. correct?
Thanks,
Pavan
[1]
https://lore.kernel.org/all/20240222-gunyah-v17-19-1e9da6763d38@quicinc.com/
[2]
https://lore.kernel.org/all/20260317141031.514-3-kalyazin@amazon.com/
^ permalink raw reply
* Re: [PATCH 0/4] Add hstimer support for H616 and T113-S3
From: Michal Piekos @ 2026-04-20 11:27 UTC (permalink / raw)
To: Andre Przywara
Cc: Daniel Lezcano, Thomas Gleixner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
Maxime Ripard, linux-kernel, devicetree, linux-arm-kernel,
linux-sunxi
In-Reply-To: <20260419225539.718367e0@ryzen.lan>
On Sun, Apr 19, 2026 at 10:55:39PM +0200, Andre Przywara wrote:
> On Sun, 19 Apr 2026 14:46:06 +0200
> Michal Piekos <michal.piekos@mmpsystems.pl> wrote:
>
> Hi Michal,
>
> > Add support for Allwinner H616 high speed timer in sun5i hstimer driver
> > and describe corresponding nodes in dts for H616 and T113-S3.
> >
> > H616 uses same model as existing driver except register shift compared
> > to older variants.
> >
> > Added register layout abstraction in the driver, extended the binding
> > with new compatibles and wired up dts nodes for H616 and T113-S3 which
> > uses H616 as fallback compatible.
>
> Can you say *why* we need this? IIUC Linux only ever uses one clock
> source, and selects the (non-optional) Generic Timer (aka arch timer)
> for that? So can you say what this hstimer clock source adds? I guess
> higher resolution, but what is your use case, so why would you need the
> 200 MHz? And does this offset the higher access cost of an MMIO
> access, compared to the arch timer's sysreg based access? Also, IIUC,
> people would need to manually select this as the clocksource, why and
> when would they do so? (Given they even know about it in the first
> place).
> Also the hstimer hasn't been used since the A20, so nobody seemed to
> have missed it meanwhile?
>
> Cheers,
> Andre
>
I took the table from https://linux-sunxi.org/Linux_mainlining_effort as
a todo list and wanted to help with it. I do not have own use case for
this timer. If it is not needed then I will spin v2 to include your
comments and abandon it.
Michal
> >
> > Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
> > ---
> > Michal Piekos (4):
> > dt-bindings: timer: allwinner,sun5i-a13-hstimer: add H616 and T113-S3
> > clocksource/drivers/sun5i: add H616 hstimer support
> > arm64: dts: allwinner: h616: add hstimer node
> > arm: dts: allwinner: t113s: add hstimer node
> >
> > .../timer/allwinner,sun5i-a13-hstimer.yaml | 8 +++-
> > arch/arm/boot/dts/allwinner/sun8i-t113s.dtsi | 12 +++++
> > arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 9 ++++
> > drivers/clocksource/timer-sun5i.c | 56 +++++++++++++++++++---
> > 4 files changed, 78 insertions(+), 7 deletions(-)
> > ---
> > base-commit: faeab166167f5787719eb8683661fd41a3bb1514
> > change-id: 20260413-h616-t113s-hstimer-62939948f91c
> >
> > Best regards,
>
>
^ permalink raw reply
* Re: [PATCH v2 2/2] arm64: dts: amlogic: add support for X98Q
From: Ferass El Hafidi @ 2026-04-20 10:43 UTC (permalink / raw)
To: linux-amlogic, christian.koever-draxl, robh, krzk+dt, conor+dt,
neil.armstrong, khilman
Cc: jbrunet, martin.blumenstingl, funderscore, devicetree,
linux-kernel, linux-arm-kernel, linux-amlogic,
christian.koever-draxl
In-Reply-To: <20260420061854.5421-3-christian.koever-draxl@student.uibk.ac.at>
On Mon, 20 Apr 2026 06:18, christian.koever-draxl@student.uibk.ac.at wrote:
>From: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
>
>Signed-off-by: Christian Stefan Kövér-Draxl <christian.koever-draxl@student.uibk.ac.at>
>---
> arch/arm64/boot/dts/amlogic/Makefile | 1 +
> .../boot/dts/amlogic/meson-s4-s905w2-x98q.dts | 250 ++++++++++++++++++
> 2 files changed, 251 insertions(+)
> create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
>
>diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
>index 15f9c817e502..c7752684dea6 100644
>--- a/arch/arm64/boot/dts/amlogic/Makefile
>+++ b/arch/arm64/boot/dts/amlogic/Makefile
>@@ -85,6 +85,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-ugoos-am3.dtb
> dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
> dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
> dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
>+dtb-$(CONFIG_ARCH_MESON) += meson-s4-s905w2-x98q.dtb
> dtb-$(CONFIG_ARCH_MESON) += meson-s4-s905y4-khadas-vim1s.dtb
> dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
> dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
>diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
>new file mode 100644
>index 000000000000..26c60a4c2a43
>--- /dev/null
>+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s905w2-x98q.dts
>@@ -0,0 +1,250 @@
>+
nit: Trailing newline
>+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>+/*
>+ * Copyright (c) 2026 Christian Stefan Köver-Draxl
>+ * Based on meson-s4-s905y4-khadas-vim1s.dts:
>+ * - Copyright (c) 2026 Khadas Technology Co., Ltd.
>+ */
>+
>+/dts-v1/;
>+
>+#include "meson-s4.dtsi"
>+
>+/ {
>+ model = "Shenzhen Amediatech Technology Co., Ltd X98Q";
>+ compatible = "amediatech,x98q", "amlogic,s905w2", "amlogic,s4";
>+ interrupt-parent = <&gic>;
>+ #address-cells = <2>;
>+ #size-cells = <2>;
>+
>+ aliases {
>+ mmc0 = &emmc; /* eMMC */
>+ mmc1 = &sd; /* SD card */
>+ mmc2 = &sdio; /* SDIO */
>+ serial0 = &uart_b;
>+ };
>+
>+ memory@0 {
>+ device_type = "memory";
>+ reg = <0x0 0x0 0x0 0x40000000>;
>+ };
>+
>+ reserved-memory {
>+ #address-cells = <2>;
>+ #size-cells = <2>;
>+ ranges;
>+
>+ /* 52 MiB reserved for ARM Trusted Firmware */
>+ secmon_reserved: secmon@5000000 {
>+ reg = <0x0 0x05000000 0x0 0x3400000>;
>+ no-map;
>+ };
>+ };
>+
>+ emmc_pwrseq: emmc-pwrseq {
>+ compatible = "mmc-pwrseq-emmc";
>+ reset-gpios = <&gpio GPIOB_9 GPIO_ACTIVE_LOW>;
>+ };
>+
>+ sdio_32k: sdio-32k {
>+ compatible = "pwm-clock";
>+ #clock-cells = <0>;
>+ clock-frequency = <32768>;
>+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
>+ };
>+
>+ sdio_pwrseq: sdio-pwrseq {
>+ compatible = "mmc-pwrseq-simple";
>+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
>+ clocks = <&sdio_32k>;
>+ clock-names = "ext_clock";
>+ };
>+
>+ main_5v: regulator-main-5v {
>+ compatible = "regulator-fixed";
>+ regulator-name = "5V";
>+ regulator-min-microvolt = <5000000>;
>+ regulator-max-microvolt = <5000000>;
>+ regulator-always-on;
>+ };
>+
>+ sd_3v3: regulator-sd-3v3 {
>+ compatible = "regulator-fixed";
>+ regulator-name = "SD_3V3";
>+ regulator-min-microvolt = <3300000>;
>+ regulator-max-microvolt = <3300000>;
>+ gpio = <&gpio GPIOD_4 GPIO_ACTIVE_LOW>;
>+ regulator-always-on;
>+ };
>+
>+ vddio_sd: regulator-vddio-sd {
>+ compatible = "regulator-gpio";
>+ regulator-name = "VDDIO_SD";
>+ regulator-min-microvolt = <1800000>;
>+ regulator-max-microvolt = <3300000>;
>+ gpios = <&gpio GPIOD_9 GPIO_ACTIVE_HIGH>;
>+ gpios-states = <1>;
>+ states = <1800000 1 3300000 0>;
>+ };
>+
>+ vddao_3v3: regulator-vddao-3v3 {
>+ compatible = "regulator-fixed";
>+ regulator-name = "VDDAO_3V3";
>+ regulator-min-microvolt = <3300000>;
>+ regulator-max-microvolt = <3300000>;
>+ vin-supply = <&main_5v>;
>+ regulator-always-on;
>+ };
>+
>+ vddio_ao1v8: regulator-vddio-ao1v8 {
>+ compatible = "regulator-fixed";
>+ regulator-name = "VDDIO_AO1V8";
>+ regulator-min-microvolt = <1800000>;
>+ regulator-max-microvolt = <1800000>;
>+ vin-supply = <&vddao_3v3>;
>+ regulator-always-on;
>+ };
>+
>+ /* SY8120B1ABC DC/DC Regulator. */
>+ vddcpu: regulator-vddcpu {
>+ compatible = "pwm-regulator";
>+
>+ regulator-name = "VDDCPU";
>+ regulator-min-microvolt = <689000>;
>+ regulator-max-microvolt = <1049000>;
>+
>+ vin-supply = <&main_5v>;
>+
>+ pwms = <&pwm_ij 1 1500 0>;
>+ pwm-dutycycle-range = <100 0>;
>+
>+ regulator-boot-on;
>+ regulator-always-on;
>+ /* Voltage Duty-Cycle */
>+ voltage-table = <1049000 0>,
>+ <1039000 3>,
>+ <1029000 6>,
>+ <1019000 9>,
>+ <1009000 12>,
>+ <999000 14>,
>+ <989000 17>,
>+ <979000 20>,
>+ <969000 23>,
>+ <959000 26>,
>+ <949000 29>,
>+ <939000 31>,
>+ <929000 34>,
>+ <919000 37>,
>+ <909000 40>,
>+ <899000 43>,
>+ <889000 45>,
>+ <879000 48>,
>+ <869000 51>,
>+ <859000 54>,
>+ <849000 56>,
>+ <839000 59>,
>+ <829000 62>,
>+ <819000 65>,
>+ <809000 68>,
>+ <799000 70>,
>+ <789000 73>,
>+ <779000 76>,
>+ <769000 79>,
>+ <759000 81>,
>+ <749000 84>,
>+ <739000 87>,
>+ <729000 89>,
>+ <719000 92>,
>+ <709000 95>,
>+ <699000 98>,
>+ <689000 100>;
>+ };
>+};
>+
>+&emmc {
>+ status = "okay";
>+ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
>+ pinctrl-1 = <&emmc_clk_gate_pins>;
>+ pinctrl-names = "default", "clk-gate";
>+
>+ bus-width = <8>;
>+ cap-mmc-highspeed;
>+ mmc-ddr-1_8v;
>+ mmc-hs200-1_8v;
>+ max-frequency = <200000000>;
>+ non-removable;
>+ disable-wp;
>+
>+ mmc-pwrseq = <&emmc_pwrseq>;
>+ vmmc-supply = <&vddao_3v3>;
>+ vqmmc-supply = <&vddio_ao1v8>;
>+};
>+
>+ðmac {
>+ status = "okay";
>+ phy-handle = <&internal_ephy>;
>+ phy-mode = "rmii";
>+};
>+
>+&ir {
>+ status = "okay";
>+ pinctrl-0 = <&remote_pins>;
>+ pinctrl-names = "default";
>+};
>+
>+&pwm_ef {
>+ status = "okay";
>+ pinctrl-0 = <&pwm_e_pins1>;
>+ pinctrl-names = "default";
>+};
>+
>+&pwm_ij {
>+ status = "okay";
>+};
>+
>+&sd {
>+ status = "okay";
>+ pinctrl-0 = <&sdcard_pins>;
>+ pinctrl-1 = <&sdcard_clk_gate_pins>;
>+ pinctrl-names = "default", "clk-gate";
>+ bus-width = <4>;
>+ cap-sd-highspeed;
>+ max-frequency = <50000000>;
>+ disable-wp;
>+
>+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
>+
>+ vmmc-supply = <&vddao_3v3>;
>+ vqmmc-supply = <&vddao_3v3>;
>+};
>+
>+/*
>+* Wireless SDIO Module (Amlogic W150S1)
>+* Note: There is no driver for this at the moment.
>+*/
Align like this:
/*
* Wireless SDIO Module (Amlogic W150S1)
* Note: There is no driver for this at the moment.
*/
>+
>+&sdio {
>+ status = "okay";
>+ pinctrl-0 = <&sdio_pins>;
>+ pinctrl-1 = <&sdio_clk_gate_pins>;
>+ pinctrl-names = "default", "clk-gate";
>+ #address-cells = <1>;
>+ #size-cells = <0>;
>+ bus-width = <4>;
>+ cap-sd-highspeed;
>+ sd-uhs-sdr50;
>+ sd-uhs-sdr104;
>+ max-frequency = <200000000>;
>+ non-removable;
>+ disable-wp;
>+
>+ no-sd;
>+ no-mmc;
>+ mmc-pwrseq = <&sdio_pwrseq>;
>+ vmmc-supply = <&vddao_3v3>;
>+ vqmmc-supply = <&vddio_ao1v8>;
>+};
>+
>+&uart_b {
>+ status = "okay";
>+};
>--
>2.53.0
--
Best regards,
Ferass
^ permalink raw reply
* Re: [PATCH RFC v3 2/4] mm/pgtable: Make pfn_pte() filter out huge page attributes
From: Yin Tirui @ 2026-04-20 11:43 UTC (permalink / raw)
To: Will Deacon
Cc: linux-kernel, linux-mm, x86, linux-arm-kernel, willy, david,
catalin.marinas, tglx, mingo, bp, dave.hansen, hpa, luto, peterz,
akpm, lorenzo.stoakes, ziy, baolin.wang, Liam.Howlett, npache,
ryan.roberts, dev.jain, baohua, lance.yang, vbabka, rppt, surenb,
mhocko, anshuman.khandual, rmclure, kevin.brodsky, apopple, ajd,
pasha.tatashin, bhe, thuth, coxu, dan.j.williams, yu-cheng.yu,
yangyicong, baolu.lu, jgross, conor.dooley, Jonathan.Cameron,
riel, wangkefeng.wang, chenjun102
In-Reply-To: <aeXoY7lrRJev0P83@willie-the-truck>
Hi Will,
On 4/20/2026 4:48 PM, Will Deacon wrote:
> On Sat, Feb 28, 2026 at 03:09:04PM +0800, Yin Tirui wrote:
>> A fundamental principle of page table type safety is that `pte_t` represents
>> the lowest level page table entry and should never carry huge page attributes.
>>
>> Currently, passing a pgprot with huge page bits (e.g., extracted via
>> pmd_pgprot()) into pfn_pte() creates a malformed PTE that retains the huge
>> attribute, leading to the necessity of the ugly `pte_clrhuge()` anti-pattern.
>>
>> Enforce type safety by making `pfn_pte()` inherently filter out huge page
>> attributes:
>> - On x86: Strip the `_PAGE_PSE` bit.
>> - On ARM64: Mask out the block descriptor bits in `PTE_TYPE_MASK` and
>> enforce the `PTE_TYPE_PAGE` format.
>> - On RISC-V: No changes required, as RISC-V leaf PMDs and PTEs share the
>> exact same hardware format and do not use a distinct huge bit.
>>
>> Signed-off-by: Yin Tirui <yintirui@huawei.com>
>> ---
>> arch/arm64/include/asm/pgtable.h | 4 +++-
>> arch/x86/include/asm/pgtable.h | 4 ++++
>> 2 files changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index b3e58735c49b..f2a7a40106d2 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -141,7 +141,9 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>>
>> #define pte_pfn(pte) (__pte_to_phys(pte) >> PAGE_SHIFT)
>> #define pfn_pte(pfn,prot) \
>> - __pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
>> + __pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | \
>> + ((pgprot_val(prot) & ~(PTE_TYPE_MASK & ~PTE_VALID)) | \
>> + (PTE_TYPE_PAGE & ~PTE_VALID)))
> Why are you touching arch/arm64? We don't implement pte_clrhuge() afaict.
> What does this actually fix?
Originally, this patch aimed to ensure that pfn_pte() always returns a
PTE without any
huge page attributes by embedding the logic of pte_clrhuge() directly
into pfn_pte().
However, we found this approach doesn't work well on x86, so we've
abandoned this design.
Following Matthew Wilcox's suggestion, the current approach is instead
to have pmd_pgprot()
return a 4K–formatted pgprot_t (i.e., without huge page attributes), and
then explicitly add the
huge page attributes when constructing a PMD via pfn_pmd().
I've already implemented this in my recent commit:
https://github.com/torvalds/linux/commit/5b8ce6d33822dd7776432e03a08fe6d2dedac079
>
> Will
--
Yin Tirui
^ permalink raw reply
* Re: [PATCH 1/6] drm/connector: report IRQ_HPD events to drm_connector_oob_hotplug_event()
From: Dmitry Baryshkov @ 2026-04-20 11:45 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Bjorn Andersson,
Konrad Dybcio, Pengyu Luo, Nikita Travkin, Yongxing Mou
In-Reply-To: <f74ecd0a-3ff3-45b4-935e-44b89cd0c92d@ideasonboard.com>
On Mon, Apr 20, 2026 at 02:01:57PM +0300, Tomi Valkeinen wrote:
> Hi,
>
> On 20/04/2026 12:50, Dmitry Baryshkov wrote:
> > On Mon, Apr 20, 2026 at 07:50:46AM +0300, Tomi Valkeinen wrote:
> > > Hi,
> > >
> > > On 18/04/2026 01:32, Dmitry Baryshkov wrote:
> > > > On Thu, Apr 16, 2026 at 11:10:03AM +0300, Tomi Valkeinen wrote:
> > > > > Hi,
> > > > >
> > > > > On 16/04/2026 02:22, Dmitry Baryshkov wrote:
> > > > > > The DisplayPort standard defines a special kind of events called IRQ.
> > > > > > These events are used to notify DP Source about the events on the Sink
> > > > > > side. It is extremely important for DP MST handling, where the MST
> > > > > > events are reported through this IRQ.
> > > > > >
> > > > > > In case of the USB-C DP AltMode there is no actual HPD pulse, but the
> > > > > > events are ported through the bits in the AltMode VDOs.
> > > > > >
> > > > > > Extend the drm_connector_oob_hotplug_event() interface and report IRQ
> > > > > > events to the DisplayPort Sink drivers.
> > > > > >
> > > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> > > > > > ---
> > > > > > drivers/gpu/drm/drm_connector.c | 4 +++-
> > > > > > drivers/usb/typec/altmodes/displayport.c | 12 ++++++++----
> > > > > > include/drm/drm_connector.h | 3 ++-
> > > > > > 3 files changed, 13 insertions(+), 6 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > > > > > index 47dc53c4a738..5fdacbd84bd7 100644
> > > > > > --- a/drivers/gpu/drm/drm_connector.c
> > > > > > +++ b/drivers/gpu/drm/drm_connector.c
> > > > > > @@ -3510,6 +3510,7 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> > > > > > * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
> > > > > > * @connector_fwnode: fwnode_handle to report the event on
> > > > > > * @status: hot plug detect logical state
> > > > > > + * @irq_hpd: HPD pulse detected
> > > > > > *
> > > > > > * On some hardware a hotplug event notification may come from outside the display
> > > > > > * driver / device. An example of this is some USB Type-C setups where the hardware
> > > > > > @@ -3520,7 +3521,8 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> > > > > > * a drm_connector reference through calling drm_connector_find_by_fwnode().
> > > > > > */
> > > > > > void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
> > > > > > - enum drm_connector_status status)
> > > > > > + enum drm_connector_status status,
> > > > > > + bool irq_hpd)
> > > > > I find the "IRQ HPD" naming always confusing, even if I'm somewhat familiar
> > > > > with DP, but if someone has mainly worked on HDMI, I'm sure it's even worse.
> > > > >
> > > > > Can we define this a bit more precisely? Is 'irq_hpd' only for displayport?
> > > > > If so, perhaps 'dp_irq_hpd' or 'displayport_irq_hpd'. I might even call it
> > > > > 'dp_hpd_pulse', but maybe that's not good as the spec talks about HPD pulse
> > > > > for both short and long ones (although in the kernel doc you just write "HPD
> > > > > pulse")... The kernel doc could be expanded a bit to make it clear what this
> > > > > flag indicates.
> > > >
> > > > I attempted to stay away from defining a DP-specific flag, keeping it
> > > > generic enough. HDMI is pretty close (IMO) to requiring separate flag in
> > >
> > > If it's not specifically the DP IRQ HPD, then we need to define what it
> > > means. I tried to think what it would mean with HDMI, but I didn't come up
> > > with anything.
> >
> > I might be mistaken, but I had someting like HEAC HPD / EDID status
> > changes in mind (or HDCP-triggered HPD status changes). But here I
> > admit, I hadn't checked if it is actually applicable or not.
>
> Possibly, I'm not familiar with those.
>
> > Anyway, for e.g. DVI or VGA that means nothing. But, my point really is
> > to abstain from defining someting as DP-only in the top-level API.
>
> I'm fine with that, but then it really has to be defined =).
>
> > > > Linux. Likewise I'd rather not use "pulse". The DP AltMode defines a bit
> > > > in the VDO rather than a pulse.
> > > >
> > > > Anyway, if irq_hpd doesn't sound precise enough, what about "bool
> > > > extra_irq"? This would convey that this is the extra hpd-related IRQ,
> > > > but it would also be obvious that it's not related to the HPD pin
> > > > itself.
> > > We'd still need to define what exactly it means. I think it might be better
> > > to just define it as the DP IRQ HPD, as then the meaning is clear.
> > >
> > > Also, would an enum flags parameter be better than a bool parameter?
> >
> > Maybe not enum, but u32 param. Then it can become:
> >
> > @extra_status: additional type-specific information provided by the sink
> > without changing the HPD state
> >
> > void drm_connector_oob_hotplug_event(..., u32 extra_status);
> >
> > /* DP short HPD pulse or corresponding AltMode flag */
> > #define DRM_CONNECTOR_OOB_DP_IRQ_HPD BIT(0)
> > /* DP long HPD pulse, debounced XXX: do we need this? */
> > #define DRM_CONNECTOR_OOB_DP_REPLUG BIT(1)
>
> Why is u32 better than enum? So that we could e.g. pass short values inside
> the extra_status?
No, my thought was to be able to define values specific to the
particular connector types and to be able to combine those values.
After sending the email I started thinking about the bridged and
corresponding notifications. There having overlapping values will not
work becasue bridges in the chanin don't easily know the final connector
type.
I think you are correct here, it should be the enum. With the first
iteration defined as:
/**
* enum drm_connector_status_extra - additional events sent by the sink
* together or in replacement of the HPD status changes
/
enum drm_connector_status_extra {
/**
* @DRM_CONNECTOR_DP_IRQ_HPD: DisplayPort Sink has sent the
* IRQ_HPD (either by the HPD short pulse or via the AltMode event).
*/
DRM_CONNECTOR_DP_IRQ_HPD = BIT(0),
};
/**
* @extra_status: additional information provided by the sink without
* changing the HPD state (or in addition to such a change). It is an
* OR of the values defined in the drm_connector_status_extra enum.
*/
void drm_connector_oob_hotplug_event(..., u32 extra_status);
>
> > For HDMI we might want to define:
> >
> > /* HDMI 1.4b 8.5, HPD pulse */
> > #define DRM_CONNECTOR_OOB_HDMI_REPLUG BIT(0)
> >
> > Or might not, 100ms is long enough for all debouncers.
>
> As I read the spec, there's no usable HPD pulse in HDMI as such. It just
> means that if HPD is low less than 100ms, it should be ignored, and if it's
> low more than 100ms, it should be handled. In other words, from spec
> perspective there's no difference between HPD being low 105ms or five days,
> there's no upper limit for the "pulse".
Yes... Let's see. I don't think we should define any extra API or values
for HDMI until the need arises.
>
> Still, we probably want to handle the case where the HPD is low only for a
> short period, so that we don't do a full disable/enable-cycle. We can
> interpret it as the same monitor still being connected, we just need to
> check the EDID again.
>
> But isn't that just a drm_connector_hotplug_event with drm_connector_status
> staying connected? The callee can see that the connector was connected
> before, it's connected now, but we got an event, so let's read the EDID
> again.
As I wrote, I'd be more concerned with the CDC / HEAC / eARC. For the
normal EDID changes I think we are doing a good enough job.
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 1/6] drm/connector: report IRQ_HPD events to drm_connector_oob_hotplug_event()
From: Tomi Valkeinen @ 2026-04-20 11:51 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Bjorn Andersson,
Konrad Dybcio, Pengyu Luo, Nikita Travkin, Yongxing Mou
In-Reply-To: <v7h3a5pwx32dfcumc3diysylja6lhkhobyzemfthb6dsadcxnp@2kkidnsgov4e>
Hi,
On 20/04/2026 14:45, Dmitry Baryshkov wrote:
> On Mon, Apr 20, 2026 at 02:01:57PM +0300, Tomi Valkeinen wrote:
>> Hi,
>>
>> On 20/04/2026 12:50, Dmitry Baryshkov wrote:
>>> On Mon, Apr 20, 2026 at 07:50:46AM +0300, Tomi Valkeinen wrote:
>>>> Hi,
>>>>
>>>> On 18/04/2026 01:32, Dmitry Baryshkov wrote:
>>>>> On Thu, Apr 16, 2026 at 11:10:03AM +0300, Tomi Valkeinen wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 16/04/2026 02:22, Dmitry Baryshkov wrote:
>>>>>>> The DisplayPort standard defines a special kind of events called IRQ.
>>>>>>> These events are used to notify DP Source about the events on the Sink
>>>>>>> side. It is extremely important for DP MST handling, where the MST
>>>>>>> events are reported through this IRQ.
>>>>>>>
>>>>>>> In case of the USB-C DP AltMode there is no actual HPD pulse, but the
>>>>>>> events are ported through the bits in the AltMode VDOs.
>>>>>>>
>>>>>>> Extend the drm_connector_oob_hotplug_event() interface and report IRQ
>>>>>>> events to the DisplayPort Sink drivers.
>>>>>>>
>>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
>>>>>>> ---
>>>>>>> drivers/gpu/drm/drm_connector.c | 4 +++-
>>>>>>> drivers/usb/typec/altmodes/displayport.c | 12 ++++++++----
>>>>>>> include/drm/drm_connector.h | 3 ++-
>>>>>>> 3 files changed, 13 insertions(+), 6 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
>>>>>>> index 47dc53c4a738..5fdacbd84bd7 100644
>>>>>>> --- a/drivers/gpu/drm/drm_connector.c
>>>>>>> +++ b/drivers/gpu/drm/drm_connector.c
>>>>>>> @@ -3510,6 +3510,7 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
>>>>>>> * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
>>>>>>> * @connector_fwnode: fwnode_handle to report the event on
>>>>>>> * @status: hot plug detect logical state
>>>>>>> + * @irq_hpd: HPD pulse detected
>>>>>>> *
>>>>>>> * On some hardware a hotplug event notification may come from outside the display
>>>>>>> * driver / device. An example of this is some USB Type-C setups where the hardware
>>>>>>> @@ -3520,7 +3521,8 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
>>>>>>> * a drm_connector reference through calling drm_connector_find_by_fwnode().
>>>>>>> */
>>>>>>> void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
>>>>>>> - enum drm_connector_status status)
>>>>>>> + enum drm_connector_status status,
>>>>>>> + bool irq_hpd)
>>>>>> I find the "IRQ HPD" naming always confusing, even if I'm somewhat familiar
>>>>>> with DP, but if someone has mainly worked on HDMI, I'm sure it's even worse.
>>>>>>
>>>>>> Can we define this a bit more precisely? Is 'irq_hpd' only for displayport?
>>>>>> If so, perhaps 'dp_irq_hpd' or 'displayport_irq_hpd'. I might even call it
>>>>>> 'dp_hpd_pulse', but maybe that's not good as the spec talks about HPD pulse
>>>>>> for both short and long ones (although in the kernel doc you just write "HPD
>>>>>> pulse")... The kernel doc could be expanded a bit to make it clear what this
>>>>>> flag indicates.
>>>>>
>>>>> I attempted to stay away from defining a DP-specific flag, keeping it
>>>>> generic enough. HDMI is pretty close (IMO) to requiring separate flag in
>>>>
>>>> If it's not specifically the DP IRQ HPD, then we need to define what it
>>>> means. I tried to think what it would mean with HDMI, but I didn't come up
>>>> with anything.
>>>
>>> I might be mistaken, but I had someting like HEAC HPD / EDID status
>>> changes in mind (or HDCP-triggered HPD status changes). But here I
>>> admit, I hadn't checked if it is actually applicable or not.
>>
>> Possibly, I'm not familiar with those.
>>
>>> Anyway, for e.g. DVI or VGA that means nothing. But, my point really is
>>> to abstain from defining someting as DP-only in the top-level API.
>>
>> I'm fine with that, but then it really has to be defined =).
>>
>>>>> Linux. Likewise I'd rather not use "pulse". The DP AltMode defines a bit
>>>>> in the VDO rather than a pulse.
>>>>>
>>>>> Anyway, if irq_hpd doesn't sound precise enough, what about "bool
>>>>> extra_irq"? This would convey that this is the extra hpd-related IRQ,
>>>>> but it would also be obvious that it's not related to the HPD pin
>>>>> itself.
>>>> We'd still need to define what exactly it means. I think it might be better
>>>> to just define it as the DP IRQ HPD, as then the meaning is clear.
>>>>
>>>> Also, would an enum flags parameter be better than a bool parameter?
>>>
>>> Maybe not enum, but u32 param. Then it can become:
>>>
>>> @extra_status: additional type-specific information provided by the sink
>>> without changing the HPD state
>>>
>>> void drm_connector_oob_hotplug_event(..., u32 extra_status);
>>>
>>> /* DP short HPD pulse or corresponding AltMode flag */
>>> #define DRM_CONNECTOR_OOB_DP_IRQ_HPD BIT(0)
>>> /* DP long HPD pulse, debounced XXX: do we need this? */
>>> #define DRM_CONNECTOR_OOB_DP_REPLUG BIT(1)
>>
>> Why is u32 better than enum? So that we could e.g. pass short values inside
>> the extra_status?
>
> No, my thought was to be able to define values specific to the
> particular connector types and to be able to combine those values.
>
> After sending the email I started thinking about the bridged and
> corresponding notifications. There having overlapping values will not
> work becasue bridges in the chanin don't easily know the final connector
> type.
An enum can have overlapping values. I don't think there's much
difference between u32 and an enum in C. I just like enum because 1) it
groups the possible values in the header file, and 2) the function
parameters can use the enum type, making it obvious what flags you are
supposed to use there.
> I think you are correct here, it should be the enum. With the first
> iteration defined as:
>
> /**
> * enum drm_connector_status_extra - additional events sent by the sink
> * together or in replacement of the HPD status changes
> /
> enum drm_connector_status_extra {
> /**
> * @DRM_CONNECTOR_DP_IRQ_HPD: DisplayPort Sink has sent the
> * IRQ_HPD (either by the HPD short pulse or via the AltMode event).
> */
> DRM_CONNECTOR_DP_IRQ_HPD = BIT(0),
> };
>
> /**
> * @extra_status: additional information provided by the sink without
> * changing the HPD state (or in addition to such a change). It is an
> * OR of the values defined in the drm_connector_status_extra enum.
> */
> void drm_connector_oob_hotplug_event(..., u32 extra_status);
Looks good to me, except I'd use "enum drm_connector_status_extra"
instead of u32 there in the function parameters.
Tomi
^ permalink raw reply
* [PATCH v3 1/4] arm64: dts: amlogic: t7: Add uart_c pinctrl pins group
From: Ronald Claveau @ 2026-04-20 11:58 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Ronald Claveau
In-Reply-To: <20260420-add-bluetooth-t7-vim4-v3-0-669cd2530ae5@aliel.fr>
Add the pin multiplexing configuration for UART C (TX, RX, CTS, RTS)
in the T7 SoC pinctrl node, required to route the UART C signals
through the correct pads before enabling the controller.
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index 7fe72c94ed623..4a55d9641bc9b 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -553,6 +553,18 @@ mux {
bias-pull-up;
};
};
+
+ uart_c_pins: uart-c {
+ mux {
+ groups = "uart_c_tx",
+ "uart_c_rx",
+ "uart_c_cts",
+ "uart_c_rts";
+ bias-pull-up;
+ output-high;
+ function = "uart_c";
+ };
+ };
};
gpio_intc: interrupt-controller@4080 {
--
2.49.0
^ permalink raw reply related
* [PATCH v3 2/4] arm64: dts: amlogic: t7: Add UART controllers nodes
From: Ronald Claveau @ 2026-04-20 11:58 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Ronald Claveau
In-Reply-To: <20260420-add-bluetooth-t7-vim4-v3-0-669cd2530ae5@aliel.fr>
Add device tree nodes for UART B through F (serial@7a000 to
serial@82000), completing the UART controller description for the T7
SoC. Each node includes the peripheral clock.
While at it, move the uart_a node to its correct position in the
bus address order (0x78000) to comply with the DT requirement that
nodes be sorted by their reg address. Complete the
uart_a node with its peripheral clock (CLKID_SYS_UART_A) and the
associated clock-names, matching the vendor default clock assignment,
consistent with the other UART nodes.
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 61 +++++++++++++++++++++++++----
1 file changed, 54 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index 4a55d9641bc9b..81c26b1e3e7a4 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -577,13 +577,6 @@ gpio_intc: interrupt-controller@4080 {
<10 11 12 13 14 15 16 17 18 19 20 21>;
};
- uart_a: serial@78000 {
- compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
- reg = <0x0 0x78000 0x0 0x18>;
- interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
- status = "disabled";
- };
-
gp0: clock-controller@8080 {
compatible = "amlogic,t7-gp0-pll";
reg = <0x0 0x8080 0x0 0x20>;
@@ -713,6 +706,60 @@ pwm_ao_cd: pwm@60000 {
status = "disabled";
};
+ uart_a: serial@78000 {
+ compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
+ reg = <0x0 0x78000 0x0 0x18>;
+ interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_A>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+
+ uart_b: serial@7a000 {
+ compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
+ reg = <0x0 0x7a000 0x0 0x18>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_B>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+
+ uart_c: serial@7c000 {
+ compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
+ reg = <0x0 0x7c000 0x0 0x18>;
+ interrupts = <GIC_SPI 170 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_C>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+
+ uart_d: serial@7e000 {
+ compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
+ reg = <0x0 0x7e000 0x0 0x18>;
+ interrupts = <GIC_SPI 171 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_D>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+
+ uart_e: serial@80000 {
+ compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
+ reg = <0x0 0x80000 0x0 0x18>;
+ interrupts = <GIC_SPI 172 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_E>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+
+ uart_f: serial@82000 {
+ compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
+ reg = <0x0 0x82000 0x0 0x18>;
+ interrupts = <GIC_SPI 173 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_F>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+
sd_emmc_a: mmc@88000 {
compatible = "amlogic,t7-mmc", "amlogic,meson-axg-mmc";
reg = <0x0 0x88000 0x0 0x800>;
--
2.49.0
^ permalink raw reply related
* [PATCH v3 0/4] arm64: dts: amlogic: t7: Add UART support and enable Bluetooth on VIM4
From: Ronald Claveau @ 2026-04-20 11:58 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Ronald Claveau
This series adds all UART controllers for the Amlogic T7 SoC and enables
the Bluetooth controller on the Khadas VIM4 board.
The T7 SoC ships with six UART controllers (A through F), but only
uart_a was previously described in the device tree.
- Patch 1 adds the pinctrl group for UART C, which is needed to route
its four signals (TX, RX, CTS, RTS) through the correct pads.
- Patch 2 completes the uart_a node (peripheral clock) and
repositions it to respect the ascending reg address order required
by the DT specification. It then adds nodes for UART B through F,
each with their respective peripheral clock.
- Patch 3 removes redundant clocks and clock-names for UART A on
Khadas VIM4 DT. It then uses those defined from DTSI.
- Patch 4 enables UART C on the Khadas VIM4 board and attaches the
on-board BCM43438 Bluetooth controller to it, with hardware flow
control, wakeup GPIOs, LPO clock and power supplies.
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
Changes in v3:
- Patches 3-4: split into two separate patches:
3. remove redundant clocks from UART A
4. add UART C node according to Neil's feedback.
- Link to v2: https://lore.kernel.org/r/20260416-add-bluetooth-t7-vim4-v2-0-9a57098fd055@aliel.fr
Changes in v2:
- PATCH 1: change underscore to dash in pin node name,
according to Xianwei's feedback.
- PATCH 3: remove clocks and clock-names as already defined in DTSI,
according to Xianwei's feedback.
- Link to v1: https://lore.kernel.org/r/20260415-add-bluetooth-t7-vim4-v1-0-0ba0746cc1d6@aliel.fr
---
Ronald Claveau (4):
arm64: dts: amlogic: t7: Add uart_c pinctrl pins group
arm64: dts: amlogic: t7: Add UART controllers nodes
arm64: dts: amlogic: t7: khadas-vim4: Remove redundant clocks from UART A
arm64: dts: amlogic: t7: khadas-vim4: Enable Bluetooth
.../dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 21 ++++++-
arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 73 +++++++++++++++++++---
2 files changed, 85 insertions(+), 9 deletions(-)
---
base-commit: 6aa9edb4f8266cfb913ee74f5e55116550b5574d
change-id: 20260414-add-bluetooth-t7-vim4-f01e03c4ec2a
Best regards,
--
Ronald Claveau <linux-kernel-dev@aliel.fr>
^ permalink raw reply
* [PATCH v3 4/4] arm64: dts: amlogic: t7: khadas-vim4: Enable Bluetooth
From: Ronald Claveau @ 2026-04-20 11:58 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Ronald Claveau
In-Reply-To: <20260420-add-bluetooth-t7-vim4-v3-0-669cd2530ae5@aliel.fr>
Enable UART C on the Khadas VIM4 board and attach the BCM43438
compatible Bluetooth controller to it. The node configures the RTS/CTS
hardware flow control, the associated pinmux, the power supplies (vddao_3v3
and vddao_1v8), the 32 kHz LPO clock shared with the wifi32k fixed
clock, and the GPIO lines used for host wakeup, device wakeup and
shutdown.
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
.../dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
index 3227ab27de107..8ea7ae609fbd5 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
@@ -251,3 +251,22 @@ &sd_emmc_c {
&uart_a {
status = "okay";
};
+
+&uart_c {
+ status = "okay";
+ pinctrl-0 = <&uart_c_pins>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ host-wakeup-gpios = <&gpio GPIOX_18 GPIO_ACTIVE_HIGH>;
+ device-wakeup-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>;
+ max-speed = <3000000>;
+ clocks = <&wifi32k>;
+ clock-names = "lpo";
+ vbat-supply = <&vddao_3v3>;
+ vddio-supply = <&vddao_1v8>;
+ };
+};
--
2.49.0
^ permalink raw reply related
* [PATCH v3 3/4] arm64: dts: amlogic: t7: khadas-vim4: Remove redundant clocks from UART A
From: Ronald Claveau @ 2026-04-20 11:58 UTC (permalink / raw)
To: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
Ronald Claveau
In-Reply-To: <20260420-add-bluetooth-t7-vim4-v3-0-669cd2530ae5@aliel.fr>
Remove clocks and clock-names for UART A, as they are defined in DTSI.
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
index 69d6118ba57e7..3227ab27de107 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
@@ -250,6 +250,4 @@ &sd_emmc_c {
&uart_a {
status = "okay";
- clocks = <&xtal>, <&xtal>, <&xtal>;
- clock-names = "xtal", "pclk", "baud";
};
--
2.49.0
^ permalink raw reply related
* Re: [PATCH v3 4/5] counter: Add rockchip-pwm-capture driver
From: Nicolas Frattaroli @ 2026-04-20 12:02 UTC (permalink / raw)
To: William Breathitt Gray
Cc: William Breathitt Gray, Uwe Kleine-König, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner, Lee Jones,
kernel, Jonas Karlman, Alexey Charkov, linux-rockchip, linux-pwm,
devicetree, linux-arm-kernel, linux-kernel, linux-iio
In-Reply-To: <20251206093419.40067-1-wbg@kernel.org>
Hi,
finally got an opportunity to work on this again.
I'll respond to some things in-line. If a review isn't directly
addressed, you can assume I acknowledge it and will address it
in the next revision with no further comment needed.
On Saturday, 6 December 2025 10:34:17 Central European Summer Time William Breathitt Gray wrote:
> > +struct rockchip_pwm_capture {
> > + struct rockchip_mfpwm_func *pwmf;
> > + struct counter_device *counter;
>
> Is this structure member used at all? If not, you should just remove it.
The counter member is used in the interrupt handler. I actually
noticed that I request the interrupt before pc->counter is set,
so if an interrupt fires before the probe function finishes then
I think the handler would run with a NULL counter member. Oops,
I'll rectify that.
> > + bool is_enabled;
>
> Does this device offer some way to probe whether PWM capture mode is
> enabled? I suspect so, because I see PWM_ENABLE.pwm_en enables the
> channel and PWM_CTRL.pwm_mode selects capture mode, so perhaps we're
> able to read the current state of those registers. If you're able to
> read those registers to determine the enable state, I'd suggest wrapping
> that into a helper function and calling it when you need to determine
> whether the capture mode is currently enabled.
I'm going to read the hardware state in the next revision, you're right
that this is generally a better idea.
>
> If we're not able to probe the enable state, is it safe to assume we're
> in a disabled state when the module loads, or should we ensure it by
> unconditionally disabling PWM capture mode during
> rockchip_pwm_capture_probe()?
In my next revision, I've now modified it to mfpwm_acquire if the hardware
state has the counter enabled during probe. This sounds niche but I'm also
doing this on the PWM output side, where Uwe rightfully pointed out that
a bootloader may have enabled PWM output in hardware and Linux needs to
recognise that state without any heavy-handed actions. For the counter
PWM capture side, resetting it to a known state wouldn't be disruptive in
the same way as it would be for PWM output, but I think it's a good idea
to keep the state as-is since we can read it.
> [... snip ...]
> > +static int rkpwmc_count_read(struct counter_device *counter,
> > + struct counter_count *count, u64 *value)
> > +{
> > + struct rockchip_pwm_capture *pc = counter_priv(counter);
> > +
> > + guard(spinlock)(&pc->enable_lock);
> > +
> > + if (!pc->is_enabled) {
> > + *value = 0;
> > + return 0;
> > + }
>
> I don't think there's a need to check whether capture mode is disabled.
> The user should be aware of the enable state of the Count by checking
> the respective "enable" attribute; and if they ignore that, a value of
> "0" doesn't inherently tell them that the Count is disabled which makes
> it moot to do so. I'd suggest just removing this check entirely and
> returning the register values unconditionally.
I see what you're going for, but if the counter isn't enabled, we can't
rely in the counter having an mfpwm_acquire, and consequently, we can't
rely on the PWM core clock being on, which is required for reading the
registers.
In my next revision, I'll still be returning 0 if the counter is disabled,
but the is_enabled member is gone, so there's a new function called
rkpwmc_acquire_if_enabled to still make this correct.
I could of course also extend the core driver to let me poke at these
non-shared registers without exclusive control over the hardware, but
that may be more trouble than it's worth.
I'll also no longer return 0 on bogus count IDs when the counter is
disabled.
> > +
> > + switch (count->id) {
> > + case COUNT_LPC:
> > + *value = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_LPC);
> > + return 0;
> > + case COUNT_HPC:
> > + *value = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_HPC);
> > + return 0;
> > + default:
> > + return -EINVAL;
> > + }
> > +}
> > +
> > +static const struct counter_ops rkpwmc_ops = {
> > + .count_read = rkpwmc_count_read,
> > +};
>
> You should implement a signal_read() callback if its possible to probe
> the current state of PWM Clock. You should implement action_read() if
> its possible to probe the current polarity of "pwm_in" in order to set
> which Synapse is currently active.
Unfortunately, it doesn't seem like the hardware allows direct access to
read the signal. "pwm_in" as it appears in the block diagram seems to be
an entirely internal signal that's not accessible through MMIO.
Thank you for the reviews!
Kind regards,
Nicolas Frattaroli
>
> William Breathitt Gray
>
> [^1] https://opensource.rock-chips.com/images/3/36/Rockchip_RK3506_TRM_Part_1_V1.2-20250811.pdf
>
^ permalink raw reply
* Re: [PATCH v3 3/4] arm64: dts: amlogic: t7: khadas-vim4: Remove redundant clocks from UART A
From: Neil Armstrong @ 2026-04-20 12:02 UTC (permalink / raw)
To: Ronald Claveau, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel
In-Reply-To: <20260420-add-bluetooth-t7-vim4-v3-3-669cd2530ae5@aliel.fr>
On 4/20/26 13:58, Ronald Claveau wrote:
> Remove clocks and clock-names for UART A, as they are defined in DTSI.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> index 69d6118ba57e7..3227ab27de107 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
> @@ -250,6 +250,4 @@ &sd_emmc_c {
>
> &uart_a {
> status = "okay";
> - clocks = <&xtal>, <&xtal>, <&xtal>;
> - clock-names = "xtal", "pclk", "baud";
> };
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v3 2/4] arm64: dts: amlogic: t7: Add UART controllers nodes
From: Neil Armstrong @ 2026-04-20 12:03 UTC (permalink / raw)
To: Ronald Claveau, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel
In-Reply-To: <20260420-add-bluetooth-t7-vim4-v3-2-669cd2530ae5@aliel.fr>
On 4/20/26 13:58, Ronald Claveau wrote:
> Add device tree nodes for UART B through F (serial@7a000 to
> serial@82000), completing the UART controller description for the T7
> SoC. Each node includes the peripheral clock.
>
> While at it, move the uart_a node to its correct position in the
> bus address order (0x78000) to comply with the DT requirement that
> nodes be sorted by their reg address. Complete the
> uart_a node with its peripheral clock (CLKID_SYS_UART_A) and the
> associated clock-names, matching the vendor default clock assignment,
> consistent with the other UART nodes.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 61 +++++++++++++++++++++++++----
> 1 file changed, 54 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index 4a55d9641bc9b..81c26b1e3e7a4 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -577,13 +577,6 @@ gpio_intc: interrupt-controller@4080 {
> <10 11 12 13 14 15 16 17 18 19 20 21>;
> };
>
> - uart_a: serial@78000 {
> - compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
> - reg = <0x0 0x78000 0x0 0x18>;
> - interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
> - status = "disabled";
> - };
> -
> gp0: clock-controller@8080 {
> compatible = "amlogic,t7-gp0-pll";
> reg = <0x0 0x8080 0x0 0x20>;
> @@ -713,6 +706,60 @@ pwm_ao_cd: pwm@60000 {
> status = "disabled";
> };
>
> + uart_a: serial@78000 {
> + compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
> + reg = <0x0 0x78000 0x0 0x18>;
> + interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_A>, <&xtal>;
> + clock-names = "xtal", "pclk", "baud";
> + status = "disabled";
> + };
> +
> + uart_b: serial@7a000 {
> + compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
> + reg = <0x0 0x7a000 0x0 0x18>;
> + interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_B>, <&xtal>;
> + clock-names = "xtal", "pclk", "baud";
> + status = "disabled";
> + };
> +
> + uart_c: serial@7c000 {
> + compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
> + reg = <0x0 0x7c000 0x0 0x18>;
> + interrupts = <GIC_SPI 170 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_C>, <&xtal>;
> + clock-names = "xtal", "pclk", "baud";
> + status = "disabled";
> + };
> +
> + uart_d: serial@7e000 {
> + compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
> + reg = <0x0 0x7e000 0x0 0x18>;
> + interrupts = <GIC_SPI 171 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_D>, <&xtal>;
> + clock-names = "xtal", "pclk", "baud";
> + status = "disabled";
> + };
> +
> + uart_e: serial@80000 {
> + compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
> + reg = <0x0 0x80000 0x0 0x18>;
> + interrupts = <GIC_SPI 172 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_E>, <&xtal>;
> + clock-names = "xtal", "pclk", "baud";
> + status = "disabled";
> + };
> +
> + uart_f: serial@82000 {
> + compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
> + reg = <0x0 0x82000 0x0 0x18>;
> + interrupts = <GIC_SPI 173 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&xtal>, <&clkc_periphs CLKID_SYS_UART_F>, <&xtal>;
> + clock-names = "xtal", "pclk", "baud";
> + status = "disabled";
> + };
> +
> sd_emmc_a: mmc@88000 {
> compatible = "amlogic,t7-mmc", "amlogic,meson-axg-mmc";
> reg = <0x0 0x88000 0x0 0x800>;
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v7 3/4] KVM: arm64: PMU: Introduce FIXED_COUNTERS_ONLY
From: Akihiko Odaki @ 2026-04-20 12:07 UTC (permalink / raw)
To: Marc Zyngier
Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
Catalin Marinas, Will Deacon, Kees Cook, Gustavo A. R. Silva,
Paolo Bonzini, Jonathan Corbet, Shuah Khan, linux-arm-kernel,
kvmarm, linux-kernel, linux-hardening, devel, kvm, linux-doc,
linux-kselftest
In-Reply-To: <86qzoa0xj6.wl-maz@kernel.org>
On 2026/04/20 18:51, Marc Zyngier wrote:
> On Mon, 20 Apr 2026 09:36:16 +0100,
> Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
>>
>> On 2026/04/20 2:19, Marc Zyngier wrote:
>>> On Sat, 18 Apr 2026 09:14:25 +0100,
>>> Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> wrote:
>>>>
>>>> On a heterogeneous arm64 system, KVM's PMU emulation is based on the
>>>> features of a single host PMU instance. When a vCPU is migrated to a
>>>> pCPU with an incompatible PMU, counters such as PMCCNTR_EL0 stop
>>>> incrementing.
>>>>
>>>> Although this behavior is permitted by the architecture, Windows does
>>>> not handle it gracefully and may crash with a division-by-zero error.
>>>>
>>>> The current workaround requires VMMs to pin vCPUs to a set of pCPUs
>>>> that share a compatible PMU. This is difficult to implement correctly in
>>>> QEMU/libvirt, where pinning occurs after vCPU initialization, and it
>>>> also restricts the guest to a subset of available pCPUs.
>>>>
>>>> Introduce the KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY attribute to
>>>> create a "fixed-counters-only" PMU. When set, KVM exposes a PMU that is
>>>> compatible with all pCPUs but that does not support programmable
>>>> event counters which may have different feature sets on different PMUs.
>>>>
>>>> This allows Windows guests to run reliably on heterogeneous systems
>>>> without crashing, even without vCPU pinning, and enables VMMs to
>>>> schedule vCPUs across all available pCPUs, making full use of the host
>>>> hardware.
>>>>
>>>> Much like KVM_ARM_VCPU_PMU_V3_IRQ and other read-write attributes, this
>>>> attribute provides a getter that facilitates kernel and userspace
>>>> debugging/testing.
>>>
>>> OK, so that's the sales pitch. But how is it implemented? I would like
>>> to be able to read a high-level description of the implementation
>>> trade-offs.
>>
>> Implementation-wise it is very trivial. Essentially the following
>> addition in kvm_arm_pmu_v3_get_attr() is the entire implementation:
>> + case KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY:
>> + if (test_bit(KVM_ARCH_FLAG_PMU_V3_FIXED_COUNTERS_ONLY,
>> &vcpu->kvm->arch.flags))
>> + return 0;
>>
>> Both its functionality and code complexity is trivial. So we can argue that:
>> - the functionality is too trivial to be useful or
>> - the interface/implementation complexity is so trivial that it does not
>> incur maintenance burden
>>
>> In this case the selftest uses the getter so I was more inclined to
>> have it, but adding one just for the selftest sounds too ad-hoc, so
>> here I looked into other attributes to ensure that it was not
>> introducing inconsistency with existing interfaces.
>>
>> As the result, I found there are other read-write attributes; in fact
>> there are more read-write attributes than write-only ones.
>
> You're completely missing the point. I'm referring to the whole of the
> commit message, which is more of a marketing slide than a technical
> description.
In terms of implementation, the obvious tradeoff is that it adds more
code to implement the feature. One thing to note is that
kvm_vcpu_load_pmu() is added and is called each time a vCPU migrates
across pCPUs. The heavy part, making the KVM_REQ_RELOAD_PMU request,
only happens when the feature is enabled.
>
> I really don't care about the getter at this stage, which while
> pointless, does not make things more awful than they already are.
>
>>
>>>
>>>>
>>>> Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
>>>> ---
>>>> Documentation/virt/kvm/devices/vcpu.rst | 29 ++++++
>>>> arch/arm64/include/asm/kvm_host.h | 2 +
>>>> arch/arm64/include/uapi/asm/kvm.h | 1 +
>>>> arch/arm64/kvm/arm.c | 1 +
>>>> arch/arm64/kvm/pmu-emul.c | 155 +++++++++++++++++++++++---------
>>>> include/kvm/arm_pmu.h | 2 +
>>>> 6 files changed, 147 insertions(+), 43 deletions(-)
>>>>
>>>> diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
>>>> index 60bf205cb373..e0aeb1897d77 100644
>>>> --- a/Documentation/virt/kvm/devices/vcpu.rst
>>>> +++ b/Documentation/virt/kvm/devices/vcpu.rst
>>>> @@ -161,6 +161,35 @@ explicitly selected, or the number of counters is out of range for the
>>>> selected PMU. Selecting a new PMU cancels the effect of setting this
>>>> attribute.
>>>> +1.6 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY
>>>> +------------------------------------------------------
>>>> +
>>>> +:Parameters: no additional parameter in kvm_device_attr.addr
>>>> +
>>>> +:Returns:
>>>> +
>>>> + ======= =====================================================
>>>> + -EBUSY Attempted to set after initializing PMUv3 or running
>>>> + VCPU, or attempted to set for the first time after
>>>> + setting an event filter
>>>> + -ENXIO Attempted to get before setting
>>>> + -ENODEV Attempted to set while PMUv3 not supported
>>>> + ======= =====================================================
>>>> +
>>>> +If set, PMUv3 will be emulated without programmable event counters. The VCPU
>>>> +will use any compatible hardware PMU. This attribute is particularly useful on
>>>
>>> Not quite "any PMU". It will use *the* PMU of the physical CPU,
>>> irrespective of the implementation.
>>
>> I think:
>>
>> - this comment
>> - one on the KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED note
>> - one on kvm_pmu_create_perf_event()
>> - and one on kvm_arm_pmu_v3_set_pmu_fixed_counters_only()
>>
>> All boil down into one question: will it support all possible CPUs, or
>> will it support a subset? Let me answer here:
>>
>> This patch is written to support a subset instead of all possible
>> CPUs. If a pCPU does not have a compatible PMU, the pCPU will not be
>> supported and cause KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED.
>
> This is not a thing. Either *all* the CPUs have a PMU that can be used
> for KVM, or PMU support is not offered to guests. That's a hard line
> in the sand. And the code already upholds this by checking the
> sanitised PMUVer field.
>
>>
>> This patch does not enforce all possible CPUs are covered by the
>> compatible PMUs. Theoretically speaking,
>> kvm_arm_pmu_get_pmuver_limit() enables the PMU emulation when real
>> PMUv3 hardware covers all possible CPUs *or* the relevant registers
>> can be trapped with IMPDEF, so some pCPU may not have a compatible PMU
>> and only provide the IMPDEF trapping.
>
> How is that possible? Please describe the case where that can happen,
> and I will make sure that such a system stops booting. The intent is
> definitely that that:
>
> - for early CPUs, we take the minimal capability of all CPUs
>
> - for late CPUs, either they match at least the capability recorded by
> early CPUs, or they don't boot.
All CPUs may trap the relevant registers with IMPDEF but some of them
may not have compatible PMUs. As I wrote in the previous email, I don't
think it will happen in practice.
>
>> Practically, I don't think any sane configuration will ever have such
>> a subset support, so we can explicitly enforce all possible CPUs are
>> covered by the compatible PMUs if desired.
>
> That's not just desired. This is a requirement. And it is already
> enforced AFAICS.
>
>>
>>>
>>>> +heterogeneous systems where different hardware PMUs cover different physical
>>>> +CPUs. The compatibility of hardware PMUs can be checked with
>>>> +KVM_ARM_VCPU_PMU_V3_SET_PMU. All VCPUs in a VM share this attribute. It isn't
>>>> +possible to set it for the first time if a PMU event filter is already present.
>>>
>>> "for the first time" gives the impression that it will work if you try
>>> again. I'd rather we say that "This feature is incompatible with the
>>> existence of a PMU event filter".
>>
>> The following sequence will work:
>> 1. Set KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY
>> 2. Set KVM_ARM_VCPU_PMU_V3_FILTER
>> 3. Set KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY
>>
>> This is to make the behavior conistent with KVM_ARM_VCPU_PMU_V3_SET_PMU.
>
> I don't think this is correct. Filtering is completely at odds with
> this patch, and I don't want to have to reason about the combination.
kvm_arm_pmu_v3_set_pmu() has the following condition:
if (kvm_vm_has_ran_once(kvm) ||
(kvm->arch.pmu_filter && kvm->arch.arm_pmu != arm_pmu)) {
ret = -EBUSY;
break;
}
kvm_arm_pmu_v3_set_pmu_fixed_counters_only() has the corresponding
condition for consistency:
if (kvm_vm_has_ran_once(kvm) ||
(kvm->arch.pmu_filter &&
!test_bit(KVM_ARCH_FLAG_PMU_V3_FIXED_COUNTERS_ONLY,
&kvm->arch.flags)))
return -EBUSY;
We can of course kill the PMU event filter for FIXED_COUNTERS_ONLY. The
filter is effectively no-op with FIXED_COUNTERS_ONLY and I don't think
that consistency matters much.
>
> [...]
>
>>>> + int i;
>>>> +
>>>> + for_each_set_bit(i, &mask, 32) {
>>>> + pmc = kvm_vcpu_idx_to_pmc(vcpu, i);
>>>> + if (!pmc->perf_event)
>>>> + continue;
>>>> +
>>>> + cpu_pmu = to_arm_pmu(pmc->perf_event->pmu);
>>>> + if (!cpumask_test_cpu(vcpu->cpu, &cpu_pmu->supported_cpus)) {
>>>> + kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu);
>>>> + break;
>>>> + }
>>>> + }
>>>> +}
>>>> +
>>>
>>> Why do we need to inflict this on VMs that do not have the fixed
>>> counter restriction?
>>
>> This function is to re-create the perf_event in case the current
>> perf_event does not support the pCPU because e.g., the pCPU is a
>> E-core while the perf_event only covers the P-cores.
>
> That's not what I meant. This code is only here to support the
> fixed-function feature. It makes no sense outside of it, because *we
> don't support counter migration across implementations*.
>
> So what's the purpose of this stuff for the normal KVM setup?
None. It's only for this feature. We can add a check of the feature flag
at the beginning of the function to avoid that loop.
>
>>
>>>
>>> And even then, all you have to reconfigure is the cycle counter. So
>>> why the loop? All we want to find out is whether the cycle counter is
>>> instantiated on the PMU that matches the current CPU.
>>
>> I just wanted to avoid hardcoding assumptions on the fixed
>> counter(s). FEAT_PMUv3_ICNTR will be naturaly handled with a loop, for
>> example.
>
> Well, not that loop, since ICNTR is counter 32. So please let's stop
> the nonsense and only add what is required?
>
> [...]
>
>>>> +
>>>> clear_bit(KVM_ARCH_FLAG_PMU_V3_FIXED_COUNTERS_ONLY,
>>>> &kvm->arch.flags);
>>>
>>> Why does this need to be cleared? I'd rather we make sure it is never
>>> set the first place.
>>
>> KVM_ARM_VCPU_PMU_V3_SET_PMU and
>> KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY can be set on the same
>> VCPU. The last KVM_ARM_VCPU_PMU_V3_SET_PMU or
>> KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY setting will be effective.
>>
>> A VMM may try set these attributes to check if the setting is
>> supported. For example, the RFC QEMU patch first uses
>> KVM_ARM_VCPU_PMU_V3_SET_PMU to find a compatible PMU that covers all
>> pCPUs, and then falls back to
>> KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY. The order of such probing is
>> up to the VMM.
>
> KVM_ARM_VCPU_PMU_V3_SET_PMU is not a probing mechanism. You must probe
> the PMUs by looking in /sys/bus/event_source/devices/, like kvmtool
> does.
>
> So there is no reason to support this stuff, and the two flags should
> be made mutually exclusive.
Thanks for the pointer. I'll make a change to make the flags mutually
exclusive and test it with an amended QEMU patch that follows what
kvmtool does.
>
> [...]
>
>>>>
>>>
>>> In conclusion, I find this patch to be rather messy. For a start, it
>>> needs to be split in at least 5 patches:
>>>
>>> - at least two for the refactoring
>>> - one for the PMU core changes
>>> - one for the UAPI
>>> - one for documentation
>>
>> That clarifies the expected granurarity of patches. The next version
>> will be in that layout, perhaps with more patches if an additional
>> change. Thanks for the guidance.
>>
>>>
>>> I'd also like some clarification on how this is intended to work if we
>>> enable FEAT_PMUv3_ICNTR, because the definition seems to be designed
>>> to encompass all fixed-function counters, and I expect this to grow
>>> over time.
>>
>> Indeed the UAPI was designed to encompass all fixed-function counters
>> as suggested by Oliver.
>>
>> To support the UAPI, the implementation avoids hardcoding the
>> assumption on the fixed counter(s). FEAT_PMUv3_INCTR will be naturaly
>> supported once the common code is properly updated (i.e., the size of
>> the event counter bitmask is grown the corresponding registers are
>> wired up with a proper check of the feature.)
>>
>> I expect migration will be handled with the conventional register
>> getters and setters, but please share if you have a concern.
>
> At the very least I want to see some documentation explaining that.
What kind of documentation do you expect? If we change
kvm_vcpu_load_pmu() to avoid for_each_set_bit(), there would be a good
chance to forget updating it when mechanically updating existing
for_each_set_bit() instances, so it is a candidate for documentation.
But I don't have a good idea where to place it either.
Regards,
Akihiko Odaki
^ permalink raw reply
* Re: [PATCH v3 2/8] arm64, unwind: build kernel with sframe V3 info
From: Jens Remus @ 2026-04-20 12:16 UTC (permalink / raw)
To: Dylan Hatch
Cc: Roman Gushchin, Weinan Liu, Will Deacon, Josh Poimboeuf,
Indu Bhagat, Peter Zijlstra, Steven Rostedt, Catalin Marinas,
Jiri Kosina, Mark Rutland, Prasanna Kumar T S M, Puranjay Mohan,
Song Liu, joe.lawrence, linux-toolchains, linux-kernel,
live-patching, linux-arm-kernel, Heiko Carstens, Vasily Gorbik,
Ilya Leoshkevich
In-Reply-To: <CADBMgpyFd=id0M0Q+nZouBt9Ph6T=0PfP9xWuKOFWoLQd7zvng@mail.gmail.com>
On 4/18/2026 2:20 AM, Dylan Hatch wrote:
> On Tue, Apr 14, 2026 at 5:43 AM Jens Remus <jremus@linux.ibm.com> wrote:
>> You are introducing two new Kconfig options (SFRAME_UNWINDER and
>> ARCH_SUPPORTS_SFRAME_UNWINDER). I wonder whether they could somehow be
>> combined into a single new option. Although I am not sure how an option
>> can be both selectable and depending at the same time, so that the ARM64
>> config could select it, but it would also depend on the above.
>
> I don't think this is recommended, since the behavior of 'select'
> appears to override a 'depends' requirement.
>
> From Documentation/kbuild/kconfig-language.rst: "select should be used
> with care. select will force a symbol to a value without visiting the
> dependencies. By abusing select you are able to select a symbol FOO
> even if FOO depends on BAR that is not set. In general use select only
> for non-visible symbols (no prompts anywhere) and for symbols with no
> dependencies. That will limit the usefulness but on the other hand
> avoid the illegal configurations all over."
Thanks for the explanation! So both options cannot be merged into one.
Maybe the option names can still be aligned, so that they have
UNWIND_KERNEL_SFRAME in common and the kernel and user space sframe
unwinder options have HAVE_UNWIND in common?
SFRAME_UNWINDER -> HAVE_UNWIND_KERNEL_SFRAME
ARCH_SUPPORTS_SFRAME_UNWINDER -> ARCH_SUPPORTS_UNWIND_KERNEL_SFRAME
That would then align nicely with the existing:
HAVE_UNWIND_USER_SFRAME
The only downside is that the user variant would get selected via
HAVE_UNWIND_USER_SFRAME and the kernel variant via
ARCH_SUPPORTS_UNWIND_KERNEL_SFRAME.
>>> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
>>
>>> @@ -491,6 +491,8 @@
>>> *(.rodata1) \
>>> } \
>>> \
>>> + SFRAME \
>>> + \
>>> /* PCI quirks */ \
>>> .pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \
>>> BOUNDED_SECTION_PRE_LABEL(.pci_fixup_early, _pci_fixups_early, __start, __end) \
>>> @@ -911,6 +913,19 @@
>>> #define TRACEDATA
>>> #endif
>>>
>>> +#ifdef CONFIG_SFRAME_UNWINDER
>>> +#define SFRAME \
>>> + /* sframe */ \
>>> + .sframe : AT(ADDR(.sframe) - LOAD_OFFSET) { \
>>> + __start_sframe_header = .; \
>>
>> __start_sframe[_section] = .;
>>
>>> + KEEP(*(.sframe)) \
>>> + KEEP(*(.init.sframe)) \
>>> + __stop_sframe_header = .; \
>>
>> __stop_sframe[_section] = .;
>>
>> Unless I am missing something both are not the start/stop of the .sframe
>> header (in the .sframe section) but the .sframe section itself (see also
>> your subsequent "[PATCH v3 4/8] sframe: Provide PC lookup for vmlinux
>> .sframe section." where you assign both to kernel_sfsec.sframe_start
>> and kernel_sfsec.sframe_end.
>>
>>> + }
>>> +#else
>>> +#define SFRAME
>>> +#endif
>>> +
>>> #ifdef CONFIG_PRINTK_INDEX
>>> #define PRINTK_INDEX \
>>> .printk_index : AT(ADDR(.printk_index) - LOAD_OFFSET) { \
What about the following? Note that I also aligned the indentation in
vmlinux.lds.h to the one in the blocks above/below.
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
@@ -31,6 +31,7 @@
* __irqentry_text_start, __irqentry_text_end
* __softirqentry_text_start, __softirqentry_text_end
* __start_opd, __end_opd
+ * __start_sframe, __end_sframe
*/
extern char _text[], _stext[], _etext[];
extern char _data[], _sdata[], _edata[];
@@ -53,6 +54,9 @@ extern char __ctors_start[], __ctors_end[];
/* Start and end of .opd section - used for function descriptors. */
extern char __start_opd[], __end_opd[];
+/* Stand end end of .sframe section - used for stack unwinding. */
+extern char __start_sframe[], __end_sframe[];
+
/* Start and end of instrumentation protected text section */
extern char __noinstr_text_start[], __noinstr_text_end[];
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
@@ -914,13 +914,13 @@
#endif
#ifdef CONFIG_SFRAME_UNWINDER
-#define SFRAME \
- /* sframe */ \
- .sframe : AT(ADDR(.sframe) - LOAD_OFFSET) { \
- __start_sframe_header = .; \
- KEEP(*(.sframe)) \
- KEEP(*(.init.sframe)) \
- __stop_sframe_header = .; \
+#define SFRAME \
+ /* sframe */ \
+ .sframe : AT(ADDR(.sframe) - LOAD_OFFSET) { \
+ __start_sframe = .; \
+ KEEP(*(.sframe)) \
+ KEEP(*(.init.sframe)) \
+ __end_sframe = .; \
}
#else
#define SFRAME
Regards,
Jens
--
Jens Remus
Linux on Z Development (D3303)
jremus@de.ibm.com / jremus@linux.ibm.com
IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
^ permalink raw reply
* Re: [PATCH 1/6] drm/connector: report IRQ_HPD events to drm_connector_oob_hotplug_event()
From: Dmitry Baryshkov @ 2026-04-20 12:22 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Bjorn Andersson,
Konrad Dybcio, Pengyu Luo, Nikita Travkin, Yongxing Mou
In-Reply-To: <ac330f76-24dc-4f6b-aeaf-69176eb41298@ideasonboard.com>
On Mon, Apr 20, 2026 at 02:51:49PM +0300, Tomi Valkeinen wrote:
> Hi,
>
> On 20/04/2026 14:45, Dmitry Baryshkov wrote:
> > On Mon, Apr 20, 2026 at 02:01:57PM +0300, Tomi Valkeinen wrote:
> > > Hi,
> > >
> > > On 20/04/2026 12:50, Dmitry Baryshkov wrote:
> > > > On Mon, Apr 20, 2026 at 07:50:46AM +0300, Tomi Valkeinen wrote:
> > > > > Hi,
> > > > >
> > > > > On 18/04/2026 01:32, Dmitry Baryshkov wrote:
> > > > > > On Thu, Apr 16, 2026 at 11:10:03AM +0300, Tomi Valkeinen wrote:
> > > > > > > Hi,
> > > > > > >
> > > > > > > On 16/04/2026 02:22, Dmitry Baryshkov wrote:
> > > > > > > > The DisplayPort standard defines a special kind of events called IRQ.
> > > > > > > > These events are used to notify DP Source about the events on the Sink
> > > > > > > > side. It is extremely important for DP MST handling, where the MST
> > > > > > > > events are reported through this IRQ.
> > > > > > > >
> > > > > > > > In case of the USB-C DP AltMode there is no actual HPD pulse, but the
> > > > > > > > events are ported through the bits in the AltMode VDOs.
> > > > > > > >
> > > > > > > > Extend the drm_connector_oob_hotplug_event() interface and report IRQ
> > > > > > > > events to the DisplayPort Sink drivers.
> > > > > > > >
> > > > > > > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> > > > > > > > ---
> > > > > > > > drivers/gpu/drm/drm_connector.c | 4 +++-
> > > > > > > > drivers/usb/typec/altmodes/displayport.c | 12 ++++++++----
> > > > > > > > include/drm/drm_connector.h | 3 ++-
> > > > > > > > 3 files changed, 13 insertions(+), 6 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > > > > > > > index 47dc53c4a738..5fdacbd84bd7 100644
> > > > > > > > --- a/drivers/gpu/drm/drm_connector.c
> > > > > > > > +++ b/drivers/gpu/drm/drm_connector.c
> > > > > > > > @@ -3510,6 +3510,7 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> > > > > > > > * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector
> > > > > > > > * @connector_fwnode: fwnode_handle to report the event on
> > > > > > > > * @status: hot plug detect logical state
> > > > > > > > + * @irq_hpd: HPD pulse detected
> > > > > > > > *
> > > > > > > > * On some hardware a hotplug event notification may come from outside the display
> > > > > > > > * driver / device. An example of this is some USB Type-C setups where the hardware
> > > > > > > > @@ -3520,7 +3521,8 @@ struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> > > > > > > > * a drm_connector reference through calling drm_connector_find_by_fwnode().
> > > > > > > > */
> > > > > > > > void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
> > > > > > > > - enum drm_connector_status status)
> > > > > > > > + enum drm_connector_status status,
> > > > > > > > + bool irq_hpd)
> > > > > > > I find the "IRQ HPD" naming always confusing, even if I'm somewhat familiar
> > > > > > > with DP, but if someone has mainly worked on HDMI, I'm sure it's even worse.
> > > > > > >
> > > > > > > Can we define this a bit more precisely? Is 'irq_hpd' only for displayport?
> > > > > > > If so, perhaps 'dp_irq_hpd' or 'displayport_irq_hpd'. I might even call it
> > > > > > > 'dp_hpd_pulse', but maybe that's not good as the spec talks about HPD pulse
> > > > > > > for both short and long ones (although in the kernel doc you just write "HPD
> > > > > > > pulse")... The kernel doc could be expanded a bit to make it clear what this
> > > > > > > flag indicates.
> > > > > >
> > > > > > I attempted to stay away from defining a DP-specific flag, keeping it
> > > > > > generic enough. HDMI is pretty close (IMO) to requiring separate flag in
> > > > >
> > > > > If it's not specifically the DP IRQ HPD, then we need to define what it
> > > > > means. I tried to think what it would mean with HDMI, but I didn't come up
> > > > > with anything.
> > > >
> > > > I might be mistaken, but I had someting like HEAC HPD / EDID status
> > > > changes in mind (or HDCP-triggered HPD status changes). But here I
> > > > admit, I hadn't checked if it is actually applicable or not.
> > >
> > > Possibly, I'm not familiar with those.
> > >
> > > > Anyway, for e.g. DVI or VGA that means nothing. But, my point really is
> > > > to abstain from defining someting as DP-only in the top-level API.
> > >
> > > I'm fine with that, but then it really has to be defined =).
> > >
> > > > > > Linux. Likewise I'd rather not use "pulse". The DP AltMode defines a bit
> > > > > > in the VDO rather than a pulse.
> > > > > >
> > > > > > Anyway, if irq_hpd doesn't sound precise enough, what about "bool
> > > > > > extra_irq"? This would convey that this is the extra hpd-related IRQ,
> > > > > > but it would also be obvious that it's not related to the HPD pin
> > > > > > itself.
> > > > > We'd still need to define what exactly it means. I think it might be better
> > > > > to just define it as the DP IRQ HPD, as then the meaning is clear.
> > > > >
> > > > > Also, would an enum flags parameter be better than a bool parameter?
> > > >
> > > > Maybe not enum, but u32 param. Then it can become:
> > > >
> > > > @extra_status: additional type-specific information provided by the sink
> > > > without changing the HPD state
> > > >
> > > > void drm_connector_oob_hotplug_event(..., u32 extra_status);
> > > >
> > > > /* DP short HPD pulse or corresponding AltMode flag */
> > > > #define DRM_CONNECTOR_OOB_DP_IRQ_HPD BIT(0)
> > > > /* DP long HPD pulse, debounced XXX: do we need this? */
> > > > #define DRM_CONNECTOR_OOB_DP_REPLUG BIT(1)
> > >
> > > Why is u32 better than enum? So that we could e.g. pass short values inside
> > > the extra_status?
> >
> > No, my thought was to be able to define values specific to the
> > particular connector types and to be able to combine those values.
> >
> > After sending the email I started thinking about the bridged and
> > corresponding notifications. There having overlapping values will not
> > work becasue bridges in the chanin don't easily know the final connector
> > type.
>
> An enum can have overlapping values. I don't think there's much difference
> between u32 and an enum in C. I just like enum because 1) it groups the
> possible values in the header file, and 2) the function parameters can use
> the enum type, making it obvious what flags you are supposed to use there.
>
> > I think you are correct here, it should be the enum. With the first
> > iteration defined as:
> >
> > /**
> > * enum drm_connector_status_extra - additional events sent by the sink
> > * together or in replacement of the HPD status changes
> > /
> > enum drm_connector_status_extra {
> > /**
> > * @DRM_CONNECTOR_DP_IRQ_HPD: DisplayPort Sink has sent the
> > * IRQ_HPD (either by the HPD short pulse or via the AltMode event).
> > */
> > DRM_CONNECTOR_DP_IRQ_HPD = BIT(0),
> > };
> >
> > /**
> > * @extra_status: additional information provided by the sink without
> > * changing the HPD state (or in addition to such a change). It is an
> > * OR of the values defined in the drm_connector_status_extra enum.
> > */
> > void drm_connector_oob_hotplug_event(..., u32 extra_status);
>
> Looks good to me, except I'd use "enum drm_connector_status_extra" instead
> of u32 there in the function parameters.
I had bad feelings about passing OR or enum values as an enum value.
But then... I don't see values to OR. All expected events come one by
one. Let's drop that part too. Thanks for your comments!
>
> Tomi
>
>
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH v3 2/3] remoteproc: imx_rproc: Program non-zero SM CPU/LMM reset vector
From: Daniel Baluta @ 2026-04-20 12:28 UTC (permalink / raw)
To: Peng Fan (OSS)
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta,
linux-remoteproc, devicetree, imx, linux-arm-kernel, linux-kernel,
Peng Fan
In-Reply-To: <20260415-imx943-rproc-v3-2-9fa7528db8ca@nxp.com>
On Wed, Apr 15, 2026 at 10:49 AM Peng Fan (OSS) <peng.fan@oss.nxp.com> wrote:
>
> From: Peng Fan <peng.fan@nxp.com>
>
> Cortex-M[7,33] processors use a fixed reset vector table format:
>
> 0x00 Initial SP value
> 0x04 Reset vector
> 0x08 NMI
> 0x0C ...
> ...
> IRQ[n]
>
> In ELF images, the corresponding layout is:
>
> reset_vectors: --> hardware reset address
> .word __stack_end__
> .word Reset_Handler
> .word NMI_Handler
> .word HardFault_Handler
> ...
> .word UART_IRQHandler
> .word SPI_IRQHandler
> ...
>
> Reset_Handler: --> ELF entry point address
> ...
>
> The hardware fetches the first two words from reset_vectors and populates
> SP with __stack_end__ and PC with Reset_Handler. Execution proceeds from
> Reset_Handler.
>
> However, the ELF entry point does not always match the hardware reset
> address. For example, on i.MX94 CM33S:
>
> ELF entry point: 0x0ffc211d
> hardware reset base: 0x0ffc0000 (default reset value, sw programmable)
>
> Current driver always programs the reset vector as 0. But i.MX94 CM33S's
> default reset base is 0x0ffc0000, so the correct reset vector must be
> passed to the SM API; otherwise the M33 Sync core cannot boot successfully.
>
> rproc_elf_get_boot_addr() returns the ELF entry point, which is not the
> hardware reset vector address. Fix the issue by deriving the hardware reset
> vector locally using a SoC-specific mask:
>
> reset_vector = rproc->bootaddr & reset_vector_mask
>
> The ELF entry point semantics remain unchanged. The masking is applied only
> at the point where the SM reset vector is programmed.
>
> Add reset_vector_mask = GENMASK_U32(31, 16) to the i.MX95 M7 configuration
> so the hardware reset vector is derived correctly. Without this mask, the
> SM reset vector would be programmed with an unaligned ELF entry point and
> the M7 core would fail to boot.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
^ permalink raw reply
* Re: [PATCH v3 7/8] sframe: Introduce in-kernel SFRAME_VALIDATION.
From: Jens Remus @ 2026-04-20 12:30 UTC (permalink / raw)
To: Dylan Hatch, Indu Bhagat
Cc: Roman Gushchin, Weinan Liu, Will Deacon, Josh Poimboeuf,
Indu Bhagat, Peter Zijlstra, Steven Rostedt, Catalin Marinas,
Jiri Kosina, Mark Rutland, Prasanna Kumar T S M, Puranjay Mohan,
Song Liu, joe.lawrence, linux-toolchains, linux-kernel,
live-patching, linux-arm-kernel, Heiko Carstens
In-Reply-To: <CADBMgpzbEGTm-sZ71a5hvFOHbu5VgSR406F3NsMLF1+oDWbO6A@mail.gmail.com>
On 4/20/2026 7:02 AM, Dylan Hatch wrote:
> On Thu, Apr 16, 2026 at 8:04 AM Jens Remus <jremus@linux.ibm.com> wrote:
>> On 4/6/2026 8:49 PM, Dylan Hatch wrote:
>>> Generalize the __safe* helpers to support a non-user-access code path.
>>> Allow for kernel FDE read failures due to the presence of .rodata.text.
>>> This section contains code that can't be executed by the kernel
>>> direclty, and thus lies ouside the normal kernel-text bounds.
>>
>> Nits: s/direclty/directly/ s/ouside/outside/
>>
>> Could you please explain the issue? How/why does .sframe for
>> .rodata.text pose an issue for .sframe verification?
>
> __read_fde checks that the fde_addr it extracts is within the bounds
> of sec->text_start and sec->text_end. In the case of the vmlinux
Looking at the existing check in __read_fde(), do you agree that it is
wrong, as sec->text_end IIUC points behind .text and thus the check
should be:
if (func_addr < sec->text_start || func_addr >= sec->text_end)
return -EINVAL;
> .sframe section, this is _stext and _etext. However on arm64, there is
> an .rodata.text section that lies outside this range. From
> arch/arm64/kernel/vmlinux.lds.S:
>
> /* code sections that are never executed via the kernel mapping */
> .rodata.text : {
> TRAMP_TEXT
> HIBERNATE_TEXT
> KEXEC_TEXT
> IDMAP_TEXT
> . = ALIGN(PAGE_SIZE);
> }
>
> So __read_fde fails for functions in this section. Under normal SFrame
> usage for unwinding, we should never need to look up a PC value in
> these functions because they will never be executed by the kernel.
> However, we still hit this error when validating all FDEs.
Thanks for the explanation! Could you please improve the commit
message, for instance as follows:
__read_fde() checks that the extracted FDE function start address is
within the bounds of the .text section start and end. In case of
vmlinux this is _stext and _etext. However on arm64, .rodata.text
resides outside this range, causing __read_fde() to fail.
> I think ideally we might prevent sframe data from being generated for
> this code (maybe from the linker script somehow?), but I don't know of
> a simple way to do this.
I dont't know of any way to exclude a single function or a whole section
from .sframe generation. The GNU linker would discard SFrame FDEs and
its FREs for discarded functions. But in this case the function itself
is not discarded. As .sframe is not generated separately per section it
is also not possible to discard e.g. .sframe.rodata.
> Alternatively, we can check for FDEs located
> in .rodata.text during validation, but this seems to only be present
> in arm64, so maybe we would need an arch-specific hook to do this? I'm
> open to suggestions.
Maybe that is better than ignoring __read_fde() failures? I first
thought this would get nasty, but maybe it would not be too bad.
Following is what I came up with (note tabs replaced by spaces due to
copy&paste from terminal):
diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
@@ -23,6 +23,7 @@ extern char __irqentry_text_start[], __irqentry_text_end[];
extern char __mmuoff_data_start[], __mmuoff_data_end[];
extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[];
+extern char _srodatatext[], _erodatatext[];
static inline size_t entry_tramp_text_size(void)
{
diff --git a/arch/arm64/include/asm/unwind_sframe.h b/arch/arm64/include/asm/unwind_sframe.h
@@ -2,11 +2,28 @@
#ifndef _ASM_ARM64_UNWIND_SFRAME_H
#define _ASM_ARM64_UNWIND_SFRAME_H
+#include <linux/sframe.h>
+
#ifdef CONFIG_ARM64
#define SFRAME_REG_SP 31
#define SFRAME_REG_FP 29
+static inline bool sframe_func_start_addr_valid(struct sframe_section *sec,
+ unsigned long func_addr)
+{
+ return (sec->text_start >= func_addr && func_addr < sec->text_end) ||
+ (sec->rodatatext_start >= func_addr && func_addr < sec->rodatatext_end);
+}
+#define sframe_func_start_addr_valid sframe_func_start_addr_valid
+
+static void arch_init_sframe_table(struct sframe_section *kernel_sfsec)
+{
+ kernel_sfsec->rodatatext_start = (unsigned long)_srodatatext;
+ kernel_sfsec->rodatatext_end = (unsigned long)_erodatatext;
+}
+#define arch_init_sframe_table arch_init_sframe_table
+
#endif
#endif /* _ASM_ARM64_UNWIND_SFRAME_H */
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
@@ -213,12 +213,14 @@ SECTIONS
/* code sections that are never executed via the kernel mapping */
.rodata.text : {
+ _srodatatext = .;
TRAMP_TEXT
HIBERNATE_TEXT
KEXEC_TEXT
IDMAP_TEXT
. = ALIGN(PAGE_SIZE);
}
+ _erodatatext = .;
idmap_pg_dir = .;
. += PAGE_SIZE;
diff --git a/include/linux/sframe.h b/include/linux/sframe.h
@@ -63,6 +63,10 @@ struct sframe_section {
unsigned long sframe_end;
unsigned long text_start;
unsigned long text_end;
+#if defined(CONFIG_SFRAME_UNWINDER) && defined(CONFIG_ARM64)
+ unsigned long rodatatext_start;
+ unsigned long rodatatext_end;
+#endif
bool fdes_sorted;
unsigned long fdes_start;
diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c
@@ -20,11 +20,23 @@
#include "sframe.h"
#include "sframe_debug.h"
+#ifndef sframe_func_start_addr_valid
+static inline bool sframe_func_start_addr_valid(struct sframe_section *sec,
+ unsigned long func_addr)
+{
+ return (sec->text_start <= func_addr && func_addr < sec->text_end);
+}
+#endif
+
#ifdef CONFIG_SFRAME_UNWINDER
static bool sframe_init __ro_after_init;
static struct sframe_section kernel_sfsec __ro_after_init;
+#ifndef arch_init_sframe_table
+static void arch_init_sframe_table(struct sframe_section *kernel_sfsec) {}
+#endif
+
#endif /* CONFIG_SFRAME_UNWINDER */
struct sframe_fde_internal {
@@ -152,7 +164,7 @@ static __always_inline int __read_fde(struct sframe_section *sec,
sizeof(struct sframe_fde_v3), Efault);
func_addr = fde_addr + _fde.func_start_off;
- if (func_addr < sec->text_start || func_addr > sec->text_end)
+ if (!sframe_func_start_addr_valid(sec, func_addr))
return -EINVAL;
fda_addr = sec->fres_start + _fde.fres_off;
@@ -696,13 +708,6 @@ static int sframe_validate_section(struct sframe_section *sec)
int ret;
ret = safe_read_fde(sec, i, &fde);
- /*
- * Code in .rodata.text is not considered part of normal kernel
- * text, but there is no easy way to prevent sframe data from
- * being generated for it.
- */
- if (ret && sec->sec_type == SFRAME_KERNEL)
- continue;
if (ret)
return ret;
@@ -1031,6 +1036,8 @@ void __init init_sframe_table(void)
if (WARN_ON(sframe_validate_section(&kernel_sfsec)))
return;
+ arch_init_sframe_table(&kernel_sfsec);
+
sframe_init = true;
}
Regards,
Jens
--
Jens Remus
Linux on Z Development (D3303)
jremus@de.ibm.com / jremus@linux.ibm.com
IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
^ permalink raw reply
* Re: [RFC PATCH 4/4] firmware: arm_ffa: check pkvm initailised when initailise ffa driver
From: Sebastian Ene @ 2026-04-20 12:32 UTC (permalink / raw)
To: Yeoreum Yun
Cc: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, zohar,
roberto.sassu, dmitry.kasatkin, eric.snowberg, peterhuewe, jarkko,
jgg, sudeep.holla, maz, oupton, joey.gouly, suzuki.poulose,
yuzenghui, catalin.marinas, will
In-Reply-To: <20260417175759.3191279-5-yeoreum.yun@arm.com>
On Fri, Apr 17, 2026 at 06:57:59PM +0100, Yeoreum Yun wrote:
Hello Yeoreum,
> When pKVM is enabled, the FF-A driver must be initialized after pKVM.
> Otherwise, pKVM cannot negotiate the FF-A version or
> obtain RX/TX buffer information, leading to failures in FF-A calls.
At the moment this already happens after you move back ffa_init() to
device_initcall().
>
> During FF-A driver initialization, check whether pKVM has been initialized.
> If not, defer probing of the FF-A driver.
>
I don't think you need to add this dependency. pKVM is
installed through KVM's module_init() which ends up calling hyp_ffa_init() to
do the proxy initialization. The ARM-FFA driver comes after it (since
pKVM is arch specific code). We don't have to call finalize_pkvm(..) to
be able to handle smc(FF-A) calls in the hyp-proxy.
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
> arch/arm64/kvm/arm.c | 1 +
> drivers/firmware/arm_ffa/driver.c | 12 ++++++++++++
> 2 files changed, 13 insertions(+)
>
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 410ffd41fd73..0f517b1c05cd 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -119,6 +119,7 @@ bool is_kvm_arm_initialised(void)
> {
> return kvm_arm_initialised;
> }
> +EXPORT_SYMBOL(is_kvm_arm_initialised);
>
> int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
> {
> diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> index 02c76ac1570b..2647d6554afd 100644
> --- a/drivers/firmware/arm_ffa/driver.c
> +++ b/drivers/firmware/arm_ffa/driver.c
> @@ -42,6 +42,8 @@
> #include <linux/uuid.h>
> #include <linux/xarray.h>
>
> +#include <asm/virt.h>
> +
> #include "common.h"
>
> #define FFA_DRIVER_VERSION FFA_VERSION_1_2
> @@ -2035,6 +2037,16 @@ static int __init ffa_init(void)
> u32 buf_sz;
> size_t rxtx_bufsz = SZ_4K;
>
> + /*
> + * When pKVM is enabled, the FF-A driver must be initialized
> + * after pKVM initialization. Otherwise, pKVM cannot negotiate
> + * the FF-A version or obtain RX/TX buffer information,
> + * which leads to failures in FF-A calls.
> + */
> + if (IS_ENABLED(CONFIG_KVM) && is_protected_kvm_enabled() &&
> + !is_kvm_arm_initialised())
> + return -EPROBE_DEFER;
> +
> ret = ffa_transport_init(&invoke_ffa_fn);
> if (ret)
> return ret;
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
>
Thanks,
Sebastian
^ permalink raw reply
* [PATCH] iommu/arm-smmu-v3: Allow disabling Stage 1 translation
From: Evangelos Petrongonas @ 2026-04-20 12:32 UTC (permalink / raw)
To: Will Deacon
Cc: Evangelos Petrongonas, Robin Murphy, Joerg Roedel,
Jason Gunthorpe, Nicolin Chen, Pranjal Shrivastava, Lu Baolu,
linux-arm-kernel, iommu, linux-kernel, nh-open-source,
Zeev Zilberman
When the hardware advertises both Stage 1 and Stage 2 translation, the
driver prefers Stage 1 for DMA domain allocation and only falls back to
Stage 2 if Stage 1 is not supported.
Some configurations may want to force Stage 2 translation even when the
hardware supports Stage 1. Introduce a module parameter 'disable_s1'
that, when set, prevents the driver from advertising
ARM_SMMU_FEAT_TRANS_S1, causing all DMA domains to use Stage 2 instead.
Co-developed-by: Zeev Zilberman <zeev@amazon.com>
Signed-off-by: Zeev Zilberman <zeev@amazon.com>
Signed-off-by: Evangelos Petrongonas <epetron@amazon.de>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index e8d7dbe495f0..afb21c210e24 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -39,6 +39,11 @@ module_param(disable_msipolling, bool, 0444);
MODULE_PARM_DESC(disable_msipolling,
"Disable MSI-based polling for CMD_SYNC completion.");
+static bool disable_s1;
+module_param(disable_s1, bool, 0444);
+MODULE_PARM_DESC(disable_s1,
+ "Disable Stage 1 translation even if supported by hardware.");
+
static const struct iommu_ops arm_smmu_ops;
static struct iommu_dirty_ops arm_smmu_dirty_ops;
@@ -5087,13 +5092,13 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
smmu->features |= ARM_SMMU_FEAT_STALLS;
}
- if (reg & IDR0_S1P)
+ if ((reg & IDR0_S1P) && !disable_s1)
smmu->features |= ARM_SMMU_FEAT_TRANS_S1;
if (reg & IDR0_S2P)
smmu->features |= ARM_SMMU_FEAT_TRANS_S2;
- if (!(reg & (IDR0_S1P | IDR0_S2P))) {
+ if (!(smmu->features & (ARM_SMMU_FEAT_TRANS_S1 | ARM_SMMU_FEAT_TRANS_S2))) {
dev_err(smmu->dev, "no translation support!\n");
return -ENXIO;
}
--
2.47.3
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597
^ permalink raw reply related
* Re: [PATCH v3 1/8] ARM: zte: Add zx297520v3 platform support
From: Linus Walleij @ 2026-04-20 12:36 UTC (permalink / raw)
To: Stefan Dösinger
Cc: linux-arm-kernel, Arnd Bergmann, Krzysztof Kozlowski, Rob Herring
In-Reply-To: <20260414211215.152850-2-stefandoesinger@gmail.com>
On Tue, Apr 14, 2026 at 11:12 PM Stefan Dösinger
<stefandoesinger@gmail.com> wrote:
> This SoC is used in low end LTE-to-WiFi routers, for example some D-Link
> DWR 932 revisions, ZTE K10, ZLT S10 4G, but also models that are branded
> and sold by ISPs themselves. They are widespread in Africa, China,
> Russia and Eastern Europe.
>
> This SoC is a relative of the zx296702 and zx296718 that had some
> upstream support until commit 89d4f98ae90d ("ARM: remove zte zx
> platform"). My eventual goal is to enable OpenWRT to run on these
> devices.
>
> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
From what I have understood the arm64 people would be fine
with having the A53 hardwired to ARM32 without VFP and NEON
as an arm32 machine because it makes their life simpler.
So from my side:
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v3 4/8] ARM: zte: Add support for zx29 low level debug
From: Linus Walleij @ 2026-04-20 12:37 UTC (permalink / raw)
To: Stefan Dösinger
Cc: linux-arm-kernel, Arnd Bergmann, Krzysztof Kozlowski, Rob Herring
In-Reply-To: <20260414211215.152850-5-stefandoesinger@gmail.com>
On Tue, Apr 14, 2026 at 11:12 PM Stefan Dösinger
<stefandoesinger@gmail.com> wrote:
> This is based on the removed zx29 code. A separate (more complicated)
> patch will re-add the register map to the pl011 serial driver.
>
> Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH] iommu/arm-smmu-v3: Allow disabling Stage 1 translation
From: Jason Gunthorpe @ 2026-04-20 12:40 UTC (permalink / raw)
To: Evangelos Petrongonas
Cc: Will Deacon, Robin Murphy, Joerg Roedel, Nicolin Chen,
Pranjal Shrivastava, Lu Baolu, linux-arm-kernel, iommu,
linux-kernel, nh-open-source, Zeev Zilberman
In-Reply-To: <20260420123221.20801-1-epetron@amazon.de>
On Mon, Apr 20, 2026 at 12:32:01PM +0000, Evangelos Petrongonas wrote:
> When the hardware advertises both Stage 1 and Stage 2 translation, the
> driver prefers Stage 1 for DMA domain allocation and only falls back to
> Stage 2 if Stage 1 is not supported.
>
> Some configurations may want to force Stage 2 translation even when the
> hardware supports Stage 1.
Why? You really need to explain why for a patch like this.
If there really is some HW issue I think it is more appropriate to get
an IORT flag or IDR detection that the HW has a problem.
Jason
^ permalink raw reply
* [PATCH RFC] arm64/irqflags: force inline of arch_local_irq_enable()
From: Breno Leitao @ 2026-04-20 12:42 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon
Cc: leo.bras, mark.rutland, leo.yan, linux-arm-kernel, linux-kernel,
palmer, paulmck, puranjay, usama.arif, kernel-team, Breno Leitao
arch_local_irq_enable() is a small wrapper that dispatches between two
unmask paths: __daif_local_irq_enable() on most systems, and
__pmr_local_irq_enable() on builds that use GIC PMR-based masking
(Pseudo-NMI). Both leaf primitives are already __always_inline; the
wrapper itself is plain "static inline".
In practice the compiler does not always inline the wrapper. When it
gets emitted out-of-line, samples taken inside it during the post-WFI
IRQ unmask in default_idle_call() show up as arch_local_irq_enable
overhead in profiles, with default_idle_call() lost from the unwound
chain.
This matters most at fleet scale. On a large arm64 fleet, the
aggregate effect is that idle CPUs show up in fleet-wide profilers as
"busy stuck in arch_local_irq_enable" instead of as idle
(default_idle_call / cpu_startup_entry). Engineers looking at
fleet-wide top-symbol dashboards see what looks like significant
CPU-bound work in IRQ unmasking and chase a phantom hot path, when in
fact the cost is the WFI wake-up cycle being attributed to the wrong
function. Tooling has to special-case this symbol to suppress it,
which is fragile across kernel versions. Inlining the wrapper makes
idle CPUs appear idle in profiles - which is what they are.
The same misattribution affects driver stalls. arm64 PMU overflow is
delivered as a regular IRQ (no NMI on default builds), so a driver
that holds local_irq_disable() for milliseconds defers every PMU
sample to the moment it calls local_irq_enable(). With the wrapper
out-of-line, the resulting fat sample is credited to
arch_local_irq_enable rather than to the driver, and the FP-unwinder
points the call chain at the driver's caller instead of the driver
itself (the immediate caller is skipped because arch_local_irq_enable
is a leaf with no saved frame). The driver is still visible in the
profile from its other samples, but the stall cost itself is
mis-attributed and the chain leading to it is one frame off, making
fleet-wide root-cause analysis harder than it needs to be. Inlining
the wrapper attributes the stall sample to the driver function that
actually held IRQs disabled.
Trade-offs:
- Minor .text effect: every caller now expands the dispatch +
underlying primitive at its call site. system_uses_irq_prio_masking()
is a static-key check, so on non-pNMI systems the inlined body
collapses to a single MSR daifclr; on pNMI systems it collapses to a
single sysreg write.
- Loss of a debugging convenience: there is no longer an
arch_local_irq_enable symbol to set a breakpoint on. Callers must be
targeted individually.
- Compiler trust: __always_inline overrides size heuristics. The body
is small enough that this should be unobjectionable, but it is a
policy change.
This patch only flips arch_local_irq_enable(). The same reasoning
applies to arch_local_irq_disable()/save()/restore() which share the
identical static-inline-wrapper-around-__always_inline-primitives
pattern. Holding those off until profiles motivate them.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
arch/arm64/include/asm/irqflags.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index d4d7451c2c129..505ef5be53a71 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -40,7 +40,7 @@ static __always_inline void __pmr_local_irq_enable(void)
barrier();
}
-static inline void arch_local_irq_enable(void)
+static __always_inline void arch_local_irq_enable(void)
{
if (system_uses_irq_prio_masking()) {
__pmr_local_irq_enable();
---
base-commit: 615aad0f61e0c7a898184a394dc895c610100d4f
change-id: 20260420-arm64_always_inline-6bc9dd3c17e6
Best regards,
--
Breno Leitao <leitao@debian.org>
^ 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