Skip to content

Commit

Permalink
nix: build static QEMU
Browse files Browse the repository at this point in the history
This is based on nixpkgs PRs #30070, #309929, and #314998.
  • Loading branch information
Freax13 committed Jul 10, 2024
1 parent 392696f commit 52e07ff
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 21 deletions.
23 changes: 2 additions & 21 deletions packages/by-name/kata/runtime-class-files/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,16 @@
{
stdenvNoCC,
kata,
fetchzip,
OVMF,
debugRuntime ? false,
qemu-static,
}:

let
image = kata.kata-image;
kernel = "${kata.kata-kernel-uvm}/bzImage";

# TODO(msanft): building a static qemu with nix.
qemu-bin =
let
qemuDrv = stdenvNoCC.mkDerivation rec {
pname = "qemu-static-kata";
version = "3.6.0";

src = fetchzip {
url = "https://github.com/kata-containers/kata-containers/releases/download/${version}/kata-static-${version}-amd64.tar.xz";
hash = "sha256-ynMzMoJ90BzKuE6ih6DmbM2zWTDxsMwkAKsI8pbO3sg=";
};

dontBuild = true;

installPhase = ''
install -Dt $out/bin kata/bin/qemu-system-x86_64
'';
};
in
"${qemuDrv}/bin/qemu-system-x86_64";
qemu-bin = "${qemu-static}/bin/qemu-system-x86_64";

ovmf = "${OVMF.fd}/FV/OVMF.fd";

Expand Down
44 changes: 44 additions & 0 deletions packages/by-name/qemu-static/aio-fdt-find-static-library.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
diff --git a/meson.build b/meson.build
index 91a0aa64c6..dd72a76c86 100644
--- a/meson.build
+++ b/meson.build
@@ -990,7 +990,8 @@ zlib = dependency('zlib', required: true)
libaio = not_found
if not get_option('linux_aio').auto() or have_block
libaio = cc.find_library('aio', has_headers: ['libaio.h'],
- required: get_option('linux_aio'))
+ required: get_option('linux_aio'),
+ dirs: [get_option('linux_aio_path')])
endif

linux_io_uring_test = '''
@@ -3171,7 +3172,8 @@ if fdt_required.length() > 0 or fdt_opt == 'enabled'
if get_option('wrap_mode') == 'nodownload'
fdt_opt = 'system'
endif
- fdt = cc.find_library('fdt', required: fdt_opt == 'system')
+ fdt = cc.find_library('fdt', required: fdt_opt == 'system',
+ dirs: [get_option('linux_fdt_path')])
if fdt.found() and cc.links('''
#include <libfdt.h>
#include <libfdt_env.h>
diff --git a/meson_options.txt b/meson_options.txt
index 0a99a059ec..ad5067e84d 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -186,6 +186,7 @@ option('libusb', type : 'feature', value : 'auto',
description: 'libusb support for USB passthrough')
option('linux_aio', type : 'feature', value : 'auto',
description: 'Linux AIO support')
+option('linux_aio_path', type: 'string', value: '', description: 'Path for libaio.a')
option('linux_io_uring', type : 'feature', value : 'auto',
description: 'Linux io_uring support')
option('lzfse', type : 'feature', value : 'auto',
@@ -311,6 +312,7 @@ option('capstone', type: 'feature', value: 'auto',
option('fdt', type: 'combo', value: 'auto',
choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],
description: 'Whether and how to find the libfdt library')
+option('linux_fdt_path', type: 'string', value: '', description: 'Path for libfdt.a')

option('selinux', type: 'feature', value: 'auto',
description: 'SELinux support in qemu-nbd')
123 changes: 123 additions & 0 deletions packages/by-name/qemu-static/crc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
Another library already defines crc32c and this causes linker errors. Rename the function in QEMU to avoid conflicts.
> /nix/store/q7cd30gzrkq720riqfm1myrvygv9v516-x86_64-unknown-linux-musl-binutils-2.42/bin/x86_64-unknown-linux-musl-ld: /nix/store/bnkaijycj1svgfkglzzwbzr76my1b0xz-util-linux-minimal-static-x86_64-unknown-linux-musl-2.39.4-lib/lib/libblkid.a(libcommon_la-crc32c.o): in function `crc32c':
> (.text+0x0): multiple definition of `crc32c'; libqemuutil.a.p/util_crc32c.c.o:/build/qemu-9.0.1/build/../util/crc32c.c:109: first defined here

diff --git a/block/vhdx.c b/block/vhdx.c
index 5aa1a13506..52723d7cc0 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -157,7 +157,7 @@ uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset)
assert(size > (crc_offset + sizeof(crc)));

