From: Vitaly Kuznetsov <vkuzn...@redhat.com>

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é <berra...@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuzn...@redhat.com>

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 efiunified 1
+%else
+%global efiunified 0
+%endif
+
 %if %{zipmodules}
 %global zipsed -e 's/\.ko$/\.ko.xz/'
 %endif
@@ -698,6 +704,18 @@ BuildRequires: llvm
 BuildRequires: lld
 %endif
 
+%if %{efiunified}
+BuildRequires: dracut
+# For dracut UEFI unified binaries
+BuildRequires: binutils
+# For the initrd
+BuildRequires: lvm2
+# For systemd-stub
+BuildRequires: systemd-udev >= 250-13
+# 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
@@ -825,6 +843,8 @@ Source82: update_scripts.sh
 Source84: mod-internal.list
 Source85: mod-partner.list
 
+Source86: dracut-virt.conf
+
 Source100: rheldup3.x509
 Source101: rhelkpatch1.x509
 
@@ -1333,6 +1353,13 @@ Requires: kernel-%{?1:%{1}-}-modules-core-uname-r = 
%{KVERREL}%{?1:+%{1}}\
 %endif\
 %{expand:%%kernel_debuginfo_package %{?1:%{1}}}\
 %endif\
+%if %{efiunified}\
+%package %{?1:%{1}-}unified-virt\
+Summary: %{variant_summary} unified kernel image for virtual machines\
+Requires: kernel%{?1:-%{1}}-modules-core-uname-r = %{KVERREL}%{?1:+%{1}}\
+Provides: kernel-uname-r = %{KVERREL}%{?1:+%{1}}\
+Provides: installonlypkg(kernel)\
+%endif\
 %{nil}
 
 #
@@ -1402,6 +1429,14 @@ Linux operating system.  The kernel handles the basic 
functions
 of the operating system: memory allocation, process allocation, device
 input and output, etc.
 
+%if %{efiunified}
+%description debug-unified-virt
+Prebuilt debug unified kernel image for virtual machines.
+
+%description unified-virt
+Prebuilt default unified kernel image for virtual machines.
+%endif
+
 %if %{with_ipaclones}
 %kernel_ipaclones_package
 %endif
@@ -2182,6 +2217,46 @@ BuildKernel() {
        touch lib/modules/$KernelVer/modules.builtin
     fi
 
+    popd
+
+    %if %{efiunified}
+
+    KernelUnifiedImageDir="$RPM_BUILD_ROOT/%{image_install_path}/efi/EFI/Linux"
+    
KernelUnifiedImage="$KernelUnifiedImageDir/$InstallName-$KernelVer-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 earlyprintk=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
+
+    # efiunified
+    %endif
+
+    pushd $RPM_BUILD_ROOT
+
     remove_depmod_files
 
     # Go back and find all of the various directories in the tree.  We use this
@@ -3190,6 +3265,10 @@ fi
 %{expand:%%files -f debuginfo%{?3}.list %{?3:%{3}-}debuginfo}\
 %endif\
 %endif\
+%if %{efiunified}\
+%{expand:%%files %{?3:%{3}-}unified-virt}\
+/%{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@lists.fedoraproject.org
To unsubscribe send an email to kernel-le...@lists.fedoraproject.org
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@lists.fedoraproject.org
Do not reply to spam, report it: 
https://pagure.io/fedora-infrastructure/new_issue

Reply via email to