Allow to do finalize and abort from kernel modules, so LUO could
drive the KHO sequence via its own state machine.
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
---
include/linux/kexec_handover.h | 15 +++++++
kernel/kexec_handover.c | 74 ++++++++++++++++++++--------------
2 files changed, 59 insertions(+), 30 deletions(-)
diff --git a/include/linux/kexec_handover.h b/include/linux/kexec_handover.h
index 25042c1d8d54..04d0108db98e 100644
--- a/include/linux/kexec_handover.h
+++ b/include/linux/kexec_handover.h
@@ -67,6 +67,10 @@ void kho_memory_init(void);
void kho_populate(phys_addr_t fdt_phys, u64 fdt_len, phys_addr_t scratch_phys,
u64 scratch_len);
+
+int kho_finalize(void);
+int kho_abort(void);
+
#else
static inline bool kho_is_enabled(void)
{
@@ -139,6 +143,17 @@ static inline void kho_populate(phys_addr_t fdt_phys, u64 fdt_len,
phys_addr_t scratch_phys, u64 scratch_len)
{
}
+
+static inline int kho_finalize(void)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int kho_abort(void)
+{
+ return -EOPNOTSUPP;
+}
+
#endif /* CONFIG_KEXEC_HANDOVER */
#endif /* LINUX_KEXEC_HANDOVER_H */
diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c
index 76f0940fb485..76c34ea923f0 100644
--- a/kernel/kexec_handover.c
+++ b/kernel/kexec_handover.c
@@ -1067,7 +1067,7 @@ static int kho_out_update_debugfs_fdt(void)
return err;
}
-static int kho_abort(void)
+static int __kho_abort(void)
{
int err;
unsigned long order;
@@ -1100,7 +1100,27 @@ static int kho_abort(void)
return err;
}
-static int kho_finalize(void)
+int kho_abort(void)
+{
+ int ret = 0;
+
+ if (!kho_enable)
+ return -EOPNOTSUPP;
+
+ guard(mutex)(&kho_out.lock);
+ if (!kho_out.finalized)
+ return -ENOENT;
+
+ ret = __kho_abort();
+ if (ret)
+ return ret;
+
+ kho_out.finalized = false;
+
+ return kho_out_update_debugfs_fdt();
+}
+
+static int __kho_finalize(void)
{
int err = 0;
u64 *preserved_mem_map;
@@ -1143,12 +1163,32 @@ static int kho_finalize(void)
abort:
if (err) {
pr_err("Failed to convert KHO state tree: %d\n", err);
- kho_abort();
+ __kho_abort();
}
return err;
}
+int kho_finalize(void)
+{
+ int ret;
+
+ if (!kho_enable)
+ return -EOPNOTSUPP;
+
+ guard(mutex)(&kho_out.lock);
+ if (kho_out.finalized)
+ return -EEXIST;
+
+ ret = __kho_finalize();
+ if (ret)
+ return ret;
+
+ kho_out.finalized = true;
+
+ return kho_out_update_debugfs_fdt();
+}
+
static int kho_out_finalize_get(void *data, u64 *val)
{
mutex_lock(&kho_out.lock);
@@ -1160,33 +1200,7 @@ static int kho_out_finalize_get(void *data, u64 *val)
static int kho_out_finalize_set(void *data, u64 _val)
{
- int ret = 0;
- bool val = !!_val;
-
- mutex_lock(&kho_out.lock);
-
- if (val == kho_out.finalized) {
- if (kho_out.finalized)
- ret = -EEXIST;
- else
- ret = -ENOENT;
- goto unlock;
- }
-
- if (val)
- ret = kho_finalize();
- else
- ret = kho_abort();
-
- if (ret)
- goto unlock;
-
- kho_out.finalized = val;
- ret = kho_out_update_debugfs_fdt();
-
-unlock:
- mutex_unlock(&kho_out.lock);
- return ret;
+ return (!!_val) ? kho_finalize() : kho_abort();
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_kho_out_finalize, kho_out_finalize_get,
--
2.51.0.915.g61a8936c21-goog
On Sat, Oct 18, 2025 at 01:17:47PM -0400, Pasha Tatashin wrote:
> Allow to do finalize and abort from kernel modules, so LUO could
We surely don't want modules being able to drive that. Maybe
allow kernel to drive finalize and abort without requiring triggers
from the userspace
> drive the KHO sequence via its own state machine.
>
> Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
> ---
> include/linux/kexec_handover.h | 15 +++++++
> kernel/kexec_handover.c | 74 ++++++++++++++++++++--------------
> 2 files changed, 59 insertions(+), 30 deletions(-)
...
> diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c
> index 76f0940fb485..76c34ea923f0 100644
> --- a/kernel/kexec_handover.c
> +++ b/kernel/kexec_handover.c
> @@ -1067,7 +1067,7 @@ static int kho_out_update_debugfs_fdt(void)
> return err;
> }
>
> -static int kho_abort(void)
> +static int __kho_abort(void)
> {
> int err;
> unsigned long order;
> @@ -1100,7 +1100,27 @@ static int kho_abort(void)
> return err;
> }
>
> -static int kho_finalize(void)
> +int kho_abort(void)
> +{
> + int ret = 0;
> +
> + if (!kho_enable)
> + return -EOPNOTSUPP;
> +
> + guard(mutex)(&kho_out.lock);
Please include linux/cleanup.h explicitly
> + if (!kho_out.finalized)
> + return -ENOENT;
> +
...
> -unlock:
> - mutex_unlock(&kho_out.lock);
> - return ret;
> + return (!!_val) ? kho_finalize() : kho_abort();
An 'if' would be cleared IMO:
if (val)
return kho_finalize();
else
return kho_abort();
and we can rename u64 _val to u64 val as we are dropping the boolean.
> }
--
Sincerely yours,
Mike.
On Mon, Oct 20, 2025 at 3:43 AM Mike Rapoport <rppt@kernel.org> wrote:
>
> On Sat, Oct 18, 2025 at 01:17:47PM -0400, Pasha Tatashin wrote:
> > Allow to do finalize and abort from kernel modules, so LUO could
>
> We surely don't want modules being able to drive that. Maybe
>
> allow kernel to drive finalize and abort without requiring triggers
> from the userspace
done
>
> > drive the KHO sequence via its own state machine.
> >
> > Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> > Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
> > ---
> > include/linux/kexec_handover.h | 15 +++++++
> > kernel/kexec_handover.c | 74 ++++++++++++++++++++--------------
> > 2 files changed, 59 insertions(+), 30 deletions(-)
>
> ...
>
> > diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c
> > index 76f0940fb485..76c34ea923f0 100644
> > --- a/kernel/kexec_handover.c
> > +++ b/kernel/kexec_handover.c
> > @@ -1067,7 +1067,7 @@ static int kho_out_update_debugfs_fdt(void)
> > return err;
> > }
> >
> > -static int kho_abort(void)
> > +static int __kho_abort(void)
> > {
> > int err;
> > unsigned long order;
> > @@ -1100,7 +1100,27 @@ static int kho_abort(void)
> > return err;
> > }
> >
> > -static int kho_finalize(void)
> > +int kho_abort(void)
> > +{
> > + int ret = 0;
> > +
> > + if (!kho_enable)
> > + return -EOPNOTSUPP;
> > +
> > + guard(mutex)(&kho_out.lock);
>
> Please include linux/cleanup.h explicitly
That is going to be included via kfence fixes which will come before this patch.
>
> > + if (!kho_out.finalized)
> > + return -ENOENT;
> > +
>
> ...
>
> > -unlock:
> > - mutex_unlock(&kho_out.lock);
> > - return ret;
> > + return (!!_val) ? kho_finalize() : kho_abort();
>
> An 'if' would be cleared IMO:
>
> if (val)
> return kho_finalize();
> else
> return kho_abort();
>
> and we can rename u64 _val to u64 val as we are dropping the boolean.
done
>
> > }
>
> --
> Sincerely yours,
> Mike.
© 2016 - 2026 Red Hat, Inc.