memset(buf + crc_offset, 0, sizeof(crc));
- crc = crc32c(0xffffffff, buf, size);
+ crc = __crc32c(0xffffffff, buf, size);
crc = cpu_to_le32(crc);
memcpy(buf + crc_offset, &crc, sizeof(crc));

@@ -176,7 +176,7 @@ uint32_t vhdx_checksum_calc(uint32_t crc, uint8_t *buf, size_t size,
memset(buf + crc_offset, 0, sizeof(crc_orig));
}

- crc_new = crc32c(crc, buf, size);
+ crc_new = __crc32c(crc, buf, size);
if (crc_offset > 0) {
memcpy(buf + crc_offset, &crc_orig, sizeof(crc_orig));
}
diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c
index 32e5f3f9cf..1cffe29d80 100644
--- a/hw/net/net_rx_pkt.c
+++ b/hw/net/net_rx_pkt.c
@@ -579,7 +579,7 @@ _net_rx_pkt_validate_sctp_sum(struct NetRxPkt *pkt)
return false;
}

- calculated = crc32c(0xffffffff,
+ calculated = __crc32c(0xffffffff,
(uint8_t *)vec->iov_base + off, vec->iov_len - off);
calculated = iov_crc32c(calculated ^ 0xffffffff, vec + 1, vec_len - 1);
valid = calculated == le32_to_cpu(original);
diff --git a/include/qemu/crc32c.h b/include/qemu/crc32c.h
index 88b4d2b3b3..52ba066c2e 100644
--- a/include/qemu/crc32c.h
+++ b/include/qemu/crc32c.h
@@ -29,7 +29,7 @@
#define QEMU_CRC32C_H


-uint32_t crc32c(uint32_t crc, const uint8_t *data, unsigned int length);
+uint32_t __crc32c(uint32_t crc, const uint8_t *data, unsigned int length);
uint32_t iov_crc32c(uint32_t crc, const struct iovec *iov, size_t iov_cnt);

#endif
diff --git a/target/arm/helper.c b/target/arm/helper.c
index a620481d7c..17b45161e2 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12316,7 +12316,7 @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
stl_le_p(buf, val);

/* Linux crc32c converts the output to one's complement. */
- return crc32c(acc, buf, bytes) ^ 0xffffffff;
+ return __crc32c(acc, buf, bytes) ^ 0xffffffff;
}

/*
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
index ebaa7f00df..e818f34079 100644
--- a/target/arm/tcg/helper-a64.c
+++ b/target/arm/tcg/helper-a64.c
@@ -478,7 +478,7 @@ float32 HELPER(fcvtx_f64_to_f32)(float64 a, CPUARMState *env)
}

/* 64-bit versions of the CRC helpers. Note that although the operation
- * (and the prototypes of crc32c() and crc32() mean that only the bottom
+ * (and the prototypes of __crc32c() and crc32() mean that only the bottom
* 32 bits of the accumulator and result are used, we pass and return
* uint64_t for convenience of the generated code. Unlike the 32-bit
* instruction set versions, val may genuinely have 64 bits of data in it.
@@ -502,7 +502,7 @@ uint64_t HELPER(crc32c_64)(uint64_t acc, uint64_t val, uint32_t bytes)
stq_le_p(buf, val);

/* Linux crc32c converts the output to one's complement. */
- return crc32c(acc, buf, bytes) ^ 0xffffffff;
+ return __crc32c(acc, buf, bytes) ^ 0xffffffff;
}

