drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++ drivers/firmware/efi/runtime-wrappers.c | 14 +++------ include/linux/efi.h | 10 ++++++ 3 files changed, 55 insertions(+), 10 deletions(-)
On platforms that allows to update firmware in runtime, UpdateCapsule()
may immediately write a firmware image to persistent storage.
This operation can take longer than EFI_RTS_TIMEOUT.
Use a separate timeout for the UpdateCapsule() runtime service. By
default, wait indefinitely to avoid interrupting an ongoing firmware
update. Administrators may configure an appropriate timeout, in seconds,
through /sys/firmware/efi/capsule_update_timeout.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++
drivers/firmware/efi/runtime-wrappers.c | 14 +++------
include/linux/efi.h | 10 ++++++
3 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 0327a39d31fa..aef0ba170e3c 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -63,6 +63,18 @@ static unsigned long __initdata mem_reserve = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR;
+/*
+ * Depending on the platform, UpdateCapsule() may update the firmware
+ * immediately if the platform allows to update the firmware while in runtime.
+ * In this case, writing the image to firmware storage may take longer than
+ * EFI_RTS_TIMEOUT (120 seconds).
+ *
+ * To handle this, use a separate timeout for the UpdateCapsule() runtime
+ * service. Wait indefinitely by default, and allow administrators to set
+ * an appropriate timeout in seconds through /sys/firmware/efi/capsule_update_timeout.
+ */
+unsigned long efi_capsule_update_timeout = MAX_SCHEDULE_TIMEOUT;
+
extern unsigned long primary_display_table;
struct mm_struct efi_mm = {
@@ -163,15 +175,44 @@ static ssize_t fw_platform_size_show(struct kobject *kobj,
return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
}
+static ssize_t capsule_update_timeout_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "%lu\n", efi_capsule_update_timeout / HZ);
+}
+
+static ssize_t capsule_update_timeout_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+ unsigned long secs, timeout;
+
+ ret = kstrtoul(buf, 0, &secs);
+ if (ret)
+ return ret;
+ if (check_mul_overflow(secs, HZ, &timeout))
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ if (timeout < EFI_RTS_TIMEOUT)
+ timeout = EFI_RTS_TIMEOUT;
+
+ efi_capsule_update_timeout = timeout;
+
+ return count;
+}
+
extern __weak struct kobj_attribute efi_attr_fw_vendor;
extern __weak struct kobj_attribute efi_attr_runtime;
extern __weak struct kobj_attribute efi_attr_config_table;
static struct kobj_attribute efi_attr_fw_platform_size =
__ATTR_RO(fw_platform_size);
+static struct kobj_attribute efi_attr_capsule_update_timeout =
+ __ATTR_RW_MODE(capsule_update_timeout, 0600);
static struct attribute *efi_subsys_attrs[] = {
&efi_attr_systab.attr,
&efi_attr_fw_platform_size.attr,
+ &efi_attr_capsule_update_timeout.attr,
&efi_attr_fw_vendor.attr,
&efi_attr_runtime.attr,
&efi_attr_config_table.attr,
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
index 2344b9d1e81f..b0f867f828c1 100644
--- a/drivers/firmware/efi/runtime-wrappers.c
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -118,14 +118,6 @@ union efi_rts_args {
struct efi_runtime_work efi_rts_work;
-/*
- * Upper bound on how long we wait for a single EFI runtime service
- * call to finish before declaring firmware wedged. Chosen to be longer
- * than any plausible legitimate call (including UpdateCapsule on slow
- * SPI-NOR) while still bounding userspace wait time.
- */
-#define EFI_RTS_TIMEOUT (120 * HZ)
-
/*
* efi_queue_work: Queue EFI runtime service call and wait for completion
* @_rts: EFI runtime service function identifier
@@ -347,6 +339,8 @@ static void __nocfi efi_call_rts(struct work_struct *work)
static efi_status_t __efi_queue_work(enum efi_rts_ids id,
union efi_rts_args *args)
{
+ unsigned long timeout;
+
if (!efi_enabled(EFI_RUNTIME_SERVICES)) {
pr_warn_once("EFI Runtime Services are disabled!\n");
return EFI_DEVICE_ERROR;
@@ -369,8 +363,8 @@ static efi_status_t __efi_queue_work(enum efi_rts_ids id,
goto exit;
}
- if (!wait_for_completion_timeout(&efi_rts_work.efi_rts_comp,
- EFI_RTS_TIMEOUT)) {
+ timeout = (id == EFI_UPDATE_CAPSULE) ? efi_capsule_update_timeout : EFI_RTS_TIMEOUT;
+ if (!wait_for_completion_timeout(&efi_rts_work.efi_rts_comp, timeout)) {
pr_err("EFI runtime service %d wedged in firmware; disabling EFI runtime services\n",
id);
clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index aa15ff88539b..8e14ca5e57de 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1345,4 +1345,14 @@ extern struct blocking_notifier_head efivar_ops_nh;
void efivars_generic_ops_register(void);
void efivars_generic_ops_unregister(void);
+/*
+ * Upper bound on how long we wait for a single EFI runtime service
+ * call to finish before declaring firmware wedged. Chosen to be longer
+ * than any plausible legitimate call (excluding UpdateCapsule() while
+ * still bounding userspace wait time.
+ */
+#define EFI_RTS_TIMEOUT (120 * HZ)
+
+extern unsigned long efi_capsule_update_timeout;
+
#endif /* _LINUX_EFI_H */
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
Hello Yeoreum Yun,
On Thu, 3 Sep 2026, at 13:32, Yeoreum Yun wrote:
> On platforms that allows to update firmware in runtime, UpdateCapsule()
> may immediately write a firmware image to persistent storage.
> This operation can take longer than EFI_RTS_TIMEOUT.
>
> Use a separate timeout for the UpdateCapsule() runtime service. By
> default, wait indefinitely to avoid interrupting an ongoing firmware
> update. Administrators may configure an appropriate timeout, in seconds,
> through /sys/firmware/efi/capsule_update_timeout.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
> drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++
> drivers/firmware/efi/runtime-wrappers.c | 14 +++------
> include/linux/efi.h | 10 ++++++
> 3 files changed, 55 insertions(+), 10 deletions(-)
>
Given that UpdateCapsule() is rarely used these days at runtime, I
wonder if we should just call it synchronously instead of via the
EFI workqueue.
I assume that would also solve the timeout issue?
> diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
> index 0327a39d31fa..aef0ba170e3c 100644
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -63,6 +63,18 @@ static unsigned long __initdata mem_reserve =
> EFI_INVALID_TABLE_ADDR;
> static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR;
> static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR;
>
> +/*
> + * Depending on the platform, UpdateCapsule() may update the firmware
> + * immediately if the platform allows to update the firmware while in
> runtime.
> + * In this case, writing the image to firmware storage may take longer
> than
> + * EFI_RTS_TIMEOUT (120 seconds).
> + *
> + * To handle this, use a separate timeout for the UpdateCapsule()
> runtime
> + * service. Wait indefinitely by default, and allow administrators to
> set
> + * an appropriate timeout in seconds through
> /sys/firmware/efi/capsule_update_timeout.
> + */
> +unsigned long efi_capsule_update_timeout = MAX_SCHEDULE_TIMEOUT;
> +
> extern unsigned long primary_display_table;
>
> struct mm_struct efi_mm = {
> @@ -163,15 +175,44 @@ static ssize_t fw_platform_size_show(struct kobject *kobj,
> return sprintf(buf, "%d\n", efi_enabled(EFI_64BIT) ? 64 : 32);
> }
>
> +static ssize_t capsule_update_timeout_show(struct kobject *kobj,
> + struct kobj_attribute *attr, char *buf)
> +{
> + return sysfs_emit(buf, "%lu\n", efi_capsule_update_timeout / HZ);
> +}
> +
> +static ssize_t capsule_update_timeout_store(struct kobject *kobj,
> + struct kobj_attribute *attr,
> + const char *buf, size_t count)
> +{
> + int ret;
> + unsigned long secs, timeout;
> +
> + ret = kstrtoul(buf, 0, &secs);
> + if (ret)
> + return ret;
> + if (check_mul_overflow(secs, HZ, &timeout))
> + timeout = MAX_SCHEDULE_TIMEOUT;
> + if (timeout < EFI_RTS_TIMEOUT)
> + timeout = EFI_RTS_TIMEOUT;
> +
> + efi_capsule_update_timeout = timeout;
> +
> + return count;
> +}
> +
> extern __weak struct kobj_attribute efi_attr_fw_vendor;
> extern __weak struct kobj_attribute efi_attr_runtime;
> extern __weak struct kobj_attribute efi_attr_config_table;
> static struct kobj_attribute efi_attr_fw_platform_size =
> __ATTR_RO(fw_platform_size);
> +static struct kobj_attribute efi_attr_capsule_update_timeout =
> + __ATTR_RW_MODE(capsule_update_timeout, 0600);
>
> static struct attribute *efi_subsys_attrs[] = {
> &efi_attr_systab.attr,
> &efi_attr_fw_platform_size.attr,
> + &efi_attr_capsule_update_timeout.attr,
> &efi_attr_fw_vendor.attr,
> &efi_attr_runtime.attr,
> &efi_attr_config_table.attr,
> diff --git a/drivers/firmware/efi/runtime-wrappers.c
> b/drivers/firmware/efi/runtime-wrappers.c
> index 2344b9d1e81f..b0f867f828c1 100644
> --- a/drivers/firmware/efi/runtime-wrappers.c
> +++ b/drivers/firmware/efi/runtime-wrappers.c
> @@ -118,14 +118,6 @@ union efi_rts_args {
>
> struct efi_runtime_work efi_rts_work;
>
> -/*
> - * Upper bound on how long we wait for a single EFI runtime service
> - * call to finish before declaring firmware wedged. Chosen to be longer
> - * than any plausible legitimate call (including UpdateCapsule on slow
> - * SPI-NOR) while still bounding userspace wait time.
> - */
> -#define EFI_RTS_TIMEOUT (120 * HZ)
> -
> /*
> * efi_queue_work: Queue EFI runtime service call and wait for completion
> * @_rts: EFI runtime service function identifier
> @@ -347,6 +339,8 @@ static void __nocfi efi_call_rts(struct work_struct *work)
> static efi_status_t __efi_queue_work(enum efi_rts_ids id,
> union efi_rts_args *args)
> {
> + unsigned long timeout;
> +
> if (!efi_enabled(EFI_RUNTIME_SERVICES)) {
> pr_warn_once("EFI Runtime Services are disabled!\n");
> return EFI_DEVICE_ERROR;
> @@ -369,8 +363,8 @@ static efi_status_t __efi_queue_work(enum efi_rts_ids id,
> goto exit;
> }
>
> - if (!wait_for_completion_timeout(&efi_rts_work.efi_rts_comp,
> - EFI_RTS_TIMEOUT)) {
> + timeout = (id == EFI_UPDATE_CAPSULE) ? efi_capsule_update_timeout :
> EFI_RTS_TIMEOUT;
> + if (!wait_for_completion_timeout(&efi_rts_work.efi_rts_comp,
> timeout)) {
> pr_err("EFI runtime service %d wedged in firmware; disabling EFI
> runtime services\n",
> id);
> clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index aa15ff88539b..8e14ca5e57de 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -1345,4 +1345,14 @@ extern struct blocking_notifier_head
> efivar_ops_nh;
> void efivars_generic_ops_register(void);
> void efivars_generic_ops_unregister(void);
>
> +/*
> + * Upper bound on how long we wait for a single EFI runtime service
> + * call to finish before declaring firmware wedged. Chosen to be longer
> + * than any plausible legitimate call (excluding UpdateCapsule() while
> + * still bounding userspace wait time.
> + */
> +#define EFI_RTS_TIMEOUT (120 * HZ)
> +
> +extern unsigned long efi_capsule_update_timeout;
> +
> #endif /* _LINUX_EFI_H */
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
Hi Ard, > Hello Yeoreum Yun, > > On Thu, 3 Sep 2026, at 13:32, Yeoreum Yun wrote: > > On platforms that allows to update firmware in runtime, UpdateCapsule() > > may immediately write a firmware image to persistent storage. > > This operation can take longer than EFI_RTS_TIMEOUT. > > > > Use a separate timeout for the UpdateCapsule() runtime service. By > > default, wait indefinitely to avoid interrupting an ongoing firmware > > update. Administrators may configure an appropriate timeout, in seconds, > > through /sys/firmware/efi/capsule_update_timeout. > > > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > > --- > > drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++ > > drivers/firmware/efi/runtime-wrappers.c | 14 +++------ > > include/linux/efi.h | 10 ++++++ > > 3 files changed, 55 insertions(+), 10 deletions(-) > > > > Given that UpdateCapsule() is rarely used these days at runtime, I > wonder if we should just call it synchronously instead of via the > EFI workqueue. > > I assume that would also solve the timeout issue? Might be. But it would make *non-preemptible* for UpdateCapsule(). AFAIK the purpose of running runtime service with efi_queue to run it in indepdent context and to be preemtible in case of arm64. Since most of UpdateCapsule() will be called via capsule-loader's misc device, if UpdateCaspule() is called synchronously, It would be non-preemtible in arm64 platform. But, some platform could be preemptible while updating firmware so I think it would be better that it would be called via EFI workqueue. [...] Thanks! -- Sincerely, Yeoreum Yun
On Thu, 3 Sep 2026, at 16:10, Yeoreum Yun wrote: > Hi Ard, > >> Hello Yeoreum Yun, >> >> On Thu, 3 Sep 2026, at 13:32, Yeoreum Yun wrote: >> > On platforms that allows to update firmware in runtime, UpdateCapsule() >> > may immediately write a firmware image to persistent storage. >> > This operation can take longer than EFI_RTS_TIMEOUT. >> > >> > Use a separate timeout for the UpdateCapsule() runtime service. By >> > default, wait indefinitely to avoid interrupting an ongoing firmware >> > update. Administrators may configure an appropriate timeout, in seconds, >> > through /sys/firmware/efi/capsule_update_timeout. >> > >> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> >> > --- >> > drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++ >> > drivers/firmware/efi/runtime-wrappers.c | 14 +++------ >> > include/linux/efi.h | 10 ++++++ >> > 3 files changed, 55 insertions(+), 10 deletions(-) >> > >> >> Given that UpdateCapsule() is rarely used these days at runtime, I >> wonder if we should just call it synchronously instead of via the >> EFI workqueue. >> >> I assume that would also solve the timeout issue? > > Might be. But it would make *non-preemptible* for UpdateCapsule(). > AFAIK the purpose of running runtime service with efi_queue to > run it in indepdent context and to be preemtible in case of arm64. > No. > Since most of UpdateCapsule() will be called via capsule-loader's misc > device, if UpdateCaspule() is called synchronously, It would be > non-preemtible in arm64 platform. > > But, some platform could be preemptible while updating firmware so > I think it would be better that it would be called via EFI workqueue. > EFI runtime service invocations are preemptible on arm64, so this is not a problem.
On Thu, 3 Sep 2026, at 16:29, Ard Biesheuvel wrote: > On Thu, 3 Sep 2026, at 16:10, Yeoreum Yun wrote: >> Hi Ard, >> >>> Hello Yeoreum Yun, >>> >>> On Thu, 3 Sep 2026, at 13:32, Yeoreum Yun wrote: >>> > On platforms that allows to update firmware in runtime, UpdateCapsule() >>> > may immediately write a firmware image to persistent storage. >>> > This operation can take longer than EFI_RTS_TIMEOUT. >>> > >>> > Use a separate timeout for the UpdateCapsule() runtime service. By >>> > default, wait indefinitely to avoid interrupting an ongoing firmware >>> > update. Administrators may configure an appropriate timeout, in seconds, >>> > through /sys/firmware/efi/capsule_update_timeout. >>> > >>> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> >>> > --- >>> > drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++ >>> > drivers/firmware/efi/runtime-wrappers.c | 14 +++------ >>> > include/linux/efi.h | 10 ++++++ >>> > 3 files changed, 55 insertions(+), 10 deletions(-) >>> > >>> >>> Given that UpdateCapsule() is rarely used these days at runtime, I >>> wonder if we should just call it synchronously instead of via the >>> EFI workqueue. >>> >>> I assume that would also solve the timeout issue? >> >> Might be. But it would make *non-preemptible* for UpdateCapsule(). >> AFAIK the purpose of running runtime service with efi_queue to >> run it in indepdent context and to be preemtible in case of arm64. >> > > No. > >> Since most of UpdateCapsule() will be called via capsule-loader's misc >> device, if UpdateCaspule() is called synchronously, It would be >> non-preemtible in arm64 platform. >> >> But, some platform could be preemptible while updating firmware so >> I think it would be better that it would be called via EFI workqueue. >> > > EFI runtime service invocations are preemptible on arm64, so this is > not a problem. Ah wait - you're right, they are only preemptible when invoked from the work queue.
> On Thu, 3 Sep 2026, at 16:29, Ard Biesheuvel wrote: > > On Thu, 3 Sep 2026, at 16:10, Yeoreum Yun wrote: > >> Hi Ard, > >> > >>> Hello Yeoreum Yun, > >>> > >>> On Thu, 3 Sep 2026, at 13:32, Yeoreum Yun wrote: > >>> > On platforms that allows to update firmware in runtime, UpdateCapsule() > >>> > may immediately write a firmware image to persistent storage. > >>> > This operation can take longer than EFI_RTS_TIMEOUT. > >>> > > >>> > Use a separate timeout for the UpdateCapsule() runtime service. By > >>> > default, wait indefinitely to avoid interrupting an ongoing firmware > >>> > update. Administrators may configure an appropriate timeout, in seconds, > >>> > through /sys/firmware/efi/capsule_update_timeout. > >>> > > >>> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > >>> > --- > >>> > drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++ > >>> > drivers/firmware/efi/runtime-wrappers.c | 14 +++------ > >>> > include/linux/efi.h | 10 ++++++ > >>> > 3 files changed, 55 insertions(+), 10 deletions(-) > >>> > > >>> > >>> Given that UpdateCapsule() is rarely used these days at runtime, I > >>> wonder if we should just call it synchronously instead of via the > >>> EFI workqueue. > >>> > >>> I assume that would also solve the timeout issue? > >> > >> Might be. But it would make *non-preemptible* for UpdateCapsule(). > >> AFAIK the purpose of running runtime service with efi_queue to > >> run it in indepdent context and to be preemtible in case of arm64. > >> > > > > No. > > > >> Since most of UpdateCapsule() will be called via capsule-loader's misc > >> device, if UpdateCaspule() is called synchronously, It would be > >> non-preemtible in arm64 platform. > >> > >> But, some platform could be preemptible while updating firmware so > >> I think it would be better that it would be called via EFI workqueue. > >> > > > > EFI runtime service invocations are preemptible on arm64, so this is > > not a problem. > > Ah wait - you're right, they are only preemptible when invoked from the > work queue. Yes. That's why I think it would be better to call via EFI workqueue when I see arch_efi_call_virt_setup(). -- Sincerely, Yeoreum Yun
> > On Thu, 3 Sep 2026, at 16:29, Ard Biesheuvel wrote: > > > On Thu, 3 Sep 2026, at 16:10, Yeoreum Yun wrote: > > >> Hi Ard, > > >> > > >>> Hello Yeoreum Yun, > > >>> > > >>> On Thu, 3 Sep 2026, at 13:32, Yeoreum Yun wrote: > > >>> > On platforms that allows to update firmware in runtime, UpdateCapsule() > > >>> > may immediately write a firmware image to persistent storage. > > >>> > This operation can take longer than EFI_RTS_TIMEOUT. > > >>> > > > >>> > Use a separate timeout for the UpdateCapsule() runtime service. By > > >>> > default, wait indefinitely to avoid interrupting an ongoing firmware > > >>> > update. Administrators may configure an appropriate timeout, in seconds, > > >>> > through /sys/firmware/efi/capsule_update_timeout. > > >>> > > > >>> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > > >>> > --- > > >>> > drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++ > > >>> > drivers/firmware/efi/runtime-wrappers.c | 14 +++------ > > >>> > include/linux/efi.h | 10 ++++++ > > >>> > 3 files changed, 55 insertions(+), 10 deletions(-) > > >>> > > > >>> > > >>> Given that UpdateCapsule() is rarely used these days at runtime, I > > >>> wonder if we should just call it synchronously instead of via the > > >>> EFI workqueue. > > >>> > > >>> I assume that would also solve the timeout issue? > > >> > > >> Might be. But it would make *non-preemptible* for UpdateCapsule(). > > >> AFAIK the purpose of running runtime service with efi_queue to > > >> run it in indepdent context and to be preemtible in case of arm64. > > >> > > > > > > No. > > > > > >> Since most of UpdateCapsule() will be called via capsule-loader's misc > > >> device, if UpdateCaspule() is called synchronously, It would be > > >> non-preemtible in arm64 platform. > > >> > > >> But, some platform could be preemptible while updating firmware so > > >> I think it would be better that it would be called via EFI workqueue. > > >> > > > > > > EFI runtime service invocations are preemptible on arm64, so this is > > > not a problem. > > > > Ah wait - you're right, they are only preemptible when invoked from the > > work queue. > > Yes. That's why I think it would be better to call via EFI workqueue > when I see arch_efi_call_virt_setup(). Hi Ard, Could there be any issues with doing it this way, or would there be a better approach? -- Sincerely, Yeoreum Yun
On Tue, 15 Sep 2026, at 10:49, Yeoreum Yun wrote: >> > On Thu, 3 Sep 2026, at 16:29, Ard Biesheuvel wrote: >> > > On Thu, 3 Sep 2026, at 16:10, Yeoreum Yun wrote: >> > >> Hi Ard, >> > >> >> > >>> Hello Yeoreum Yun, >> > >>> >> > >>> On Thu, 3 Sep 2026, at 13:32, Yeoreum Yun wrote: >> > >>> > On platforms that allows to update firmware in runtime, UpdateCapsule() >> > >>> > may immediately write a firmware image to persistent storage. >> > >>> > This operation can take longer than EFI_RTS_TIMEOUT. >> > >>> > >> > >>> > Use a separate timeout for the UpdateCapsule() runtime service. By >> > >>> > default, wait indefinitely to avoid interrupting an ongoing firmware >> > >>> > update. Administrators may configure an appropriate timeout, in seconds, >> > >>> > through /sys/firmware/efi/capsule_update_timeout. >> > >>> > >> > >>> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> >> > >>> > --- >> > >>> > drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++ >> > >>> > drivers/firmware/efi/runtime-wrappers.c | 14 +++------ >> > >>> > include/linux/efi.h | 10 ++++++ >> > >>> > 3 files changed, 55 insertions(+), 10 deletions(-) >> > >>> > >> > >>> >> > >>> Given that UpdateCapsule() is rarely used these days at runtime, I >> > >>> wonder if we should just call it synchronously instead of via the >> > >>> EFI workqueue. >> > >>> >> > >>> I assume that would also solve the timeout issue? >> > >> >> > >> Might be. But it would make *non-preemptible* for UpdateCapsule(). >> > >> AFAIK the purpose of running runtime service with efi_queue to >> > >> run it in indepdent context and to be preemtible in case of arm64. >> > >> >> > > >> > > No. >> > > >> > >> Since most of UpdateCapsule() will be called via capsule-loader's misc >> > >> device, if UpdateCaspule() is called synchronously, It would be >> > >> non-preemtible in arm64 platform. >> > >> >> > >> But, some platform could be preemptible while updating firmware so >> > >> I think it would be better that it would be called via EFI workqueue. >> > >> >> > > >> > > EFI runtime service invocations are preemptible on arm64, so this is >> > > not a problem. >> > >> > Ah wait - you're right, they are only preemptible when invoked from the >> > work queue. >> >> Yes. That's why I think it would be better to call via EFI workqueue >> when I see arch_efi_call_virt_setup(). > > Hi Ard, > > Could there be any issues with doing it this way, or would there be > a better approach? > Would it make sense to simply have different limits for UpdateCapsule() and for everything else? How much longer than 2 minutes do you need in the typical case?
Hi Ard, > > On Tue, 15 Sep 2026, at 10:49, Yeoreum Yun wrote: > >> > On Thu, 3 Sep 2026, at 16:29, Ard Biesheuvel wrote: > >> > > On Thu, 3 Sep 2026, at 16:10, Yeoreum Yun wrote: > >> > >> Hi Ard, > >> > >> > >> > >>> Hello Yeoreum Yun, > >> > >>> > >> > >>> On Thu, 3 Sep 2026, at 13:32, Yeoreum Yun wrote: > >> > >>> > On platforms that allows to update firmware in runtime, UpdateCapsule() > >> > >>> > may immediately write a firmware image to persistent storage. > >> > >>> > This operation can take longer than EFI_RTS_TIMEOUT. > >> > >>> > > >> > >>> > Use a separate timeout for the UpdateCapsule() runtime service. By > >> > >>> > default, wait indefinitely to avoid interrupting an ongoing firmware > >> > >>> > update. Administrators may configure an appropriate timeout, in seconds, > >> > >>> > through /sys/firmware/efi/capsule_update_timeout. > >> > >>> > > >> > >>> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com> > >> > >>> > --- > >> > >>> > drivers/firmware/efi/efi.c | 41 +++++++++++++++++++++++++ > >> > >>> > drivers/firmware/efi/runtime-wrappers.c | 14 +++------ > >> > >>> > include/linux/efi.h | 10 ++++++ > >> > >>> > 3 files changed, 55 insertions(+), 10 deletions(-) > >> > >>> > > >> > >>> > >> > >>> Given that UpdateCapsule() is rarely used these days at runtime, I > >> > >>> wonder if we should just call it synchronously instead of via the > >> > >>> EFI workqueue. > >> > >>> > >> > >>> I assume that would also solve the timeout issue? > >> > >> > >> > >> Might be. But it would make *non-preemptible* for UpdateCapsule(). > >> > >> AFAIK the purpose of running runtime service with efi_queue to > >> > >> run it in indepdent context and to be preemtible in case of arm64. > >> > >> > >> > > > >> > > No. > >> > > > >> > >> Since most of UpdateCapsule() will be called via capsule-loader's misc > >> > >> device, if UpdateCaspule() is called synchronously, It would be > >> > >> non-preemtible in arm64 platform. > >> > >> > >> > >> But, some platform could be preemptible while updating firmware so > >> > >> I think it would be better that it would be called via EFI workqueue. > >> > >> > >> > > > >> > > EFI runtime service invocations are preemptible on arm64, so this is > >> > > not a problem. > >> > > >> > Ah wait - you're right, they are only preemptible when invoked from the > >> > work queue. > >> > >> Yes. That's why I think it would be better to call via EFI workqueue > >> when I see arch_efi_call_virt_setup(). > > > > Hi Ard, > > > > Could there be any issues with doing it this way, or would there be > > a better approach? > > > > Would it make sense to simply have different limits for UpdateCapsule() and > for everything else? How much longer than 2 minutes do you need in the > typical case? Although the time required to complete a firmware update depends onthe platform and other factors, such as whether the capsule contains a single firmware image or multiple images, it is generally reasonable to expect the update to complete within 10 minutes. If, for some reason, an update is expected to take longer than 10 minutes, the sysfs interface for configuring capsule_update_timeout would be useful. This would allow the timeout to be adjusted as needed, for example to 15 minutes, before capsule update. Am I missing something? -- Sincerely, Yeoreum Yun
© 2016 - 2026 Red Hat, Inc.