Skip to content

Commit dff10a9

Browse files
committed
redhat: Add sub-RPM with a EFI unified kernel image for virtual machines
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2142102 Upstream Status: RHEL only The new 'kernel-unified-virt' sub-RPM is added on x86_64 targets. This contains an EFI application that provides a combined vmlinux, initrd and cmdline, as a so called 'unified kernel image'. The spec for this is defined by the boot loader specification https://uapi-group.org/specifications/specs/boot_loader_specification/ The key benefit of a unified kernel is that its secure boot signature covers the initrd and cmdline contents, allowing a trustworthy measured boot process with attestation, which is not practical with locally generated initrds/cmdlines. Since the initrd is pre-generated its contents have to be very generic, to be usable on a wide variety of deployments. To make this problem tractable, the sub-RPM targets only usage in virtual machines. With such a restriction, the initrd only needs a very small set of block driver modules present, in order to be usable across KVM, Hyper-V and Xen hypervisors which will cover essentially all common public and private clouds. Similarly the kernel cmdline cannot contain any host specific data, which means the root filesystem to mount needs to be able to be automatically detected. A virtual machine image intending to use this unified kernel package thus needs to comply with the discoverable partitions specification: https://uapi-group.org/specifications/specs/discoverable_partitions_specification/ Based-on-patch-by: Daniel P. Berrangé <berrange@redhat.com> Based-on-patch-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
1 parent 95440c0 commit dff10a9

File tree

3 files changed

+139
-1
lines changed

3 files changed

+139
-1
lines changed

redhat/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ sources-rh: $(TARBALL) generate-testpatch-tmp setup-source dist-configs-check
645645
../Makefile.rhelver \
646646
README.rst \
647647
kernel-local \
648+
dracut-virt.conf \
648649
$(SOURCES)/
649650
@for KABIARCH in $(ARCH_LIST); do \
650651
cp kabi/Module.kabi_$$KABIARCH $(SOURCES)/; \

redhat/dracut-virt.conf

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# generic + compressed please
2+
hostonly="no"
3+
compress="xz"
4+
5+
# VMs can't update microcode anyway
6+
early_microcode="no"
7+
8+
# modules: basics
9+
dracutmodules+=" base systemd systemd-initrd dracut-systemd dbus dbus-broker usrmount shutdown "
10+
11+
# modules: storage support
12+
dracutmodules+=" dm lvm rootfs-block fs-lib "
13+
14+
# modules: tpm and crypto
15+
dracutmodules+=" crypt crypt-loop tpm2-tss "
16+
17+
# drivers: virtual buses, pci
18+
drivers+=" virtio-pci virtio-mmio " # qemu-kvm
19+
drivers+=" hv-vmbus pci-hyperv " # hyperv
20+
drivers+=" xen-pcifront " # xen
21+
22+
# drivers: storage
23+
drivers+=" ahci nvme sd_mod sr_mod " # generic
24+
drivers+=" virtio-blk virtio-scsi " # qemu-kvm
25+
drivers+=" hv-storvsc " # hyperv
26+
drivers+=" xen-blkfront " # xen
27+
28+
# root encryption
29+
drivers+=" dm_crypt "
30+
31+
# filesystems
32+
filesystems+=" vfat ext4 xfs overlay "
33+
34+
# systemd-pcrphase
35+
install_items+=" /lib/systemd/system/systemd-pcrphase-initrd.service /usr/lib/systemd/systemd-pcrphase /usr/lib/systemd/system/initrd.target.wants/systemd-pcrphase-initrd.service "

redhat/kernel.spec.template

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ Summary: The Linux kernel
112112
%global zipmodules 1
113113
%endif
114114

115+
%ifarch x86_64
116+
%global efiuki 1
117+
%else
118+
%global efiuki 0
119+
%endif
120+
115121
%if %{zipmodules}
116122
%global zipsed -e 's/\.ko$/\.ko.xz/'
117123
# for parallel xz processes, replace with 1 to go back to single process
@@ -723,6 +729,21 @@ BuildRequires: llvm
723729
BuildRequires: lld
724730
%endif
725731