/*
diff --git a/target/loongarch/tcg/op_helper.c b/target/loongarch/tcg/op_helper.c
index fe79c62fa4..41133336c0 100644
--- a/target/loongarch/tcg/op_helper.c
+++ b/target/loongarch/tcg/op_helper.c
@@ -77,7 +77,7 @@ target_ulong helper_crc32c(target_ulong val, target_ulong m, uint64_t sz)
target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1);
m &= mask;
stq_le_p(buf, m);
- return (int32_t) (crc32c(val, buf, sz) ^ 0xffffffff);
+ return (int32_t) (__crc32c(val, buf, sz) ^ 0xffffffff);
}

target_ulong helper_cpucfg(CPULoongArchState *env, target_ulong rj)
diff --git a/util/crc32c.c b/util/crc32c.c
index ea7f345de8..d6b5fab137 100644
--- a/util/crc32c.c
+++ b/util/crc32c.c
@@ -105,7 +105,7 @@ static const uint32_t crc32c_table[256] = {
};


-uint32_t crc32c(uint32_t crc, const uint8_t *data, unsigned int length)
+uint32_t __crc32c(uint32_t crc, const uint8_t *data, unsigned int length)
{
while (length--) {
crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
@@ -116,7 +116,7 @@ uint32_t crc32c(uint32_t crc, const uint8_t *data, unsigned int length)
uint32_t iov_crc32c(uint32_t crc, const struct iovec *iov, size_t iov_cnt)
{
while (iov_cnt--) {
- crc = crc32c(crc, iov->iov_base, iov->iov_len) ^ 0xffffffff;
+ crc = __crc32c(crc, iov->iov_base, iov->iov_len) ^ 0xffffffff;
iov++;
}
return crc ^ 0xffffffff;

21 changes: 21 additions & 0 deletions packages/by-name/qemu-static/fixstatic.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff -ur dtc-before/libfdt/meson.build dtc-after/libfdt/meson.build
--- dtc-before/libfdt/meson.build 2024-05-07 15:58:14.070792700 -0300
+++ dtc-after/libfdt/meson.build 2024-05-07 15:58:46.543032425 -0300
@@ -63,7 +63,7 @@
pkgconfig = import('pkgconfig')

pkgconfig.generate(
- libraries: libfdt,
+ libraries: link_with,
version: meson.project_version(),
filebase: 'libfdt',
name: 'libfdt',
--- dtc-before/tests/run_tests.sh
+++ dtc-after/tests/run_tests.sh
@@ -185,7 +185,7 @@ run_dtc_test () {
}

asm_to_so () {
- $CC -shared -o $1.test.so "$SRCDIR/data.S" $1.test.s
+ :
}
72 changes: 72 additions & 0 deletions packages/by-name/qemu-static/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2024 Edgeless Systems GmbH
# SPDX-License-Identifier: AGPL-3.0-only

{
qemu,
libaio,
dtc,
}:
let
patchedDtc = dtc.overrideAttrs (previousAttrs: {
patches = previousAttrs.patches ++ [ ./fixstatic.patch ];
});
in
(qemu.override (_previous: {
dtc = patchedDtc;

# Disable a bunch of features we don't need.
guestAgentSupport = false;
numaSupport = false;
seccompSupport = false;
alsaSupport = false;
pulseSupport = false;
pipewireSupport = false;
sdlSupport = false;
jackSupport = false;
gtkSupport = false;
vncSupport = false;
smartcardSupport = false;
spiceSupport = false;
ncursesSupport = false;
usbredirSupport = false;
xenSupport = false;
cephSupport = false;
glusterfsSupport = false;
openGLSupport = false;
rutabagaSupport = false;
virglSupport = false;
libiscsiSupport = false;
smbdSupport = false;
tpmSupport = false;
uringSupport = false;
canokeySupport = false;
capstoneSupport = false;
enableDocs = false;

# Only build for x86_64.
hostCpuOnly = true;
hostCpuTargets = [ "x86_64-softmmu" ];
})).overrideAttrs
(previousAttrs: {
propagatedBuildInputs = builtins.filter (
input: input.pname != "texinfo"
) previousAttrs.propagatedBuildInputs;
configureFlags =
(
# By the time overrideAttrs gets to see the attributes, it's too late
# for dontAddStaticConfigureFlags, so we need to manually filter out
# the flags.
builtins.filter (
flag: flag != "--enable-static" && flag != "--disable-shared"
) previousAttrs.configureFlags
)
++ [
"--static"
"-Dlinux_aio_path=${libaio}/lib"
"-Dlinux_fdt_path=${patchedDtc}/lib"
];
patches = previousAttrs.patches ++ [
./crc.patch
./aio-fdt-find-static-library.patch
];
})
1 change: 1 addition & 0 deletions packages/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ let
};
kata-runtime = pkgs.pkgsStatic.callPackage ./by-name/kata/kata-runtime/package.nix { };
};
qemu-static = pkgs.pkgsStatic.callPackage ./by-name/qemu-static/package.nix { };
};
in
self

0 comments on commit 52e07ff

Please sign in to comment.