[OS-BUILD PATCHv2] redhat: Add sub-RPM with a EFI unified kernel image for virtual machines

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx>

redhat: Add sub-RPM with a EFI unified kernel image for virtual machines

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@xxxxxxxxxx>
Based-on-patch-by: Gerd Hoffmann <kraxel@xxxxxxxxxx>
Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx>

diff --git a/redhat/Makefile b/redhat/Makefile
index blahblah..blahblah 100644
--- a/redhat/Makefile
+++ b/redhat/Makefile
@@ -639,6 +639,7 @@ sources-rh: $(TARBALL) generate-testpatch-tmp setup-source dist-configs-check
 		../Makefile.rhelver \
 		README.rst \
 		kernel-local \
+		dracut-virt.conf \
 		$(SOURCES)/
 	@if [ "$(RELEASED_KERNEL)" -ne 0 ]; then \
 		cp keys/redhatsecureboot{301,501,ca5,ca1}.cer $(SOURCES)/; \
diff --git a/redhat/dracut-virt.conf b/redhat/dracut-virt.conf
new file mode 100644
index blahblah..blahblah 100644
--- /dev/null
+++ b/redhat/dracut-virt.conf
@@ -0,0 +1,35 @@
+# generic + compressed please
+hostonly="no"
+compress="xz"
+
+# VMs can't update microcode anyway
+early_microcode="no"
+
+# modules: basics
+dracutmodules+=" base systemd systemd-initrd dracut-systemd dbus dbus-broker usrmount shutdown "
+
+# modules: storage support
+dracutmodules+=" dm lvm rootfs-block fs-lib "
+
+# modules: tpm and crypto
+dracutmodules+=" crypt crypt-loop tpm2-tss "
+
+# drivers: virtual buses, pci
+drivers+=" virtio-pci virtio-mmio "      # qemu-kvm
+drivers+=" hv-vmbus pci-hyperv "         # hyperv
+drivers+=" xen-pcifront "                # xen
+
+# drivers: storage
+drivers+=" ahci nvme scsi-hd scsi-cd "   # generic
+drivers+=" virtio-blk virtio-scsi "      # qemu-kvm
+drivers+=" hv-storvsc "                  # hyperv
+drivers+=" xen-blkfront "                # xen
+
+# root encryption
+drivers+=" dm_crypt "
+
+# filesystems
+filesystems+=" vfat ext4 xfs overlay "
+
+# systemd-pcrphase
+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 "
diff --git a/redhat/kernel.spec.template b/redhat/kernel.spec.template
index blahblah..blahblah 100755
--- a/redhat/kernel.spec.template
+++ b/redhat/kernel.spec.template
@@ -91,6 +91,12 @@ Summary: The Linux kernel
 %global zipmodules 1
 %endif
 
+%ifarch x86_64
+%global efiuki 1
+%else
+%global efiuki 0
+%endif
+
 %if %{zipmodules}
 %global zipsed -e 's/\.ko$/\.ko.xz/'
 %endif
@@ -699,6 +705,21 @@ BuildRequires: llvm
 BuildRequires: lld
 %endif
 
+%if %{efiuki}
+BuildRequires: dracut
+# For dracut UEFI uki binaries
+BuildRequires: binutils
+# For the initrd
+BuildRequires: lvm2
+%if 0%{?fedora} > 37
+BuildRequires: systemd-boot-unsigned
+%endif
+# For systemd-stub and systemd-pcrphase
+BuildRequires: systemd-udev >= 252-1
+# For TPM operations in UKI initramfs
+BuildRequires: tpm2-tools
+%endif
+
 # Because this is the kernel, it's hard to get a single upstream URL
 # to represent the base without needing to do a bunch of patching. This
 # tarball is generated from a src-git tree. If you want to see the
@@ -826,6 +847,8 @@ Source82: update_scripts.sh
 Source84: mod-internal.list
 Source85: mod-partner.list
 
+Source86: dracut-virt.conf
+
 Source100: rheldup3.x509
 Source101: rhelkpatch1.x509
 
@@ -1331,6 +1354,13 @@ Requires: kernel-%{?1:%{1}-}-modules-core-uname-r = %{KVERREL}%{?1:+%{1}}\
 %endif\
 %{expand:%%kernel_debuginfo_package %{?1:%{1}}}\
 %endif\
+%if %{efiuki}\
+%package %{?1:%{1}-}uki-virt\
+Summary: %{variant_summary} unified kernel image for virtual machines\
+Provides: installonlypkg(kernel)\
+Provides: kernel-%{?1:%{1}-}uname-r = %{KVERREL}%{?1:+%{1}}\
+Requires: kernel%{?1:-%{1}}-modules-core-uname-r = %{KVERREL}%{?1:+%{1}}\
+%endif\
 %{nil}
 
 #
@@ -1400,6 +1430,14 @@ Linux operating system.  The kernel handles the basic functions
 of the operating system: memory allocation, process allocation, device
 input and output, etc.
 
+%if %{efiuki}
+%description debug-uki-virt
+Prebuilt debug unified kernel image for virtual machines.
+
+%description uki-virt
+Prebuilt default unified kernel image for virtual machines.
+%endif
+
 %if %{with_ipaclones}
 %kernel_ipaclones_package
 %endif