732+
%if %{efiuki}
733+
BuildRequires: dracut
734+
# For dracut UEFI uki binaries
735+
BuildRequires: binutils
736+
# For the initrd
737+
BuildRequires: lvm2
738+
%if 0%{?fedora} > 37
739+
BuildRequires: systemd-boot-unsigned
740+
%endif
741+
# For systemd-stub and systemd-pcrphase
742+
BuildRequires: systemd-udev >= 252-1
743+
# For TPM operations in UKI initramfs
744+
BuildRequires: tpm2-tools
745+
%endif
746+
726747
# Because this is the kernel, it's hard to get a single upstream URL
727748
# to represent the base without needing to do a bunch of patching. This
728749
# tarball is generated from a src-git tree. If you want to see the
@@ -833,6 +854,8 @@ Source84: mod-internal.list
833854
Source100: rheldup3.x509
834855
Source101: rhelkpatch1.x509
835856

857+
Source150: dracut-virt.conf
858+
836859
Source200: check-kabi
837860

838861
Source201: Module.kabi_aarch64
@@ -1346,6 +1369,13 @@ Requires: kernel-%{?1:%{1}-}-modules-core-uname-r = %{KVERREL}%{uname_variant %{
13461369
%{expand:%%kernel_modules_internal_package %{?1:%{1}} %{!?{-n}:%{1}}%{?{-n}:%{-n*}}}\
13471370
%{expand:%%kernel_debuginfo_package %{?1:%{1}}}\
13481371
%endif\
1372+
%if %{efiuki}\
1373+
%package %{?1:%{1}-}uki-virt\
1374+
Summary: %{variant_summary} unified kernel image for virtual machines\
1375+
Provides: installonlypkg(kernel)\
1376+
Provides: kernel-%{?1:%{1}-}uname-r = %{KVERREL}%{uname_suffix %{?1:%{1}}}\
1377+
Requires: kernel%{?1:-%{1}}-modules-core-uname-r = %{KVERREL}%{uname_suffix %{?1:%{1}}}\
1378+
%endif\
13491379
%{nil}
13501380

13511381
# Now, each variant package.
@@ -1415,6 +1445,14 @@ Linux operating system. The kernel handles the basic functions
14151445
of the operating system: memory allocation, process allocation, device
14161446
input and output, etc.
14171447

1448+
%if %{efiuki}
1449+
%description debug-uki-virt
1450+
Prebuilt debug unified kernel image for virtual machines.
1451+
1452+
%description uki-virt
1453+
Prebuilt default unified kernel image for virtual machines.
1454+
%endif
1455+
14181456
%if %{with_ipaclones}
14191457
%kernel_ipaclones_package
14201458
%endif
@@ -2181,6 +2219,42 @@ BuildKernel() {
21812219
touch lib/modules/$KernelVer/modules.builtin
21822220
fi
21832221

2222+
%if %{efiuki}
2223+
popd
2224+
2225+
KernelUnifiedImageDir="$RPM_BUILD_ROOT/lib/modules/$KernelVer"
2226+
KernelUnifiedImage="$KernelUnifiedImageDir/$InstallName-virt.efi"
2227+
2228+
mkdir -p $KernelUnifiedImageDir
2229+
2230+
dracut --conf=%{SOURCE150} \
2231+
--confdir=$(mktemp -d) \
2232+
--verbose \
2233+
--kver "$KernelVer" \
2234+
--kmoddir "$RPM_BUILD_ROOT/lib/modules/$KernelVer/" \
2235+
--logfile=$(mktemp) \
2236+
--uefi \
2237+
--kernel-image $(realpath $KernelImage) \
2238+
--kernel-cmdline 'console=tty0 console=ttyS0' \
2239+
$KernelUnifiedImage
2240+
2241+
%if %{signkernel}
2242+
2243+
%pesign -s -i $KernelUnifiedImage -o $KernelUnifiedImage.signed -a %{secureboot_ca_0} -c %{secureboot_key_0} -n %{pesign_name_0}
2244+
if [ ! -s $KernelUnifiedImage.signed ]; then
2245+
echo "pesigning failed"
2246+
exit 1
2247+
fi
2248+
mv $KernelUnifiedImage.signed $KernelUnifiedImage
2249+
2250+
# signkernel
2251+
%endif
2252+
2253+
pushd $RPM_BUILD_ROOT
2254+
2255+
# efiuki
2256+
%endif
2257+
21842258
remove_depmod_files
21852259

21862260
# Go back and find all of the various directories in the tree. We use this
@@ -2883,12 +2957,14 @@ fi\
28832957
# It also defines a %%postun script that does the same thing.
28842958
# %%kernel_modules_core_post [<subpackage>]
28852959
#
2960+
# FIXME: /bin/kernel-install can't handle UKIs (yet), so cleanup depmod files in %postun for now.
2961+
#
28862962
%define kernel_modules_core_post() \
28872963
%{expand:%%posttrans %{?1:%{1}-}modules-core}\
28882964
/sbin/depmod -a %{KVERREL}%{?1:+%{1}}\
28892965
%{nil}\
28902966
%{expand:%%postun %{?1:%{1}-}modules-core}\
2891-
/sbin/depmod -a %{KVERREL}%{?1:+%{1}}\
2967+
rm -f /lib/modules/%{KVERREL}%{?1:+%{1}}/modules.*\
28922968
%{nil}
28932969

28942970
# This macro defines a %%posttrans script for a kernel package.
@@ -2933,6 +3009,20 @@ mkdir -p %{_localstatedir}/lib/rpm-state/%{name}\
29333009
touch %{_localstatedir}/lib/rpm-state/%{name}/installing_core_%{KVERREL}%{?-v:+%{-v*}}\
29343010
%{nil}
29353011

3012+
#
3013+
# This macro defines scripts for a kernel*-uki-virt package
3014+
#
3015+
# FIXME: /bin/kernel-install can't handle UKIs (yet), so just cp/rm as temporary stop-gap
3016+
#
3017+
%define kernel_uki_virt_scripts() \
3018+
%{expand:%%posttrans %{?1:%{1}-}uki-virt}\
3019+
mkdir -p /boot/efi/EFI/Linux\
3020+
cp /lib/modules/%{KVERREL}%{?1:+%{1}}/vmlinuz-virt.efi /boot/efi/EFI/Linux/vmlinuz-%{KVERREL}%{?1:+%{1}}-virt.efi\
3021+
%{nil}\
3022+
%{expand:%%postun %{?1:%{1}-}uki-virt}\
3023+
rm -f /boot/efi/EFI/Linux/vmlinuz-%{KVERREL}%{?1:+%{1}}-virt.efi\
3024+
%{nil}
3025+
29363026
#
29373027
# This macro defines a %%preun script for a kernel package.
29383028
# %%kernel_variant_preun <subpackage>
@@ -2946,6 +3036,10 @@ then\
29463036
fi\
29473037
%{nil}
29483038

3039+
%if %{efiuki}
3040+
%kernel_uki_virt_scripts
3041+
%endif
3042+
29493043
%kernel_variant_preun
29503044
%kernel_variant_post -r kernel-smp
29513045

@@ -2970,6 +3064,9 @@ fi\
29703064
%endif
29713065

29723066
%if %{with_debug}
3067+
%if %{efiuki}
3068+
%kernel_uki_virt_scripts debug
3069+
%endif
29733070
%kernel_variant_preun debug
29743071
%kernel_variant_post -v debug
29753072
%endif
@@ -3204,6 +3301,11 @@ fi
32043301
%{expand:%%files -f debuginfo%{?3}.list %{?3:%{3}-}debuginfo}\
32053302
%endif\
32063303
%endif\
3304+
%if %{efiuki}\
3305+
%{expand:%%files %{?3:%{3}-}uki-virt}\
3306+
/lib/modules/%{KVERREL}%{?3:+%{3}}/%{?-k:%{-k*}}%{!?-k:vmlinuz}-virt.efi\
3307+
%ghost /%{image_install_path}/efi/EFI/Linux/%{?-k:%{-k*}}%{!?-k:vmlinuz}-%{KVERREL}%{?3:+%{3}}-virt.efi\
3308+
%endif\
32073309
%if %{?3:1} %{!?3:0}\
32083310
%{expand:%%files %{3}}\
32093311
%endif\

0 commit comments

Comments
 (0)