From: Pasha Tatashin <pasha.tatashin@soleen.com>
To: Oskar Gerlicz Kowalczuk <oskar@gerlicz.space>
Cc: Mike Rapoport <rppt@kernel.org>, Baoquan He <bhe@redhat.com>,
Pratyush Yadav <pratyush@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
linux-kernel@vger.kernel.org, kexec@lists.infradead.org,
linux-mm@kvack.org
Subject: Re: [PATCH v3 2/5] kexec: abort liveupdate handover on kernel_kexec() unwind
Date: Mon, 23 Mar 2026 10:12:21 -0400 [thread overview]
Message-ID: <CA+CK2bDvv44+YLX6PcTOX_8eM5iET0RrC3gS4BCjMQRUjOSF1g@mail.gmail.com> (raw)
In-Reply-To: <CA+CK2bCVge7xybLshgLLphHAdRSHMLD3egT1nEyESBUFi7kHCw@mail.gmail.com>
On Sat, Mar 21, 2026 at 7:05 PM Pasha Tatashin
<pasha.tatashin@soleen.com> wrote:
>
> On Sat, Mar 21, 2026 at 10:39 AM Oskar Gerlicz Kowalczuk
> <oskar@gerlicz.space> wrote:
> >
> > liveupdate_reboot() can freeze outgoing session state before the kexec
> > transition completes. v2 only unwound that state when kernel_kexec()
> > returned a non-zero error, which misses the preserve_context path where
> > machine_kexec() can return to the old kernel with error == 0.
> >
> > If that return path skips the abort, outgoing sessions remain stuck in
> > the reboot state and later user space operations cannot make progress.
> >
> > Treat every return to the original kernel after a prepared liveupdate
> > handover as an unwind point and call liveupdate_reboot_abort() there as
> > well.
> >
> > Fixes: 8b32d3ced269 ("kexec: abort liveupdate handover on kernel_kexec() unwind")
> > Signed-off-by: Oskar Gerlicz Kowalczuk <oskar@gerlicz.space>
>
> AFAIK, preserve-context reboot is no longer used; in fact, it is
> currently broken. I tried using it six years ago and hit an old
> spinlock bug in the x86 code that prevented it, which means this path
> touches dead code.
>
> It was originally developed for machines lacking hardware support for
> hibernation, and I can't imagine anyone using it today. (I know Amazon
> is using it for a non intended reason and that is a very specific
> scenario in a costumized kernel that internally fixes the upstream
> bugs, and would not conlict with live update).
>
> During live update, we cannot return to userspace after a successful
> liveupdate_reboot(). We specifically place liveupdate_reboot() in the
> kexec path as the last possible point of failure. Perhap, to guarantee
> this behavior, we could add !KEXEC_JUMP as a dependency to KHO and
> LUO or crash the kernel.
So, I think the right approach to address this issue is simply skip
liveupdate_reboot() call when we are doing preserve context kexec.
With preserve context we are going to get back to the current kernel,
there is absolutly no need to do serialization. So something like this
should work:
https://git.kernel.org/pub/scm/linux/kernel/git/tatashin/linux.git/commit/?h=luo-reboot-sync/rfc/1&id=b13cf19ebbf2f8483a3c5a61a7358611b391edf6
>
> Pasha
>
> > ---
> > include/linux/liveupdate.h | 5 +++++
> > kernel/kexec_core.c | 6 +++++-
> > kernel/liveupdate/luo_core.c | 11 ++++++++++-
> > kernel/liveupdate/luo_internal.h | 1 +
> > kernel/liveupdate/luo_session.c | 23 +++++++++++++++++++++++
> > 5 files changed, 44 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h
> > index dd11fdc76a5f..d93b043a0421 100644
> > --- a/include/linux/liveupdate.h
> > +++ b/include/linux/liveupdate.h
> > @@ -226,6 +226,7 @@ bool liveupdate_enabled(void);
> >
> > /* Called during kexec to tell LUO that entered into reboot */
> > int liveupdate_reboot(void);
> > +void liveupdate_reboot_abort(void);
> >
> > int liveupdate_register_file_handler(struct liveupdate_file_handler *fh);
> > int liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh);
> > @@ -250,6 +251,10 @@ static inline int liveupdate_reboot(void)
> > return 0;
> > }
> >
> > +static inline void liveupdate_reboot_abort(void)
> > +{
> > +}
> > +
> > static inline int liveupdate_register_file_handler(struct liveupdate_file_handler *fh)
> > {
> > return -EOPNOTSUPP;
> > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> > index 2fea396d29b9..95710a7d5e56 100644
> > --- a/kernel/kexec_core.c
> > +++ b/kernel/kexec_core.c
> > @@ -1139,6 +1139,7 @@ bool kexec_load_permitted(int kexec_image_type)
> > int kernel_kexec(void)
> > {
> > int error = 0;
> > + bool liveupdate_prepared = false;
> >
> > if (!kexec_trylock())
> > return -EBUSY;
> > @@ -1147,6 +1148,7 @@ int kernel_kexec(void)
> > goto Unlock;
> > }
> >
> > + liveupdate_prepared = true;
> > error = liveupdate_reboot();
> > if (error)
> > goto Unlock;
> > @@ -1230,7 +1232,9 @@ int kernel_kexec(void)
> > }
> > #endif
> >
> > - Unlock:
> > +Unlock:
> > + if (liveupdate_prepared)
> > + liveupdate_reboot_abort();
> > kexec_unlock();
> > return error;
> > }
> > diff --git a/kernel/liveupdate/luo_core.c b/kernel/liveupdate/luo_core.c
> > index dda7bb57d421..95a0b81ce60d 100644
> > --- a/kernel/liveupdate/luo_core.c
> > +++ b/kernel/liveupdate/luo_core.c
> > @@ -233,8 +233,9 @@ int liveupdate_reboot(void)
> > err = kho_finalize();
> > if (err) {
> > pr_err("kho_finalize failed %d\n", err);
> > + liveupdate_reboot_abort();
> > /*
> > - * kho_finalize() may return libfdt errors, to aboid passing to
> > + * kho_finalize() may return libfdt errors, to avoid passing to
> > * userspace unknown errors, change this to EAGAIN.
> > */
> > err = -EAGAIN;
> > @@ -243,6 +244,14 @@ int liveupdate_reboot(void)
> > return err;
> > }
> >
> > +void liveupdate_reboot_abort(void)
> > +{
> > + if (!liveupdate_enabled())
> > + return;
> > +
> > + luo_session_abort_reboot();
> > +}
> > +
> > /**
> > * liveupdate_enabled - Check if the live update feature is enabled.
> > *
> > diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_internal.h
> > index 0cfc0269d746..8a6b1f6c9b4f 100644
> > --- a/kernel/liveupdate/luo_internal.h
> > +++ b/kernel/liveupdate/luo_internal.h
> > @@ -88,6 +88,7 @@ int luo_session_retrieve(const char *name, struct file **filep);
> > int __init luo_session_setup_outgoing(void *fdt);
> > int __init luo_session_setup_incoming(void *fdt);
> > int luo_session_serialize(void);
> > +void luo_session_abort_reboot(void);
> > int luo_session_deserialize(void);
> > bool luo_session_quiesce(void);
> > void luo_session_resume(void);
> > diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c
> > index d97ec91e1118..200dd3b8229c 100644
> > --- a/kernel/liveupdate/luo_session.c
> > +++ b/kernel/liveupdate/luo_session.c
> > @@ -788,6 +788,29 @@ int luo_session_serialize(void)
> > return err;
> > }
> >
> > +void luo_session_abort_reboot(void)
> > +{
> > + struct luo_session_header *sh = &luo_session_global.outgoing;
> > + struct luo_session *session;
> > + int i = 0;
> > +
> > + guard(rwsem_write)(&sh->rwsem);
> > + if (!READ_ONCE(sh->rebooting))
> > + return;
> > +
> > + list_for_each_entry(session, &sh->list, list) {
> > + if (i >= sh->header_ser->count)
> > + break;
> > +
> > + luo_session_unfreeze_one(session, &sh->ser[i]);
> > + memset(&sh->ser[i], 0, sizeof(sh->ser[i]));
> > + i++;
> > + }
> > +
> > + sh->header_ser->count = 0;
> > + luo_session_reboot_done(sh);
> > +}
> > +
> > /**
> > * luo_session_quiesce - Ensure no active sessions exist and lock session lists.
> > *
> > --
> > 2.53.0
> >
> >
next prev parent reply other threads:[~2026-03-23 14:13 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-21 14:36 [PATCH v3 1/5] liveupdate: block outgoing session updates during reboot Oskar Gerlicz Kowalczuk
2026-03-21 14:36 ` [PATCH v3 2/5] kexec: abort liveupdate handover on kernel_kexec() unwind Oskar Gerlicz Kowalczuk
2026-03-21 14:36 ` [PATCH v3 3/5] liveupdate: fail session restore on file deserialization errors Oskar Gerlicz Kowalczuk
2026-03-21 14:36 ` [PATCH v3 4/5] liveupdate: validate handover metadata before using it Oskar Gerlicz Kowalczuk
2026-03-21 14:36 ` [PATCH v3 5/5] liveupdate: harden FLB lifetime and teardown paths Oskar Gerlicz Kowalczuk
2026-03-21 23:05 ` [PATCH v3 2/5] kexec: abort liveupdate handover on kernel_kexec() unwind Pasha Tatashin
2026-03-23 14:12 ` Pasha Tatashin [this message]
2026-03-21 17:45 ` [PATCH v3 1/5] liveupdate: block outgoing session updates during reboot Andrew Morton
2026-03-21 22:28 ` Pasha Tatashin
2026-03-23 19:00 ` Pasha Tatashin
2026-03-23 20:52 ` oskar
2026-03-23 22:23 ` Pasha Tatashin
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=CA+CK2bDvv44+YLX6PcTOX_8eM5iET0RrC3gS4BCjMQRUjOSF1g@mail.gmail.com \
--to=pasha.tatashin@soleen.com \
--cc=akpm@linux-foundation.org \
--cc=bhe@redhat.com \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=oskar@gerlicz.space \
--cc=pratyush@kernel.org \
--cc=rppt@kernel.org \
/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