Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jay Buddhabhatti <jay.buddhabhatti@amd.com>
To: <michal.simek@amd.com>, <git@amd.com>
Cc: <linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>,
	Jay Buddhabhatti <jay.buddhabhatti@amd.com>,
	Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>,
	Prasanna Kumar T S M <ptsm@linux.microsoft.com>
Subject: [PATCH v4 1/3] firmware: xilinx: Add support to clear EL3 PM state
Date: Wed, 29 Jul 2026 05:25:20 -0700	[thread overview]
Message-ID: <20260729122522.3732875-2-jay.buddhabhatti@amd.com> (raw)
In-Reply-To: <20260729122522.3732875-1-jay.buddhabhatti@amd.com>

Currently, during a kexec restart, only the kernel is reloaded, while
EL3-specific data remain unchanged. This leads to a mismatch between the
kernel state and secure firmware state like SGI number and shutdown scope
variable.

For example, the kernel registers an SGI number with EL3 firmware so that
secure firmware can notify the kernel of events via that SGI. EL3 stores
this SGI number in its internal state. After a kexec, the newly loaded
kernel re-registers and may request a different SGI number, but the stale
value programmed in EL3 remains, so event notifications are delivered on
the old SGI and are missed by the new kernel. The shutdown scope variable
has a similar stale state problem.

To resolve this, the TF_A_CLEAR_PM_STATE PM API is introduced to clear
EL3 PM subsystem state during kexec. On a graceful reboot, this API is
triggered by zynqmp_firmware_shutdown(), while in a crash kernel scenario,
it is invoked by zynqmp_firmware_probe() in the reloaded kernel.

Signed-off-by: Jay Buddhabhatti <jay.buddhabhatti@amd.com>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Reviewed-by: Prasanna Kumar T S M <ptsm@linux.microsoft.com>
---
 drivers/firmware/xilinx/zynqmp.c     | 50 +++++++++++++++++++++++++++-
 include/linux/firmware/xlnx-zynqmp.h |  3 +-
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index af838b2dc327..b99dca9b8cac 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -3,7 +3,7 @@
  * Xilinx Zynq MPSoC Firmware layer
  *
  *  Copyright (C) 2014-2022 Xilinx, Inc.
- *  Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc.
+ *  Copyright (C) 2022 - 2026 Advanced Micro Devices, Inc.
  *
  *  Michal Simek <michal.simek@amd.com>
  *  Davorin Mista <davorin.mista@aggios.com>
@@ -13,6 +13,7 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/compiler.h>
+#include <linux/crash_dump.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/mfd/core.h>
@@ -2065,6 +2066,44 @@ static struct attribute *zynqmp_firmware_attrs[] = {
 
 ATTRIBUTE_GROUPS(zynqmp_firmware);
 
+/**
+ * zynqmp_clear_pm_state() - Clear subsystem state
+ * @dev: Device pointer used for logging
+ *
+ * Clears PM specific data in EL3 firmware.
+ *
+ * Return: Returns status, either success or error
+ */
+static int zynqmp_clear_pm_state(struct device *dev)
+{
+	u32 pm_family_code;
+	int ret;
+
+	/* Get the Family code of platform */
+	ret = zynqmp_pm_get_family_info(&pm_family_code);
+	if (ret < 0)
+		return ret;
+
+	/* Supporting on Versal and Versal Net platforms only */
+	if (pm_family_code == PM_VERSAL_FAMILY_CODE ||
+	    pm_family_code == PM_VERSAL_NET_FAMILY_CODE) {
+		/* Check if EL3 firmware supports TF_A_CLEAR_PM_STATE */
+		ret = do_feature_check_call(TF_A_CLEAR_PM_STATE);
+		if (ret >= 0 && ((ret & FIRMWARE_VERSION_MASK) >= PM_API_VERSION_1)) {
+			/* Clear PM specific data in EL3 firmware */
+			ret = zynqmp_pm_invoke_fn(TF_A_CLEAR_PM_STATE, NULL, 0);
+			if (ret)
+				dev_err(dev,
+					"Failed to clear EL3 PM subsystem state: %d\n", ret);
+		} else {
+			dev_warn(dev, "TF_A_CLEAR_PM_STATE is not supported by EL3 firmware: %d\n", ret);
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+
 static int zynqmp_firmware_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -2118,6 +2157,9 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
+	if (is_kdump_kernel())
+		zynqmp_clear_pm_state(dev);
+
 	/* Check trustzone version number */
 	ret = zynqmp_pm_get_trustzone_version(&pm_tz_version);
 	if (ret)
@@ -2151,6 +2193,11 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)
 	return of_platform_populate(dev->of_node, NULL, NULL, dev);
 }
 
+static void zynqmp_firmware_shutdown(struct platform_device *pdev)
+{
+	zynqmp_clear_pm_state(&pdev->dev);
+}
+
 static void zynqmp_firmware_remove(struct platform_device *pdev)
 {
 	struct pm_api_feature_data *feature_data;
@@ -2210,5 +2257,6 @@ static struct platform_driver zynqmp_firmware_driver = {
 	},
 	.probe = zynqmp_firmware_probe,
 	.remove = zynqmp_firmware_remove,
+	.shutdown = zynqmp_firmware_shutdown,
 };
 module_platform_driver(zynqmp_firmware_driver);
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 7e27b0f7bf7e..baaa88b0b197 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -3,7 +3,7 @@
  * Xilinx Zynq MPSoC Firmware layer
  *
  *  Copyright (C) 2014-2021 Xilinx
- *  Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc.
+ *  Copyright (C) 2022 - 2026 Advanced Micro Devices, Inc.
  *
  *  Michal Simek <michal.simek@amd.com>
  *  Davorin Mista <davorin.mista@aggios.com>
@@ -66,6 +66,7 @@
 #define FIRMWARE_VERSION_MASK		0xFFFFU
 
 /* ATF only commands */
+#define TF_A_CLEAR_PM_STATE		0xa05
 #define TF_A_PM_REGISTER_SGI		0xa04
 #define PM_GET_TRUSTZONE_VERSION	0xa03
 #define PM_SET_SUSPEND_MODE		0xa02
-- 
2.34.1



  reply	other threads:[~2026-07-29 12:26 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-23 12:48 [PATCH 0/4] firmware: xilinx: Clean up firmware and TF-A state on kexec Jay Buddhabhatti
2026-07-23 12:48 ` [PATCH 1/4] firmware: xilinx: Add support to clear TF-A PM state Jay Buddhabhatti
2026-07-23 16:25   ` Pandey, Radhey Shyam
2026-07-24  6:17   ` Prasanna Kumar T S M
2026-07-23 12:48 ` [PATCH 2/4] firmware: xilinx: Release all peripheral devices from firmware Jay Buddhabhatti
2026-07-23 16:25   ` Pandey, Radhey Shyam
2026-07-24  6:17   ` Prasanna Kumar T S M
2026-07-23 12:48 ` [PATCH 3/4] firmware: xilinx: Clear firmware notifiers across kexec transitions Jay Buddhabhatti
2026-07-23 16:27   ` Pandey, Radhey Shyam
2026-07-24  6:18   ` Prasanna Kumar T S M
2026-07-23 12:48 ` [PATCH 4/4] firmware: xilinx: Use TF-A feature check for TF-A specific APIs Jay Buddhabhatti
2026-07-23 16:28   ` Pandey, Radhey Shyam
2026-07-24  6:31   ` Prasanna Kumar T S M
2026-07-24  7:37     ` Buddhabhatti, Jay
2026-07-24  9:52 ` [PATCH v2 0/3] firmware: xilinx: Clean up firmware and TF-A state on kexec Jay Buddhabhatti
2026-07-24  9:52   ` [PATCH v2 1/4] firmware: xilinx: Add support to clear TF-A PM state Jay Buddhabhatti
2026-07-24  9:53   ` [PATCH v2 2/4] firmware: xilinx: Release all peripheral devices from firmware Jay Buddhabhatti
2026-07-24  9:53   ` [PATCH v2 3/4] firmware: xilinx: Clear firmware notifiers across kexec transitions Jay Buddhabhatti
2026-07-24 10:19   ` [PATCH v3 0/3] firmware: xilinx: Clean up firmware and TF-A state on kexec Jay Buddhabhatti
2026-07-24 10:19     ` [PATCH v3 1/3] firmware: xilinx: Add support to clear TF-A PM state Jay Buddhabhatti
2026-07-24 11:13       ` Sudeep Holla
2026-07-29  7:05         ` Jay Buddhabhatti
2026-07-24 10:19     ` [PATCH v3 2/3] firmware: xilinx: Release all peripheral devices from firmware Jay Buddhabhatti
2026-07-24 10:19     ` [PATCH v3 3/3] firmware: xilinx: Clear firmware notifiers across kexec transitions Jay Buddhabhatti
2026-07-29 12:25     ` [PATCH v4 0/3] firmware: xilinx: Clean up firmware and EL3 state on kexec Jay Buddhabhatti
2026-07-29 12:25       ` Jay Buddhabhatti [this message]
2026-07-29 12:25       ` [PATCH v4 2/3] firmware: xilinx: Release all peripheral devices from firmware Jay Buddhabhatti
2026-07-29 12:25       ` [PATCH v4 3/3] firmware: xilinx: Clear firmware notifiers across kexec transitions Jay Buddhabhatti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260729122522.3732875-2-jay.buddhabhatti@amd.com \
    --to=jay.buddhabhatti@amd.com \
    --cc=git@amd.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michal.simek@amd.com \
    --cc=ptsm@linux.microsoft.com \
    --cc=radhey.shyam.pandey@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox