[PATCH 0/2] x86/kexec: Implement crash kexec for Secure Boot

Kevin Lampis posted 2 patches 1 month, 3 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://gitlab.com/xen-project/patchew/xen tags/patchew/20260602164911.2684471-1-kevin.lampis@citrix.com
xen/arch/x86/bzimage.c                   |  40 +---
xen/arch/x86/include/asm/machine_kexec.h |   2 +-
xen/arch/x86/machine_kexec.c             |  10 +-
xen/arch/x86/setup.c                     |   1 +
xen/arch/x86/x86_64/kexec_reloc.S        |  16 ++
xen/common/Kconfig                       |   8 +
xen/common/Makefile                      |   1 +
xen/common/kernel.c                      |   4 +
xen/common/kexec.c                       |  41 +++-
xen/common/kimage.c                      | 264 +++++++++++++++++++----
xen/common/lockdown.c                    |  56 +++++
xen/include/public/kexec.h               |  23 +-
xen/include/xen/kimage.h                 |  23 +-
xen/include/xen/lockdown.h               |   9 +
xen/include/xen/x86-linux.h              |  62 ++++++
15 files changed, 460 insertions(+), 100 deletions(-)
create mode 100644 xen/common/lockdown.c
create mode 100644 xen/include/xen/lockdown.h
create mode 100644 xen/include/xen/x86-linux.h
[PATCH 0/2] x86/kexec: Implement crash kexec for Secure Boot
Posted by Kevin Lampis 1 month, 3 weeks ago
This replaces the previous series
[PATCH v2 0/4] Allows Secure Boot for Kexec
https://lore.kernel.org/xen-devel/20250507094253.10395-1-freddy77@gmail.com/

The main feedback last time was that almost all the purgatory code could
be removed.
- The digest check is now done in machine_kexec() instead of purgatory
- GPRs are cleared in kexec_reloc.S which shouldn't affect non-EFI kexec

Kevin Lampis (1):
  x86: Implement crash kexec for EFI

Ross Lagerwall (1):
  Add lockdown mode

 xen/arch/x86/bzimage.c                   |  40 +---
 xen/arch/x86/include/asm/machine_kexec.h |   2 +-
 xen/arch/x86/machine_kexec.c             |  10 +-
 xen/arch/x86/setup.c                     |   1 +
 xen/arch/x86/x86_64/kexec_reloc.S        |  16 ++
 xen/common/Kconfig                       |   8 +
 xen/common/Makefile                      |   1 +
 xen/common/kernel.c                      |   4 +
 xen/common/kexec.c                       |  41 +++-
 xen/common/kimage.c                      | 264 +++++++++++++++++++----
 xen/common/lockdown.c                    |  56 +++++
 xen/include/public/kexec.h               |  23 +-
 xen/include/xen/kimage.h                 |  23 +-
 xen/include/xen/lockdown.h               |   9 +
 xen/include/xen/x86-linux.h              |  62 ++++++
 15 files changed, 460 insertions(+), 100 deletions(-)
 create mode 100644 xen/common/lockdown.c
 create mode 100644 xen/include/xen/lockdown.h
 create mode 100644 xen/include/xen/x86-linux.h

-- 
2.52.0
Re: [PATCH 0/2] x86/kexec: Implement crash kexec for Secure Boot
Posted by Andrew Cooper 1 month, 2 weeks ago
On 02/06/2026 5:49 pm, Kevin Lampis wrote:
> This replaces the previous series
> [PATCH v2 0/4] Allows Secure Boot for Kexec
> https://lore.kernel.org/xen-devel/20250507094253.10395-1-freddy77@gmail.com/
>
> The main feedback last time was that almost all the purgatory code could
> be removed.
> - The digest check is now done in machine_kexec() instead of purgatory
> - GPRs are cleared in kexec_reloc.S which shouldn't affect non-EFI kexec
>
> Kevin Lampis (1):
>   x86: Implement crash kexec for EFI
>
> Ross Lagerwall (1):
>   Add lockdown mode
>
>  xen/arch/x86/bzimage.c                   |  40 +---
>  xen/arch/x86/include/asm/machine_kexec.h |   2 +-
>  xen/arch/x86/machine_kexec.c             |  10 +-
>  xen/arch/x86/setup.c                     |   1 +
>  xen/arch/x86/x86_64/kexec_reloc.S        |  16 ++
>  xen/common/Kconfig                       |   8 +
>  xen/common/Makefile                      |   1 +
>  xen/common/kernel.c                      |   4 +
>  xen/common/kexec.c                       |  41 +++-
>  xen/common/kimage.c                      | 264 +++++++++++++++++++----
>  xen/common/lockdown.c                    |  56 +++++
>  xen/include/public/kexec.h               |  23 +-
>  xen/include/xen/kimage.h                 |  23 +-
>  xen/include/xen/lockdown.h               |   9 +
>  xen/include/xen/x86-linux.h              |  62 ++++++
>  15 files changed, 460 insertions(+), 100 deletions(-)
>  create mode 100644 xen/common/lockdown.c
>  create mode 100644 xen/include/xen/lockdown.h
>  create mode 100644 xen/include/xen/x86-linux.h

Thankyou for doing this work.  This is a far more palatable diff-stat
than adding all of Purgatory.

But, the lockdown work is still blocked on some open questions and (in
practice) the security statement.  It only matters for the -EPERMs in
the top levels of the hypercall, and that comes from a bad split of
patches in the XenServer patchqueue.  You'll want to drop it from this
series.

The rest of the work (just patch 2) needs splitting into several.

First, moving the thing called setup_header wants to be it's own patch. 
It wants to move into the existing bzimage.h (itself fixing a bug with
the copyright header) and probably wants to be renamed to bzimage_header
because, despite that being it's Linux name, "setup" is far too generic.

You have identified that bzimage is x86 specific, and for that reason it
should not be included in common/kexec.c.  We are going to need an
architecture specific way of figuring out the alignment, but looking at
kimage_find_kernel_entry_maddr(), why can't we just use the EFI header?


Doing the digest checks should be its own patch.  Why is it tied to
KEXEC_TYPE_CRASH_EFI?  It's applicable to all kexec types.  This ought
to be first first in the series so it's not tied to EFI.

As to performing and failing the digest checks, it probably wants to be
a little earlier.  Functions like kexec_crash() want to return rather
than hanging, so hwdom_shutdown() can fall through into
reboot_or_halt().  kexec_exec() wants to return propagate an error back
into the hypercall to identify that the image appears to be corrupt.

Failing the digest check should print both the expected and obtained
values.  See check_xen_buildid() for a related example that you should
follow.


Swapping xen_kexec_segment_t to struct kimage_segment wants to be it's
own patch too.  It's mechanical but needs to not be mixed in with
logical changes.


For the %rsi/boot_params pointer, that wants to be a separate patch
too.  I wouldn't label it as EFI-only, nor as rsi.  Maybe just "arg"? 
It should be wired up on the 32bit path where it's %esi too, so really
you just need to move it out of %r9 before the 32bit split.

Zeroing the other registers is fine, but again wants to be a separate
patch.  It's unrelated to the rest of the content, and wants to happen
on both paths.  Also, when zeroing registers, always use the 32bit
register form even in 64bit code.  See PUSH_AND_CLEAR_GPRS; there are
some 64bit CPUs which care.

There are a bunch of style issues too, but lets focus on getting the
structure right first.

~Andrew

Re: [PATCH 0/2] x86/kexec: Implement crash kexec for Secure Boot
Posted by Kevin Lampis 1 month, 2 weeks ago
>You have identified that bzimage is x86 specific, and for that reason it
>should not be included in common/kexec.c.

I believe Ross moved the definition of setup_header out of kexec.c because
kimage.c also needs to use it now.

>We are going to need an
>architecture specific way of figuring out the alignment, but looking at
>kimage_find_kernel_entry_maddr(), why can't we just use the EFI header?

"Going to need" like "it would be nice" or "we absolutely can't merge this"? :)
I feel like I might get bludgeoned to death by a set of bagpipes if I have to
tell a certain someone that there's more kexec work to do...

>Why is it [digest checks] tied to
>KEXEC_TYPE_CRASH_EFI?  It's applicable to all kexec types.  This ought
>to be first first in the series so it's not tied to EFI.

I can do KEXEC_TYPE_CRASH_EFI and KEXEC_TYPE_CRASH but there's an extra layer
of complexity with normal kexec.

kimage_load_normal_segment() copies the segments data into temporary,
non-contiguous buffers and then sets up a relocation table which kexec_reloc.S
uses to copy the segments data into the correct place before jumping to the new
kernel. Calculating and verifying the digest for normal kexec would mean new
code to walk the relocation table to find every temporary buffer.

As we discussed internally I'd rather not touch the normal kexec code
unless I'm fixing all the existing issues and can actually test the changes.

I've sorted out all the other things you mentioned but still in the process of
splitting the patches up.
Re: [PATCH 0/2] x86/kexec: Implement crash kexec for Secure Boot
Posted by Andrew Cooper 1 month, 2 weeks ago
On 04/06/2026 8:46 pm, Kevin Lampis wrote:
>> You have identified that bzimage is x86 specific, and for that reason it
>> should not be included in common/kexec.c.
> I believe Ross moved the definition of setup_header out of kexec.c because
> kimage.c also needs to use it now.

Moving the definition is fine.  But it's still x86 specific and cannot
be in common code, because you'll break ARM, RISC-V and PPC by doing so.

>
>> We are going to need an
>> architecture specific way of figuring out the alignment, but looking at
>> kimage_find_kernel_entry_maddr(), why can't we just use the EFI header?
> "Going to need" like "it would be nice" or "we absolutely can't merge this"?

The latter.  But really it depends on "why can't we just use the EFI
header?"

The EFI header is common across architectures, so if we can use that,
its easy.  If we can't use the EFI header and are forced to inspect the
bzImage header, then getting the adequate alignment needs abstracting
properly for the common <-> arch split.

>> Why is it [digest checks] tied to
>> KEXEC_TYPE_CRASH_EFI?  It's applicable to all kexec types.  This ought
>> to be first first in the series so it's not tied to EFI.
> I can do KEXEC_TYPE_CRASH_EFI and KEXEC_TYPE_CRASH but there's an extra layer
> of complexity with normal kexec.
>
> kimage_load_normal_segment() copies the segments data into temporary,
> non-contiguous buffers and then sets up a relocation table which kexec_reloc.S
> uses to copy the segments data into the correct place before jumping to the new
> kernel. Calculating and verifying the digest for normal kexec would mean new
> code to walk the relocation table to find every temporary buffer.

Oh - we can calculate the digest easily when it's loaded, but we can't
check the digest easily at kexec time while we've still got the ability
to fail the action.

In which case lets do it only for the crash types in the short term. 
They're the important ones to check.

It's ok to "return 0; /* TODO, non-crash types */" or equivalent.

~Andrew