@@ -2180,6 +2218,45 @@ BuildKernel() {
 	touch lib/modules/$KernelVer/modules.builtin
     fi
 
+%if %{efiuki}
+    popd
+
+    KernelUnifiedImageDir="$RPM_BUILD_ROOT/lib/modules/$KernelVer"
+    KernelUnifiedImage="$KernelUnifiedImageDir/$InstallName-virt.efi"
+
+    mkdir -p $KernelUnifiedImageDir
+
+    dracut --conf=%{SOURCE86} \
+           --confdir=$(mktemp -d) \
+           --verbose \
+           --kver "$KernelVer" \
+           --kmoddir "$RPM_BUILD_ROOT/lib/modules/$KernelVer/" \
+           --logfile=$(mktemp) \
+           --uefi \
+           --kernel-image $(realpath $KernelImage) \
+           --kernel-cmdline 'console=tty0 console=ttyS0' \
+	   $KernelUnifiedImage
+
+%if %{signkernel}
+
+    %pesign -s -i $KernelUnifiedImage -o $KernelUnifiedImage.tmp -a %{secureboot_ca_0} -c %{secureboot_key_0} -n %{pesign_name_0}
+    %pesign -s -i $KernelUnifiedImage.tmp -o $KernelUnifiedImage.signed -a %{secureboot_ca_1} -c %{secureboot_key_1} -n %{pesign_name_1}
+    rm -f $KernelUnifiedImage.tmp
+
+    if [ ! -s $KernelUnifiedImage.signed ]; then
+      echo "pesigning failed"
+      exit 1
+    fi
+    mv $KernelUnifiedImage.signed $KernelUnifiedImage
+
+# signkernel
+%endif
+
+    pushd $RPM_BUILD_ROOT
+
+# efiuki
+%endif
+
     remove_depmod_files
 
     # Go back and find all of the various directories in the tree.  We use this
@@ -2873,12 +2950,14 @@ fi\
 # It also defines a %%postun script that does the same thing.
 #	%%kernel_modules_core_post [<subpackage>]
 #
+# FIXME: /bin/kernel-install can't handle UKIs (yet), so cleanup depmod files in %postun for now.
+#
 %define kernel_modules_core_post() \
 %{expand:%%posttrans %{?1:%{1}-}modules-core}\
 /sbin/depmod -a %{KVERREL}%{?1:+%{1}}\
 %{nil}\
 %{expand:%%postun %{?1:%{1}-}modules-core}\
-/sbin/depmod -a %{KVERREL}%{?1:+%{1}}\
+rm -f /lib/modules/%{KVERREL}%{?1:+%{1}}/modules.*\
 %{nil}
 
 # This macro defines a %%posttrans script for a kernel package.
@@ -2926,6 +3005,20 @@ mkdir -p %{_localstatedir}/lib/rpm-state/%{name}\
 touch %{_localstatedir}/lib/rpm-state/%{name}/installing_core_%{KVERREL}%{?-v:+%{-v*}}\
 %{nil}
 
+#
+# This macro defines scripts for a kernel*-uki-virt package
+#
+# FIXME: /bin/kernel-install can't handle UKIs (yet), so just cp/rm as temporary stop-gap
+#
+%define kernel_uki_virt_scripts() \
+%{expand:%%posttrans %{?1:%{1}-}uki-virt}\
+mkdir -p /boot/efi/EFI/Linux\
+cp /lib/modules/%{KVERREL}%{?1:+%{1}}/vmlinuz-virt.efi /boot/efi/EFI/Linux/vmlinuz-%{KVERREL}%{?1:+%{1}}-virt.efi\
+%{nil}\
+%{expand:%%postun %{?1:%{1}-}uki-virt}\
+rm -f /boot/efi/EFI/Linux/vmlinuz-%{KVERREL}%{?1:+%{1}}-virt.efi\
+%{nil}
+
 #
 # This macro defines a %%preun script for a kernel package.
 #	%%kernel_variant_preun <subpackage>
@@ -2939,6 +3032,10 @@ then\
 fi\
 %{nil}
 
+%if %{efiuki}
+%kernel_uki_virt_scripts
+%endif
+
 %kernel_variant_preun
 %kernel_variant_post -r kernel-smp
 
@@ -2948,6 +3045,9 @@ fi\
 %endif
 
 %if %{with_debug}
+%if %{efiuki}
+%kernel_uki_virt_scripts debug
+%endif
 %kernel_variant_preun debug
 %kernel_variant_post -v debug
 %endif
@@ -3188,6 +3288,11 @@ fi
 %{expand:%%files -f debuginfo%{?3}.list %{?3:%{3}-}debuginfo}\
 %endif\
 %endif\
+%if %{efiuki}\
+%{expand:%%files %{?3:%{3}-}uki-virt}\
+/lib/modules/%{KVERREL}%{?3:+%{3}}/%{?-k:%{-k*}}%{!?-k:vmlinuz}-virt.efi\
+%ghost /%{image_install_path}/efi/EFI/Linux/%{?-k:%{-k*}}%{!?-k:vmlinuz}-%{KVERREL}%{?3:+%{3}}-virt.efi\
+%endif\
 %if %{?3:1} %{!?3:0}\
 %{expand:%%files %{3}}\
 %endif\

--
https://gitlab.com/cki-project/kernel-ark/-/merge_requests/2175
_______________________________________________
kernel mailing list -- kernel@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to kernel-leave@xxxxxxxxxxxxxxxxxxxxxxx
Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/kernel@xxxxxxxxxxxxxxxxxxxxxxx
Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue




[Index of Archives]     [Fedora General Discussion]     [Older Fedora Users Archive]     [Fedora Advisory Board]     [Fedora Security]     [Fedora Devel Java]     [Fedora Legacy]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Mentors]     [Fedora Package Announce]     [Fedora Package Review]     [Fedora Music]     [Fedora Packaging]     [Centos]     [Fedora SELinux]     [Coolkey]     [Yum Users]     [Tux]     [Yosemite News]     [KDE Users]     [Fedora Art]     [Fedora Docs]     [USB]     [Asterisk PBX]

  Powered by Linux