diff --git a/pkgs/applications/qubes/qubes-core-vchan-xen/default.nix b/pkgs/applications/qubes/qubes-core-vchan-xen/default.nix
index 21b80fcf51dd6..7def14890300d 100644
--- a/pkgs/applications/qubes/qubes-core-vchan-xen/default.nix
+++ b/pkgs/applications/qubes/qubes-core-vchan-xen/default.nix
@@ -28,8 +28,9 @@ stdenv.mkDerivation rec {
description = "Libraries required for the higher-level Qubes daemons and tools";
homepage = "https://qubes-os.org";
license = licenses.gpl2Plus;
- maintainers = with maintainers; [ _0x4A6F ];
+ maintainers = [ ];
platforms = platforms.linux;
+ broken = true;
};
}
diff --git a/pkgs/applications/virtualization/xen/0000-fix-install-python.4.15.patch b/pkgs/applications/virtualization/xen/0000-fix-install-python.4.15.patch
deleted file mode 100644
index 5fc5a6012ee30..0000000000000
--- a/pkgs/applications/virtualization/xen/0000-fix-install-python.4.15.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-tools/python/install-wrap script brakes shebangs patching, disable
-
-diff --git a/tools/Rules.mk b/tools/Rules.mk
-index 444e5bacdd..c99ea959ff 100644
---- a/tools/Rules.mk
-+++ b/tools/Rules.mk
-@@ -135,8 +135,7 @@ CFLAGS += $(CFLAGS-y)
-
- CFLAGS += $(EXTRA_CFLAGS_XEN_TOOLS)
-
--INSTALL_PYTHON_PROG = \
-- $(XEN_ROOT)/tools/python/install-wrap "$(PYTHON_PATH)" $(INSTALL_PROG)
-+INSTALL_PYTHON_PROG = $(INSTALL_PROG)
-
- %.opic: %.c
- $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) $(CFLAGS_$*.opic) -fPIC -c -o $@ $< $(APPEND_CFLAGS)
diff --git a/pkgs/applications/virtualization/xen/0000-qemu-seabios-enable-ATA_DMA.patch b/pkgs/applications/virtualization/xen/0000-qemu-seabios-enable-ATA_DMA.patch
deleted file mode 100644
index 339972a2cdeb1..0000000000000
--- a/pkgs/applications/virtualization/xen/0000-qemu-seabios-enable-ATA_DMA.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-diff -uNr a/src/Kconfig b/src/Kconfig
---- a/src/Kconfig 2015-08-31 10:15:13.231134858 +0200
-+++ b/src/Kconfig 2015-08-31 10:14:24.039180178 +0200
-@@ -144,13 +144,13 @@
- config ATA_DMA
- depends on ATA
- bool "ATA DMA"
-- default n
-+ default y
- help
- Detect and try to use ATA bus mastering DMA controllers.
- config ATA_PIO32
- depends on ATA
- bool "ATA 32bit PIO"
-- default n
-+ default y
- help
- Use 32bit PIO accesses on ATA (minor optimization on PCI transfers).
- config AHCI
diff --git a/pkgs/applications/virtualization/xen/0004-makefile-use-efi-ld.4.15.patch b/pkgs/applications/virtualization/xen/0004-makefile-use-efi-ld.4.15.patch
deleted file mode 100644
index c64ec52315c92..0000000000000
--- a/pkgs/applications/virtualization/xen/0004-makefile-use-efi-ld.4.15.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
-index b6567c4127..83defeee95 100644
---- a/xen/arch/x86/Makefile
-+++ b/xen/arch/x86/Makefile
-@@ -124,11 +124,11 @@ ifneq ($(efi-y),)
- export XEN_BUILD_EFI := $(shell $(CC) $(XEN_CFLAGS) -c efi/check.c -o efi/check.o 2>/dev/null && echo y)
- # Check if the linker supports PE.
- EFI_LDFLAGS = $(patsubst -m%,-mi386pep,$(XEN_LDFLAGS)) --subsystem=10 --strip-debug
--XEN_BUILD_PE := $(if $(XEN_BUILD_EFI),$(shell $(LD) $(EFI_LDFLAGS) -o efi/check.efi efi/check.o 2>/dev/null && echo y))
-+XEN_BUILD_PE := $(if $(XEN_BUILD_EFI),$(shell $(EFI_LD) $(EFI_LDFLAGS) -o efi/check.efi efi/check.o 2>/dev/null && echo y))
- CFLAGS-$(XEN_BUILD_EFI) += -DXEN_BUILD_EFI
- # Check if the linker produces fixups in PE by default (we need to disable it doing so for now).
- XEN_NO_PE_FIXUPS := $(if $(XEN_BUILD_EFI), \
-- $(shell $(LD) $(EFI_LDFLAGS) --disable-reloc-section -o efi/check.efi efi/check.o 2>/dev/null && \
-+ $(shell $(EFI_LD) $(EFI_LDFLAGS) --disable-reloc-section -o efi/check.efi efi/check.o 2>/dev/null && \
- echo --disable-reloc-section))
- endif
-
-@@ -217,20 +217,20 @@ note_file_option ?= $(note_file)
- ifeq ($(XEN_BUILD_PE),y)
- $(TARGET).efi: prelink-efi.o $(note_file) efi.lds efi/relocs-dummy.o efi/mkreloc
- $(foreach base, $(VIRT_BASE) $(ALT_BASE), \
-- $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \
-+ $(EFI_LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< efi/relocs-dummy.o \
- $(BASEDIR)/common/symbols-dummy.o $(note_file_option) -o $(@D)/.$(@F).$(base).0 &&) :
- efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).0) >$(@D)/.$(@F).0r.S
- $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).0 \
- | $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).0s.S
- $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o
- $(foreach base, $(VIRT_BASE) $(ALT_BASE), \
-- $(LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< \
-+ $(EFI_LD) $(call EFI_LDFLAGS,$(base)) -T efi.lds -N $< \
- $(@D)/.$(@F).0r.o $(@D)/.$(@F).0s.o $(note_file_option) -o $(@D)/.$(@F).$(base).1 &&) :
- efi/mkreloc $(foreach base,$(VIRT_BASE) $(ALT_BASE),$(@D)/.$(@F).$(base).1) >$(@D)/.$(@F).1r.S
- $(NM) -pa --format=sysv $(@D)/.$(@F).$(VIRT_BASE).1 \
- | $(BASEDIR)/tools/symbols $(all_symbols) --sysv --sort >$(@D)/.$(@F).1s.S
- $(MAKE) -f $(BASEDIR)/Rules.mk $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o
-- $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \
-+ $(EFI_LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T efi.lds -N $< \
- $(@D)/.$(@F).1r.o $(@D)/.$(@F).1s.o $(note_file_option) -o $@
- $(NM) -pa --format=sysv $(@D)/$(@F) \
- | $(BASEDIR)/tools/symbols --all-symbols --xensyms --sysv --sort >$(@D)/$(@F).map
diff --git a/pkgs/applications/virtualization/xen/0005-makefile-fix-efi-mountdir-use.4.15.patch b/pkgs/applications/virtualization/xen/0005-makefile-fix-efi-mountdir-use.4.15.patch
deleted file mode 100644
index 8f07c1a8e29ff..0000000000000
--- a/pkgs/applications/virtualization/xen/0005-makefile-fix-efi-mountdir-use.4.15.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-EFI_MOUNTPOINT is conventionally /boot/efi or /boot/EFI or something
-like that, and (on my machine) has directories within that called
-{Boot, nixos, gummiboot}.
-
-This patch does two things:
-
-1) Xen apparently wants to put files in
-$(EFI_MOUNTPOINT)/efi/$(EFI_VENDOR) - we remove the duplicate 'efi' name
-because I can't see why we have it
-
-2) Ensures the said directory exists
-
-
-diff --git a/xen/Makefile b/xen/Makefile
-index acb2d28891..d0763fbbe7 100644
---- a/xen/Makefile
-+++ b/xen/Makefile
-@@ -289,7 +289,9 @@ _install: $(TARGET)$(CONFIG_XEN_INSTALL_SUFFIX)
- ln -sf $(T)-$(XEN_FULLVERSION).efi $(D)$(EFI_DIR)/$(T)-$(XEN_VERSION).efi; \
- ln -sf $(T)-$(XEN_FULLVERSION).efi $(D)$(EFI_DIR)/$(T).efi; \
- if [ -n '$(EFI_MOUNTPOINT)' -a -n '$(EFI_VENDOR)' ]; then \
-- $(INSTALL_DATA) $(TARGET).efi $(D)$(EFI_MOUNTPOINT)/efi/$(EFI_VENDOR)/$(T)-$(XEN_FULLVERSION).efi; \
-+ [ -d $(D)$(EFI_MOUNTPOINT)/$(EFI_VENDOR) ] || \
-+ $(INSTALL_DIR) $(D)$(EFI_MOUNTPOINT)/$(EFI_VENDOR) ;\
-+ $(INSTALL_DATA) $(TARGET).efi $(D)$(EFI_MOUNTPOINT)/$(EFI_VENDOR)/$(T)-$(XEN_FULLVERSION).efi; \
- elif [ "$(D)" = "$(patsubst $(shell cd $(XEN_ROOT) && pwd)/%,%,$(D))" ]; then \
- echo 'EFI installation only partially done (EFI_VENDOR not set)' >&2; \
- fi; \
-@@ -319,7 +321,7 @@ _uninstall:
- rm -f $(D)$(DEBUG_DIR)/$(T)-$(XEN_FULLVERSION).efi.map
- rm -f $(D)$(EFI_DIR)/$(T)-$(XEN_VERSION).efi
- rm -f $(D)$(EFI_DIR)/$(T).efi
-- rm -f $(D)$(EFI_MOUNTPOINT)/efi/$(EFI_VENDOR)/$(T)-$(XEN_FULLVERSION).efi
-+ rm -f $(D)$(EFI_MOUNTPOINT)/$(EFI_VENDOR)/$(T)-$(XEN_FULLVERSION).efi
-
- .PHONY: _debug
- _debug:
diff --git a/pkgs/applications/virtualization/xen/4.15.nix b/pkgs/applications/virtualization/xen/4.15.nix
deleted file mode 100644
index d4905088ae1e3..0000000000000
--- a/pkgs/applications/virtualization/xen/4.15.nix
+++ /dev/null
@@ -1,183 +0,0 @@
-{ lib, callPackage, fetchurl, fetchpatch, fetchgit
-, ocaml-ng
-, withInternalQemu ? true
-, withInternalTraditionalQemu ? true
-, withInternalSeabios ? true
-, withSeabios ? !withInternalSeabios, seabios
-, withInternalOVMF ? false # FIXME: tricky to build
-, withOVMF ? false, OVMF
-, withLibHVM ? false
-
-# xen
-, python3Packages
-
-# qemu
-, udev, pciutils, xorg, SDL, pixman, acl, glusterfs, spice-protocol, usbredir
-, alsa-lib, glib, python3
-, ... } @ args:
-
-assert withInternalSeabios -> !withSeabios;
-assert withInternalOVMF -> !withOVMF;
-assert !withLibHVM;
-
-with lib;
-
-# Patching XEN? Check the XSAs at
-# https://xenbits.xen.org/xsa/
-# and try applying all the ones we don't have yet.
-
-let
- xsa = import ./xsa-patches.nix { inherit fetchpatch; };
-
- qemuMemfdBuildFix = fetchpatch {
- name = "xen-4.8-memfd-build-fix.patch";
- url = "https://github.com/qemu/qemu/commit/75e5b70e6b5dcc4f2219992d7cffa462aa406af0.patch";
- sha256 = "0gaz93kb33qc0jx6iphvny0yrd17i8zhcl3a9ky5ylc2idz0wiwa";
- };
-
- qemuDeps = [
- udev pciutils xorg.libX11 SDL pixman acl glusterfs spice-protocol usbredir
- alsa-lib glib python3
- ];
-in
-
-callPackage (import ./generic.nix (rec {
- version = "4.15.1";
-
- src = fetchurl {
- url = "https://downloads.xenproject.org/release/xen/${version}/xen-${version}.tar.gz";
- sha256 = "1rmc7gb72xwhr3h9rc3bkac41s8kjjzz45miwdq6yalyq7j7vss5";
- };
-
- # Sources needed to build tools and firmwares.
- xenfiles = optionalAttrs withInternalQemu {
- qemu-xen = {
- src = fetchgit {
- url = "https://xenbits.xen.org/git-http/qemu-xen.git";
- # rev = "refs/tags/qemu-xen-${version}";
- # use revision hash - reproducible but must be updated with each new version
- rev = "e2af2d050338c99e8436e251ad67aafb3ebbd501";
- sha256 = "sha256-gVykPtzAA7tmpe6iVvnulaW+b0jD3gwL1JXC5yeIA7M=";
- };
- buildInputs = qemuDeps;
- postPatch = ''
- # needed in build but /usr/bin/env is not available in sandbox
- substituteInPlace scripts/tracetool.py \
- --replace "/usr/bin/env python" "${python3}/bin/python"
- '';
- meta.description = "Xen's fork of upstream Qemu";
- };
- } // optionalAttrs withInternalTraditionalQemu {
- # TODO 4.15: something happened with traditional in this release?
- qemu-xen-traditional = {
- src = fetchgit {
- url = "https://xenbits.xen.org/git-http/qemu-xen-traditional.git";
- # rev = "refs/tags/xen-${version}";
- # use revision hash - reproducible but must be updated with each new version
- rev = "3d273dd05e51e5a1ffba3d98c7437ee84e8f8764";
- sha256 = "1dc6dhjp4y2irmi9yiyw1kzmm1habyy8j1s2zkf6qyak850krqj7";
- };
- buildInputs = qemuDeps;
- patches = [
- ];
- postPatch = ''
- substituteInPlace xen-hooks.mak \
- --replace /usr/include/pci ${pciutils}/include/pci
- '';
- meta.description = "Xen's fork of upstream Qemu that uses old device model";
- };
- } // optionalAttrs withInternalSeabios {
- "firmware/seabios-dir-remote" = {
- src = fetchgit {
- url = "https://xenbits.xen.org/git-http/seabios.git";
- rev = "155821a1990b6de78dde5f98fa5ab90e802021e0";
- sha256 = "sha256-F3lzr00CMAObJtpz0eZFT/rwjFx+bvlI37/JtHXP5Eo=";
- };
- patches = [ ./0000-qemu-seabios-enable-ATA_DMA.patch ];
- meta.description = "Xen's fork of Seabios";
- };
- } // optionalAttrs withInternalOVMF {
- "firmware/ovmf-dir-remote" = {
- src = fetchgit {
- url = "https://xenbits.xen.org/git-http/ovmf.git";
- rev = "a3741780fe3535e19e02efa869a7cac481891129";
- sha256 = "0000000000000000000000000000000000000000000000000000";
- };
- meta.description = "Xen's fork of OVMF";
- };
- } // {
- # TODO: patch Xen to make this optional?
- "firmware/etherboot/ipxe.git" = {
- src = fetchgit {
- url = "https://git.ipxe.org/ipxe.git";
- rev = "988d2c13cdf0f0b4140685af35ced70ac5b3283c";
- sha256 = "1pkf1n1c0rdlzfls8fvjvi1sd9xjd9ijqlyz3wigr70ijcv6x8i9";
- };
- meta.description = "Xen's fork of iPXE";
- };
- };
-
- configureFlags = []
- ++ optional (!withInternalQemu) "--with-system-qemu" # use qemu from PATH
- ++ optional (withInternalTraditionalQemu) "--enable-qemu-traditional"
- ++ optional (!withInternalTraditionalQemu) "--disable-qemu-traditional"
-
- ++ optional (withSeabios) "--with-system-seabios=${seabios}/share/seabios"
- ++ optional (!withInternalSeabios && !withSeabios) "--disable-seabios"
-
- ++ optional (withOVMF) "--with-system-ovmf=${OVMF.firmware}"
- ++ optional (withInternalOVMF) "--enable-ovmf";
-
- NIX_CFLAGS_COMPILE = toString [
- # TODO 4.15: drop unneeded ones
- # Fix build on Glibc 2.24.
- "-Wno-error=deprecated-declarations"
- # Fix build with GCC 8
- "-Wno-error=maybe-uninitialized"
- "-Wno-error=stringop-truncation"
- "-Wno-error=format-truncation"
- "-Wno-error=array-bounds"
- # Fix build with GCC 9
- "-Wno-error=address-of-packed-member"
- "-Wno-error=format-overflow"
- "-Wno-error=absolute-value"
- # Fix build with GCC 10
- "-Wno-error=enum-conversion"
- "-Wno-error=zero-length-bounds"
- # Fix build with GCC 12
- # xentoollog_stubs.c:57: error: "Some_val" redefined [-Werror]
- "-Wno-error"
- ];
-
- patches = with xsa; flatten [
- ./0000-fix-ipxe-src.4.15.patch
- ./0000-fix-install-python.4.15.patch
- ./0004-makefile-use-efi-ld.4.15.patch
- ./0005-makefile-fix-efi-mountdir-use.4.15.patch
-
- XSA_386
- ];
-
- postPatch = ''
- # Avoid a glibc >= 2.25 deprecation warnings that get fatal via -Werror.
- sed 1i'#include ' \
- -i tools/libs/light/libxl_device.c
-
- # Fix missing pkg-config dir
- mkdir -p tools/pkg-config
- '';
-
- preBuild = ''
- # PKG_CONFIG env var collides with variables used in tools Makefiles.
- unset PKG_CONFIG
- '';
-
- passthru = {
- qemu-system-i386 = if withInternalQemu
- then "lib/xen/bin/qemu-system-i386"
- else throw "this xen has no qemu builtin";
- };
-
-})) ({
- ocamlPackages = ocaml-ng.ocamlPackages_4_14;
-} // args)
diff --git a/pkgs/applications/virtualization/xen/0000-fix-ipxe-src.4.15.patch b/pkgs/applications/virtualization/xen/4.16/0000-xen-ipxe-src-4.16.patch
similarity index 93%
rename from pkgs/applications/virtualization/xen/0000-fix-ipxe-src.4.15.patch
rename to pkgs/applications/virtualization/xen/4.16/0000-xen-ipxe-src-4.16.patch
index 08e9aa5ad2fb9..d96023d1946ae 100644
--- a/pkgs/applications/virtualization/xen/0000-fix-ipxe-src.4.15.patch
+++ b/pkgs/applications/virtualization/xen/4.16/0000-xen-ipxe-src-4.16.patch
@@ -1,21 +1,21 @@
-hack to make etherboot use prefetched ipxe
+Hack to make etherboot use pre-fetched iPXE.
diff --git a/tools/firmware/etherboot/Makefile b/tools/firmware/etherboot/Makefile
index ed9e11305f..979a3acea8 100644
--- a/tools/firmware/etherboot/Makefile
+++ b/tools/firmware/etherboot/Makefile
@@ -16,6 +16,7 @@ IPXE_TARBALL_URL ?= $(XEN_EXTFILES_URL)/ipxe-git-$(IPXE_GIT_TAG).tar.gz
-
+
D=ipxe
T=ipxe.tar.gz
+G=ipxe.git
-
+
ROMS = $(addprefix $D/src/bin/, $(addsuffix .rom, $(ETHERBOOT_NICS)))
ROM = $D/src/bin/ipxe.bin
@@ -41,9 +42,9 @@ $T:
fi
mv _$T $T
-
+
-$D/src/arch/i386/Makefile: $T Config
- rm -rf $D
- gzip -dc $T | tar xf -
diff --git a/pkgs/applications/virtualization/xen/4.16/default.nix b/pkgs/applications/virtualization/xen/4.16/default.nix
new file mode 100644
index 0000000000000..33aba63846236
--- /dev/null
+++ b/pkgs/applications/virtualization/xen/4.16/default.nix
@@ -0,0 +1,49 @@
+{
+ lib,
+ fetchpatch,
+ callPackage,
+ ocaml-ng,
+ ...
+}@genericDefinition:
+
+let
+ upstreamPatches = import ../patches.nix {
+ inherit lib;
+ inherit fetchpatch;
+ };
+
+ upstreamPatchList = lib.lists.flatten [ upstreamPatches.XSA_458 ];
+in
+
+callPackage (import ../generic.nix {
+ branch = "4.16";
+ version = "4.16.6";
+ latest = false;
+ pkg = {
+ xen = {
+ rev = "4b33780de790bd438dd7cbb6143b410d94f0f049";
+ hash = "sha256-2kcmfKwBo3w1U5CSxLSYSteqvzcJaB+cA7keVb3amyA=";
+ patches = [ ./0000-xen-ipxe-src-4.16.patch ] ++ upstreamPatchList;
+ };
+ qemu = {
+ rev = "c02cb236b5e4a76cf74e641cc35a0e3ebd3e52f3";
+ hash = "sha256-LwlPry04az9QQowaDG2la8PYlGOUMbZaQAsCHxj+pwM=";
+ patches = [ ];
+ };
+ seaBIOS = {
+ rev = "d239552ce7220e448ae81f41515138f7b9e3c4db";
+ hash = "sha256-UKMceJhIprN4/4Xe4EG2EvKlanxVcEi5Qcrrk3Ogiik=";
+ patches = [ ];
+ };
+ ovmf = {
+ rev = "7b4a99be8a39c12d3a7fc4b8db9f0eab4ac688d5";
+ hash = "sha256-Qq2RgktCkJZBsq6Ch+6tyRHhme4lfcN7d2oQfxwhQt8=";
+ patches = [ ];
+ };
+ ipxe = {
+ rev = "3c040ad387099483102708bb1839110bc788cefb";
+ hash = "sha256-y2QdZEoGsGUQjrrvD8YRa8VoqcZSr4tjLM//I/MrsLI=";
+ patches = [ ];
+ };
+ };
+}) ({ ocamlPackages = ocaml-ng.ocamlPackages_4_14; } // genericDefinition)
diff --git a/pkgs/applications/virtualization/xen/4.17/0000-xen-ipxe-src-4.17.patch b/pkgs/applications/virtualization/xen/4.17/0000-xen-ipxe-src-4.17.patch
new file mode 100644
index 0000000000000..d96023d1946ae
--- /dev/null
+++ b/pkgs/applications/virtualization/xen/4.17/0000-xen-ipxe-src-4.17.patch
@@ -0,0 +1,27 @@
+Hack to make etherboot use pre-fetched iPXE.
+
+diff --git a/tools/firmware/etherboot/Makefile b/tools/firmware/etherboot/Makefile
+index ed9e11305f..979a3acea8 100644
+--- a/tools/firmware/etherboot/Makefile
++++ b/tools/firmware/etherboot/Makefile
+@@ -16,6 +16,7 @@ IPXE_TARBALL_URL ?= $(XEN_EXTFILES_URL)/ipxe-git-$(IPXE_GIT_TAG).tar.gz
+
+ D=ipxe
+ T=ipxe.tar.gz
++G=ipxe.git
+
+ ROMS = $(addprefix $D/src/bin/, $(addsuffix .rom, $(ETHERBOOT_NICS)))
+ ROM = $D/src/bin/ipxe.bin
+@@ -41,9 +42,9 @@ $T:
+ fi
+ mv _$T $T
+
+-$D/src/arch/i386/Makefile: $T Config
+- rm -rf $D
+- gzip -dc $T | tar xf -
++$D/src/arch/i386/Makefile: $G Config
++ mkdir $D
++ cp -a $G/* $D
+ for i in $$(cat patches/series) ; do \
+ patch -d $D -p1 --quiet
+
+
+
+
+
+
+
+
+
+# Xen Hypervisor
+
+This directory includes the build recipes for the [Xen Hypervisor](https://xenproject.org/).
+
+Some other notable packages that compose the Xen Ecosystem include:
+
+- `ocamlPackages.xenstore`: Mirage's `oxenstore` implementation.
+- `ocamlPackages.vchan`: Mirage's `xen-vchan` implementation.
+- `ocamlPackages.xenstore-tool`: XAPI's `oxenstore` utilities.
+- `xen-guest-agent`: Guest drivers for UNIX domUs.
+- `win-pvdrivers`: Guest drivers for Windows domUs.
+
+## Updating
+
+### Automatically
+
+An automated update script is available in this directory. To produce up-to-date
+files for all supported Xen branches, simply run `./update.sh`, and follow the
+instructions given to you by the script. Notably, it will request that you verify
+the Xen Project code signing PGP key. This README understands that the fingerprint
+of that key is [`23E3 222C 145F 4475 FA80 60A7 83FE 14C9 57E8 2BD9`](https://keys.openpgp.org/search?q=pgp%40xen.org),
+but you should verify this information by seeking the fingerprint from other trusted
+sources, as this document may be compromised. Once the PGP key is verified, it will
+use `git verify-tag` to ascertain the validity of the cloned Xen sources.
+
+After the script is done, follow the steps in [**For Both Update Methods**](#for-both-update-methods) below.
+
+#### Downstream Patch Names
+
+The script expects local patch names to follow a certain specification.
+Please name any required patches using the template below:
+
+```console
+0000-project-description-branch.patch
+```
+
+Where:
+
+1. The first four numbers define the patch order.
+ **0001** will be applied after **0000**, and so on.
+1. `project` means the name of the source the patch should be applied to.
+ - If you are applying patches to the main Xen sources, use `xen`.
+ - For the pre-fetched QEMU, use `qemu`.
+ - For SeaBIOS, use `seabios`.
+ - For OVMF, use `ovmf`.
+ - For iPXE, use `ipxe`.
+1. `description` is a string with uppercase and lowercase letters, numbers and
+ dashes. It describes the patch name and what it does to the upstream code.
+1. `branch` is the branch for which this patch is supposed to patch.
+ It should match the name of the directory it is in.
+
+For example, a patch fixing `xentop`'s output in the 4.15 branch should have
+the following name: `0000-xen-xentop-output-4.15.patch`, and it should be added
+to the `4.15/` directory.
+
+### Manually
+
+The script is not infallible, and it may break in the future. If that happens,
+open a PR fixing the script, and update Xen manually:
+
+1. Check the support matrix to see which branches are security-supported.
+1. Create one directory per branch.
+1. [Update](https://xenbits.xenproject.org/gitweb/) the `default.nix` files for
+ the branches that already exist and copy a new one to any branches that do
+ not yet exist in Nixpkgs.
+ - Do not forget to set the `branch`, `version`, and `latest` attributes for
+ each of the `default.nix` files.
+ - The revisions are preferably commit hashes, but tag names are acceptable
+ as well.
+
+### For Both Update Methods
+
+1. Make sure all branches build. (Both the `standard` and `slim` versions)
+1. Use the NixOS module to test if dom0 boots successfully on all new versions.
+1. Clean up your changes and commit them, making sure to follow the
+ [Nixpkgs Contribution Guidelines](../../../../CONTRIBUTING.md).
+1. Open a PR and await a review from the current maintainers.
+
+## Features
+
+### Pre-fetched Sources
+
+On a typical Xen build, the Xen Makefiles will fetch more required sources with
+`git` and `wget`. Due to the Nix Sandbox, build-time fetching will fail, so we
+pre-fetch the required sources before building.[^1] To accomplish this, we have
+a `prefetchedSources` attribute that contains the required derivations, if they
+are requested by the main Xen build.
+
+### EFI
+
+Building `xen.efi` requires an `ld` with PE support.[^2]
+
+We use a `makeFlag` to override the `$LD` environment variable to point to our
+patched `efiBinutils`. For more information, see the comment in `./generic.nix`.
+
+> [!TIP]
+> If you are certain you will not be running Xen in an x86 EFI environment, disable
+the `withEFI` flag with an [override](https://nixos.org/manual/nixpkgs/stable/#chap-overrides)
+to save you the need to compile `efiBinutils`.
+
+### Default Overrides
+
+By default, Xen also builds
+[QEMU](https://www.qemu.org/),
+[SeaBIOS](https://www.seabios.org/SeaBIOS),
+[OVMF](https://github.com/tianocore/tianocore.github.io/wiki/OVMF) and
+[iPXE](https://ipxe.org/).
+
+- QEMU is used for stubdomains and handling devices.
+- SeaBIOS is the default legacy BIOS ROM for HVM domains.
+- OVMF is the default UEFI ROM for HVM domains.
+- iPXE provides a PXE boot environment for HVMs.
+
+However, those packages are already available on Nixpkgs, and Xen does not
+necessarily need to build them into the main hypervisor build. For this reason,
+we also have the `withInternal` flags, which enables and disables
+building those built-in components. The two most popular Xen configurations will
+be the default build, with all built-in components, and a `slim` build, with none
+of those components. To simplify this process, the `./packages.nix` file includes
+the `xen-slim` package overrides that have all `withInternal` flags
+disabled. See the `meta.longDescription` attribute for the `xen-slim` packages
+for more information.
+
+## Security
+
+We aim to support all **security-supported** versions of Xen at any given time.
+See the [Xen Support Matrix](https://xenbits.xen.org/docs/unstable/support-matrix.html)
+for a list of versions. As soon as a version is no longer **security-supported**,
+it should be removed from Nixpkgs.
+
+> [!CAUTION]
+> Pull requests that introduce XSA patches
+should have the `1.severity: security` label.
+
+### Maintainers
+
+Xen is a particularly complex piece of software, so we are always looking for new
+maintainers. Help out by [making and triaging issues](https://github.com/NixOS/nixpkgs/issues/new/choose),
+[sending build fixes and improvements through PRs](https://github.com/NixOS/nixpkgs/compare),
+updating the branches, and [patching security flaws](https://xenbits.xenproject.org/xsa/).
+
+We are also looking for testers, particularly those who can test Xen on AArch64
+machines. Open issues for any build failures or runtime errors you find!
+
+## Tests
+
+So far, we only have had one simple automated test that checks for
+the correct `pkg-config` output files.
+
+Due to Xen's nature as a type-1 hypervisor, it is not a trivial matter to design
+new tests, as even basic functionality requires a machine booted in a dom0
+kernel. For this reason, most testing done with this package must be done
+manually in a NixOS machine with `virtualisation.xen.enable` set to `true`.
+
+Another unfortunate thing is that none of the Xen commands have a `--version`
+flag. This means that `testers.testVersion` cannot ascertain the Xen version.
+The only way to verify that you have indeed built the correct version is to
+boot into the freshly built Xen kernel and run `xl info`.
+
+
+
+
+
+
+
+[^1]: We also produce fake `git`, `wget` and `hostname` binaries that do nothing,
+ to prevent the build from failing because Xen cannot fetch the sources that
+ were already fetched by Nix.
+[^2]: From the [Xen Documentation](https://xenbits.xenproject.org/docs/unstable/misc/efi.html):
+ > For x86, building `xen.efi` requires `gcc` 4.5.x or above (4.6.x or newer
+ recommended, as 4.5.x was probably never really tested for this purpose)
+ and `binutils` 2.22 or newer. Additionally, the `binutils` build must be
+ configured to include support for the x86_64-pep emulation (i.e.
+ `--enable-targets=x86_64-pep` or an option of equivalent effect should be
+ passed to the configure script).
diff --git a/pkgs/applications/virtualization/xen/generic.nix b/pkgs/applications/virtualization/xen/generic.nix
index 826cd8a3d9d84..94abe86e85e53 100644
--- a/pkgs/applications/virtualization/xen/generic.nix
+++ b/pkgs/applications/virtualization/xen/generic.nix
@@ -1,265 +1,687 @@
-config:
-{ lib, stdenv, cmake, pkg-config, which
-
-# Xen
-, bison, bzip2, checkpolicy, dev86, figlet, flex, gettext, glib
-, acpica-tools, libaio, libiconv, libuuid, ncurses, openssl, perl
-, xz, yajl, zlib
-, python3Packages
-
-# Xen Optional
-, ocamlPackages
-
-# Scripts
-, coreutils, gawk, gnused, gnugrep, diffutils, multipath-tools
-, iproute2, inetutils, iptables, bridge-utils, openvswitch, nbd, drbd
-, util-linux, procps, systemd
-
-# Documentation
-# python3Packages.markdown
-, fig2dev, ghostscript, texinfo, pandoc
-
-, binutils-unwrapped
-
-, ...} @ args:
-
-with lib;
+versionDefinition:
+{
+ lib,
+ stdenv,
+ autoPatchelfHook,
+ cmake,
+ ninja,
+ pkg-config,
+ testers,
+ which,
+
+ fetchgit,
+ fetchFromGitHub,
+
+ # Xen
+ acpica-tools,
+ bison,
+ bzip2,
+ dev86,
+ e2fsprogs,
+ flex,
+ libnl,
+ libuuid,
+ lzo,
+ ncurses,
+ ocamlPackages,
+ perl,
+ python311Packages,
+ systemdMinimal,
+ xz,
+ yajl,
+ zlib,
+ zstd,
+
+ # Xen Optional
+ withInternalQEMU ? true,
+ pixman,
+ glib,
+
+ withInternalSeaBIOS ? true,
+ withSeaBIOS ? !withInternalSeaBIOS,
+ seabios,
+
+ withInternalOVMF ? true,
+ withOVMF ? !withInternalOVMF,
+ OVMF,
+ nasm,
+
+ withInternalIPXE ? true,
+ withIPXE ? !withInternalIPXE,
+ ipxe,
+
+ withFlask ? false,
+ checkpolicy,
+
+ efiVendor ? "nixos", # Allow downstreams with custom branding to quickly override the EFI Vendor string.
+ withEFI ? true,
+ binutils-unwrapped,
+
+ # Documentation
+ fig2dev,
+ pandoc,
+
+ # Scripts
+ bridge-utils,
+ coreutils,
+ diffutils,
+ gawk,
+ gnugrep,
+ gnused,
+ inetutils,
+ iproute2,
+ iptables,
+ multipath-tools,
+ nbd,
+ openvswitch,
+ util-linux,
+ ...
+}@packageDefinition:
let
- #TODO: fix paths instead
- scriptEnvPath = concatMapStringsSep ":" (x: "${x}/bin") [
- which perl
- coreutils gawk gnused gnugrep diffutils util-linux multipath-tools
- iproute2 inetutils iptables bridge-utils openvswitch nbd drbd
+ #TODO: fix paths instead.
+ scriptEnvPath = lib.strings.concatMapStringsSep ":" (x: "${x}/bin") [
+ bridge-utils
+ coreutils
+ diffutils
+ gawk
+ gnugrep
+ gnused
+ inetutils
+ iproute2
+ iptables
+ multipath-tools
+ nbd
+ openvswitch
+ perl
+ util-linux
+ which
];
- withXenfiles = f: concatStringsSep "\n" (mapAttrsToList f config.xenfiles);
-
- withTools = a: f: withXenfiles (name: x: optionalString (hasAttr a x) ''
- echo "processing ${name}"
- __do() {
- cd "tools/${name}"
- ${f name x}
+ inherit (versionDefinition) branch;
+ inherit (versionDefinition) version;
+ inherit (versionDefinition) latest;
+ inherit (versionDefinition) pkg;
+ pname = "xen";
+
+ # Sources needed to build tools and firmwares.
+ prefetchedSources =
+ lib.attrsets.optionalAttrs withInternalQEMU {
+ qemu-xen = {
+ src = fetchgit {
+ url = "https://xenbits.xen.org/git-http/qemu-xen.git";
+ fetchSubmodules = true;
+ inherit (pkg.qemu) rev;
+ inherit (pkg.qemu) hash;
+ };
+ patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.qemu) pkg.qemu.patches;
+ postPatch = ''
+ substituteInPlace scripts/tracetool.py \
+ --replace-fail "/usr/bin/env python" "${python311Packages.python}/bin/python"
+ '';
+ };
}
- ( __do )
- '');
-
- # We don't want to use the wrapped version, because this version of ld is
- # only used for linking the Xen EFI binary, and the build process really
- # needs control over the LDFLAGS used
+ // lib.attrsets.optionalAttrs withInternalSeaBIOS {
+ "firmware/seabios-dir-remote" = {
+ src = fetchgit {
+ url = "https://xenbits.xen.org/git-http/seabios.git";
+ inherit (pkg.seaBIOS) rev;
+ inherit (pkg.seaBIOS) hash;
+ };
+ patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [
+ "patches"
+ ] pkg.seaBIOS) pkg.seaBIOS.patches;
+ };
+ }
+ // lib.attrsets.optionalAttrs withInternalOVMF {
+ "firmware/ovmf-dir-remote" = {
+ src = fetchgit {
+ url = "https://xenbits.xen.org/git-http/ovmf.git";
+ fetchSubmodules = true;
+ inherit (pkg.ovmf) rev;
+ inherit (pkg.ovmf) hash;
+ };
+ patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.ovmf) pkg.ovmf.patches;
+ postPatch = ''
+ substituteInPlace \
+ OvmfPkg/build.sh BaseTools/BinWrappers/PosixLike/{AmlToC,BrotliCompress,build,GenFfs,GenFv,GenFw,GenSec,LzmaCompress,TianoCompress,Trim,VfrCompile} \
+ --replace-fail "/usr/bin/env bash" ${stdenv.shell}
+ '';
+ };
+ }
+ // lib.attrsets.optionalAttrs withInternalIPXE {
+ "firmware/etherboot/ipxe.git" = {
+ src = fetchFromGitHub {
+ owner = "ipxe";
+ repo = "ipxe";
+ inherit (pkg.ipxe) rev;
+ inherit (pkg.ipxe) hash;
+ };
+ patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.ipxe) pkg.ipxe.patches;
+ };
+ };
+ withPrefetchedSources =
+ sourcePkg: lib.strings.concatLines (lib.attrsets.mapAttrsToList sourcePkg prefetchedSources);
+
+ # Sometimes patches are sourced through a path, like ./0000-xen.patch.
+ # This would break the patch attribute parser functions, so we normalise
+ # all patches sourced through paths by setting them to a { type = "path"; }
+ # attribute set.
+ # Patches from fetchpatch are already attribute sets.
+ normalisedPatchList = builtins.map (
+ patch:
+ if !builtins.isAttrs patch then
+ if builtins.isPath patch then
+ { type = "path"; }
+ else
+ throw "xen/generic.nix: normalisedPatchList attempted to normalise something that is not a Path or an Attribute Set."
+ else
+ patch
+ ) pkg.xen.patches;
+
+ # Simple counter for the number of attrsets (patches) in the patches list after normalisation.
+ numberOfPatches = lib.lists.count (patch: builtins.isAttrs patch) normalisedPatchList;
+
+ # builtins.elemAt's index begins at 0, so we subtract 1 from the number of patches in order to
+ # produce the range that will be used in the following builtin.map calls.
+ availablePatchesToTry = lib.lists.range 0 (numberOfPatches - 1);
+
+ # Takes in an attrByPath input, and outputs the attribute value for each patch in a list.
+ # If a patch does not have a given attribute, returns `null`. Use lib.lists.remove null
+ # to remove these junk values, if necessary.
+ retrievePatchAttributes =
+ attributeName:
+ builtins.map (
+ x: lib.attrsets.attrByPath attributeName null (builtins.elemAt normalisedPatchList x)
+ ) availablePatchesToTry;
+
+ # Produces a list of newline-separated strings that lists the vulnerabilities this
+ # Xen is NOT affected by, due to the applied Xen Security Advisory patches. This is
+ # then used in meta.longDescription, to let users know their Xen is patched against
+ # known vulnerabilities, as the package version isn't always the best indicator.
+ #
+ # Produces something like this: (one string for each XSA)
+ # * [Xen Security Advisory #1](https://xenbits.xenproject.org/xsa/advisory-1.html): **Title for XSA.**
+ # >Description of issue in XSA
+ #Extra lines
+ #are not indented,
+ #but markdown should be
+ #fine with it.
+ # Fixes:
+ # * [CVE-1999-00001](https://www.cve.org/CVERecord?id=CVE-1999-00001)
+ # * [CVE-1999-00002](https://www.cve.org/CVERecord?id=CVE-1999-00002)
+ # * [CVE-1999-00003](https://www.cve.org/CVERecord?id=CVE-1999-00003)
+ writeAdvisoryDescription =
+ if (lib.lists.remove null (retrievePatchAttributes [ "xsa" ]) != [ ]) then
+ lib.lists.zipListsWith (a: b: a + b)
+ (lib.lists.zipListsWith (a: b: a + "**" + b + ".**\n >")
+ (lib.lists.zipListsWith (a: b: "* [Xen Security Advisory #" + a + "](" + b + "): ")
+ (lib.lists.remove null (retrievePatchAttributes [ "xsa" ]))
+ (
+ lib.lists.remove null (retrievePatchAttributes [
+ "meta"
+ "homepage"
+ ])
+ )
+ )
+ (
+ lib.lists.remove null (retrievePatchAttributes [
+ "meta"
+ "description"
+ ])
+ )
+ )
+ (
+ lib.lists.remove null (retrievePatchAttributes [
+ "meta"
+ "longDescription"
+ ])
+ )
+ else
+ [ ];
+
+ withTools =
+ attr: file:
+ withPrefetchedSources (
+ name: source:
+ lib.strings.optionalString (builtins.hasAttr attr source) ''
+ echo "processing ${name}"
+ __do() {
+ cd "tools/${name}"
+ ${file name source}
+ }
+ ( __do )
+ ''
+ );
+
+ # Originally, there were two versions of binutils being used: the standard one and
+ # this patched one. Unfortunately, that required patches to the Xen Makefiles, and
+ # quickly became too complex to maintain. The new solution is to simply build this
+ # efi-binutils derivation and use it for the whole build process, except if
+ # enableEFI is disabled; it'll then use `binutils`.
efiBinutils = binutils-unwrapped.overrideAttrs (oldAttrs: {
name = "efi-binutils";
- configureFlags = oldAttrs.configureFlags ++ [
- "--enable-targets=x86_64-pep"
- ];
- doInstallCheck = false; # We get a spurious failure otherwise, due to host/target mis-match
+ configureFlags = oldAttrs.configureFlags ++ [ "--enable-targets=x86_64-pep" ];
+ doInstallCheck = false; # We get a spurious failure otherwise, due to a host/target mismatch.
});
in
-stdenv.mkDerivation (rec {
- inherit (config) version;
-
- name = "xen-${version}";
+stdenv.mkDerivation (finalAttrs: {
+ inherit pname;
+ inherit version;
- dontUseCmakeConfigure = true;
-
- hardeningDisable = [ "stackprotector" "fortify" "pic" ];
-
- nativeBuildInputs = [ pkg-config cmake ];
- buildInputs = [
- which
-
- # Xen
- bison bzip2 checkpolicy dev86 figlet flex gettext glib acpica-tools libaio
- libiconv libuuid ncurses openssl perl python3Packages.python xz yajl zlib
-
- # oxenstored
- ocamlPackages.findlib ocamlPackages.ocaml systemd
+ outputs = [
+ "out" # TODO: Split $out in $bin for binaries and $lib for libraries.
+ "man" # Manual pages for Xen userspace utilities.
+ "dev" # Development headers.
+ "boot" # xen.gz kernel, policy file if Flask is enabled, xen.efi if EFI is enabled.
+ ];
- # Python fixes
- python3Packages.wrapPython
+ # Main Xen source.
+ src = fetchgit {
+ url = "https://xenbits.xen.org/git-http/xen.git";
+ inherit (pkg.xen) rev;
+ inherit (pkg.xen) hash;
+ };
+
+ # Gets the patches from the pkg.xen.patches attribute from the versioned files.
+ patches = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "patches" ] pkg.xen) pkg.xen.patches;
+
+ nativeBuildInputs =
+ [
+ autoPatchelfHook
+ bison
+ cmake
+ fig2dev
+ flex
+ pandoc
+ pkg-config
+ ]
+ ++ lib.lists.optionals withInternalQEMU [
+ ninja
+ python311Packages.sphinx
+ ];
+ buildInputs =
+ [
+ # Xen
+ acpica-tools
+ bzip2
+ dev86
+ e2fsprogs.dev
+ libnl
+ libuuid
+ lzo
+ ncurses
+ perl
+ python311Packages.python
+ xz
+ yajl
+ zlib
+ zstd
+
+ # oxenstored
+ ocamlPackages.findlib
+ ocamlPackages.ocaml
+ systemdMinimal
+
+ # Python Fixes
+ python311Packages.wrapPython
+ ]
+ ++ lib.lists.optionals withInternalQEMU [
+ glib
+ pixman
+ ]
+ ++ lib.lists.optional withInternalOVMF nasm
+ ++ lib.lists.optional withFlask checkpolicy;
+
+ configureFlags =
+ [ "--enable-systemd" ]
+ ++ lib.lists.optional (!withInternalQEMU) "--with-system-qemu"
+
+ ++ lib.lists.optional withSeaBIOS "--with-system-seabios=${seabios}/share/seabios"
+ ++ lib.lists.optional (!withInternalSeaBIOS && !withSeaBIOS) "--disable-seabios"
+
+ ++ lib.lists.optional withOVMF "--with-system-ovmf=${OVMF.firmware}"
+ ++ lib.lists.optional withInternalOVMF "--enable-ovmf"
+
+ ++ lib.lists.optional withIPXE "--with-system-ipxe=${ipxe}"
+ ++ lib.lists.optional withInternalIPXE "--enable-ipxe";
+
+ makeFlags =
+ [
+ "PREFIX=$(out)"
+ "CONFIG_DIR=/etc"
+ "XEN_EXTFILES_URL=\\$(XEN_ROOT)/xen_ext_files"
+ "XEN_SCRIPT_DIR=$(CONFIG_DIR)/xen/scripts"
+ "BASH_COMPLETION_DIR=$(PREFIX)/share/bash-completion/completions"
+ ]
+ ++ lib.lists.optionals withEFI [
+ "EFI_VENDOR=${efiVendor}"
+ "INSTALL_EFI_STRIP=1"
+ "LD=${efiBinutils}/bin/ld" # See the comment in the efiBinutils definition above.
+ ]
+ # These flags set the CONFIG_* options in /boot/xen.config
+ # and define if the default policy file is built. However,
+ # the Flask binaries always get compiled by default.
+ ++ lib.lists.optionals withFlask [
+ "XSM_ENABLE=y"
+ "FLASK_ENABLE=y"
+ ]
+ ++ (pkg.xen.makeFlags or [ ]);
+
+ buildFlags = [
+ "xen" # Build the Xen Hypervisor.
+ "tools" # Build the userspace tools, such as `xl`.
+ "docs" # Build the Xen Documentation
+ # TODO: Enable the Stubdomains target. This requires another pre-fetched source: mini-os. Currently, Xen appears to build a limited version of stubdomains which does not include mini-os.
+ # "stubdom"
+ ];
- # Documentation
- python3Packages.markdown fig2dev ghostscript texinfo pandoc
+ enableParallelBuilding = true;
- # Others
- ] ++ (concatMap (x: x.buildInputs or []) (attrValues config.xenfiles))
- ++ (config.buildInputs or []);
+ env.NIX_CFLAGS_COMPILE = builtins.toString (
+ [
+ "-Wno-error=maybe-uninitialized"
+ "-Wno-error=array-bounds"
+ ]
+ ++ lib.lists.optionals withInternalOVMF [
+ "-Wno-error=format-security"
+ "-Wno-error=use-after-free"
+ "-Wno-error=vla-parameter"
+ "-Wno-error=dangling-pointer"
+ "-Wno-error=stringop-overflow"
+ ]
+ );
- prePatch = ''
- ### Generic fixes
+ dontUseCmakeConfigure = true;
+ dontUseNinjaBuild = withInternalQEMU;
+ prePatch =
# Xen's stubdoms, tools and firmwares need various sources that
# are usually fetched at build time using wget and git. We can't
- # have that, so we prefetch them in nix-expression and setup
- # fake wget and git for debugging purposes.
-
- mkdir fake-bin
-
- # Fake git: just print what it wants and die
- cat > fake-bin/wget << EOF
- #!${stdenv.shell} -e
- echo ===== FAKE WGET: Not fetching \$*
- [ -e \$3 ]
- EOF
-
- # Fake git: just print what it wants and die
- cat > fake-bin/git << EOF
- #!${stdenv.shell}
- echo ===== FAKE GIT: Not cloning \$*
- [ -e \$3 ]
- EOF
-
- chmod +x fake-bin/*
- export PATH=$PATH:$PWD/fake-bin
-
- # Remove in-tree qemu stuff in case we build from a tar-ball
- rm -rf tools/qemu-xen tools/qemu-xen-traditional
-
- # Fix shebangs, mainly for build-scripts
- # We want to do this before getting prefetched stuff to speed things up
- # (prefetched stuff has lots of files)
- find . -type f | xargs sed -i 's@/usr/bin/\(python\|perl\)@/usr/bin/env \1@g'
- find . -type f -not -path "./tools/hotplug/Linux/xendomains.in" \
- | xargs sed -i 's@/bin/bash@${stdenv.shell}@g'
-
- # Get prefetched stuff
- ${withXenfiles (name: x: ''
- echo "${x.src} -> tools/${name}"
- cp -r ${x.src} tools/${name}
- chmod -R +w tools/${name}
- '')}
- '';
-
- patches = [
- ] ++ (config.patches or []);
-
- postPatch = ''
- ### Hacks
-
- # Work around a bug in our GCC wrapper: `gcc -MF foo -v' doesn't
- # print the GCC version number properly.
- substituteInPlace xen/Makefile \
- --replace '$(CC) $(CFLAGS) -v' '$(CC) -v'
-
- # Hack to get `gcc -m32' to work without having 32-bit Glibc headers.
- mkdir -p tools/include/gnu
- touch tools/include/gnu/stubs-32.h
-
- ### Fixing everything else
-
- substituteInPlace tools/libfsimage/common/fsimage_plugin.c \
- --replace /usr $out
-
- substituteInPlace tools/misc/xenpvnetboot \
- --replace /usr/sbin/mount ${util-linux}/bin/mount \
- --replace /usr/sbin/umount ${util-linux}/bin/umount
-
- substituteInPlace tools/xenmon/xenmon.py \
- --replace /usr/bin/pkill ${procps}/bin/pkill
-
- ${optionalString (builtins.compareVersions config.version "4.8" >= 0) ''
+ # have that, so we pre-fetch them in the versioned Nix expressions,
+ # and produce fake wget and git executables for debugging purposes.
+ #
+ # We also produce a fake hostname executable to prevent spurious
+ # command-not-found errors during compilation.
+ #
+ # The snippet below produces executables that simply print in stdout
+ # what they were supposed to fetch, and exit gracefully.
+ ''
+ mkdir fake-bin
+
+ cat > fake-bin/wget << EOF
+ #!${stdenv.shell} -e
+ echo ===== FAKE WGET: Not fetching \$*
+ [ -e \$3 ]
+ EOF
+
+ cat > fake-bin/git << EOF
+ #!${stdenv.shell}
+ echo ===== FAKE GIT: Not cloning \$*
+ [ -e \$3 ]
+ EOF
+
+ cat > fake-bin/hostname << EOF
+ #!${stdenv.shell}
+ echo ${efiVendor}
+ [ -e \$3 ]
+ EOF
+
+ chmod +x fake-bin/*
+ export PATH=$PATH:$PWD/fake-bin
+ ''
+
+ # Remove in-tree QEMU sources, as we either pre-fetch them through
+ # the versioned Nix expressions if withInternalQEMU is true, or we
+ # don't build QEMU at all if withInternalQEMU is false.
+ + ''
+ rm --recursive --force tools/qemu-xen tools/qemu-xen-traditional
+ ''
+
+ # The following expression moves the sources we fetched in the
+ # versioned Nix expressions to their correct locations inside
+ # the Xen source tree.
+ + ''
+ ${withPrefetchedSources (
+ name: source: ''
+ echo "Copying pre-fetched source: ${source.src} -> tools/${name}"
+ cp --recursive ${source.src} tools/${name}
+ chmod --recursive +w tools/${name}
+ ''
+ )}
+ '';
+
+ postPatch =
+ # The following patch forces Xen to install xen.efi on $out/boot
+ # instead of $out/boot/efi/efi/nixos, as the latter directory
+ # would otherwise need to be created manually. This also creates
+ # a more consistent output for downstreams who override the
+ # efiVendor attribute above.
+ ''
+ substituteInPlace xen/Makefile \
+ --replace-fail "\$(D)\$(EFI_MOUNTPOINT)/efi/\$(EFI_VENDOR)/\$(T)-\$(XEN_FULLVERSION).efi" \
+ "\$(D)\$(BOOT_DIR)/\$(T)-\$(XEN_FULLVERSION).efi"
+ ''
+
+ # The following patch fixes the call to /bin/mkdir on the
+ # launch_xenstore.sh helper script.
+ + ''
substituteInPlace tools/hotplug/Linux/launch-xenstore.in \
- --replace /bin/mkdir mkdir
- ''}
-
- ${optionalString (builtins.compareVersions config.version "4.6" < 0) ''
- # TODO: use this as a template and support our own if-up scripts instead?
- substituteInPlace tools/hotplug/Linux/xen-backend.rules.in \
- --replace "@XEN_SCRIPT_DIR@" $out/etc/xen/scripts
-
- # blktap is not provided by xen, but by xapi
- sed -i '/blktap/d' tools/hotplug/Linux/xen-backend.rules.in
- ''}
-
- ${withTools "patches" (name: x: ''
- ${concatMapStringsSep "\n" (p: ''
- echo "# Patching with ${p}"
- patch -p1 < ${p}
- '') x.patches}
- '')}
-
- ${withTools "postPatch" (name: x: x.postPatch)}
-
- ${config.postPatch or ""}
- '';
-
- postConfigure = ''
- substituteInPlace tools/hotplug/Linux/xendomains \
- --replace /bin/ls ls
- '';
-
- EFI_LD = "${efiBinutils}/bin/ld";
- EFI_VENDOR = "nixos";
-
- # TODO: Flask needs more testing before enabling it by default.
- #makeFlags = [ "XSM_ENABLE=y" "FLASK_ENABLE=y" "PREFIX=$(out)" "CONFIG_DIR=/etc" "XEN_EXTFILES_URL=\\$(XEN_ROOT)/xen_ext_files" ];
- makeFlags = [ "PREFIX=$(out) CONFIG_DIR=/etc" "XEN_SCRIPT_DIR=/etc/xen/scripts" ]
- ++ (config.makeFlags or []);
-
- preBuild = ''
- ${config.preBuild or ""}
- '';
-
- buildFlags = [ "xen" "tools" ];
+ --replace-fail "/bin/mkdir" "${coreutils}/bin/mkdir"
+ ''
+
+ # The following expression fixes the paths called by Xen's systemd
+ # units, so we can use them in the NixOS module.
+ + ''
+ substituteInPlace \
+ tools/hotplug/Linux/systemd/{xen-init-dom0,xen-qemu-dom0-disk-backend,xenconsoled,xendomains,xenstored}.service.in \
+ --replace-fail /bin/grep ${gnugrep}/bin/grep
+ substituteInPlace \
+ tools/hotplug/Linux/systemd/{xen-qemu-dom0-disk-backend,xenconsoled}.service.in \
+ --replace-fail "/bin/mkdir" "${coreutils}/bin/mkdir"
+ ''
+
+ # The following expression applies the patches defined on each
+ # prefetchedSources attribute.
+ + ''
+ ${withTools "patches" (
+ name: source: ''
+ ${lib.strings.concatMapStringsSep "\n" (patch: ''
+ echo "Patching with ${patch}"
+ patch --strip 1 < ${patch}
+ '') source.patches}
+ ''
+ )}
+
+ ${withTools "postPatch" (name: source: source.postPatch)}
+
+ ${pkg.xen.postPatch or ""}
+ '';
+
+ preBuild = lib.lists.optionals (lib.attrsets.hasAttrByPath [ "preBuild" ] pkg.xen) pkg.xen.preBuild;
postBuild = ''
- make -C docs man-pages
-
- ${withTools "buildPhase" (name: x: x.buildPhase)}
- '';
-
- installPhase = ''
- mkdir -p $out $out/share $out/share/man
- cp -prvd dist/install/nix/store/*/* $out/
- cp -prvd dist/install/boot $out/boot
- cp -prvd dist/install/etc $out
- cp -dR docs/man1 docs/man5 $out/share/man/
-
- ${withTools "installPhase" (name: x: x.installPhase)}
-
- # Hack
- substituteInPlace $out/etc/xen/scripts/hotplugpath.sh \
- --replace SBINDIR=\"$out/sbin\" SBINDIR=\"$out/bin\"
+ ${withTools "buildPhase" (name: source: source.buildPhase)}
- wrapPythonPrograms
- # We also need to wrap pygrub, which lies in lib
- wrapPythonProgramsIn "$out/lib" "$out $pythonPath"
-
- shopt -s extglob
- for i in $out/etc/xen/scripts/!(*.sh); do
- sed -i "2s@^@export PATH=$out/bin:${scriptEnvPath}\n@" $i
- done
+ ${pkg.xen.postBuild or ""}
'';
- enableParallelBuilding = true;
+ installPhase =
+ let
+ cpFlags = builtins.toString [
+ "--preserve=mode,ownership,timestamps,link"
+ "--recursive"
+ "--verbose"
+ "--no-dereference"
+ ];
+ in
+ # Run the preInstall tasks.
+ ''
+ runHook preInstall
+ ''
+
+ # Create $out directories and copy build output.
+ + ''
+ mkdir --parents $out $out/share $boot
+ cp ${cpFlags} dist/install/nix/store/*/* $out/
+ cp ${cpFlags} dist/install/etc $out
+ cp ${cpFlags} dist/install/boot $boot
+ ''
+
+ # Run the postInstall tasks.
+ + ''
+ runHook postInstall
+ '';
+
+ postInstall =
+ # Wrap xencov_split, xenmon and xentrace_format.
+ ''
+ wrapPythonPrograms
+ ''
+
+ # We also need to wrap pygrub, which lies in $out/libexec/xen/bin.
+ + ''
+ wrapPythonProgramsIn "$out/libexec/xen/bin" "$out $pythonPath"
+ ''
+
+ # Fix shebangs in Xen's various scripts.
+ #TODO: Remove any and all usage of `sed` and replace these complicated magic runes with readable code.
+ + ''
+ shopt -s extglob
+ for i in $out/etc/xen/scripts/!(*.sh); do
+ sed --in-place "2s@^@export PATH=$out/bin:${scriptEnvPath}\n@" $i
+ done
+ ''
+
+ + ''
+ ${withTools "installPhase" (name: source: source.installPhase)}
+
+ ${pkg.xen.installPhase or ""}
+ '';
+
+ postFixup =
+ # Fix binaries in $out/lib/xen/bin.
+ ''
+ addAutoPatchelfSearchPath $out/lib
+ autoPatchelf $out/libexec/xen/bin/
+ ''
+ # Flask is particularly hard to disable. Even after
+ # setting the make flags to `n`, it still gets compiled.
+ # If withFlask is disabled, delete the extra binaries.
+ + lib.strings.optionalString (!withFlask) ''
+ rm -f $out/bin/flask-*
+ '';
+
+ passthru = {
+ efi =
+ if withEFI then "boot/xen-${version}.efi" else throw "This Xen was compiled without an EFI binary.";
+ flaskPolicy =
+ if withFlask then
+ "boot/xenpolicy-${version}"
+ else
+ throw "This Xen was compiled without FLASK support.";
+ qemu-system-i386 =
+ if withInternalQEMU then
+ "libexec/xen/bin/qemu-system-i386"
+ else
+ throw "This Xen was compiled without a built-in QEMU.";
+ # This test suite is very simple, as Xen's userspace
+ # utilities require the hypervisor to be booted.
+ tests = {
+ pkg-config = testers.hasPkgConfigModules {
+ package = finalAttrs.finalPackage;
+ moduleNames = [
+ "xencall"
+ "xencontrol"
+ "xendevicemodel"
+ "xenevtchn"
+ "xenforeignmemory"
+ "xengnttab"
+ "xenguest"
+ "xenhypfs"
+ "xenlight"
+ "xenstat"
+ "xenstore"
+ "xentoolcore"
+ "xentoollog"
+ "xenvchan"
+ "xlutil"
+ ];
+ };
+ };
+ };
- # TODO(@oxij): Stop referencing args here
meta = {
- homepage = "http://www.xen.org/";
- description = "Xen hypervisor and related components"
- + optionalString (args ? meta && args.meta ? description)
- " (${args.meta.description})";
- longDescription = (args.meta.longDescription or "")
- + "\nIncludes:\n"
- + withXenfiles (name: x: "* ${name}: ${x.meta.description or "(No description)"}.");
- platforms = [ "x86_64-linux" ];
- maintainers = [ ];
- license = lib.licenses.gpl2;
- knownVulnerabilities = [
- # https://www.openwall.com/lists/oss-security/2023/03/21/1
- # Affects 3.2 (at *least*) - 4.17
- "CVE-2022-42332"
- # https://www.openwall.com/lists/oss-security/2023/03/21/2
- # Affects 4.11 - 4.17
- "CVE-2022-42333"
- "CVE-2022-42334"
- # https://www.openwall.com/lists/oss-security/2023/03/21/3
- # Affects 4.15 - 4.17
- "CVE-2022-42331"
- # https://xenbits.xen.org/docs/unstable/support-matrix.html
- ] ++ lib.optionals (lib.versionOlder version "4.15") [
- "This version of Xen has reached its end of life. See https://xenbits.xen.org/docs/unstable/support-matrix.html"
+ inherit branch;
+ # Short description for Xen.
+ description =
+ "Xen Hypervisor"
+ # The "and related components" addition is automatically hidden if said components aren't being built.
+ + lib.strings.optionalString (prefetchedSources != { }) " and related components"
+ # To alter the description inside the paranthesis, edit ./packages.nix.
+ + lib.strings.optionalString (lib.attrsets.hasAttrByPath [
+ "meta"
+ "description"
+ ] packageDefinition) " (${packageDefinition.meta.description})";
+ # Long description for Xen.
+ longDescription =
+ # Starts with the longDescription from ./packages.nix.
+ (packageDefinition.meta.longDescription or "")
+ +
+ lib.strings.optionalString (!withInternalQEMU)
+ "\nUse with `qemu_xen_${lib.stringAsChars (x: if x == "." then "_" else x) branch}`"
+ + lib.strings.optionalString latest "or `qemu_xen`"
+ + "."
+ # Then, if any of the optional with* components are being built, add the "Includes:" string.
+ +
+ lib.strings.optionalString
+ (
+ withInternalQEMU
+ || withInternalSeaBIOS
+ || withInternalOVMF
+ || withInternalIPXE
+ || withEFI
+ || withFlask
+ )
+ (
+ "\nIncludes:\n"
+ # Originally, this was a call for the complicated withPrefetchedSources. Since there aren't
+ # that many optional components, we just use lib.strings.optionalString, because it's simpler.
+ # Optional components that aren't being built are automatically hidden.
+ + lib.strings.optionalString withEFI "* `xen.efi`: Xen's [EFI binary](https://xenbits.xenproject.org/docs/${branch}-testing/misc/efi.html), available on the `boot` output of this package.\n"
+ + lib.strings.optionalString withFlask "* `xsm-flask`: The [FLASK Xen Security Module](https://wiki.xenproject.org/wiki/Xen_Security_Modules_:_XSM-FLASK). The `xenpolicy-${version}` file is available on the `boot` output of this package.\n"
+ + lib.strings.optionalString withInternalQEMU "* `qemu-xen`: Xen's mirror of [QEMU](https://www.qemu.org/).\n"
+ + lib.strings.optionalString withInternalSeaBIOS "* `seabios-xen`: Xen's mirror of [SeaBIOS](https://www.seabios.org/SeaBIOS).\n"
+ + lib.strings.optionalString withInternalOVMF "* `ovmf-xen`: Xen's mirror of [OVMF](https://github.com/tianocore/tianocore.github.io/wiki/OVMF).\n"
+ + lib.strings.optionalString withInternalIPXE "* `ipxe-xen`: Xen's pinned version of [iPXE](https://ipxe.org/).\n"
+ )
+ # Finally, we write a notice explaining which vulnerabilities this Xen is NOT vulnerable to.
+ # This will hopefully give users the peace of mind that their Xen is secure, without needing
+ # to search the source code for the XSA patches.
+ + lib.strings.optionalString (writeAdvisoryDescription != [ ]) (
+ "\nThis Xen (${version}) has been patched against the following known security vulnerabilities:\n"
+ + lib.strings.removeSuffix "\n" (lib.strings.concatLines writeAdvisoryDescription)
+ );
+ homepage = "https://xenproject.org/";
+ downloadPage = "https://downloads.xenproject.org/release/xen/${version}/";
+ changelog = "https://wiki.xenproject.org/wiki/Xen_Project_${branch}_Release_Notes";
+ license = with lib.licenses; [
+ # Documentation.
+ cc-by-40
+ # Most of Xen is licensed under the GPL v2.0.
+ gpl2Only
+ # Xen Libraries and the `xl` command-line utility.
+ lgpl21Only
+ # Development headers in $dev/include.
+ mit
+ ];
+ maintainers = [ lib.maintainers.sigmasquadron ];
+ mainProgram = "xl";
+ # Evaluates to x86_64-linux.
+ platforms = lib.lists.intersectLists lib.platforms.linux lib.platforms.x86_64;
+ knownVulnerabilities = lib.lists.optionals (lib.strings.versionOlder version "4.16") [
+ "Xen ${version} is no longer supported by the Xen Security Team. See https://xenbits.xenproject.org/docs/unstable/support-matrix.html"
];
- } // (config.meta or {});
-} // removeAttrs config [ "xenfiles" "buildInputs" "patches" "postPatch" "meta" ])
+ };
+})
diff --git a/pkgs/applications/virtualization/xen/packages.nix b/pkgs/applications/virtualization/xen/packages.nix
index c55a719995c0b..96bd42e052013 100644
--- a/pkgs/applications/virtualization/xen/packages.nix
+++ b/pkgs/applications/virtualization/xen/packages.nix
@@ -1,58 +1,68 @@
-{ callPackage
-
-}:
-
-# TODO(@oxij) on new Xen version: generalize this to generate [vanilla slim
-# light] for each ./.nix.
-
-rec {
- xen_4_15-vanilla = callPackage ./4.15.nix {
+{ callPackage }:
+let
+ standard = {
meta = {
- description = "vanilla";
+ description = "Standard Xen";
longDescription = ''
- Vanilla version of Xen. Uses forks of Qemu and Seabios bundled
- with Xen. This gives vanilla experince, but wastes space and
- build time: typical NixOS setup that runs lots of VMs will
- build three different versions of Qemu when using this (two
- forks and upstream).
+ Standard version of Xen. Uses forks of QEMU, SeaBIOS, OVMF and iPXE provided
+ by the Xen Project. This provides the vanilla Xen experince, but wastes space
+ and build time. A typical NixOS setup that runs lots of VMs will usually need
+ to build two different versions of QEMU when using this Xen derivation (one
+ fork and upstream).
'';
};
};
-
- xen_4_15-slim = xen_4_15-vanilla.override {
- withInternalQemu = false;
- withInternalTraditionalQemu = true;
- withInternalSeabios = false;
- withSeabios = true;
-
+ slim = {
meta = {
- description = "slim";
+ description = "Without Internal Components";
longDescription = ''
- Slimmed-down version of Xen that reuses nixpkgs packages as
- much as possible. Different parts may get out of sync, but
- this builds faster and uses less space than vanilla. Use with
- `qemu_xen` from nixpkgs.
+ Slimmed-down version of Xen that reuses nixpkgs packages as much as possible.
+ Instead of using the Xen forks for various internal components, this version uses
+ `seabios`, `ovmf` and `ipxe` from nixpkgs. These components may ocasionally get
+ out of sync with the hypervisor itself, but this builds faster and uses less space
+ than the default derivation.
'';
};
};
+in
+# TODO: generalise this to automatically generate both Xen variants for each .//default.nix.
+rec {
+ xen_4_19 = callPackage ./4.19/default.nix { inherit (standard) meta; };
+ xen_4_19-slim = xen_4_19.override {
+ withInternalQEMU = false;
+ withInternalSeaBIOS = false;
+ withInternalOVMF = false;
+ withInternalIPXE = false;
+ inherit (slim) meta;
+ };
- xen_4_15-light = xen_4_15-vanilla.override {
- withInternalQemu = false;
- withInternalTraditionalQemu = false;
- withInternalSeabios = false;
- withSeabios = true;
+ xen_4_18 = callPackage ./4.18/default.nix { inherit (standard) meta; };
+ xen_4_18-slim = xen_4_18.override {
+ withInternalQEMU = false;
+ withInternalSeaBIOS = false;
+ withInternalOVMF = false;
+ withInternalIPXE = false;
+ inherit (slim) meta;
+ };
- meta = {
- description = "light";
- longDescription = ''
- Slimmed-down version of Xen without `qemu-traditional` (you
- don't need it if you don't know what it is). Use with
- `qemu_xen-light` from nixpkgs.
- '';
- };
+ xen_4_17 = callPackage ./4.17/default.nix { inherit (standard) meta; };
+ xen_4_17-slim = xen_4_17.override {
+ withInternalQEMU = false;
+ withInternalSeaBIOS = false;
+ withInternalOVMF = false;
+ withInternalIPXE = false;
+ inherit (slim) meta;
+ };
+
+ xen_4_16 = callPackage ./4.16/default.nix { inherit (standard) meta; };
+ xen_4_16-slim = xen_4_16.override {
+ withInternalQEMU = false;
+ withInternalSeaBIOS = false;
+ withInternalOVMF = false;
+ withInternalIPXE = false;
+ inherit (slim) meta;
};
- xen-vanilla = xen_4_15-vanilla;
- xen-slim = xen_4_15-slim;
- xen-light = xen_4_15-light;
+ xen = xen_4_19;
+ xen-slim = xen_4_19-slim;
}
diff --git a/pkgs/applications/virtualization/xen/patches.nix b/pkgs/applications/virtualization/xen/patches.nix
new file mode 100644
index 0000000000000..050bb91a544c5
--- /dev/null
+++ b/pkgs/applications/virtualization/xen/patches.nix
@@ -0,0 +1,114 @@
+# Patching Xen? Check the XSAs at https://xenbits.xen.org/xsa/
+# and try applying all the ones we haven't gotten around to
+# yet, if any are necessary. Patches from other downstreams
+# are also welcome if they fix important issues with vanilla Xen.
+
+{ lib, fetchpatch }:
+
+let
+ xsaPatch =
+ {
+ id,
+ title,
+ description,
+ type ? "xsa",
+ hash ? "",
+ cve ? null,
+ }:
+ (fetchpatch {
+ name =
+ "XSA-" + id + lib.strings.optionalString (cve != null) ("-" + builtins.concatStringsSep "+" cve);
+ url = "https://xenbits.xen.org/xsa/xsa${id}.patch";
+ inherit hash;
+ passthru = {
+ xsa = id;
+ inherit type;
+ };
+ meta = {
+ description = title;
+ longDescription =
+ description
+ + "\n"
+ + (
+ if (cve == null) then
+ # Why the two spaces preceding these CVE messages?
+ # This is parsed by writeAdvisoryDescription in generic.nix,
+ # and doing this was easier than messing with lib.strings even more.
+ " _No CVE was assigned to this XSA._"
+ else
+ " Fixes:${
+ lib.strings.concatMapStrings (
+ x: "\n * [" + x + "](https://www.cve.org/CVERecord?id=" + x + ")"
+ ) cve
+ }"
+ );
+ homepage = "https://xenbits.xenproject.org/xsa/advisory-${id}.html";
+ };
+ });
+ qubesPatch =
+ {
+ name,
+ tag,
+ type ? "qubes",
+ hash ? "",
+ }:
+ (fetchpatch {
+ inherit name;
+ url = "https://raw.githubusercontent.com/QubesOS/qubes-vmm-xen/v${tag}/${name}.patch";
+ inherit hash;
+ passthru.type = type;
+ });
+in
+{
+ # Example patches:
+ #
+ # "XSA_100" = xsaPatch {
+ # id = "100";
+ # name = "Verbatim Title of XSA";
+ # cve = [ "CVE-1999-0001" "CVE-1999-0002" ]; # Not all XSAs have CVEs. This attribute is optional.
+ # hash = "sha256-0000000000000000000000000000000000000000000000000000";
+ # };
+ #
+ # "QUBES_libxl-fix-all-issues" = qubesPatch {
+ # name = "1000-libxl-fix-all-issues";
+ # tag = "4.20.0-1";
+ # hash = "sha256-0000000000000000000000000000000000000000000000000000";
+ # };
+
+ # Build reproducibility patches for Xen.
+ # Qubes OS has not updated them to later versions of Xen yet,
+ # but they appear to work on Xen 4.17.4 - 4.19.0.
+ QUBES_REPRODUCIBLE_BUILDS = [
+ (qubesPatch {
+ name = "1100-Define-build-dates-time-based-on-SOURCE_DATE_EPOCH";
+ tag = "4.17.4-5";
+ hash = "sha256-OwKA9oPTwhRcSmiOb+PxzifbO/IG8IHWlvddFh/nP6s=";
+ })
+ (qubesPatch {
+ name = "1101-docs-rename-DATE-to-PANDOC_REL_DATE-and-allow-to-spe";
+ tag = "4.17.4-5";
+ hash = "sha256-BUtYt0mM3bURVaGv4oDznzxx1Wo4sfOpGV5GB8qc5Ns=";
+ })
+ (qubesPatch {
+ name = "1102-docs-xen-headers-use-alphabetical-sorting-for-incont";
+ tag = "4.17.4-5";
+ hash = "sha256-mQUp2w9lUb7KDq5MuPQjs6y7iuMDeXoZjDjlXfa5z44=";
+ })
+ ];
+
+ # Xen Security Advisory #458: (4.16 - 4.19-rc3)
+ "XSA_458" = xsaPatch {
+ id = "458";
+ title = "Double unlock in x86 guest IRQ handling";
+ description = ''
+ An optional feature of PCI MSI called "Multiple Message" allows a device
+ to use multiple consecutive interrupt vectors. Unlike for MSI-X, the
+ setting up of these consecutive vectors needs to happen all in one go.
+ In this handling an error path could be taken in different situations,
+ with or without a particular lock held. This error path wrongly releases
+ the lock even when it is not currently held.
+ '';
+ cve = [ "CVE-2024-31143" ];
+ hash = "sha256-yHI9Sp/7Ed40iIYQ/HOOIULlfzAzL0c0MGqdF+GR+AQ=";
+ };
+}
diff --git a/pkgs/applications/virtualization/xen/update.sh b/pkgs/applications/virtualization/xen/update.sh
new file mode 100755
index 0000000000000..0b0c7516fa835
--- /dev/null
+++ b/pkgs/applications/virtualization/xen/update.sh
@@ -0,0 +1,194 @@
+#!/usr/bin/env nix-shell
+#!nix-shell -i bash -p gitMinimal curl gnupg nix-prefetch-git nixfmt-rfc-style
+# shellcheck disable=SC2206,SC2207 shell=bash
+set -e
+
+# Set a temporary $HOME in /tmp for GPG.
+HOME=/tmp/xenUpdateScript
+
+# This script expects to be called in an interactive terminal somewhere inside Nixpkgs.
+echo "Preparing..."
+nixpkgs=$(git rev-parse --show-toplevel)
+xenPath="$nixpkgs/pkgs/applications/virtualization/xen"
+rm -rf /tmp/xenUpdateScript
+mkdir /tmp/xenUpdateScript
+
+# Import and verify PGP key.
+curl --silent --output /tmp/xenUpdateScript/xen.asc https://keys.openpgp.org/vks/v1/by-fingerprint/23E3222C145F4475FA8060A783FE14C957E82BD9
+gpg --quiet --import /tmp/xenUpdateScript/xen.asc
+fingerprint="$(gpg --with-colons --fingerprint "pgp@xen.org" 2>/dev/null | awk -F: '/^pub:.*/ { getline; print $10}')"
+echo -e "Please ascertain through multiple external sources that the \e[1;32mXen Project PGP Key Fingerprint\e[0m is indeed \e[1;33m$fingerprint\e[0m. If that is not the case, \e[1;31mexit immediately\e[0m."
+read -r -p $'Press \e[1;34menter\e[0m to continue with a pre-filled expected fingerprint, or input an arbitrary PGP fingerprint to match with the key\'s fingerprint: ' userInputFingerprint
+userInputFingerprint=${userInputFingerprint:-"23E3222C145F4475FA8060A783FE14C957E82BD9"}
+
+# Clone xen.git.
+echo -e "Cloning \e[1;34mxen.git\e[0m..."
+git clone --quiet https://xenbits.xen.org/git-http/xen.git /tmp/xenUpdateScript/xen
+cd /tmp/xenUpdateScript/xen
+
+# Get list of versions and branches.
+versionList="$(git tag --list "RELEASE-*" | sed s/RELEASE-//g | sed s/4.1.6.1//g | sort --numeric-sort)"
+latestVersion=$(echo "$versionList" | tr ' ' '\n' | tail --lines=1)
+branchList=($(echo "$versionList" | tr ' ' '\n' | sed s/\.[0-9]*$//g | awk '!seen[$0]++'))
+
+# Figure out which versions we're actually going to install.
+minSupportedBranch="$(grep " knownVulnerabilities = lib.lists.optionals (lib.strings.versionOlder version " "$xenPath"/generic.nix | sed s/' knownVulnerabilities = lib.lists.optionals (lib.strings.versionOlder version "'//g | sed s/'") \['//g)"
+supportedBranches=($(for version in "${branchList[@]}"; do if [ "$(printf '%s\n' "$minSupportedBranch" "$version" | sort -V | head -n1)" = "$minSupportedBranch" ]; then echo "$version"; fi; done))
+supportedVersions=($(for version in "${supportedBranches[@]}"; do echo "$versionList" | tr ' ' '\n' | grep "$version" | tail --lines=1; done))
+
+# Main loop that installs every supportedVersion.
+for version in "${supportedVersions[@]}"; do
+ echo -e "\n------------------------------------------------"
+ branch=${version/%.[0-9]/}
+ if [[ "$version" == "$latestVersion" ]]; then
+ latest=true
+ echo -e "\nFound \e[1;34mlatest\e[0m release: \e[1;32mXen $version\e[0m in branch \e[1;36m$branch\e[0m."
+ else
+ latest=false
+ echo -e "\nFound \e[1;33msecurity-supported\e[0m release: \e[1;32mXen $version\e[0m in branch \e[1;36m$branch\e[0m."
+ fi
+
+ # Verify PGP key automatically. If the fingerprint matches what the user specified, or the default fingerprint, then we consider it trusted.
+ cd /tmp/xenUpdateScript/xen
+ if [[ "$fingerprint" = "$userInputFingerprint" ]]; then
+ echo "$fingerprint:6:" | gpg --quiet --import-ownertrust
+ (git verify-tag RELEASE-"$version" 2>/dev/null && echo -e "\n\e[1;32mSuccessfully authenticated Xen $version.\e[0m") || (echo -e "\e[1;31merror:\e[0m Unable to verify tag \e[1;32mRELEASE-$version\e[0m.\n- It is possible that \e[1;33mthis script has broken\e[0m, the Xen Project has \e[1;33mcycled their PGP keys\e[0m, or a \e[1;31msupply chain attack is in progress\e[0m.\n\n\e[1;31mPlease update manually.\e[0m" && exit 1)
+ else
+ echo -e "\e[1;31merror:\e[0m Unable to verify \e[1;34mpgp@xen.org\e[0m's fingerprint.\n- It is possible that \e[1;33mthis script has broken\e[0m, the Xen Project has \e[1;33mcycled their PGP keys\e[0m, or an \e[1;31mimpersonation attack is in progress\e[0m.\n\n\e[1;31mPlease update manually.\e[0m" && exit 1
+ fi
+
+ git switch --quiet --detach RELEASE-"$version"
+
+ # Originally we told people to go check the Makefile themselves.
+ echo -e "\nDetermining source versions from Xen Makefiles..."
+ qemuVersion="$(grep -ie "QEMU_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"QEMU_UPSTREAM_REVISION ?= "//g)"
+ seaBIOSVersion="$(grep -ie "SEABIOS_UPSTREAM_REVISION ?= rel-" /tmp/xenUpdateScript/xen/Config.mk | sed s/"SEABIOS_UPSTREAM_REVISION ?= "//g)"
+ ovmfVersion="$(grep -ie "OVMF_UPSTREAM_REVISION ?=" /tmp/xenUpdateScript/xen/Config.mk | sed s/"OVMF_UPSTREAM_REVISION ?= "//g)"
+ ipxeVersion="$(grep -ie "IPXE_GIT_TAG :=" /tmp/xenUpdateScript/xen/tools/firmware/etherboot/Makefile | sed s/"IPXE_GIT_TAG := "//g)"
+
+ # Use `nix-prefetch-git` to fetch `rev`s and `hash`es.
+ echo "Pre-fetching sources and determining hashes..."
+ echo -e -n " \e[1;32mXen\e[0m..."
+ fetchXen=$(nix-prefetch-git --url https://xenbits.xen.org/git-http/xen.git --rev RELEASE-"$version" --quiet)
+ finalVersion="$(echo "$fetchXen" | tr ', ' '\n ' | grep -ie rev | sed s/' "rev": "'//g | sed s/'"'//g)"
+ hash="$(echo "$fetchXen" | tr ', ' '\n ' | grep -ie hash | sed s/' "hash": "'//g | sed s/'"'//g)"
+ echo "done!"
+ echo -e -n " \e[1;36mQEMU\e[0m..."
+ fetchQEMU=$(nix-prefetch-git --url https://xenbits.xen.org/git-http/qemu-xen.git --rev "$qemuVersion" --quiet --fetch-submodules)
+ finalQEMUVersion="$(echo "$fetchQEMU" | tr ', ' '\n ' | grep -ie rev | sed s/' "rev": "'//g | sed s/'"'//g)"
+ qemuHash="$(echo "$fetchQEMU" | tr ', ' '\n ' | grep -ie hash | sed s/' "hash": "'//g | sed s/'"'//g)"
+ echo "done!"
+ echo -e -n " \e[1;36mSeaBIOS\e[0m..."
+ fetchSeaBIOS=$(nix-prefetch-git --url https://xenbits.xen.org/git-http/seabios.git --rev "$seaBIOSVersion" --quiet)
+ finalSeaBIOSVersion="$(echo "$fetchSeaBIOS" | tr ', ' '\n ' | grep -ie rev | sed s/' "rev": "'//g | sed s/'"'//g)"
+ seaBIOSHash="$(echo "$fetchSeaBIOS" | tr ', ' '\n ' | grep -ie hash | sed s/' "hash": "'//g | sed s/'"'//g)"
+ echo "done!"
+ echo -e -n " \e[1;36mOVMF\e[0m..."
+ ovmfHash="$(nix-prefetch-git --url https://xenbits.xen.org/git-http/ovmf.git --rev "$ovmfVersion" --quiet --fetch-submodules | grep -ie hash | sed s/' "hash": "'//g | sed s/'",'//g)"
+ echo "done!"
+ echo -e -n " \e[1;36miPXE\e[0m..."
+ ipxeHash="$(nix-prefetch-git --url https://github.com/ipxe/ipxe.git --rev "$ipxeVersion" --quiet | grep -ie hash | sed s/' "hash": "'//g | sed s/'",'//g)"
+ echo "done!"
+
+ cd "$xenPath"
+
+ echo -e "\nFound the following revisions:\n \e[1;32mXen\e[0m: \e[1;33m$finalVersion\e[0m (\e[1;33m$hash\e[0m)\n \e[1;36mQEMU\e[0m: \e[1;33m$finalQEMUVersion\e[0m (\e[1;33m$qemuHash\e[0m)\n \e[1;36mSeaBIOS\e[0m: \e[1;33m$finalSeaBIOSVersion\e[0m (\e[1;33m$seaBIOSHash\e[0m)\n \e[1;36mOVMF\e[0m: \e[1;33m$ovmfVersion\e[0m (\e[1;33m$ovmfHash\e[0m)\n \e[1;36miPXE\e[0m: \e[1;33m$ipxeVersion\e[0m (\e[1;33m$ipxeHash\e[0m)"
+
+ # Set OCaml Version
+ read -r -p $'\nEnter the corresponding \e[1;33mOCaml\e[0m version for \e[1;32mXen '"$version"$'\e[0m, or press \e[1;34menter\e[0m for the default value of \e[1;32m4_14\e[0m: ' ocamlVersion
+ ocamlVersion=${ocamlVersion:-"4_14"}
+
+ mkdir -p "$branch"/
+ rm -f "$branch"/default.nix
+
+ # Prepare any .patch files that are called by Nix through a path value.
+ echo -e "\nPlease add any required patches to version \e[1;32m$branch\e[0m in \e[1;34m$branch/\e[0m, and press \e[1;34menter\e[0m when done."
+ read -r -p $'Remember to follow the naming specification as defined in \e[1;34m./README.md\e[0m.'
+
+ echo -e "\nDiscovering patches..."
+ discoveredXenPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-xen-*-$branch.patch" -printf "./%f ")"
+ discoveredQEMUPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-qemu-*-$branch.patch" -printf "./%f ")"
+ discoveredSeaBIOSPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-seabios-*-$branch.patch" -printf "./%f ")"
+ discoveredOVMFPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-ovmf-*-$branch.patch" -printf "./%f ")"
+ discoveredIPXEPatches="$(find "$branch"/ -type f -name "[0-9][0-9][0-9][0-9]-ipxe-*-$branch.patch" -printf "./%f ")"
+
+ discoveredXenPatchesEcho=${discoveredXenPatches:-"\e[1;31mNone found!\e[0m"}
+ discoveredQEMUPatchesEcho=${discoveredQEMUPatches:-"\e[1;31mNone found!\e[0m"}
+ discoveredSeaBIOSPatchesEcho=${discoveredSeaBIOSPatches:-"\e[1;31mNone found!\e[0m"}
+ discoveredOVMFPatchesEcho=${discoveredOVMFPatches:-"\e[1;31mNone found!\e[0m"}
+ discoveredIPXEPatchesEcho=${discoveredIPXEPatches:-"\e[1;31mNone found!\e[0m"}
+
+ echo -e "Found the following patches:\n \e[1;32mXen\e[0m: \e[1;33m$discoveredXenPatchesEcho\e[0m\n \e[1;36mQEMU\e[0m: \e[1;33m$discoveredQEMUPatchesEcho\e[0m\n \e[1;36mSeaBIOS\e[0m: \e[1;33m$discoveredSeaBIOSPatchesEcho\e[0m\n \e[1;36mOVMF\e[0m: \e[1;33m$discoveredOVMFPatchesEcho\e[0m\n \e[1;36miPXE\e[0m: \e[1;33m$discoveredIPXEPatchesEcho\e[0m"
+
+ # Prepare patches that are called in ./patches.nix.
+ defaultPatchListInit=("QUBES_REPRODUCIBLE_BUILDS" "XSA_458")
+ read -r -a defaultPatchList -p $'\nWould you like to override the \e[1;34mupstreamPatches\e[0m list for \e[1;32mXen '"$version"$'\e[0m? If no, press \e[1;34menter\e[0m to use the default patch list: [ \e[1;34m'"${defaultPatchListInit[*]}"$' \e[0m]: '
+ defaultPatchList=(${defaultPatchList[@]:-${defaultPatchListInit[@]}})
+ spaceSeparatedPatchList=${defaultPatchList[*]}
+ upstreamPatches="upstreamPatches.${spaceSeparatedPatchList// / upstreamPatches.}"
+
+ # Write and format default.nix file.
+ echo -e "\nWriting updated \e[1;34mversionDefinition\e[0m..."
+ cat >"$branch"/default.nix <