Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nix: build static QEMU #702

Merged
merged 1 commit into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
140 changes: 140 additions & 0 deletions packages/by-name/qemu-static/0001-avoid-duplicate-definitions.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
From 96b8af73b050482c83a3d3f7056e381724581884 Mon Sep 17 00:00:00 2001
From: Tom Dohrmann <[email protected]>
Date: Wed, 10 Jul 2024 13:30:51 +0200
Subject: [PATCH 1/2] avoid duplicate definitions

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
---
block/vhdx.c | 4 ++--
hw/net/net_rx_pkt.c | 2 +-
include/qemu/crc32c.h | 2 +-
target/arm/helper.c | 2 +-
target/arm/tcg/helper-a64.c | 4 ++--
target/loongarch/tcg/op_helper.c | 2 +-
util/crc32c.c | 4 ++--
7 files changed, 10 insertions(+), 10 deletions(-)

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;
--
2.45.1

39 changes: 39 additions & 0 deletions packages/by-name/qemu-static/0001-fix-static-build.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
From 810a25b750a9852cb916e596cb94a40191c57e04 Mon Sep 17 00:00:00 2001
From: Tom Dohrmann <[email protected]>
Date: Wed, 10 Jul 2024 13:26:36 +0200
Subject: [PATCH] fix static build

---
libfdt/meson.build | 2 +-
tests/run_tests.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libfdt/meson.build b/libfdt/meson.build
index 240bdf4..91b05f3 100644
--- a/libfdt/meson.build
+++ b/libfdt/meson.build
@@ -53,7 +53,7 @@ install_headers(
pkgconfig = import('pkgconfig')

pkgconfig.generate(
- libraries: libfdt,
+ libraries: link_with,
version: meson.project_version(),
filebase: 'libfdt',
name: 'libfdt',
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 91350ad..a398e03 100755
--- a/tests/run_tests.sh
+++ b/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
+ :
}

asm_to_so_test () {
--
2.45.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
From c72d6884359e14fddb5da54d9bf57939985ba323 Mon Sep 17 00:00:00 2001
From: Tom Dohrmann <[email protected]>
Date: Wed, 10 Jul 2024 13:31:34 +0200
Subject: [PATCH 2/2] add options for library paths

For some reason meson fails to find these when building with pkgsStatic
in Nix.
---
meson.build | 6 ++++--
meson_options.txt | 2 ++
2 files changed, 6 insertions(+), 2 deletions(-)

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')
--
2.45.1

80 changes: 80 additions & 0 deletions packages/by-name/qemu-static/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright 2024 Edgeless Systems GmbH
# SPDX-License-Identifier: AGPL-3.0-only

{
qemu,
libaio,
dtc,
}:
let
patchedDtc = dtc.overrideAttrs (previousAttrs: {
patches = previousAttrs.patches ++ [
# Based on https://github.com/NixOS/nixpkgs/pull/309929/commits/13efe012c484484d48661ce3ad1862a718d1991c.
# We dropped the change to the output library name from "fdt-so" to "fdt"
# because it's not entirely clear what this change intended and because
# this actually breaks the QEMU build.
./0001-fix-static-build.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 ++ [
./0001-avoid-duplicate-definitions.patch
# Based on https://github.com/NixOS/nixpkgs/pull/300070/commits/96054ca98020df125bb91e5cf49bec107bea051b#diff-7246126ac058898e6da6aadc1e831bb26afe07fa145958e55c5e112dc2c578fd.
# We applied the same change done to libaio to libfdt as well.
./0002-add-options-for-library-paths.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