* Re: [PATCH v2 00/15] var-som-6ul: improve support for variants
From: Hugo Villeneuve @ 2026-04-23 13:44 UTC (permalink / raw)
To: Hugo Villeneuve
Cc: robh, krzk+dt, conor+dt, andrzej.hajda, neil.armstrong, rfoss,
Laurent.pinchart, jonas, jernej.skrabec, maarten.lankhorst,
mripard, tzimmermann, airlied, simona, Frank.Li, s.hauer, kernel,
festevam, shawnguo, laurent.pinchart+renesas, antonin.godard,
devicetree, linux-kernel, dri-devel, imx, linux-arm-kernel,
Hugo Villeneuve
In-Reply-To: <20260305180651.1827087-1-hugo@hugovil.com>
On Thu, 5 Mar 2026 13:06:15 -0500
Hugo Villeneuve <hugo@hugovil.com> wrote:
> From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
>
> Hello,
> this patch series improves support for Variscite VAR-SOM-6UL based boards.
Hi,
simple ping to know if anything is missing for this series to be
applied/picked-up?
Hugo.
>
> The first two patches fix DT/dmesg warnings.
>
> The next patches fix the incorrect use of VAR-SOM-MX6UL to refer to the
> VAR-SOM-6UL.
>
> The next patches add support for the imx6ull CPU variant of the VAR-SOM-6UL.
>
> Then improves/fixes the following features/options that are currently not
> working on the concerto EVK board:
> - ethernet ports ENET1
> - LVDS display panel
> - Wifi/Bt
>
> Note that the previous configuration of the optional Wifi/Bluetooth module
> was copied from the original Variscite kernel tree, and required custom
> shell scripts to properly configure the Wifi/Bluetooth module.
>
> Also factor out optional features into separate DTSI include files, so it will
> be easier to support them for other boards, and to make sure they are not
> unconditionnally enabled.
>
> I have tested these changes on a Variscite concerto EVK board using a
> VAR-SOM-6UL with the following options:
> - EC (ethernet phy on SOM)
> - LD (LVDS encoder assembled on SOM)
> - WBD (Wi-Fi 802.11 ac/a/b/g/n and Bluetooth 5.2/BLE on SOM)
> Result of tests:
> - Both ethernet ports Ok
> - LVDS display panel Ok
> - Wifi/Bt Ok
>
> Also tested on a custom board with a VAR-SOM-6UL SOM (will be submitted in
> a future series).
>
> Thank you.
>
> Link: [v1] https://lore.kernel.org/all/20260302190953.669325-1-hugo@hugovil.com/
>
> Changes for v2:
> - Place imx6ull-var-som-concerto.dtb in alphabetical order (Frank)
> - s/include/dtsi in commit msgs (Frank)
> - Clarify and improve patches to change VAR-SOM-MX6UL (Krzysztof)
> - Collect tags for some acked patches (Krzysztof)
> - Reorder pinctrl_gpio_leds in separate patch (Frank)
> - Improve git commit messages ((Frank)/Krzysztof)
>
> Hugo Villeneuve (15):
> ARM: dts: imx6ul-var-som: fix warning for non-existent dc-supply
> property
> ARM: dts: imx6ul-var-som: fix warning for boolean property with a
> value
> ARM: dts: imx6ul-var-som: change incorrect VAR-SOM-MX6UL references
> dt-bindings: arm: fsl: change incorrect VAR-SOM-MX6UL references
> dt-bindings: arm: fsl: add variscite,var-som-imx6ull
> ARM: dts: imx6ul-var-som: Factor out common parts for all CPU variants
> ARM: dts: imx6ul-var-som-concerto: Factor out common parts for all CPU
> variants
> ARM: dts: imx6ul-var-som-concerto: order DT properties
> ARM: dts: imx6ul-var-som: factor out SD card support
> ARM: dts: imx6ul-var-som: add proper Wifi and Bluetooth support
> ARM: dts: imx6ul-var-som: factor out ENET2 ethernet support
> ARM: dts: imx6ul-var-som: add support for EC configuration option
> (ENET1)
> ARM: dts: imx6ul-var-som: factor out audio support
> dt-bindings: display/lvds-codec: add ti,sn65lvds93
> ARM: dts: imx6ul-var-som: add support for LVDS display panel
>
> .../devicetree/bindings/arm/fsl.yaml | 8 +-
> .../bindings/display/bridge/lvds-codec.yaml | 1 +
> arch/arm/boot/dts/nxp/imx/Makefile | 3 +
> .../dts/nxp/imx/imx6ul-var-som-audio.dtsi | 30 ++
> ...ar-som.dtsi => imx6ul-var-som-common.dtsi} | 140 +++-----
> ...ts => imx6ul-var-som-concerto-common.dtsi} | 159 ++-------
> .../nxp/imx/imx6ul-var-som-concerto-full.dts | 22 ++
> .../dts/nxp/imx/imx6ul-var-som-concerto.dts | 318 +-----------------
> .../dts/nxp/imx/imx6ul-var-som-enet1.dtsi | 44 +++
> .../dts/nxp/imx/imx6ul-var-som-enet2.dtsi | 79 +++++
> .../nxp/imx/imx6ul-var-som-lvds-panel.dtsi | 112 ++++++
> .../boot/dts/nxp/imx/imx6ul-var-som-sd.dtsi | 27 ++
> .../boot/dts/nxp/imx/imx6ul-var-som-wifi.dtsi | 75 +++++
> arch/arm/boot/dts/nxp/imx/imx6ul-var-som.dtsi | 219 +-----------
> .../nxp/imx/imx6ull-var-som-concerto-full.dts | 22 ++
> .../dts/nxp/imx/imx6ull-var-som-concerto.dts | 21 ++
> .../arm/boot/dts/nxp/imx/imx6ull-var-som.dtsi | 36 ++
> 17 files changed, 575 insertions(+), 741 deletions(-)
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ul-var-som-audio.dtsi
> copy arch/arm/boot/dts/nxp/imx/{imx6ul-var-som.dtsi => imx6ul-var-som-common.dtsi} (60%)
> copy arch/arm/boot/dts/nxp/imx/{imx6ul-var-som-concerto.dts => imx6ul-var-som-concerto-common.dtsi} (50%)
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ul-var-som-concerto-full.dts
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ul-var-som-enet1.dtsi
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ul-var-som-enet2.dtsi
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ul-var-som-lvds-panel.dtsi
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ul-var-som-sd.dtsi
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ul-var-som-wifi.dtsi
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-var-som-concerto-full.dts
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-var-som-concerto.dts
> create mode 100644 arch/arm/boot/dts/nxp/imx/imx6ull-var-som.dtsi
>
>
> base-commit: c107785c7e8dbabd1c18301a1c362544b5786282
> --
> 2.47.3
>
>
--
Hugo Villeneuve
^ permalink raw reply
* [PATCH v2] arm64: smp: Do not mark secondary CPUs possible under nosmp
From: Pengjie Zhang @ 2026-04-23 13:46 UTC (permalink / raw)
To: catalin.marinas, will
Cc: maz, timothy.hayes, lpieralisi, mrigendra.chaubey, arnd,
linux-arm-kernel, linux-kernel, zhanjie9, zhenglifeng1, lihuisong,
yubowen8, linhongye, linuxarm, zhangpengjie2, wangzhi12
Under nosmp (maxcpus=0), arm64 never brings up secondary CPUs.
However, arm64 still enumerates firmware-described CPUs during SMP
initialization, which can leave secondary CPUs visible to
for_each_possible_cpu() users even though they never reach the
bringup path in this configuration.
This is not just a cosmetic mask mismatch: code iterating over
possible CPUs may observe secondary CPU per-CPU state that is never
fully initialized under nosmp.
Return early from smp_init_cpus() when nosmp/maxcpus=0 is in effect
so that secondary CPUs are not marked possible on arm64.
Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Pengjie Zhang <zhangpengjie2@huawei.com>
---
Changes in v2:
- Drop the arch_disable_smp_support() approach.
- Handle nosmp/maxcpus=0 directly in smp_init_cpus().
- Update the changelog accordingly.
Link to v1:https://lore.kernel.org/all/20260422095831.2926775-1-zhangpengjie2@huawei.com/
---
arch/arm64/kernel/smp.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 1aa324104afb..1b63846f646a 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -745,15 +745,21 @@ void __init smp_init_cpus(void)
else
acpi_parse_and_init_cpus();
- if (cpu_count > nr_cpu_ids)
- pr_warn("Number of cores (%d) exceeds configured maximum of %u - clipping\n",
- cpu_count, nr_cpu_ids);
-
if (!bootcpu_valid) {
pr_err("missing boot CPU MPIDR, not enabling secondaries\n");
return;
}
+ /*
+ * For the nosmp/maxcpus=0 case, do not mark the secondary CPUs
+ * possible.
+ */
+ if (!setup_max_cpus)
+ return;
+
+ if (cpu_count > nr_cpu_ids)
+ pr_warn("Number of cores (%d) exceeds configured maximum of %u - clipping\n",
+ cpu_count, nr_cpu_ids);
/*
* We need to set the cpu_logical_map entries before enabling
* the cpus so that cpu processor description entries (DT cpu nodes
--
2.33.0
^ permalink raw reply related
* Re: [PATCH v13 0/4] Enable Remote GPIO over RPMSG on i.MX Platform
From: Andrew Lunn @ 2026-04-23 13:53 UTC (permalink / raw)
To: Mathieu Poirier
Cc: Shenwei Wang, Linus Walleij, Bartosz Golaszewski, Jonathan Corbet,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Frank Li, Sascha Hauer, Shuah Khan, linux-gpio, linux-doc,
linux-kernel, Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
devicetree, linux-remoteproc, imx, linux-arm-kernel, linux-imx
In-Reply-To: <CANLsYkypRaFTTP7MLLLR+=AB5JnRTA4i130qvWzB1qoAuM9FWQ@mail.gmail.com>
On Thu, Apr 23, 2026 at 06:53:12AM -0600, Mathieu Poirier wrote:
> Once again Andrew Lunn was left out.
>
> On Wed, 22 Apr 2026 at 15:29, Shenwei Wang <shenwei.wang@nxp.com> wrote:
> >
> > Support the remote devices on the remote processor via the RPMSG bus on
> > i.MX platform.
> >
> > Changes in v13:
> > - drop the support for legacy NXP firmware.
> > - remove the fixed_up hooks from the rpmsg gpio driver.
> > - code cleanup.
That looks like a step forward. Now we don't care about legacy NXP
firmware, it makes it easier to make bigger changes, like use the
messages format from gpio-virtio.
Andrew
^ permalink raw reply
* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Yeoreum Yun @ 2026-04-23 13:55 UTC (permalink / raw)
To: Mimi Zohar
Cc: Jonathan McDowell, linux-security-module, linux-kernel,
linux-integrity, linux-arm-kernel, kvmarm, paul, jmorris, serge,
roberto.sassu, dmitry.kasatkin, eric.snowberg, jarkko, jgg,
sudeep.holla, maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, noodles, sebastianene
In-Reply-To: <bd908e28298d968740d03c97bc7e441de188b7b4.camel@linux.ibm.com>
> On Thu, 2026-04-23 at 13:53 +0100, Jonathan McDowell wrote:
> > On Thu, Apr 23, 2026 at 01:34:13PM +0100, Yeoreum Yun wrote:
> > > > > On Thu, 2026-04-23 at 06:55 +0100, Yeoreum Yun wrote:
> > > > > > > On Wed, 2026-04-22 at 20:41 +0100, Yeoreum Yun wrote:
> > > > > > > > > Hi Mimi,
> > > > > > > > >
> > > > > > > > > > On Wed, 2026-04-22 at 17:24 +0100, Yeoreum Yun wrote:
> > > > > > > > > > > To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
> > > > > > > > > > > the TPM driver must be built as built-in and
> > > > > > > > > > > must be probed before the IMA subsystem is initialized.
> > > > > > > > > > >
> > > > > > > > > > > However, when the TPM device operates over the FF-A protocol using
> > > > > > > > > > > the CRB interface, probing fails and returns -EPROBE_DEFER if
> > > > > > > > > > > the tpm_crb_ffa device — an FF-A device that provides the communication
> > > > > > > > > > > interface to the tpm_crb driver — has not yet been probed.
> > > > > > > > > > >
> > > > > > > > > > > To ensure the TPM device operating over the FF-A protocol with
> > > > > > > > > > > the CRB interface is probed before IMA initialization,
> > > > > > > > > > > the following conditions must be met:
> > > > > > > > > > >
> > > > > > > > > > > 1. The corresponding ffa_device must be registered,
> > > > > > > > > > > which is done via ffa_init().
> > > > > > > > > > >
> > > > > > > > > > > 2. The tpm_crb_driver must successfully probe this device via
> > > > > > > > > > > tpm_crb_ffa_init().
> > > > > > > > > > >
> > > > > > > > > > > 3. The tpm_crb driver using CRB over FF-A can then
> > > > > > > > > > > be probed successfully. (See crb_acpi_add() and
> > > > > > > > > > > tpm_crb_ffa_init() for reference.)
> > > > > > > > > > >
> > > > > > > > > > > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
> > > > > > > > > > > all registered with device_initcall, which means crb_acpi_driver_init() may
> > > > > > > > > > > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
> > > > > > > > > > >
> > > > > > > > > > > When this occurs, probing the TPM device is deferred.
> > > > > > > > > > > However, the deferred probe can happen after the IMA subsystem
> > > > > > > > > > > has already been initialized, since IMA initialization is performed
> > > > > > > > > > > during late_initcall, and deferred_probe_initcall() is performed
> > > > > > > > > > > at the same level.
> > > > > > > > > > >
> > > > > > > > > > > To resolve this, call ima_init() again at late_inicall_sync level
> > > > > > > > > > > so that let IMA not miss TPM PCR value when generating boot_aggregate
> > > > > > > > > > > log though TPM device presents in the system.
> > > > > > > > > > >
> > > > > > > > > > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> > > > > > > > > >
> > > > > > > > > > A lot of change for just detecting whether ima_init() is being called on
> > > > > > > > > > late_initcall or late_initcall_sync(), without any explanation for all the other
> > > > > > > > > > changes (e.g. ima_init_core).
> > > > > > > > > >
> > > > > > > > > > Please just limit the change to just calling ima_init() twice.
> > > > > > > > >
> > > > > > > > > My concern is that ima_update_policy_flags() will be called
> > > > > > > > > when ima_init() is deferred -- not initialised anything.
> > > > > > > > > though functionally, it might be okay however,
> > > > > > > > > I think ima_update_policy_flags() and notifier should work after ima_init()
> > > > > > > > > works logically.
> > > > > > > > >
> > > > > > > > > This change I think not much quite a lot. just wrapper ima_init() with
> > > > > > > > > ima_init_core() with some error handling.
> > > > > > > > >
> > > > > > > > > Am I missing something?
> > > > > > > >
> > > > > > > > Also, if we handle in ima_init() only, but it failed with other reason,
> > > > > > > > we shouldn't call again ima_init() in the late_initcall_sync.
> > > > > > > >
> > > > > > > > To handle this, It wouldn't do in the ima_init() but we need to handle
> > > > > > > > it by caller of ima_init().
> > > > > > >
> > > > > > > Only tpm_default_chip() is being called to set the ima_tpm_chip. On failure,
> > > > > > > instead of going into TPM-bypass mode, return immediately. There are no calls
> > > > > > > to anything else. Just call ima_init() a second time.
> > > > > >
> > > > > > I’m not fully convinced this is sufficient.
> > > > > >
> > > > > > What I meant is the case where ima_init() fails due to other
> > > > > > initialisation steps, not only tpm_default_chip() (e.g. ima_fs_init()).
> > > > >
> > > > > The purpose of THIS patch is to add late_initcall_sync, when the TPM is not
> > > > > available at late_initcall. This would be classified as a bug fix and would be
> > > > > backported. No other changes should be included in this patch.
> > > >
> > > > Okay.
> > > >
> > > > > >
> > > > > > I’d also like to ask again whether it is fine to call
> > > > > > ima_update_policy_flags() and keep the notifier registered in the
> > > > > > deferred TPM case. While this may be functionally acceptable, it seems
> > > > > > logically questionable to do so when ima_init() has not completed.
> > > > >
> > > > > Other than extending the TPM, IMA should behave exactly the same whether there
> > > > > is a TPM or goes into TPM-bypass mode.
> > > > >
> > > > > >
> > > > > > There is also a possibility that a deferred case ultimately fails (e.g.
> > > > > > deferred at late_initcall, but then failing at late_initcall_sync
> > > > > > for another reason, even while entering TPM bypass mode). In that case,
> > > > > > it seems more appropriate to handle this state in the caller of
> > > > > > ima_init(), rather than inside ima_init() itself.
> > > > >
> > > > > If the TPM isn't found at late_initcall_sync(), then IMA should go into TPM-
> > > > > bypass mode. Please don't make any other changes to the existing IMA behavior
> > > > > and hide it here behind the late_initcall_sync change.
> > > >
> > > > Okay. you're talking called ima_update_policy_flags() at late_initcall
> > > > wouldn't be not a problem even in case of late_initcall_sync's ima_init()
> > > > get failed with "TPM-bypass mode".
> > > >
> > > > I see then, I'll make a patch simpler then.
> > >
> > > But I think in case of below situation:
> > > - late_initcall's first ima_init() is deferred.
> > > - late_initcall_sync try again but failed and try again with
> > > CONFIG_IMA_DEFAULT_HASH.
> > >
> > > I would like to sustain init_ima_core to reduce the same code repeat
> > > in late_initcall_sync.
> >
> > I think what Mimi's proposing is:
> >
> > If we're in late_initcall, and the TPM isn't available, return
> > immediately with an error (the EPROBE_DEFER?), don't do any init.
> >
> > If we're in late_initcall_sync, either we're already initialised, so do
> > return and nothing, or run through the entire flow, even if the TPM
> > isn't unavailable.
> >
> > So ima_init() just needs to know a) if it's in the sync or non-sync mode
> > and b) for the sync mode, if we've already done the init at
> > non-sync.
>
> Thanks, Jonathan. That is exactly what I'm suggesting. Any other changes
> should not be included in this patch. Since Yeoreum is not hearing me, feel
> free to post a patch.
I see. so what you need to is this only
If it looks good to you. I'll send it at v3.
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d48bf0ad26f4..88fe105b7f00 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -166,6 +166,7 @@ enum lsm_order {
* @initcall_fs: LSM callback for fs_initcall setup, optional
* @initcall_device: LSM callback for device_initcall() setup, optional
* @initcall_late: LSM callback for late_initcall() setup, optional
+ * @initcall_late_sync: LSM callback for late_initcall_sync() setup, optional
*/
struct lsm_info {
const struct lsm_id *id;
@@ -181,6 +182,7 @@ struct lsm_info {
int (*initcall_fs)(void);
int (*initcall_device)(void);
int (*initcall_late)(void);
+ int (*initcall_late_sync)(void);
};
#define DEFINE_LSM(lsm) \
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index a2f34f2d8ad7..334fa8927c45 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -118,10 +118,22 @@ void __init ima_load_x509(void)
int __init ima_init(void)
{
int rc;
+ static bool deferred = false;
+ static bool initialised = false;
+
+ if (initialised)
+ return 0;
ima_tpm_chip = tpm_default_chip();
- if (!ima_tpm_chip)
+ if (!ima_tpm_chip) {
+ if (!deferred) {
+ pr_info("Defer initialisation to the late_initcall_sync stage.\n");
+ deferred = true;
+ return 0;
+ }
+
pr_info("No TPM chip found, activating TPM-bypass!\n");
+ }
rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
if (rc)
@@ -158,5 +170,7 @@ int __init ima_init(void)
UTS_RELEASE, strlen(UTS_RELEASE), false,
NULL, 0);
+ initialised = true;
+
return rc;
}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 1d6229b156fb..847ec74a183d 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -1274,6 +1274,11 @@ static int __init init_ima(void)
return error;
}
+static int __init late_init_ima(void)
+{
+ return ima_init();
+}
+
static struct security_hook_list ima_hooks[] __ro_after_init = {
LSM_HOOK_INIT(bprm_check_security, ima_bprm_check),
LSM_HOOK_INIT(bprm_creds_for_exec, ima_bprm_creds_for_exec),
@@ -1321,4 +1326,6 @@ DEFINE_LSM(ima) = {
.blobs = &ima_blob_sizes,
/* Start IMA after the TPM is available */
.initcall_late = init_ima,
+ /* Start IMA late in case of probing TPM is deferred. */
+ .initcall_late_sync = late_init_ima,
};
diff --git a/security/lsm_init.c b/security/lsm_init.c
index 573e2a7250c4..4e5c59beb82a 100644
--- a/security/lsm_init.c
+++ b/security/lsm_init.c
@@ -547,13 +547,22 @@ device_initcall(security_initcall_device);
* security_initcall_late - Run the LSM late initcalls
*/
static int __init security_initcall_late(void)
+{
+ return lsm_initcall(late);
+}
+late_initcall(security_initcall_late);
+
+/**
+ * security_initcall_late_sync - Run the LSM late initcalls sync
+ */
+static int __init security_initcall_late_sync(void)
{
int rc;
- rc = lsm_initcall(late);
+ rc = lsm_initcall(late_sync);
lsm_pr_dbg("all enabled LSMs fully activated\n");
call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL);
return rc;
}
-late_initcall(security_initcall_late);
+late_initcall_sync(security_initcall_late_sync);
...skipping...
+
pr_info("No TPM chip found, activating TPM-bypass!\n");
+ }
rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
if (rc)
@@ -158,5 +170,7 @@ int __init ima_init(void)
UTS_RELEASE, strlen(UTS_RELEASE), false,
NULL, 0);
+ initialised = true;
+
return rc;
}
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 1d6229b156fb..847ec74a183d 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -1274,6 +1274,11 @@ static int __init init_ima(void)
return error;
}
+static int __init late_init_ima(void)
+{
+ return ima_init();
+}
+
static struct security_hook_list ima_hooks[] __ro_after_init = {
LSM_HOOK_INIT(bprm_check_security, ima_bprm_check),
LSM_HOOK_INIT(bprm_creds_for_exec, ima_bprm_creds_for_exec),
@@ -1321,4 +1326,6 @@ DEFINE_LSM(ima) = {
.blobs = &ima_blob_sizes,
/* Start IMA after the TPM is available */
.initcall_late = init_ima,
+ /* Start IMA late in case of probing TPM is deferred. */
+ .initcall_late_sync = late_init_ima,
};
diff --git a/security/lsm_init.c b/security/lsm_init.c
index 573e2a7250c4..4e5c59beb82a 100644
--- a/security/lsm_init.c
+++ b/security/lsm_init.c
@@ -547,13 +547,22 @@ device_initcall(security_initcall_device);
* security_initcall_late - Run the LSM late initcalls
*/
static int __init security_initcall_late(void)
+{
+ return lsm_initcall(late);
+}
+late_initcall(security_initcall_late);
+
+/**
+ * security_initcall_late_sync - Run the LSM late initcalls sync
+ */
+static int __init security_initcall_late_sync(void)
{
int rc;
- rc = lsm_initcall(late);
+ rc = lsm_initcall(late_sync);
lsm_pr_dbg("all enabled LSMs fully activated\n");
call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL);
return rc;
}
-late_initcall(security_initcall_late);
+late_initcall_sync(security_initcall_late_sync);
--
Sincerely,
Yeoreum Yun
^ permalink raw reply related
* Re: [PATCH v2 07/15] arm64: hyperv: Add support for mshv_vtl_return_call
From: Mark Rutland @ 2026-04-23 13:56 UTC (permalink / raw)
To: Naman Jain
Cc: K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Catalin Marinas, Will Deacon, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H . Peter Anvin, Arnd Bergmann,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Michael Kelley, Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi,
Sascha Bischoff, mrigendrachaubey, linux-hyperv, linux-arm-kernel,
linux-kernel, linux-arch, linux-riscv, vdso, ssengar
In-Reply-To: <20260423124206.2410879-8-namjain@linux.microsoft.com>
On Thu, Apr 23, 2026 at 12:41:57PM +0000, Naman Jain wrote:
> Add the arm64 variant of mshv_vtl_return_call() to support the MSHV_VTL
> driver on arm64. This function enables the transition between Virtual
> Trust Levels (VTLs) in MSHV_VTL when the kernel acts as a paravisor.
>
> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> Reviewed-by: Roman Kisel <vdso@mailbox.org>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
> arch/arm64/hyperv/Makefile | 1 +
> arch/arm64/hyperv/hv_vtl.c | 158 ++++++++++++++++++++++++++++++
> arch/arm64/include/asm/mshyperv.h | 13 +++
> arch/x86/include/asm/mshyperv.h | 2 -
> drivers/hv/mshv_vtl.h | 3 +
> include/asm-generic/mshyperv.h | 2 +
> 6 files changed, 177 insertions(+), 2 deletions(-)
> create mode 100644 arch/arm64/hyperv/hv_vtl.c
>
> diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> index 87c31c001da9..9701a837a6e1 100644
> --- a/arch/arm64/hyperv/Makefile
> +++ b/arch/arm64/hyperv/Makefile
> @@ -1,2 +1,3 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-y := hv_core.o mshyperv.o
> +obj-$(CONFIG_HYPERV_VTL_MODE) += hv_vtl.o
> diff --git a/arch/arm64/hyperv/hv_vtl.c b/arch/arm64/hyperv/hv_vtl.c
> new file mode 100644
> index 000000000000..59cbeb74e7b9
> --- /dev/null
> +++ b/arch/arm64/hyperv/hv_vtl.c
> @@ -0,0 +1,158 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2026, Microsoft, Inc.
> + *
> + * Authors:
> + * Roman Kisel <romank@linux.microsoft.com>
> + * Naman Jain <namjain@linux.microsoft.com>
> + */
> +
> +#include <asm/mshyperv.h>
> +#include <asm/neon.h>
> +#include <linux/export.h>
> +
> +void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0)
> +{
> + struct user_fpsimd_state fpsimd_state;
> + u64 base_ptr = (u64)vtl0->x;
> +
> + /*
> + * Obtain the CPU FPSIMD registers for VTL context switch.
> + * This saves the current task's FP/NEON state and allows us to
> + * safely load VTL0's FP/NEON context for the hypercall.
> + */
> + kernel_neon_begin(&fpsimd_state);
> +
> + /*
> + * VTL switch for ARM64 platform - managing VTL0's CPU context.
> + * We explicitly use the stack to save the base pointer, and use x16
> + * as our working register for accessing the context structure.
> + *
> + * Register Handling:
> + * - X0-X17: Saved/restored (general-purpose, shared for VTL communication)
> + * - X18: NOT touched - hypervisor-managed per-VTL (platform register)
> + * - X19-X30: Saved/restored (part of VTL0's execution context)
> + * - Q0-Q31: Saved/restored (128-bit NEON/floating-point registers, shared)
> + * - SP: Not in structure, hypervisor-managed per-VTL
> + *
> + * X29 (FP) and X30 (LR) are in the structure and must be saved/restored
> + * as part of VTL0's complete execution state.
> + */
> + asm __volatile__ (
> + /* Save base pointer to stack explicitly, then load into x16 */
> + "str %0, [sp, #-16]!\n\t" /* Push base pointer onto stack */
> + "mov x16, %0\n\t" /* Load base pointer into x16 */
> + /* Volatile registers (Windows ARM64 ABI: x0-x17) */
> + "ldp x0, x1, [x16]\n\t"
> + "ldp x2, x3, [x16, #(2*8)]\n\t"
> + "ldp x4, x5, [x16, #(4*8)]\n\t"
> + "ldp x6, x7, [x16, #(6*8)]\n\t"
> + "ldp x8, x9, [x16, #(8*8)]\n\t"
> + "ldp x10, x11, [x16, #(10*8)]\n\t"
> + "ldp x12, x13, [x16, #(12*8)]\n\t"
> + "ldp x14, x15, [x16, #(14*8)]\n\t"
> + /* x16 will be loaded last, after saving base pointer */
> + "ldr x17, [x16, #(17*8)]\n\t"
> + /* x18 is hypervisor-managed per-VTL - DO NOT LOAD */
> +
> + /* General-purpose registers: x19-x30 */
> + "ldp x19, x20, [x16, #(19*8)]\n\t"
> + "ldp x21, x22, [x16, #(21*8)]\n\t"
> + "ldp x23, x24, [x16, #(23*8)]\n\t"
> + "ldp x25, x26, [x16, #(25*8)]\n\t"
> + "ldp x27, x28, [x16, #(27*8)]\n\t"
> +
> + /* Frame pointer and link register */
> + "ldp x29, x30, [x16, #(29*8)]\n\t"
> +
> + /* Shared NEON/FP registers: Q0-Q31 (128-bit) */
> + "ldp q0, q1, [x16, #(32*8)]\n\t"
> + "ldp q2, q3, [x16, #(32*8 + 2*16)]\n\t"
> + "ldp q4, q5, [x16, #(32*8 + 4*16)]\n\t"
> + "ldp q6, q7, [x16, #(32*8 + 6*16)]\n\t"
> + "ldp q8, q9, [x16, #(32*8 + 8*16)]\n\t"
> + "ldp q10, q11, [x16, #(32*8 + 10*16)]\n\t"
> + "ldp q12, q13, [x16, #(32*8 + 12*16)]\n\t"
> + "ldp q14, q15, [x16, #(32*8 + 14*16)]\n\t"
> + "ldp q16, q17, [x16, #(32*8 + 16*16)]\n\t"
> + "ldp q18, q19, [x16, #(32*8 + 18*16)]\n\t"
> + "ldp q20, q21, [x16, #(32*8 + 20*16)]\n\t"
> + "ldp q22, q23, [x16, #(32*8 + 22*16)]\n\t"
> + "ldp q24, q25, [x16, #(32*8 + 24*16)]\n\t"
> + "ldp q26, q27, [x16, #(32*8 + 26*16)]\n\t"
> + "ldp q28, q29, [x16, #(32*8 + 28*16)]\n\t"
> + "ldp q30, q31, [x16, #(32*8 + 30*16)]\n\t"
> +
> + /* Now load x16 itself */
> + "ldr x16, [x16, #(16*8)]\n\t"
> +
> + /* Return to the lower VTL */
> + "hvc #3\n\t"
NAK to this.
* This is a non-SMCCC hypercall, which we have NAK'd in general in the
past for various reasons that I am not going to rehash here.
* It's not clear how this is going to be extended with necessary
architecture state in future (e.g. SVE, SME). This is not
future-proof, and I don't believe this is maintainable.
* This breaks general requirements for reliable stacktracing by
clobbering state (e.g. x29) that we depend upon being valid AT ALL
TIMES outside of entry code.
* IMO, if this needs to be saved/restored, that should happen in
whatever you are calling.
Mark.
^ permalink raw reply
* Re: [PATCH v2 3/4] ARM: dts: renesas: r8a7740: Add ZT/ZTR trace clock on R-Mobile A1
From: Krzysztof Kozlowski @ 2026-04-23 14:00 UTC (permalink / raw)
To: Marek Vasut, Marek Vasut
Cc: linux-arm-kernel, Conor Dooley, Geert Uytterhoeven,
Krzysztof Kozlowski, Magnus Damm, Michael Turquette, Rob Herring,
Stephen Boyd, devicetree, linux-clk, linux-kernel,
linux-renesas-soc
In-Reply-To: <c9ef9d73-6f1b-42ea-b5f0-09fcf904c78e@mailbox.org>
On 23/04/2026 12:00, Marek Vasut wrote:
> On 4/23/26 11:26 AM, Krzysztof Kozlowski wrote:
>> On 23/04/2026 01:33, Marek Vasut wrote:
>>> On 4/21/26 10:02 AM, Krzysztof Kozlowski wrote:
>>>> On Thu, Apr 16, 2026 at 01:31:40AM +0200, Marek Vasut wrote:
>>>>> Add ZT trace bus and ZTR trace clock on the R-Mobile A1.
>>>>>
>>>>> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
>>>>> ---
>>>>> Cc: Conor Dooley <conor+dt@kernel.org>
>>>>> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
>>>>> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
>>>>> Cc: Magnus Damm <magnus.damm@gmail.com>
>>>>> Cc: Michael Turquette <mturquette@baylibre.com>
>>>>> Cc: Rob Herring <robh@kernel.org>
>>>>> Cc: Stephen Boyd <sboyd@kernel.org>
>>>>> Cc: devicetree@vger.kernel.org
>>>>> Cc: linux-clk@vger.kernel.org
>>>>> Cc: linux-kernel@vger.kernel.org
>>>>> Cc: linux-renesas-soc@vger.kernel.org
>>>>> ---
>>>>> V2: Add ztr/zt clock at the end of the list to match bindings
>>>>> ---
>>>>> arch/arm/boot/dts/renesas/r8a7740.dtsi | 2 +-
>>>>
>>>>> include/dt-bindings/clock/r8a7740-clock.h | 2 ++
>>>>
>>>> This goes to the binding patch.
>>>>
>>>> Didn't you have also a checkpatch warning?
>>> I only got this warning, but the docs 1/4 and includes 3/4 are a
>>> separate patch in this series:
>>>
>>> "
>>> WARNING: DT binding docs and includes should be a separate patch. See:
>>> Documentation/devicetree/bindings/submitting-patches.rst
>>
>> So you did not implement it... Include goes with the binding. Always.
>> Look at other commits.
> The warning says the exact opposite thing , does it not ?
>
> Maybe the warning text needs to be updated ?
The warning is shown for patches mixing stuff, like DTSI+header, so for
this context the AND means binding doc plus header are separate FROM
this patch. Not separate from each other.
To me it is clear, so I don't feel like finding different text. If you
find it unclear or confusing, you should propose something better.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2 07/15] arm64: hyperv: Add support for mshv_vtl_return_call
From: Marc Zyngier @ 2026-04-23 14:00 UTC (permalink / raw)
To: Naman Jain
Cc: K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Catalin Marinas, Will Deacon, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H . Peter Anvin, Arnd Bergmann,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Michael Kelley, Timothy Hayes, Lorenzo Pieralisi, Sascha Bischoff,
mrigendrachaubey, linux-hyperv, linux-arm-kernel, linux-kernel,
linux-arch, linux-riscv, vdso, ssengar
In-Reply-To: <20260423124206.2410879-8-namjain@linux.microsoft.com>
On Thu, 23 Apr 2026 13:41:57 +0100,
Naman Jain <namjain@linux.microsoft.com> wrote:
>
> Add the arm64 variant of mshv_vtl_return_call() to support the MSHV_VTL
> driver on arm64. This function enables the transition between Virtual
> Trust Levels (VTLs) in MSHV_VTL when the kernel acts as a paravisor.
>
> Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
> Reviewed-by: Roman Kisel <vdso@mailbox.org>
> Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
> ---
> arch/arm64/hyperv/Makefile | 1 +
> arch/arm64/hyperv/hv_vtl.c | 158 ++++++++++++++++++++++++++++++
> arch/arm64/include/asm/mshyperv.h | 13 +++
> arch/x86/include/asm/mshyperv.h | 2 -
> drivers/hv/mshv_vtl.h | 3 +
> include/asm-generic/mshyperv.h | 2 +
> 6 files changed, 177 insertions(+), 2 deletions(-)
> create mode 100644 arch/arm64/hyperv/hv_vtl.c
>
> diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> index 87c31c001da9..9701a837a6e1 100644
> --- a/arch/arm64/hyperv/Makefile
> +++ b/arch/arm64/hyperv/Makefile
> @@ -1,2 +1,3 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-y := hv_core.o mshyperv.o
> +obj-$(CONFIG_HYPERV_VTL_MODE) += hv_vtl.o
> diff --git a/arch/arm64/hyperv/hv_vtl.c b/arch/arm64/hyperv/hv_vtl.c
> new file mode 100644
> index 000000000000..59cbeb74e7b9
> --- /dev/null
> +++ b/arch/arm64/hyperv/hv_vtl.c
> @@ -0,0 +1,158 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2026, Microsoft, Inc.
> + *
> + * Authors:
> + * Roman Kisel <romank@linux.microsoft.com>
> + * Naman Jain <namjain@linux.microsoft.com>
> + */
> +
> +#include <asm/mshyperv.h>
> +#include <asm/neon.h>
> +#include <linux/export.h>
> +
> +void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0)
> +{
> + struct user_fpsimd_state fpsimd_state;
> + u64 base_ptr = (u64)vtl0->x;
> +
> + /*
> + * Obtain the CPU FPSIMD registers for VTL context switch.
> + * This saves the current task's FP/NEON state and allows us to
> + * safely load VTL0's FP/NEON context for the hypercall.
> + */
> + kernel_neon_begin(&fpsimd_state);
> +
> + /*
> + * VTL switch for ARM64 platform - managing VTL0's CPU context.
> + * We explicitly use the stack to save the base pointer, and use x16
> + * as our working register for accessing the context structure.
> + *
> + * Register Handling:
> + * - X0-X17: Saved/restored (general-purpose, shared for VTL communication)
> + * - X18: NOT touched - hypervisor-managed per-VTL (platform register)
> + * - X19-X30: Saved/restored (part of VTL0's execution context)
> + * - Q0-Q31: Saved/restored (128-bit NEON/floating-point registers, shared)
> + * - SP: Not in structure, hypervisor-managed per-VTL
> + *
> + * X29 (FP) and X30 (LR) are in the structure and must be saved/restored
> + * as part of VTL0's complete execution state.
> + */
> + asm __volatile__ (
> + /* Save base pointer to stack explicitly, then load into x16 */
> + "str %0, [sp, #-16]!\n\t" /* Push base pointer onto stack */
> + "mov x16, %0\n\t" /* Load base pointer into x16 */
> + /* Volatile registers (Windows ARM64 ABI: x0-x17) */
> + "ldp x0, x1, [x16]\n\t"
> + "ldp x2, x3, [x16, #(2*8)]\n\t"
> + "ldp x4, x5, [x16, #(4*8)]\n\t"
> + "ldp x6, x7, [x16, #(6*8)]\n\t"
> + "ldp x8, x9, [x16, #(8*8)]\n\t"
> + "ldp x10, x11, [x16, #(10*8)]\n\t"
> + "ldp x12, x13, [x16, #(12*8)]\n\t"
> + "ldp x14, x15, [x16, #(14*8)]\n\t"
> + /* x16 will be loaded last, after saving base pointer */
> + "ldr x17, [x16, #(17*8)]\n\t"
> + /* x18 is hypervisor-managed per-VTL - DO NOT LOAD */
Wut? Does it mean the kernel is not free to use x18?
> + /* General-purpose registers: x19-x30 */
> + "ldp x19, x20, [x16, #(19*8)]\n\t"
> + "ldp x21, x22, [x16, #(21*8)]\n\t"
> + "ldp x23, x24, [x16, #(23*8)]\n\t"
> + "ldp x25, x26, [x16, #(25*8)]\n\t"
> + "ldp x27, x28, [x16, #(27*8)]\n\t"
> +
> + /* Frame pointer and link register */
> + "ldp x29, x30, [x16, #(29*8)]\n\t"
> +
> + /* Shared NEON/FP registers: Q0-Q31 (128-bit) */
> + "ldp q0, q1, [x16, #(32*8)]\n\t"
> + "ldp q2, q3, [x16, #(32*8 + 2*16)]\n\t"
> + "ldp q4, q5, [x16, #(32*8 + 4*16)]\n\t"
> + "ldp q6, q7, [x16, #(32*8 + 6*16)]\n\t"
> + "ldp q8, q9, [x16, #(32*8 + 8*16)]\n\t"
> + "ldp q10, q11, [x16, #(32*8 + 10*16)]\n\t"
> + "ldp q12, q13, [x16, #(32*8 + 12*16)]\n\t"
> + "ldp q14, q15, [x16, #(32*8 + 14*16)]\n\t"
> + "ldp q16, q17, [x16, #(32*8 + 16*16)]\n\t"
> + "ldp q18, q19, [x16, #(32*8 + 18*16)]\n\t"
> + "ldp q20, q21, [x16, #(32*8 + 20*16)]\n\t"
> + "ldp q22, q23, [x16, #(32*8 + 22*16)]\n\t"
> + "ldp q24, q25, [x16, #(32*8 + 24*16)]\n\t"
> + "ldp q26, q27, [x16, #(32*8 + 26*16)]\n\t"
> + "ldp q28, q29, [x16, #(32*8 + 28*16)]\n\t"
> + "ldp q30, q31, [x16, #(32*8 + 30*16)]\n\t"
> +
> + /* Now load x16 itself */
> + "ldr x16, [x16, #(16*8)]\n\t"
> +
> + /* Return to the lower VTL */
> + "hvc #3\n\t"
No. Absolutely not. If you need to do context switching, do it in the
hypervisor. Entirely in the hypervisor. You don't even handle SVE, let
alone SME. How is that going to work?
And please use the SMCCC. Only that. Which mandates that the HVC
immediate is 0, 0 or zero.
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Jonathan McDowell @ 2026-04-23 14:03 UTC (permalink / raw)
To: Yeoreum Yun
Cc: Mimi Zohar, linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, roberto.sassu,
dmitry.kasatkin, eric.snowberg, jarkko, jgg, sudeep.holla, maz,
oupton, joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
will, noodles, sebastianene
In-Reply-To: <aeokwrC86WI7uT+K@e129823.arm.com>
On Thu, Apr 23, 2026 at 02:55:14PM +0100, Yeoreum Yun wrote:
>> On Thu, 2026-04-23 at 13:53 +0100, Jonathan McDowell wrote:
>> > On Thu, Apr 23, 2026 at 01:34:13PM +0100, Yeoreum Yun wrote:
>> > > > > On Thu, 2026-04-23 at 06:55 +0100, Yeoreum Yun wrote:
>> > > > > > > On Wed, 2026-04-22 at 20:41 +0100, Yeoreum Yun wrote:
>> > > > > > > > > Hi Mimi,
>> > > > > > > > >
>> > > > > > > > > > On Wed, 2026-04-22 at 17:24 +0100, Yeoreum Yun wrote:
>> > > > > > > > > > > To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
>> > > > > > > > > > > the TPM driver must be built as built-in and
>> > > > > > > > > > > must be probed before the IMA subsystem is initialized.
>> > > > > > > > > > >
>> > > > > > > > > > > However, when the TPM device operates over the FF-A protocol using
>> > > > > > > > > > > the CRB interface, probing fails and returns -EPROBE_DEFER if
>> > > > > > > > > > > the tpm_crb_ffa device — an FF-A device that provides the communication
>> > > > > > > > > > > interface to the tpm_crb driver — has not yet been probed.
>> > > > > > > > > > >
>> > > > > > > > > > > To ensure the TPM device operating over the FF-A protocol with
>> > > > > > > > > > > the CRB interface is probed before IMA initialization,
>> > > > > > > > > > > the following conditions must be met:
>> > > > > > > > > > >
>> > > > > > > > > > > 1. The corresponding ffa_device must be registered,
>> > > > > > > > > > > which is done via ffa_init().
>> > > > > > > > > > >
>> > > > > > > > > > > 2. The tpm_crb_driver must successfully probe this device via
>> > > > > > > > > > > tpm_crb_ffa_init().
>> > > > > > > > > > >
>> > > > > > > > > > > 3. The tpm_crb driver using CRB over FF-A can then
>> > > > > > > > > > > be probed successfully. (See crb_acpi_add() and
>> > > > > > > > > > > tpm_crb_ffa_init() for reference.)
>> > > > > > > > > > >
>> > > > > > > > > > > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
>> > > > > > > > > > > all registered with device_initcall, which means crb_acpi_driver_init() may
>> > > > > > > > > > > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
>> > > > > > > > > > >
>> > > > > > > > > > > When this occurs, probing the TPM device is deferred.
>> > > > > > > > > > > However, the deferred probe can happen after the IMA subsystem
>> > > > > > > > > > > has already been initialized, since IMA initialization is performed
>> > > > > > > > > > > during late_initcall, and deferred_probe_initcall() is performed
>> > > > > > > > > > > at the same level.
>> > > > > > > > > > >
>> > > > > > > > > > > To resolve this, call ima_init() again at late_inicall_sync level
>> > > > > > > > > > > so that let IMA not miss TPM PCR value when generating boot_aggregate
>> > > > > > > > > > > log though TPM device presents in the system.
>> > > > > > > > > > >
>> > > > > > > > > > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
>> > > > > > > > > >
>> > > > > > > > > > A lot of change for just detecting whether ima_init() is being called on
>> > > > > > > > > > late_initcall or late_initcall_sync(), without any explanation for all the other
>> > > > > > > > > > changes (e.g. ima_init_core).
>> > > > > > > > > >
>> > > > > > > > > > Please just limit the change to just calling ima_init() twice.
>> > > > > > > > >
>> > > > > > > > > My concern is that ima_update_policy_flags() will be called
>> > > > > > > > > when ima_init() is deferred -- not initialised anything.
>> > > > > > > > > though functionally, it might be okay however,
>> > > > > > > > > I think ima_update_policy_flags() and notifier should work after ima_init()
>> > > > > > > > > works logically.
>> > > > > > > > >
>> > > > > > > > > This change I think not much quite a lot. just wrapper ima_init() with
>> > > > > > > > > ima_init_core() with some error handling.
>> > > > > > > > >
>> > > > > > > > > Am I missing something?
>> > > > > > > >
>> > > > > > > > Also, if we handle in ima_init() only, but it failed with other reason,
>> > > > > > > > we shouldn't call again ima_init() in the late_initcall_sync.
>> > > > > > > >
>> > > > > > > > To handle this, It wouldn't do in the ima_init() but we need to handle
>> > > > > > > > it by caller of ima_init().
>> > > > > > >
>> > > > > > > Only tpm_default_chip() is being called to set the ima_tpm_chip. On failure,
>> > > > > > > instead of going into TPM-bypass mode, return immediately. There are no calls
>> > > > > > > to anything else. Just call ima_init() a second time.
>> > > > > >
>> > > > > > I’m not fully convinced this is sufficient.
>> > > > > >
>> > > > > > What I meant is the case where ima_init() fails due to other
>> > > > > > initialisation steps, not only tpm_default_chip() (e.g. ima_fs_init()).
>> > > > >
>> > > > > The purpose of THIS patch is to add late_initcall_sync, when the TPM is not
>> > > > > available at late_initcall. This would be classified as a bug fix and would be
>> > > > > backported. No other changes should be included in this patch.
>> > > >
>> > > > Okay.
>> > > >
>> > > > > >
>> > > > > > I’d also like to ask again whether it is fine to call
>> > > > > > ima_update_policy_flags() and keep the notifier registered in the
>> > > > > > deferred TPM case. While this may be functionally acceptable, it seems
>> > > > > > logically questionable to do so when ima_init() has not completed.
>> > > > >
>> > > > > Other than extending the TPM, IMA should behave exactly the same whether there
>> > > > > is a TPM or goes into TPM-bypass mode.
>> > > > >
>> > > > > >
>> > > > > > There is also a possibility that a deferred case ultimately fails (e.g.
>> > > > > > deferred at late_initcall, but then failing at late_initcall_sync
>> > > > > > for another reason, even while entering TPM bypass mode). In that case,
>> > > > > > it seems more appropriate to handle this state in the caller of
>> > > > > > ima_init(), rather than inside ima_init() itself.
>> > > > >
>> > > > > If the TPM isn't found at late_initcall_sync(), then IMA should go into TPM-
>> > > > > bypass mode. Please don't make any other changes to the existing IMA behavior
>> > > > > and hide it here behind the late_initcall_sync change.
>> > > >
>> > > > Okay. you're talking called ima_update_policy_flags() at late_initcall
>> > > > wouldn't be not a problem even in case of late_initcall_sync's ima_init()
>> > > > get failed with "TPM-bypass mode".
>> > > >
>> > > > I see then, I'll make a patch simpler then.
>> > >
>> > > But I think in case of below situation:
>> > > - late_initcall's first ima_init() is deferred.
>> > > - late_initcall_sync try again but failed and try again with
>> > > CONFIG_IMA_DEFAULT_HASH.
>> > >
>> > > I would like to sustain init_ima_core to reduce the same code repeat
>> > > in late_initcall_sync.
>> >
>> > I think what Mimi's proposing is:
>> >
>> > If we're in late_initcall, and the TPM isn't available, return
>> > immediately with an error (the EPROBE_DEFER?), don't do any init.
>> >
>> > If we're in late_initcall_sync, either we're already initialised, so do
>> > return and nothing, or run through the entire flow, even if the TPM
>> > isn't unavailable.
>> >
>> > So ima_init() just needs to know a) if it's in the sync or non-sync mode
>> > and b) for the sync mode, if we've already done the init at
>> > non-sync.
>>
>> Thanks, Jonathan. That is exactly what I'm suggesting. Any other changes
>> should not be included in this patch. Since Yeoreum is not hearing me, feel
>> free to post a patch.
>
>I see. so what you need to is this only
>If it looks good to you. I'll send it at v3.
FWIW, I pulled the tpm_default_chip check out a level to account for the
extra init you mentioned, and have the following (completely untested or
compiled, but gives the approach):
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d48bf0ad26f4..88fe105b7f00 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -166,6 +166,7 @@ enum lsm_order {
* @initcall_fs: LSM callback for fs_initcall setup, optional
* @initcall_device: LSM callback for device_initcall() setup, optional
* @initcall_late: LSM callback for late_initcall() setup, optional
+ * @initcall_late_sync: LSM callback for late_initcall_sync() setup, optional
*/
struct lsm_info {
const struct lsm_id *id;
@@ -181,6 +182,7 @@ struct lsm_info {
int (*initcall_fs)(void);
int (*initcall_device)(void);
int (*initcall_late)(void);
+ int (*initcall_late_sync)(void);
};
#define DEFINE_LSM(lsm) \
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index a2f34f2d8ad7..a60dfb8316d8 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -119,10 +119,6 @@ int __init ima_init(void)
{
int rc;
- ima_tpm_chip = tpm_default_chip();
- if (!ima_tpm_chip)
- pr_info("No TPM chip found, activating TPM-bypass!\n");
-
rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
if (rc)
return rc;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 1d6229b156fb..b60a85fa803a 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -1237,7 +1237,7 @@ static int ima_kernel_module_request(char *kmod_name)
#endif /* CONFIG_INTEGRITY_ASYMMETRIC_KEYS */
-static int __init init_ima(void)
+static int __init init_ima(bool sync)
{
int error;
@@ -1247,6 +1247,19 @@ static int __init init_ima(void)
return 0;
}
+ /* If we found the TPM during our first attempt, nothing further to do */
+ if (sync && ima_tpm_chip)
+ return 0;
+
+ ima_tpm_chip = tpm_default_chip();
+ if (!ima_tpm_chip && !sync) {
+ pr_debug("TPM not available, will try later\n");
+ return -EPROBE_DEFER;
+ }
+
+ if (!ima_tpm_chip)
+ pr_info("No TPM chip found, activating TPM-bypass!\n");
+
ima_appraise_parse_cmdline();
ima_init_template_list();
hash_setup(CONFIG_IMA_DEFAULT_HASH);
@@ -1274,6 +1287,16 @@ static int __init init_ima(void)
return error;
}
+static int __init init_ima_late(void)
+{
+ return init_ima(false);
+}
+
+static int __init init_ima_late_sync(void)
+{
+ return init_ima(true);
+}
+
static struct security_hook_list ima_hooks[] __ro_after_init = {
LSM_HOOK_INIT(bprm_check_security, ima_bprm_check),
LSM_HOOK_INIT(bprm_creds_for_exec, ima_bprm_creds_for_exec),
@@ -1319,6 +1342,7 @@ DEFINE_LSM(ima) = {
.init = init_ima_lsm,
.order = LSM_ORDER_LAST,
.blobs = &ima_blob_sizes,
- /* Start IMA after the TPM is available */
- .initcall_late = init_ima,
+ /* Ensure we start IMA after the TPM is available */
+ .initcall_late = init_ima_late,
+ .initcall_late_sync = init_ima_late_sync,
};
diff --git a/security/lsm_init.c b/security/lsm_init.c
index 573e2a7250c4..4e5c59beb82a 100644
--- a/security/lsm_init.c
+++ b/security/lsm_init.c
@@ -547,13 +547,22 @@ device_initcall(security_initcall_device);
* security_initcall_late - Run the LSM late initcalls
*/
static int __init security_initcall_late(void)
+{
+ return lsm_initcall(late);
+}
+late_initcall(security_initcall_late);
+
+/**
+ * security_initcall_late_sync - Run the LSM late initcalls sync
+ */
+static int __init security_initcall_late_sync(void)
{
int rc;
- rc = lsm_initcall(late);
+ rc = lsm_initcall(late_sync);
lsm_pr_dbg("all enabled LSMs fully activated\n");
call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL);
return rc;
}
-late_initcall(security_initcall_late);
+late_initcall_sync(security_initcall_late_sync);
J.
--
Rock and roll stops the traffic.
This .sig brought to you by the letter A and the number 40
Product of the Republic of HuggieTag
^ permalink raw reply related
* [PATCH 1/4] firmware: samsung: acpm: Fix cross-thread RX length corruption
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
In-Reply-To: <20260423-acpm-fixes-sashiko-reports-v1-0-2217b790925e@linaro.org>
Sashiko identified a cross-thread RX length corruption bug when
reviewing the thermal addition to ACPM [1].
When multiple threads concurrently send IPC requests, the ACPM polling
mechanism can encounter responses belonging to other threads. To drain
the queue, the driver saves these concurrent responses into an internal
cache (`rx_data->cmd`) to be retrieved later by the owning thread.
Previously, the driver incorrectly used `xfer->rxcnt` (the expected
receive length of the *current* polling thread) when copying data for
*other* threads into this cache. If the threads expected responses of
different lengths, this resulted in buffer underflows (leading to reads
of uninitialized memory) or potential buffer overflows.
Fix this by replacing the boolean `response` flag in
`struct acpm_rx_data` with `rxcnt`, caching the exact expected receive
length for each specific transaction during transfer preparation. Use
this cached length when saving concurrent responses.
Consequently, ensure that `xfer->rxcnt` is explicitly zeroed in driver
helpers (e.g., `acpm_dvfs_set_xfer`) for fire-and-forget messages to
prevent uninitialized stack garbage from being interpreted as a massive
expected receive length.
Cc: stable@vger.kernel.org
Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver")
Closes: https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org [1]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
drivers/firmware/samsung/exynos-acpm-dvfs.c | 3 +++
drivers/firmware/samsung/exynos-acpm.c | 15 ++++++++-------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c
index 06bdf62dea1f..fdea7aa24ca0 100644
--- a/drivers/firmware/samsung/exynos-acpm-dvfs.c
+++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c
@@ -31,6 +31,9 @@ static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
if (response) {
xfer->rxcnt = cmdlen;
xfer->rxd = cmd;
+ } else {
+ xfer->rxcnt = 0;
+ xfer->rxd = NULL;
}
}
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
index 16c46ed60837..e95edc350efa 100644
--- a/drivers/firmware/samsung/exynos-acpm.c
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -104,12 +104,12 @@ struct acpm_queue {
*
* @cmd: pointer to where the data shall be saved.
* @n_cmd: number of 32-bit commands.
- * @response: true if the client expects the RX data.
+ * @rxcnt: expected length of the response in 32-bit words.
*/
struct acpm_rx_data {
u32 *cmd;
size_t n_cmd;
- bool response;
+ size_t rxcnt;
};
#define ACPM_SEQNUM_MAX 64
@@ -199,7 +199,7 @@ static void acpm_get_saved_rx(struct acpm_chan *achan,
const struct acpm_rx_data *rx_data = &achan->rx_data[tx_seqnum - 1];
u32 rx_seqnum;
- if (!rx_data->response)
+ if (!rx_data->rxcnt)
return;
rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, rx_data->cmd[0]);
@@ -256,7 +256,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
seqnum = rx_seqnum - 1;
rx_data = &achan->rx_data[seqnum];
- if (rx_data->response) {
+ if (rx_data->rxcnt) {
if (rx_seqnum == tx_seqnum) {
__ioread32_copy(xfer->rxd, addr, xfer->rxcnt);
rx_set = true;
@@ -268,7 +268,8 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
* clear yet the bitmap. It will be cleared
* after the response is copied to the request.
*/
- __ioread32_copy(rx_data->cmd, addr, xfer->rxcnt);
+ __ioread32_copy(rx_data->cmd, addr,
+ rx_data->rxcnt);
}
} else {
clear_bit(seqnum, achan->bitmap_seqnum);
@@ -380,8 +381,8 @@ static void acpm_prepare_xfer(struct acpm_chan *achan,
/* Clear data for upcoming responses */
rx_data = &achan->rx_data[achan->seqnum - 1];
memset(rx_data->cmd, 0, sizeof(*rx_data->cmd) * rx_data->n_cmd);
- if (xfer->rxd)
- rx_data->response = true;
+ /* zero means no response expected */
+ rx_data->rxcnt = xfer->rxcnt;
/* Flag the index based on seqnum. (seqnum: 1~63, bitmap: 0~62) */
set_bit(achan->seqnum - 1, achan->bitmap_seqnum);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH 0/4] firmware: samsung: acpm: Various fixes for sashiko bug reports
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
Fixes for bugs that were identified by sashiko when proposing the
GS101 ACPM TMU addition:
https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
Tudor Ambarus (4):
firmware: samsung: acpm: Fix cross-thread RX length corruption
firmware: samsung: acpm: Fix sequence number leak and infinite loop
firmware: samsung: acpm: Fix mailbox channel leak on probe error
firmware: samsung: acpm: Fix dummy stubs to return ERR_PTR
drivers/firmware/samsung/exynos-acpm-dvfs.c | 3 ++
drivers/firmware/samsung/exynos-acpm.c | 32 +++++++++++++++-------
.../linux/firmware/samsung/exynos-acpm-protocol.h | 3 +-
3 files changed, 27 insertions(+), 11 deletions(-)
---
base-commit: 2e68039281932e6dc37718a1ea7cbb8e2cda42e6
change-id: 20260423-acpm-fixes-sashiko-reports-ae28b6ed5581
Best regards,
--
Tudor Ambarus <tudor.ambarus@linaro.org>
^ permalink raw reply
* [PATCH 4/4] firmware: samsung: acpm: Fix dummy stubs to return ERR_PTR
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
In-Reply-To: <20260423-acpm-fixes-sashiko-reports-v1-0-2217b790925e@linaro.org>
Sashiko identified a potential NULL pointer dereference [1].
The dummy stub implementation for devm_acpm_get_by_node() returns NULL
when CONFIG_EXYNOS_ACPM_PROTOCOL is disabled.
However, the active implementation of this function returns an ERR_PTR
on failure, and the consumer driver checks the return value using
IS_ERR(). Because IS_ERR(NULL) evaluates to false, returning NULL from
the stub tricks consumer drivers into treating the NULL return as a
valid handle. Subsequent attempts to access handle->ops result in a
fatal NULL pointer dereference.
Fix this by returning ERR_PTR(-ENODEV) in the disabled configuration
to correctly propagate the disabled state and match the API contract.
Cc: stable@vger.kernel.org
Fixes: 6837c006d4e7 ("firmware: exynos-acpm: add empty method to allow compile test")
Closes: https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org [1]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
include/linux/firmware/samsung/exynos-acpm-protocol.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h
index 13f17dc4443b..d4db2796a6fb 100644
--- a/include/linux/firmware/samsung/exynos-acpm-protocol.h
+++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h
@@ -8,6 +8,7 @@
#ifndef __EXYNOS_ACPM_PROTOCOL_H
#define __EXYNOS_ACPM_PROTOCOL_H
+#include <linux/err.h>
#include <linux/types.h>
struct acpm_handle;
@@ -57,7 +58,7 @@ struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
static inline struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
struct device_node *np)
{
- return NULL;
+ return ERR_PTR(-ENODEV);
}
#endif
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH 2/4] firmware: samsung: acpm: Fix sequence number leak and infinite loop
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
In-Reply-To: <20260423-acpm-fixes-sashiko-reports-v1-0-2217b790925e@linaro.org>
Sashiko identified a sequence number leak and a possible infinite loop
[1].
ACPM IPC sequence numbers are tracked via a 64-bit bitmap
(`bitmap_seqnum`) to manage concurrent transactions. A bit is set when
a sequence number is allocated in `acpm_prepare_xfer()`.
Previously, if a transfer timed out during RX polling, or if the
underlying hardware mailbox failed to send the message via
`mbox_send_message()`, the allocated sequence number bit was never
cleared.
As these transient errors accumulate, all 63 available sequence numbers
could eventually be leaked. Once the bitmap is full, the next call to
`acpm_prepare_xfer()` would enter an infinite `while` loop attempting
to find a free sequence number, permanently deadlocking the CPU.
Fix this by ensuring the sequence number bit is explicitly cleared on
all error paths:
1. In `acpm_do_xfer()`, clear the bit if the mailbox transmission
fails.
2. In `acpm_dequeue_by_polling()`, clear the bit if the queue read fails
or if the response times out.
Cc: stable@vger.kernel.org
Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver")
Closes: https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org [1]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
drivers/firmware/samsung/exynos-acpm.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
index e95edc350efa..a9baed5762d5 100644
--- a/drivers/firmware/samsung/exynos-acpm.c
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -311,8 +311,10 @@ static int acpm_dequeue_by_polling(struct acpm_chan *achan,
timeout = ktime_add_us(ktime_get(), ACPM_POLL_TIMEOUT_US);
do {
ret = acpm_get_rx(achan, xfer);
- if (ret)
+ if (ret) {
+ clear_bit(seqnum - 1, achan->bitmap_seqnum);
return ret;
+ }
if (!test_bit(seqnum - 1, achan->bitmap_seqnum))
return 0;
@@ -324,6 +326,8 @@ static int acpm_dequeue_by_polling(struct acpm_chan *achan,
dev_err(dev, "Timeout! ch:%u s:%u bitmap:%lx.\n",
achan->id, seqnum, achan->bitmap_seqnum[0]);
+ clear_bit(seqnum - 1, achan->bitmap_seqnum);
+
return -ETIME;
}
@@ -455,8 +459,10 @@ int acpm_do_xfer(struct acpm_handle *handle, const struct acpm_xfer *xfer)
writel(idx, achan->tx.front);
ret = mbox_send_message(achan->chan, (void *)&msg);
- if (ret < 0)
+ if (ret < 0) {
+ clear_bit(achan->seqnum - 1, achan->bitmap_seqnum);
return ret;
+ }
mbox_client_txdone(achan->chan, 0);
}
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH 3/4] firmware: samsung: acpm: Fix mailbox channel leak on probe error
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
In-Reply-To: <20260423-acpm-fixes-sashiko-reports-v1-0-2217b790925e@linaro.org>
Sashiko identified the leak at [1].
The ACPM driver allocates hardware mailbox channels using
`mbox_request_channel()` during `acpm_channels_init()`. However, the
driver lacked a `.remove` callback and did not free these channels on
subsequent error paths inside `acpm_probe()`.
Consequently, if a later step in the probe function failed (e.g.,
`platform_device_register_data()` returning an error), the mailbox
channels were permanently leaked. This prevented the driver from ever
successfully re-probing on a transient `-EPROBE_DEFER`.
Fix this by modifying `acpm_free_mbox_chans()` to match the `devres`
action signature and wrapping it with `devm_add_action_or_reset()`.
This hooks the channel cleanup directly into the device's managed
resource lifecycle, ensuring the channels are properly freed on probe
failures or driver unbind.
Cc: stable@vger.kernel.org
Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver")
Closes: https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org [1]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
drivers/firmware/samsung/exynos-acpm.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
index a9baed5762d5..896fbdc2700e 100644
--- a/drivers/firmware/samsung/exynos-acpm.c
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -535,8 +535,9 @@ static int acpm_achan_alloc_cmds(struct acpm_chan *achan)
* acpm_free_mbox_chans() - free mailbox channels.
* @acpm: pointer to driver data.
*/
-static void acpm_free_mbox_chans(struct acpm_info *acpm)
+static void acpm_free_mbox_chans(void *data)
{
+ struct acpm_info *acpm = data;
int i;
for (i = 0; i < acpm->num_chans; i++)
@@ -658,6 +659,10 @@ static int acpm_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ret = devm_add_action_or_reset(dev, acpm_free_mbox_chans, acpm);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add mbox free action.\n");
+
acpm_setup_ops(acpm);
platform_set_drvdata(pdev, acpm);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v10 01/11] drm/fourcc: Add warning for bad bpp
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
drm_format_info_bpp() cannot be used for formats which do not have an
integer bits-per-pixel in a pixel block.
E.g. DRM_FORMAT_P030's plane 0 has three 10-bit pixels (Y components),
and two padding bits, in a 4 byte block. That is 10.666... bits per
pixel when considering the whole 4 byte block, which is what
drm_format_info_bpp() does. Thus a driver that supports such formats
cannot use drm_format_info_bpp(),
It is a driver bug if this happens, but so handle wrong calls by
printing a warning and returning 0.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/drm_fourcc.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index e0d533611040..e662aea9d105 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -491,12 +491,20 @@ EXPORT_SYMBOL(drm_format_info_block_height);
*/
unsigned int drm_format_info_bpp(const struct drm_format_info *info, int plane)
{
+ unsigned int block_size;
+
if (!info || plane < 0 || plane >= info->num_planes)
return 0;
- return info->char_per_block[plane] * 8 /
- (drm_format_info_block_width(info, plane) *
- drm_format_info_block_height(info, plane));
+ block_size = drm_format_info_block_width(info, plane) *
+ drm_format_info_block_height(info, plane);
+
+ if (info->char_per_block[plane] * 8 % block_size) {
+ pr_warn("unable to return an integer bpp\n");
+ return 0;
+ }
+
+ return info->char_per_block[plane] * 8 / block_size;
}
EXPORT_SYMBOL(drm_format_info_bpp);
--
2.43.0
^ permalink raw reply related
* [PATCH v10 02/11] drm/fourcc: Add DRM_FORMAT_P230
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen,
Dmitry Baryshkov
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Add a new pixel format, DRM_FORMAT_P230 ("P230")
P230 is 2 plane 10 bit per component YCbCr 2x1 subsampled format. P230
is similar to the already existing P030 format, which is 2x2 subsampled.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Vishal Sagar <vishal.sagar@amd.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/drm_fourcc.c | 3 +++
include/uapi/drm/drm_fourcc.h | 8 ++++++++
2 files changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index e662aea9d105..5b6d8f4686c4 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -354,6 +354,9 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2,
.char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
.hsub = 2, .vsub = 2, .is_yuv = true},
+ { .format = DRM_FORMAT_P230, .depth = 0, .num_planes = 2,
+ .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
+ .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_S010, .depth = 0, .num_planes = 3,
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
.hsub = 2, .vsub = 2, .is_yuv = true},
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index c89aede3cb12..0f2f79542121 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -379,6 +379,14 @@ extern "C" {
*/
#define DRM_FORMAT_P030 fourcc_code('P', '0', '3', '0') /* 2x2 subsampled Cr:Cb plane 10 bits per channel packed */
+/*
+ * 2 plane YCbCr422.
+ * 3 10 bit components and 2 padding bits packed into 4 bytes.
+ * index 0 = Y plane, [31:0] x:Y2:Y1:Y0 2:10:10:10 little endian
+ * index 1 = Cr:Cb plane, [63:0] x:Cr2:Cb2:Cr1:x:Cb1:Cr0:Cb0 [2:10:10:10:2:10:10:10] little endian
+ */
+#define DRM_FORMAT_P230 fourcc_code('P', '2', '3', '0') /* 2x1 subsampled Cr:Cb plane 10 bits per channel packed */
+
/* 3 plane non-subsampled (444) YCbCr
* 16 bits per component, but only 10 bits are used and 6 bits are padded
* index 0: Y plane, [15:0] Y:x [10:6] little endian
--
2.43.0
^ permalink raw reply related
* [PATCH v10 04/11] drm/fourcc: Add DRM_FORMAT_XYYY2101010
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen, Pekka Paalanen
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Add XYYY2101010 ("YPA4"), a 10 bit greyscale format, with 3 pixels
packed into 32-bit container, and two bits of padding.
The fourcc for the format is 'YPA4', which comes from Y - Y only, P -
packed, A - 10 (as in 0xA), 4 - 4 bytes.
Reviewed-by: Vishal Sagar <vishal.sagar@amd.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Simon Ser <contact@emersion.fr>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/drm_fourcc.c | 3 +++
include/uapi/drm/drm_fourcc.h | 1 +
2 files changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index c30266b8d051..01761c553e7e 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -385,6 +385,9 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_S416, .depth = 0, .num_planes = 3,
.char_per_block = { 2, 2, 2 }, .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 },
.hsub = 1, .vsub = 1, .is_yuv = true},
+ { .format = DRM_FORMAT_XYYY2101010, .depth = 0, .num_planes = 1,
+ .char_per_block = { 4, 0, 0 }, .block_w = { 3, 0, 0 }, .block_h = { 1, 0, 0 },
+ .hsub = 1, .vsub = 1, .is_yuv = true },
};
unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index c5b64ed3b00a..472f95632640 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -468,6 +468,7 @@ extern "C" {
*/
#define DRM_FORMAT_Y8 fourcc_code('G', 'R', 'E', 'Y') /* 8-bit Y-only */
+#define DRM_FORMAT_XYYY2101010 fourcc_code('Y', 'P', 'A', '4') /* [31:0] x:Y2:Y1:Y0 2:10:10:10 little endian */
/*
* Format Modifiers:
--
2.43.0
^ permalink raw reply related
* [PATCH v10 03/11] drm/fourcc: Add DRM_FORMAT_Y8
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen, Pekka Paalanen,
Dmitry Baryshkov
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Add greyscale Y8 format.
The 8-bit greyscale format has been discussed before, and the earlier
guidance was to use DRM_FORMAT_R8, as a single-channel 8-bit pixel.
However, adding DRM_FORMAT_Y8 makes sense, we can mark it as 'is_yuv' in
the drm_format_info, and this can help the drivers handle e.g.
full/limited range. This will distinguish two single-channel formats:
R8, which is a RGB format with the same value for all components, and
Y8, which is a Y-only YCbCr format, with Cb and Cr being neutral.
Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Reviewed-by: Vishal Sagar <vishal.sagar@amd.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/drm_fourcc.c | 1 +
include/uapi/drm/drm_fourcc.h | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 5b6d8f4686c4..c30266b8d051 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -275,6 +275,7 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_YVU422, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_YUV444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_YVU444, .depth = 0, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+ { .format = DRM_FORMAT_Y8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_NV12, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
{ .format = DRM_FORMAT_NV21, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
{ .format = DRM_FORMAT_NV16, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 0f2f79542121..c5b64ed3b00a 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -459,6 +459,15 @@ extern "C" {
#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
+/*
+ * Y-only (greyscale) formats
+ *
+ * The Y-only formats are handled similarly to the YCbCr formats in the display
+ * pipeline, with the Cb and Cr implicitly neutral (0.0 in nominal values). This
+ * also means that COLOR_RANGE property applies to the Y-only formats.
+ */
+
+#define DRM_FORMAT_Y8 fourcc_code('G', 'R', 'E', 'Y') /* 8-bit Y-only */
/*
* Format Modifiers:
--
2.43.0
^ permalink raw reply related
* [PATCH v10 00/11] drm: Add new pixel formats for Xilinx Zynqmp
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen, Pekka Paalanen,
Dmitry Baryshkov
Add new DRM pixel formats and add support for those in the Xilinx zynqmp
display driver.
All other formats except XVUY2101010 are already supported in upstream
gstreamer, but gstreamer's kmssink does not have the support yet, as it
obviously cannot support the formats without kernel having the formats.
Xilinx has support for these formats in their BSP kernel, and Xilinx has
a branch here, adding the support to gstreamer kmssink:
https://github.com/Xilinx/gst-plugins-bad.git xlnx-rebase-v1.18.5
New formats added:
DRM_FORMAT_Y8
- 8-bit Y-only
- fourcc: "GREY"
- gstreamer: GRAY8
DRM_FORMAT_XYYY2101010
- 10-bit Y-only, three pixels packed into 32-bits
- fourcc: "YPA4"
- gstreamer: GRAY10_LE32
DRM_FORMAT_P230
- Like NV16, but with 10-bit components
- fourcc: "P230"
- gstreamer: NV16_10LE32
DRM_FORMAT_T430
- 10-bit planar 4:4:4, with three samples packed into 32-bits
- fourcc: "T430"
- gstreamer: Y444_10LE32
XVUY2101010
- 10-bit 4:4:4, one pixel in 32 bits
- fourcc: "XY30"
Some notes:
I know the 8-bit greyscale format has been discussed before, and the
guidance was to use DRM_FORMAT_R8. While I'm not totally against that, I
would argue that adding DRM_FORMAT_Y8 makes sense, as:
1) We can mark it as 'is_yuv' in the drm_format_info, and this can help
the drivers handle e.g. full/limited range. Probably some hardware
handles grayscale as a value used for all RGB components, in which case
R8 makes sense, but when the hardware handles the Y-only pixels as YCbCr,
where Cb and Cr are "neutral", it makes more sense to consider the
format as an YUV format rather than RGB.
2) We can have the same fourcc as in v4l2. While not strictly necessary,
it's a constant source of confusion when the fourccs differ.
3) It (possibly) makes more sense for the user to use Y8/GREY format
instead of R8, as, in my experience, the documentation usually refers
to gray(scale) format or Y-only format.
I have made some adjustments to the formats compared to the Xilinx's
branch. E.g. The DRM_FORMAT_XYYY2101010 format in Xilinx's kmssink uses
fourcc "Y10 ", and DRM_FORMAT_Y10. I didn't like those, as the format is
a packed format, three 10-bit pixels in a 32-bit container, and I think
Y10 means a 10-bit pixel in a 16-bit container. Xilinx also has
XV15/XV20 formats, of which XV15 already exists in the kernel as P030,
and XV20 is added here as P230.
Generally speaking, if someone has good ideas for the format define
names or fourccs, speak up, as it's not easy to invent good names =).
That said, keeping them the same as in the Xilinx trees will, of course,
be slightly easier for the users of Xilinx platforms.
Note: Earlier versions of the series had DRM_FORMAT_Y10_P32, which is
now DRM_FORMAT_XYYY2101010, DRM_FORMAT_XV15, which is now removed as
P030 already exists. DRM_FORMAT_P230 used to be DRM_FORMAT_XV20, and
DRM_FORMAT_T430 used to be DRM_FORMAT_X403.
[1] https://lore.kernel.org/all/20250109150310.219442-26-tzimmermann%40suse.de/
[2] git@github.com:tomba/kmsxx.git xilinx
[3] git@github.com:tomba/pykms.git xilinx
[4] git@github.com:tomba/pixutils.git xilinx
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
Changes in v10:
- Rename DRM_FORMAT_XV20 to DRM_FORMAT_P230 to be aligned with DRM_FORMAT_P030
- Rename DRM_FORMAT_X403 to DRM_FORMAT_T430
- Link to v9: https://lore.kernel.org/r/20260325-xilinx-formats-v9-0-d03b7e3752e4@ideasonboard.com
Changes in v9:
- Drop DRM_FORMAT_XV15 as DRM_FORMAT_P030 already exists
- Rename DRM_FORMAT_Y10_P32 to DRM_FORMAT_XYYY2101010
- I kept the Reviewed-bys related to the above, although one could say
renaming the format names is a substantial change. Ping me if you want
me to drop the Rb and re-send.
- Link to v8: https://lore.kernel.org/r/20260128-xilinx-formats-v8-0-9ea8adb70269@ideasonboard.com
Changes in v8:
- Expand the "drm/fourcc: Add DRM_FORMAT_Y8" commit description to
explain the rationale
- Add comment to "drm: xlnx: zynqmp: Add support for Y8 and Y10_P32"
explainig the Y-only matrix
- Remove extra blank line
- Link to v7: https://lore.kernel.org/r/20251201-xilinx-formats-v7-0-1e1558adfefc@ideasonboard.com
Changes in v7:
- Added Reviewed-bys
- Rebased on v6.18
- Link to v6: https://lore.kernel.org/r/20251001-xilinx-formats-v6-0-014b076b542a@ideasonboard.com
Changes in v6:
- Added tags for reviews
- Rebased on v6.17
- Link to v5: https://lore.kernel.org/r/20250425-xilinx-formats-v5-0-c74263231630@ideasonboard.com
Changes in v5:
- Add comment about Y-only formats, clarifying how the display pipeline
handles them (they're handled as YCbCr, with Cb and Cr as "neutral")
- Clarify X403 format in the patch description
- Set unused Y-only CSC offsets to 0 (instead of 0x1800).
- Add R-bs
- Link to v4: https://lore.kernel.org/r/20250326-xilinx-formats-v4-0-322a300c6d72@ideasonboard.com
Changes in v4:
- Reformat the drm_format_info entries a bit
- Calculate block size only once in drm_format_info_bpp()
- Declare local variables in separate lines
- Add review tags
- Fix commit message referring to Y10_LE32 (should be Y10_P32)
- Link to v3: https://lore.kernel.org/r/20250212-xilinx-formats-v3-0-90d0fe106995@ideasonboard.com
Changes in v3:
- Drop "drm: xlnx: zynqmp: Fix max dma segment size". It is already
pushed.
- Add XVUY2101010 format.
- Rename DRM_FORMAT_Y10_LE32 to DRM_FORMAT_Y10_P32.
- Link to v2: https://lore.kernel.org/r/20250115-xilinx-formats-v2-0-160327ca652a@ideasonboard.com
Changes in v2:
- I noticed V4L2 already has fourcc Y10P, referring to MIPI-style packed
Y10 format. So I changed Y10_LE32 fourcc to YPA4. If logic has any
relevance here, P means packed, A means 10, 4 means "in 4 bytes".
- Added tags to "Fix max dma segment size" patch
- Updated description for "Add warning for bad bpp"
- Link to v1: https://lore.kernel.org/r/20241204-xilinx-formats-v1-0-0bf2c5147db1@ideasonboard.com
---
Tomi Valkeinen (11):
drm/fourcc: Add warning for bad bpp
drm/fourcc: Add DRM_FORMAT_P230
drm/fourcc: Add DRM_FORMAT_Y8
drm/fourcc: Add DRM_FORMAT_XYYY2101010
drm/fourcc: Add DRM_FORMAT_T430
drm/fourcc: Add DRM_FORMAT_XVUY2101010
drm: xlnx: zynqmp: Use drm helpers when calculating buffer sizes
drm: xlnx: zynqmp: Add support for P030 & P230
drm: xlnx: zynqmp: Add support for Y8 and XYYY2101010
drm: xlnx: zynqmp: Add support for T430
drm: xlnx: zynqmp: Add support for XVUY2101010
drivers/gpu/drm/drm_fourcc.c | 25 +++++++++++++++--
drivers/gpu/drm/xlnx/zynqmp_disp.c | 56 +++++++++++++++++++++++++++++++++++---
include/uapi/drm/drm_fourcc.h | 28 +++++++++++++++++++
3 files changed, 102 insertions(+), 7 deletions(-)
---
base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
change-id: 20241120-xilinx-formats-f71901621833
Best regards,
--
Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
^ permalink raw reply
* [PATCH v10 05/11] drm/fourcc: Add DRM_FORMAT_T430
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Add T430, a 3 plane 10 bits per component non-subsampled YCbCr format.
A new initial letter was chosen for this one, as the format doesn't
match the existing P, Q or S formats. T is the next one in the alphabet.
It was definitely not chosen because of the initial letter in the
author's name.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Vishal Sagar <vishal.sagar@amd.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/drm_fourcc.c | 3 +++
include/uapi/drm/drm_fourcc.h | 9 +++++++++
2 files changed, 12 insertions(+)
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 01761c553e7e..20b84efc135e 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -388,6 +388,9 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_XYYY2101010, .depth = 0, .num_planes = 1,
.char_per_block = { 4, 0, 0 }, .block_w = { 3, 0, 0 }, .block_h = { 1, 0, 0 },
.hsub = 1, .vsub = 1, .is_yuv = true },
+ { .format = DRM_FORMAT_T430, .depth = 0, .num_planes = 3,
+ .char_per_block = { 4, 4, 4 }, .block_w = { 3, 3, 3 }, .block_h = { 1, 1, 1 },
+ .hsub = 1, .vsub = 1, .is_yuv = true },
};
unsigned int i;
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 472f95632640..07bfbc8a0300 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -403,6 +403,15 @@ extern "C" {
*/
#define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1')
+/*
+ * 3 plane non-subsampled (444) YCbCr LSB aligned
+ * 10 bpc, 30 bits per sample image data in a single contiguous buffer.
+ * index 0: Y plane, [31:0] x:Y2:Y1:Y0 [2:10:10:10] little endian
+ * index 1: Cb plane, [31:0] x:Cb2:Cb1:Cb0 [2:10:10:10] little endian
+ * index 2: Cr plane, [31:0] x:Cr2:Cr1:Cr0 [2:10:10:10] little endian
+ */
+#define DRM_FORMAT_T430 fourcc_code('T', '4', '3', '0')
+
/*
* 3 plane YCbCr LSB aligned
* In order to use these formats in a similar fashion to MSB aligned ones
--
2.43.0
^ permalink raw reply related
* [PATCH v10 07/11] drm: xlnx: zynqmp: Use drm helpers when calculating buffer sizes
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Use drm helpers, drm_format_info_plane_width(),
drm_format_info_plane_height() and drm_format_info_min_pitch() to
calculate sizes for the DMA.
This cleans up the code, but also makes it possible to support more
complex formats (like P030, P230).
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/xlnx/zynqmp_disp.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 9a8f38230cb4..12a8d643915f 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -1116,16 +1116,19 @@ int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
return 0;
for (i = 0; i < info->num_planes; i++) {
- unsigned int width = state->crtc_w / (i ? info->hsub : 1);
- unsigned int height = state->crtc_h / (i ? info->vsub : 1);
struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
struct dma_async_tx_descriptor *desc;
dma_addr_t dma_addr;
+ unsigned int width;
+ unsigned int height;
+
+ width = drm_format_info_plane_width(info, state->crtc_w, i);
+ height = drm_format_info_plane_height(info, state->crtc_h, i);
dma_addr = drm_fb_dma_get_gem_addr(state->fb, state, i);
dma->xt.numf = height;
- dma->sgl.size = width * info->cpp[i];
+ dma->sgl.size = drm_format_info_min_pitch(info, i, width);
dma->sgl.icg = state->fb->pitches[i] - dma->sgl.size;
dma->xt.src_start = dma_addr;
dma->xt.frame_size = 1;
--
2.43.0
^ permalink raw reply related
* [PATCH v10 08/11] drm: xlnx: zynqmp: Add support for P030 & P230
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Add support for P030 & P230 formats.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Vishal Sagar <vishal.sagar@amd.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/xlnx/zynqmp_disp.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 12a8d643915f..46ea70fd37ec 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -297,6 +297,16 @@ static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
.buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420,
.swap = true,
.sf = scaling_factors_888,
+ }, {
+ .drm_fmt = DRM_FORMAT_P030,
+ .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_420_10,
+ .swap = false,
+ .sf = scaling_factors_101010,
+ }, {
+ .drm_fmt = DRM_FORMAT_P230,
+ .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_10,
+ .swap = false,
+ .sf = scaling_factors_101010,
},
};
--
2.43.0
^ permalink raw reply related
* [PATCH v10 06/11] drm/fourcc: Add DRM_FORMAT_XVUY2101010
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Add XVUY2101010, a 10 bits per component YCbCr format in a 32 bit
container.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Vishal Sagar <vishal.sagar@amd.com>
Reviewed-by: Simon Ser <contact@emersion.fr>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/drm_fourcc.c | 1 +
include/uapi/drm/drm_fourcc.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 20b84efc135e..60cd02b7ea64 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -288,6 +288,7 @@ const struct drm_format_info *__drm_format_info(u32 format)
{ .format = DRM_FORMAT_VYUY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_XYUV8888, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_VUY888, .depth = 0, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
+ { .format = DRM_FORMAT_XVUY2101010, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_AYUV, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true },
{ .format = DRM_FORMAT_Y210, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
{ .format = DRM_FORMAT_Y212, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 07bfbc8a0300..d95638105520 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -264,6 +264,7 @@ extern "C" {
#define DRM_FORMAT_XVUY8888 fourcc_code('X', 'V', 'U', 'Y') /* [31:0] X:Cr:Cb:Y 8:8:8:8 little endian */
#define DRM_FORMAT_VUY888 fourcc_code('V', 'U', '2', '4') /* [23:0] Cr:Cb:Y 8:8:8 little endian */
#define DRM_FORMAT_VUY101010 fourcc_code('V', 'U', '3', '0') /* Y followed by U then V, 10:10:10. Non-linear modifier only */
+#define DRM_FORMAT_XVUY2101010 fourcc_code('X', 'Y', '3', '0') /* [31:0] x:Cr:Cb:Y 2:10:10:10 little endian */
/*
* packed Y2xx indicate for each component, xx valid data occupy msb
--
2.43.0
^ permalink raw reply related
* [PATCH v10 09/11] drm: xlnx: zynqmp: Add support for Y8 and XYYY2101010
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Add support for Y8 and XYYY2101010 formats. We also need to add new csc
matrices for these y-only formats.
Reviewed-by: Vishal Sagar <vishal.sagar@amd.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/xlnx/zynqmp_disp.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 46ea70fd37ec..175ae1589018 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -307,6 +307,16 @@ static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
.buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV16CI_10,
.swap = false,
.sf = scaling_factors_101010,
+ }, {
+ .drm_fmt = DRM_FORMAT_Y8,
+ .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MONO,
+ .swap = false,
+ .sf = scaling_factors_888,
+ }, {
+ .drm_fmt = DRM_FORMAT_XYYY2101010,
+ .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YONLY_10,
+ .swap = false,
+ .sf = scaling_factors_101010,
},
};
@@ -697,6 +707,17 @@ static const u32 csc_sdtv_to_rgb_offsets[] = {
0x0, 0x1800, 0x1800
};
+/* In Y-only mode the single Y channel is on the third column */
+static const u16 csc_sdtv_to_rgb_yonly_matrix[] = {
+ 0x0, 0x0, 0x1000,
+ 0x0, 0x0, 0x1000,
+ 0x0, 0x0, 0x1000,
+};
+
+static const u32 csc_sdtv_to_rgb_yonly_offsets[] = {
+ 0x0, 0x0, 0x0
+};
+
/**
* zynqmp_disp_blend_set_output_format - Set the output format of the blender
* @disp: Display controller
@@ -846,7 +867,11 @@ static void zynqmp_disp_blend_layer_enable(struct zynqmp_disp *disp,
ZYNQMP_DISP_V_BLEND_LAYER_CONTROL(layer->id),
val);
- if (layer->drm_fmt->is_yuv) {
+ if (layer->drm_fmt->format == DRM_FORMAT_Y8 ||
+ layer->drm_fmt->format == DRM_FORMAT_XYYY2101010) {
+ coeffs = csc_sdtv_to_rgb_yonly_matrix;
+ offsets = csc_sdtv_to_rgb_yonly_offsets;
+ } else if (layer->drm_fmt->is_yuv) {
coeffs = csc_sdtv_to_rgb_matrix;
offsets = csc_sdtv_to_rgb_offsets;
} else {
--
2.43.0
^ permalink raw reply related
* [PATCH v10 11/11] drm: xlnx: zynqmp: Add support for XVUY2101010
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Add support for XVUY2101010 format.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Vishal Sagar <vishal.sagar@amd.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/xlnx/zynqmp_disp.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 2e07e97c1540..52a0712e39c4 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -322,6 +322,11 @@ static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
.buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24_10,
.swap = false,
.sf = scaling_factors_101010,
+ }, {
+ .drm_fmt = DRM_FORMAT_XVUY2101010,
+ .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YUV444_10,
+ .swap = false,
+ .sf = scaling_factors_101010,
},
};
--
2.43.0
^ permalink raw reply related
* [PATCH v10 10/11] drm: xlnx: zynqmp: Add support for T430
From: Tomi Valkeinen @ 2026-04-23 14:21 UTC (permalink / raw)
To: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, Simon Ser
Cc: dri-devel, linux-kernel, linux-arm-kernel, Geert Uytterhoeven,
Dmitry Baryshkov, Pekka Paalanen, Tomi Valkeinen
In-Reply-To: <20260423-xilinx-formats-v10-0-c690c2b8ea89@ideasonboard.com>
Add support for T430 format.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Vishal Sagar <vishal.sagar@amd.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/xlnx/zynqmp_disp.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index 175ae1589018..2e07e97c1540 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -317,6 +317,11 @@ static const struct zynqmp_disp_format avbuf_vid_fmts[] = {
.buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YONLY_10,
.swap = false,
.sf = scaling_factors_101010,
+ }, {
+ .drm_fmt = DRM_FORMAT_T430,
+ .buf_fmt = ZYNQMP_DISP_AV_BUF_FMT_NL_VID_YV24_10,
+ .swap = false,
+ .sf = scaling_factors_101010,
},
};
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox