lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <669f87ac9348a0532589f17a625664cec68e0059.1761796187.git.adrianhoyin.ng@altera.com>
Date: Thu, 30 Oct 2025 11:52:14 +0800
From: adrianhoyin.ng@...era.com
To: dinguyen@...nel.org,
	linux-kernel@...r.kernel.org
Cc: adrianhoyin.ng@...era.com
Subject: [PATCH] firmware: stratix10-svc: Reduce polling interval for command status

From: Adrian Ng Ho Yin <adrianhoyin.ng@...era.com>

The service controller currently polls FPGA configuration status at a
fixed 1 second interval until the 30 second timeout expires. This leads
to slow response time for fast-returning commands and unnecessary delay
before reporting completion.

Introduce two polling modes:
 - Fast polling: 20 ms interval for up to 50 iterations (≈1s total)
 - Slow polling: 500 ms interval for up to 29 seconds

A new helper, svc_cmd_poll_status(), abstracts the polling logic and
replaces the existing loop in svc_thread_cmd_config_status(). This allows
the driver to respond quickly to short operations while still handling
long-running configuration commands within the same overall timeout
window.

Signed-off-by: Adrian Ng Ho Yin <adrianhoyin.ng@...era.com>
---
 drivers/firmware/stratix10-svc.c | 91 +++++++++++++++++++++++---------
 1 file changed, 67 insertions(+), 24 deletions(-)

diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c
index 3acfa067c5dd..adf04ea56735 100644
--- a/drivers/firmware/stratix10-svc.c
+++ b/drivers/firmware/stratix10-svc.c
@@ -36,11 +36,27 @@
  * FPGA_CONFIG_STATUS_TIMEOUT_SEC - poll the FPGA configuration status,
  * service layer will return error to FPGA manager when timeout occurs,
  * timeout is set to 30 seconds (30 * 1000) at Intel Stratix10 SoC.
+ *
+ * SVC_POLL_INTERVAL_MS_FAST - interval for polling the service status
+ * at secure world for fast response commands. Interval is set to 20ms.
+ *
+ * SVC_POLL_INTERVAL_MS_SLOW - interval for polling the service status
+ * at secure world for slow response commands. Interval is set to 500ms.
+ *
+ * SVC_POLL_COUNT_FAST - number of count for polling service status for
+ * fast response commands. Count is set to 50 (50*20ms=1sec)
+ *
+ * SVC_POLL_COUNT_SLOW - number of count for polling service status for
+ * slow response commands. Count is set to 58 (58*500ms=29sec)
  */
 #define SVC_NUM_DATA_IN_FIFO			32
 #define SVC_NUM_CHANNEL				4
 #define FPGA_CONFIG_DATA_CLAIM_TIMEOUT_MS	200
 #define FPGA_CONFIG_STATUS_TIMEOUT_SEC		30
+#define SVC_POLL_INTERVAL_MS_FAST			20
+#define SVC_POLL_INTERVAL_MS_SLOW			500
+#define SVC_POLL_COUNT_FAST					50
+#define SVC_POLL_COUNT_SLOW					58
 #define BYTE_TO_WORD_SIZE              4
 
 /* stratix10 service layer clients */
@@ -370,6 +386,47 @@ static void svc_thread_cmd_data_claim(struct stratix10_svc_controller *ctrl,
 		 wait_for_completion_timeout(&ctrl->complete_status, timeout));
 }
 
+/**
+ * svc_cmd_poll_status() - poll for service status
+ * @p_data: pointer to service data structure
+ * @ctrl: pointer to service layer controller
+ * @res: pointer to store response
+ * @poll_count: pointer to poll count value
+ * @poll_interval_in_ms: interval value in milliseconds
+ *
+ * Check whether the service at secure world has completed, and then inform the
+ * response.
+ */
+static void svc_cmd_poll_status(struct stratix10_svc_data *p_data,
+				struct stratix10_svc_controller *ctrl,
+				struct arm_smccc_res *res,
+				int *poll_count, int poll_interval_in_ms)
+{
+	unsigned long a0, a1, a2;
+
+	a0 = INTEL_SIP_SMC_FPGA_CONFIG_ISDONE;
+	a1 = (unsigned long)p_data->paddr;
+	a2 = (unsigned long)p_data->size;
+
+	if (p_data->command == COMMAND_POLL_SERVICE_STATUS)
+		a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
+
+	while (*poll_count) {
+		ctrl->invoke_fn(a0, a1, a2, 0, 0, 0, 0, 0, res);
+		if (res->a0 == INTEL_SIP_SMC_STATUS_OK ||
+		    res->a0 == INTEL_SIP_SMC_STATUS_ERROR ||
+		    res->a0 == INTEL_SIP_SMC_STATUS_REJECTED)
+			break;
+
+		/*
+		 * request is still in progress, go to sleep then
+		 * poll again
+		 */
+		msleep(poll_interval_in_ms);
+		(*poll_count)--;
+	}
+}
+
 /**
  * svc_thread_cmd_config_status() - check configuration status
  * @ctrl: pointer to service layer controller
@@ -384,8 +441,7 @@ static void svc_thread_cmd_config_status(struct stratix10_svc_controller *ctrl,
 					 struct stratix10_svc_cb_data *cb_data)
 {
 	struct arm_smccc_res res;
-	int count_in_sec;
-	unsigned long a0, a1, a2;
+	int poll_count;
 
 	cb_data->kaddr1 = NULL;
 	cb_data->kaddr2 = NULL;
@@ -394,30 +450,17 @@ static void svc_thread_cmd_config_status(struct stratix10_svc_controller *ctrl,
 
 	pr_debug("%s: polling config status\n", __func__);
 
-	a0 = INTEL_SIP_SMC_FPGA_CONFIG_ISDONE;
-	a1 = (unsigned long)p_data->paddr;
-	a2 = (unsigned long)p_data->size;
-
-	if (p_data->command == COMMAND_POLL_SERVICE_STATUS)
-		a0 = INTEL_SIP_SMC_SERVICE_COMPLETED;
-
-	count_in_sec = FPGA_CONFIG_STATUS_TIMEOUT_SEC;
-	while (count_in_sec) {
-		ctrl->invoke_fn(a0, a1, a2, 0, 0, 0, 0, 0, &res);
-		if ((res.a0 == INTEL_SIP_SMC_STATUS_OK) ||
-		    (res.a0 == INTEL_SIP_SMC_STATUS_ERROR) ||
-		    (res.a0 == INTEL_SIP_SMC_STATUS_REJECTED))
-			break;
-
-		/*
-		 * request is still in progress, wait one second then
-		 * poll again
-		 */
-		msleep(1000);
-		count_in_sec--;
+	poll_count = SVC_POLL_COUNT_FAST;
+	svc_cmd_poll_status(p_data, ctrl, &res, &poll_count,
+			    SVC_POLL_INTERVAL_MS_FAST);
+	/* Increased poll interval if response is still not ready */
+	if (!poll_count) {
+		poll_count = SVC_POLL_COUNT_SLOW;
+		svc_cmd_poll_status(p_data, ctrl, &res, &poll_count,
+				    SVC_POLL_INTERVAL_MS_SLOW);
 	}
 
-	if (!count_in_sec) {
+	if (!poll_count) {
 		pr_err("%s: poll status timeout\n", __func__);
 		cb_data->status = BIT(SVC_STATUS_BUSY);
 	} else if (res.a0 == INTEL_SIP_SMC_STATUS_OK) {
-- 
2.49.GIT


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