summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure19
-rw-r--r--docs/meson.build14
-rw-r--r--docs/system/i386/kvm-pv.rst100
-rw-r--r--docs/system/target-i386.rst1
-rw-r--r--hw/i386/x86.c25
-rw-r--r--hw/misc/applesmc.c192
m---------meson0
-rw-r--r--meson.build168
-rw-r--r--migration/block-dirty-bitmap.c5
-rw-r--r--migration/migration.c3
-rw-r--r--plugins/meson.build4
-rw-r--r--scripts/mtest2make.py7
-rw-r--r--target/hexagon/meson.build3
-rw-r--r--target/i386/sev-stub.c5
-rw-r--r--target/i386/sev.c137
-rw-r--r--target/i386/sev_i386.h12
-rw-r--r--target/xtensa/cores.list9
-rwxr-xr-xtarget/xtensa/import_core.sh3
-rw-r--r--target/xtensa/meson.build4
-rw-r--r--tests/qapi-schema/meson.build4
-rw-r--r--tests/qtest/meson.build2
-rw-r--r--tests/unit/meson.build2
-rw-r--r--trace/meson.build4
23 files changed, 597 insertions, 126 deletions
diff --git a/configure b/configure
index b0b1a1cc25..877bf3d76a 100755
--- a/configure
+++ b/configure
@@ -142,11 +142,11 @@ lines: ${BASH_LINENO[*]}"
}
do_cc() {
- do_compiler "$cc" "$@"
+ do_compiler "$cc" $CPU_CFLAGS "$@"
}
do_cxx() {
- do_compiler "$cxx" "$@"
+ do_compiler "$cxx" $CPU_CFLAGS "$@"
}
# Append $2 to the variable named $1, with space separation
@@ -1688,7 +1688,6 @@ esac
eval "cross_cc_${cpu}=\$cc"
cross_cc_vars="$cross_cc_vars cross_cc_${cpu}"
-QEMU_CFLAGS="$CPU_CFLAGS $QEMU_CFLAGS"
# For user-mode emulation the host arch has to be one we explicitly
# support, even if we're using TCI.
@@ -1995,7 +1994,7 @@ python_version=$($python -c 'import sys; print("%d.%d.%d" % (sys.version_info[0]
python="$python -B"
if test -z "$meson"; then
- if test "$explicit_python" = no && has meson && version_ge "$(meson --version)" 0.55.3; then
+ if test "$explicit_python" = no && has meson && version_ge "$(meson --version)" 0.59.2; then
meson=meson
elif test $git_submodules_action != 'ignore' ; then
meson=git
@@ -5114,9 +5113,9 @@ if test "$skip_meson" = no; then
echo "c_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
echo "[binaries]" >> $cross
- echo "c = [$(meson_quote $cc)]" >> $cross
- test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross
- test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross
+ echo "c = [$(meson_quote $cc $CPU_CFLAGS)]" >> $cross
+ test -n "$cxx" && echo "cpp = [$(meson_quote $cxx $CPU_CFLAGS)]" >> $cross
+ test -n "$objcc" && echo "objc = [$(meson_quote $objcc $CPU_CFLAGS)]" >> $cross
echo "ar = [$(meson_quote $ar)]" >> $cross
echo "nm = [$(meson_quote $nm)]" >> $cross
echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
@@ -5164,10 +5163,6 @@ if test "$skip_meson" = no; then
mv $cross config-meson.cross
rm -rf meson-private meson-info meson-logs
- unset staticpic
- if ! version_ge "$($meson --version)" 0.56.0; then
- staticpic=$(if test "$pie" = yes; then echo true; else echo false; fi)
- fi
NINJA=$ninja $meson setup \
--prefix "$prefix" \
--libdir "$libdir" \
@@ -5187,7 +5182,6 @@ if test "$skip_meson" = no; then
-Dwerror=$(if test "$werror" = yes; then echo true; else echo false; fi) \
-Dstrip=$(if test "$strip_opt" = yes; then echo true; else echo false; fi) \
-Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \
- ${staticpic:+-Db_staticpic=$staticpic} \
-Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \
-Db_lto=$lto -Dcfi=$cfi -Dcfi_debug=$cfi_debug \
-Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \
@@ -5223,6 +5217,7 @@ else
perl -i -ne '
s/^gettext = true$/gettext = auto/;
s/^gettext = false$/gettext = disabled/;
+ /^b_staticpic/ && next;
print;' meson-private/cmd_line.txt
fi
fi
diff --git a/docs/meson.build b/docs/meson.build
index cffe1ecf1d..be4dc30f39 100644
--- a/docs/meson.build
+++ b/docs/meson.build
@@ -37,14 +37,14 @@ endif
if build_docs
SPHINX_ARGS += ['-Dversion=' + meson.project_version(), '-Drelease=' + config_host['PKGVERSION']]
- sphinx_extn_depends = [ meson.source_root() / 'docs/sphinx/depfile.py',
- meson.source_root() / 'docs/sphinx/hxtool.py',
- meson.source_root() / 'docs/sphinx/kerneldoc.py',
- meson.source_root() / 'docs/sphinx/kernellog.py',
- meson.source_root() / 'docs/sphinx/qapidoc.py',
- meson.source_root() / 'docs/sphinx/qmp_lexer.py',
+ sphinx_extn_depends = [ meson.current_source_dir() / 'sphinx/depfile.py',
+ meson.current_source_dir() / 'sphinx/hxtool.py',
+ meson.current_source_dir() / 'sphinx/kerneldoc.py',
+ meson.current_source_dir() / 'sphinx/kernellog.py',
+ meson.current_source_dir() / 'sphinx/qapidoc.py',
+ meson.current_source_dir() / 'sphinx/qmp_lexer.py',
qapi_gen_depends ]
- sphinx_template_files = [ meson.source_root() / 'docs/_templates/footer.html' ]
+ sphinx_template_files = [ meson.project_source_root() / 'docs/_templates/footer.html' ]
have_ga = have_tools and config_host.has_key('CONFIG_GUEST_AGENT')
diff --git a/docs/system/i386/kvm-pv.rst b/docs/system/i386/kvm-pv.rst
new file mode 100644
index 0000000000..1e5a9923ef
--- /dev/null
+++ b/docs/system/i386/kvm-pv.rst
@@ -0,0 +1,100 @@
+Paravirtualized KVM features
+============================
+
+Description
+-----------
+
+In some cases when implementing hardware interfaces in software is slow, ``KVM``
+implements its own paravirtualized interfaces.
+
+Setup
+-----
+
+Paravirtualized ``KVM`` features are represented as CPU flags. The following
+features are enabled by default for any CPU model when ``KVM`` acceleration is
+enabled:
+
+- ``kvmclock``
+- ``kvm-nopiodelay``
+- ``kvm-asyncpf``
+- ``kvm-steal-time``
+- ``kvm-pv-eoi``
+- ``kvmclock-stable-bit``
+
+``kvm-msi-ext-dest-id`` feature is enabled by default in x2apic mode with split
+irqchip (e.g. "-machine ...,kernel-irqchip=split -cpu ...,x2apic").
+
+Note: when CPU model ``host`` is used, QEMU passes through all supported
+paravirtualized ``KVM`` features to the guest.
+
+Existing features
+-----------------
+
+``kvmclock``
+ Expose a ``KVM`` specific paravirtualized clocksource to the guest. Supported
+ since Linux v2.6.26.
+
+``kvm-nopiodelay``
+ The guest doesn't need to perform delays on PIO operations. Supported since
+ Linux v2.6.26.
+
+``kvm-mmu``
+ This feature is deprecated.
+
+``kvm-asyncpf``
+ Enable asynchronous page fault mechanism. Supported since Linux v2.6.38.
+ Note: since Linux v5.10 the feature is deprecated and not enabled by ``KVM``.
+ Use ``kvm-asyncpf-int`` instead.
+
+``kvm-steal-time``
+ Enable stolen (when guest vCPU is not running) time accounting. Supported
+ since Linux v3.1.
+
+``kvm-pv-eoi``
+ Enable paravirtualized end-of-interrupt signaling. Supported since Linux
+ v3.10.
+
+``kvm-pv-unhalt``
+ Enable paravirtualized spinlocks support. Supported since Linux v3.12.
+
+``kvm-pv-tlb-flush``
+ Enable paravirtualized TLB flush mechanism. Supported since Linux v4.16.
+
+``kvm-pv-ipi``
+ Enable paravirtualized IPI mechanism. Supported since Linux v4.19.
+
+``kvm-poll-control``
+ Enable host-side polling on HLT control from the guest. Supported since Linux
+ v5.10.
+
+``kvm-pv-sched-yield``
+ Enable paravirtualized sched yield feature. Supported since Linux v5.10.
+
+``kvm-asyncpf-int``
+ Enable interrupt based asynchronous page fault mechanism. Supported since Linux
+ v5.10.
+
+``kvm-msi-ext-dest-id``
+ Support 'Extended Destination ID' for external interrupts. The feature allows
+ to use up to 32768 CPUs without IRQ remapping (but other limits may apply making
+ the number of supported vCPUs for a given configuration lower). Supported since
+ Linux v5.10.
+
+``kvmclock-stable-bit``
+ Tell the guest that guest visible TSC value can be fully trusted for kvmclock
+ computations and no warps are expected. Supported since Linux v2.6.35.
+
+Supplementary features
+----------------------
+
+``kvm-pv-enforce-cpuid``
+ Limit the supported paravirtualized feature set to the exposed features only.
+ Note, by default, ``KVM`` allows the guest to use all currently supported
+ paravirtualized features even when they were not announced in guest visible
+ CPUIDs. Supported since Linux v5.10.
+
+
+Useful links
+------------
+
+Please refer to Documentation/virt/kvm in Linux for additional details.
diff --git a/docs/system/target-i386.rst b/docs/system/target-i386.rst
index 6a86d63863..4daa53c35d 100644
--- a/docs/system/target-i386.rst
+++ b/docs/system/target-i386.rst
@@ -26,6 +26,7 @@ Architectural features
:maxdepth: 1
i386/cpu
+ i386/kvm-pv
i386/sgx
.. _pcsys_005freq:
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 41ef9a84a9..0c7c054e3a 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -47,6 +47,7 @@
#include "hw/i386/fw_cfg.h"
#include "hw/intc/i8259.h"
#include "hw/rtc/mc146818rtc.h"
+#include "target/i386/sev_i386.h"
#include "hw/acpi/cpu_hotplug.h"
#include "hw/irq.h"
@@ -780,6 +781,7 @@ void x86_load_linux(X86MachineState *x86ms,
const char *initrd_filename = machine->initrd_filename;
const char *dtb_filename = machine->dtb;
const char *kernel_cmdline = machine->kernel_cmdline;
+ SevKernelLoaderContext sev_load_ctx = {};
/* Align to 16 bytes as a paranoia measure */
cmdline_size = (strlen(kernel_cmdline) + 16) & ~15;
@@ -926,6 +928,8 @@ void x86_load_linux(X86MachineState *x86ms,
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1);
fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
+ sev_load_ctx.cmdline_data = (char *)kernel_cmdline;
+ sev_load_ctx.cmdline_size = strlen(kernel_cmdline) + 1;
if (protocol >= 0x202) {
stl_p(header + 0x228, cmdline_addr);
@@ -1007,6 +1011,8 @@ void x86_load_linux(X86MachineState *x86ms,
fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, initrd_size);
+ sev_load_ctx.initrd_data = initrd_data;
+ sev_load_ctx.initrd_size = initrd_size;
stl_p(header + 0x218, initrd_addr);
stl_p(header + 0x21c, initrd_size);
@@ -1065,15 +1071,32 @@ void x86_load_linux(X86MachineState *x86ms,
load_image_size(dtb_filename, setup_data->data, dtb_size);
}
- memcpy(setup, header, MIN(sizeof(header), setup_size));
+ /*
+ * If we're starting an encrypted VM, it will be OVMF based, which uses the
+ * efi stub for booting and doesn't require any values to be placed in the
+ * kernel header. We therefore don't update the header so the hash of the
+ * kernel on the other side of the fw_cfg interface matches the hash of the
+ * file the user passed in.
+ */
+ if (!sev_enabled()) {
+ memcpy(setup, header, MIN(sizeof(header), setup_size));
+ }
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
+ sev_load_ctx.kernel_data = (char *)kernel;
+ sev_load_ctx.kernel_size = kernel_size;
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
+ sev_load_ctx.setup_data = (char *)setup;
+ sev_load_ctx.setup_size = setup_size;
+
+ if (sev_enabled()) {
+ sev_add_kernel_loader_hashes(&sev_load_ctx, &error_fatal);
+ }
option_rom[nb_option_roms].bootindex = 0;
option_rom[nb_option_roms].name = "linuxboot.bin";
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 1b9acaf1d3..cec247b5ee 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -38,6 +38,171 @@
#include "qemu/timer.h"
#include "qom/object.h"
+#if defined(__APPLE__) && defined(__MACH__)
+#include <IOKit/IOKitLib.h>
+
+enum {
+ kSMCSuccess = 0x00,
+ kSMCKeyNotFound = 0x84
+};
+
+enum {
+ kSMCUserClientOpen = 0x00,
+ kSMCUserClientClose = 0x01,
+ kSMCHandleYPCEvent = 0x02,
+ kSMCReadKey = 0x05,
+ kSMCGetKeyInfo = 0x09
+};
+
+typedef struct SMCVersion {
+ uint8_t major;
+ uint8_t minor;
+ uint8_t build;
+ uint8_t reserved;
+ uint16_t release;
+} SMCVersion;
+
+typedef struct SMCPLimitData {
+ uint16_t version;
+ uint16_t length;
+ uint32_t cpuPLimit;
+ uint32_t gpuPLimit;
+ uint32_t memPLimit;
+} SMCPLimitData;
+
+typedef struct SMCKeyInfoData {
+ IOByteCount dataSize;
+ uint32_t dataType;
+ uint8_t dataAttributes;
+} SMCKeyInfoData;
+
+typedef struct {
+ uint32_t key;
+ SMCVersion vers;
+ SMCPLimitData pLimitData;
+ SMCKeyInfoData keyInfo;
+ uint8_t result;
+ uint8_t status;
+ uint8_t data8;
+ uint32_t data32;
+ uint8_t bytes[32];
+} SMCParamStruct;
+
+static IOReturn smc_call_struct_method(uint32_t selector,
+ SMCParamStruct *inputStruct,
+ SMCParamStruct *outputStruct)
+{
+ IOReturn ret;
+
+ size_t inputStructCnt = sizeof(SMCParamStruct);
+ size_t outputStructCnt = sizeof(SMCParamStruct);
+
+ io_service_t smcService = IO_OBJECT_NULL;
+ io_connect_t smcConnect = IO_OBJECT_NULL;
+
+ smcService = IOServiceGetMatchingService(kIOMasterPortDefault,
+ IOServiceMatching("AppleSMC"));
+ if (smcService == IO_OBJECT_NULL) {
+ ret = kIOReturnNotFound;
+ goto exit;
+ }
+
+ ret = IOServiceOpen(smcService, mach_task_self(), 1, &smcConnect);
+ if (ret != kIOReturnSuccess) {
+ smcConnect = IO_OBJECT_NULL;
+ goto exit;
+ }
+ if (smcConnect == IO_OBJECT_NULL) {
+ ret = kIOReturnError;
+ goto exit;
+ }
+
+ ret = IOConnectCallMethod(smcConnect, kSMCUserClientOpen,
+ NULL, 0, NULL, 0,
+ NULL, NULL, NULL, NULL);
+ if (ret != kIOReturnSuccess) {
+ goto exit;
+ }
+
+ ret = IOConnectCallStructMethod(smcConnect, selector,
+ inputStruct, inputStructCnt,
+ outputStruct, &outputStructCnt);
+
+exit:
+ if (smcConnect != IO_OBJECT_NULL) {
+ IOConnectCallMethod(smcConnect, kSMCUserClientClose,
+ NULL, 0, NULL, 0, NULL,
+ NULL, NULL, NULL);
+ IOServiceClose(smcConnect);
+ }
+
+ return ret;
+}
+
+static IOReturn smc_read_key(uint32_t key,
+ uint8_t *bytes,
+ IOByteCount *dataSize)
+{
+ IOReturn ret;
+
+ SMCParamStruct inputStruct;
+ SMCParamStruct outputStruct;
+
+ if (key == 0 || bytes == NULL) {
+ ret = kIOReturnCannotWire;
+ goto exit;
+ }
+
+ /* determine key's data size */
+ memset(&inputStruct, 0, sizeof(SMCParamStruct));
+ inputStruct.data8 = kSMCGetKeyInfo;
+ inputStruct.key = key;
+
+ memset(&outputStruct, 0, sizeof(SMCParamStruct));
+ ret = smc_call_struct_method(kSMCHandleYPCEvent, &inputStruct, &outputStruct);
+ if (ret != kIOReturnSuccess) {
+ goto exit;
+ }
+ if (outputStruct.result == kSMCKeyNotFound) {
+ ret = kIOReturnNotFound;
+ goto exit;
+ }
+ if (outputStruct.result != kSMCSuccess) {
+ ret = kIOReturnInternalError;
+ goto exit;
+ }
+
+ /* get key value */
+ memset(&inputStruct, 0, sizeof(SMCParamStruct));
+ inputStruct.data8 = kSMCReadKey;
+ inputStruct.key = key;
+ inputStruct.keyInfo.dataSize = outputStruct.keyInfo.dataSize;
+
+ memset(&outputStruct, 0, sizeof(SMCParamStruct));
+ ret = smc_call_struct_method(kSMCHandleYPCEvent, &inputStruct, &outputStruct);
+ if (ret != kIOReturnSuccess) {
+ goto exit;
+ }
+ if (outputStruct.result == kSMCKeyNotFound) {
+ ret = kIOReturnNotFound;
+ goto exit;
+ }
+ if (outputStruct.result != kSMCSuccess) {
+ ret = kIOReturnInternalError;
+ goto exit;
+ }
+
+ memset(bytes, 0, *dataSize);
+ if (*dataSize > inputStruct.keyInfo.dataSize) {
+ *dataSize = inputStruct.keyInfo.dataSize;
+ }
+ memcpy(bytes, outputStruct.bytes, *dataSize);
+
+exit:
+ return ret;
+}
+#endif
+
/* #define DEBUG_SMC */
#define APPLESMC_DEFAULT_IOBASE 0x300
@@ -315,6 +480,7 @@ static const MemoryRegionOps applesmc_err_io_ops = {
static void applesmc_isa_realize(DeviceState *dev, Error **errp)
{
AppleSMCState *s = APPLE_SMC(dev);
+ bool valid_key = false;
memory_region_init_io(&s->io_data, OBJECT(s), &applesmc_data_io_ops, s,
"applesmc-data", 1);
@@ -331,7 +497,31 @@ static void applesmc_isa_realize(DeviceState *dev, Error **errp)
isa_register_ioport(&s->parent_obj, &s->io_err,
s->iobase + APPLESMC_ERR_PORT);
- if (!s->osk || (strlen(s->osk) != 64)) {
+ if (s->osk) {
+ valid_key = strlen(s->osk) == 64;
+ } else {
+#if defined(__APPLE__) && defined(__MACH__)
+ IOReturn ret;
+ IOByteCount size = 32;
+
+ ret = smc_read_key('OSK0', (uint8_t *) default_osk, &size);
+ if (ret != kIOReturnSuccess) {
+ goto failure;
+ }
+
+ ret = smc_read_key('OSK1', (uint8_t *) default_osk + size, &size);
+ if (ret != kIOReturnSuccess) {
+ goto failure;
+ }
+
+ warn_report("Using AppleSMC with host key");
+ valid_key = true;
+ s->osk = default_osk;
+failure:;
+#endif
+ }
+
+ if (!valid_key) {
warn_report("Using AppleSMC with invalid key");
s->osk = default_osk;
}
diff --git a/meson b/meson
-Subproject 776acd2a805c9b42b4f0375150977df42130317
+Subproject b25d94e7c77fda05a7fdfe8afe562cf9760d69d
diff --git a/meson.build b/meson.build
index 60f4f45165..7b596fdcd9 100644
--- a/meson.build
+++ b/meson.build
@@ -1,14 +1,10 @@
-project('qemu', ['c'], meson_version: '>=0.55.0',
- default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto'] +
- (meson.version().version_compare('>=0.56.0') ? [ 'b_staticpic=false' ] : []),
- version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
+project('qemu', ['c'], meson_version: '>=0.58.2',
+ default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
+ 'b_staticpic=false'],
+ version: files('VERSION'))
not_found = dependency('', required: false)
-if meson.version().version_compare('>=0.56.0')
- keyval = import('keyval')
-else
- keyval = import('unstable-keyval')
-endif
+keyval = import('keyval')
ss = import('sourceset')
fs = import('fs')
@@ -1972,21 +1968,21 @@ genh += configure_file(output: 'config-host.h', configuration: config_host_data)
hxtool = find_program('scripts/hxtool')
shaderinclude = find_program('scripts/shaderinclude.pl')
qapi_gen = find_program('scripts/qapi-gen.py')
-qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
- meson.source_root() / 'scripts/qapi/commands.py',
- meson.source_root() / 'scripts/qapi/common.py',
- meson.source_root() / 'scripts/qapi/error.py',
- meson.source_root() / 'scripts/qapi/events.py',
- meson.source_root() / 'scripts/qapi/expr.py',
- meson.source_root() / 'scripts/qapi/gen.py',
- meson.source_root() / 'scripts/qapi/introspect.py',
- meson.source_root() / 'scripts/qapi/parser.py',
- meson.source_root() / 'scripts/qapi/schema.py',
- meson.source_root() / 'scripts/qapi/source.py',
- meson.source_root() / 'scripts/qapi/types.py',
- meson.source_root() / 'scripts/qapi/visit.py',
- meson.source_root() / 'scripts/qapi/common.py',
- meson.source_root() / 'scripts/qapi-gen.py'
+qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
+ meson.current_source_dir() / 'scripts/qapi/commands.py',
+ meson.current_source_dir() / 'scripts/qapi/common.py',
+ meson.current_source_dir() / 'scripts/qapi/error.py',
+ meson.current_source_dir() / 'scripts/qapi/events.py',
+ meson.current_source_dir() / 'scripts/qapi/expr.py',
+ meson.current_source_dir() / 'scripts/qapi/gen.py',
+ meson.current_source_dir() / 'scripts/qapi/introspect.py',
+ meson.current_source_dir() / 'scripts/qapi/parser.py',
+ meson.current_source_dir() / 'scripts/qapi/schema.py',
+ meson.current_source_dir() / 'scripts/qapi/source.py',
+ meson.current_source_dir() / 'scripts/qapi/types.py',
+ meson.current_source_dir() / 'scripts/qapi/visit.py',
+ meson.current_source_dir() / 'scripts/qapi/common.py',
+ meson.current_source_dir() / 'scripts/qapi-gen.py'
]
tracetool = [
@@ -2635,14 +2631,14 @@ foreach target : target_dirs
if target.endswith('-softmmu')
execs = [{
'name': 'qemu-system-' + target_name,
- 'gui': false,
+ 'win_subsystem': 'console',
'sources': files('softmmu/main.c'),
'dependencies': []
}]
if targetos == 'windows' and (sdl.found() or gtk.found())
execs += [{
'name': 'qemu-system-' + target_name + 'w',
- 'gui': true,
+ 'win_subsystem': 'windows',
'sources': files('softmmu/main.c'),
'dependencies': []
}]
@@ -2651,7 +2647,7 @@ foreach target : target_dirs
specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
execs += [{
'name': 'qemu-fuzz-' + target_name,
- 'gui': false,
+ 'win_subsystem': 'console',
'sources': specific_fuzz.sources(),
'dependencies': specific_fuzz.dependencies(),
}]
@@ -2659,7 +2655,7 @@ foreach target : target_dirs
else
execs = [{
'name': 'qemu-' + target_name,
- 'gui': false,
+ 'win_subsystem': 'console',
'sources': [],
'dependencies': []
}]
@@ -2678,7 +2674,7 @@ foreach target : target_dirs
link_language: link_language,
link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
link_args: link_args,
- gui_app: exe['gui'])
+ win_subsystem: exe['win_subsystem'])
if targetos == 'darwin'
icon = 'pc-bios/qemu.rsrc'
@@ -2863,13 +2859,13 @@ summary_info = {}
summary_info += {'git': config_host['GIT']}
summary_info += {'make': config_host['MAKE']}
summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
-summary_info += {'sphinx-build': sphinx_build.found()}
+summary_info += {'sphinx-build': sphinx_build}
if config_host.has_key('HAVE_GDB_BIN')
summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
endif
summary_info += {'genisoimage': config_host['GENISOIMAGE']}
if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
- summary_info += {'wixl': wixl.found() ? wixl.full_path() : false}
+ summary_info += {'wixl': wixl}
endif
if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
@@ -2960,7 +2956,7 @@ if get_option('cfi')
summary_info += {'CFI debug support': get_option('cfi_debug')}
endif
summary_info += {'strip binaries': get_option('strip')}
-summary_info += {'sparse': sparse.found() ? sparse.full_path() : false}
+summary_info += {'sparse': sparse}
summary_info += {'mingw32 support': targetos == 'windows'}
# snarf the cross-compilation information for tests
@@ -3032,19 +3028,19 @@ if have_block
summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
- summary_info += {'FUSE exports': fuse.found()}
+ summary_info += {'FUSE exports': fuse}
endif
summary(summary_info, bool_yn: true, section: 'Block layer support')
# Crypto
summary_info = {}
summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
-summary_info += {'GNUTLS support': gnutls.found()}
-summary_info += {'GNUTLS crypto': gnutls_crypto.found()}
-# TODO: add back version
-summary_info += {'libgcrypt': gcrypt.found()}
-# TODO: add back version
-summary_info += {'nettle': nettle.found()}
+summary_info += {'GNUTLS support': gnutls}
+if gnutls.found()
+ summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
+endif
+summary_info += {'libgcrypt': gcrypt}
+summary_info += {'nettle': nettle}
if nettle.found()
summary_info += {' XTS': xts != 'private'}
endif
@@ -3056,76 +3052,72 @@ summary(summary_info, bool_yn: true, section: 'Crypto')
# Libraries
summary_info = {}
if targetos == 'darwin'
- summary_info += {'Cocoa support': cocoa.found()}
-endif
-# TODO: add back version
-summary_info += {'SDL support': sdl.found()}
-summary_info += {'SDL image support': sdl_image.found()}
-# TODO: add back version
-summary_info += {'GTK support': gtk.found()}
-summary_info += {'pixman': pixman.found()}
-# TODO: add back version
-summary_info += {'VTE support': vte.found()}
-# TODO: add back version
-summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
-summary_info += {'libtasn1': tasn1.found()}
-summary_info += {'PAM': pam.found()}
-summary_info += {'iconv support': iconv.found()}
-summary_info += {'curses support': curses.found()}
-# TODO: add back version
-summary_info += {'virgl support': virgl.found()}
-summary_info += {'curl support': curl.found()}
-summary_info += {'Multipath support': mpathpersist.found()}
-summary_info += {'VNC support': vnc.found()}
+ summary_info += {'Cocoa support': cocoa}
+endif
+summary_info += {'SDL support': sdl}
+summary_info += {'SDL image support': sdl_image}
+summary_info += {'GTK support': gtk}
+summary_info += {'pixman': pixman}
+summary_info += {'VTE support': vte}
+summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
+summary_info += {'libtasn1': tasn1}
+summary_info += {'PAM': pam}
+summary_info += {'iconv support': iconv}
+summary_info += {'curses support': curses}
+summary_info += {'virgl support': virgl}
+summary_info += {'curl support': curl}
+summary_info += {'Multipath support': mpathpersist}
+summary_info += {'VNC support': vnc}
if vnc.found()
- summary_info += {'VNC SASL support': sasl.found()}
- summary_info += {'VNC JPEG support': jpeg.found()}
- summary_info += {'VNC PNG support': png.found()}
+ summary_info += {'VNC SASL support': sasl}
+ summary_info += {'VNC JPEG support': jpeg}
+ summary_info += {'VNC PNG support': png}
endif
-summary_info += {'brlapi support': brlapi.found()}
+summary_info += {'brlapi support': brlapi}
summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
-summary_info += {'Linux io_uring support': linux_io_uring.found()}
-summary_info += {'ATTR/XATTR support': libattr.found()}
+summary_info += {'Linux io_uring support': linux_io_uring}
+summary_info += {'ATTR/XATTR support': libattr}
summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
-summary_info += {'libcap-ng support': libcap_ng.found()}
-summary_info += {'bpf support': libbpf.found()}
+summary_info += {'libcap-ng support': libcap_ng}
+summary_info += {'bpf support': libbpf}
# TODO: add back protocol and server version
summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
-summary_info += {'rbd support': rbd.found()}
+summary_info += {'rbd support': rbd}
summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
-summary_info += {'smartcard support': cacard.found()}
-summary_info += {'U2F support': u2f.found()}
-summary_info += {'libusb': libusb.found()}
-summary_info += {'usb net redir': usbredir.found()}
+summary_info += {'smartcard support': cacard}
+summary_info += {'U2F support': u2f}
+summary_info += {'libusb': libusb}
+summary_info += {'usb net redir': usbredir}
summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
-summary_info += {'GBM': gbm.found()}
-summary_info += {'libiscsi support': libiscsi.found()}
-summary_info += {'libnfs support': libnfs.found()}
+summary_info += {'GBM': gbm}
+summary_info += {'libiscsi support': libiscsi}
+summary_info += {'libnfs support': libnfs}
if targetos == 'windows'
if config_host.has_key('CONFIG_GUEST_AGENT')
summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
endif
endif
-summary_info += {'seccomp support': seccomp.found()}
-summary_info += {'GlusterFS support': glusterfs.found()}
+summary_info += {'seccomp support': seccomp}
+summary_info += {'GlusterFS support': glusterfs}
summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
-summary_info += {'lzo support': lzo.found()}
-summary_info += {'snappy support': snappy.found()}
-summary_info += {'bzip2 support': libbzip2.found()}
-summary_info += {'lzfse support': liblzfse.found()}
-summary_info += {'zstd support': zstd.found()}
+summary_info += {'lzo support': lzo}
+summary_info += {'snappy support': snappy}
+summary_info += {'bzip2 support': libbzip2}
+summary_info += {'lzfse support': liblzfse}
+summary_info += {'zstd support': zstd}
summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
-summary_info += {'libxml2': libxml2.found()}
-summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
-summary_info += {'libpmem support': libpmem.found()}
-summary_info += {'libdaxctl support': libdaxctl.found()}
-summary_info += {'libudev': libudev.found()}
+summary_info += {'libxml2': libxml2}
+summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
+summary_info += {'libpmem support': libpmem}
+summary_info += {'libdaxctl support': libdaxctl}
+summary_info += {'libudev': libudev}
+# Dummy dependency, keep .found()
summary_info += {'FUSE lseek': fuse_lseek.found()}
summary(summary_info, bool_yn: true, section: 'Dependencies')
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
index 35f5ef688d..9aba7d9c22 100644
--- a/migration/block-dirty-bitmap.c
+++ b/migration/block-dirty-bitmap.c
@@ -1215,7 +1215,10 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
{
DBMSaveState *s = &((DBMState *)opaque)->save;
SaveBitmapState *dbms = NULL;
+
+ qemu_mutex_lock_iothread();
if (init_dirty_bitmap_migration(s) < 0) {
+ qemu_mutex_unlock_iothread();
return -1;
}
@@ -1223,7 +1226,7 @@ static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque)
send_bitmap_start(f, s, dbms);
}
qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
-
+ qemu_mutex_unlock_iothread();
return 0;
}
diff --git a/migration/migration.c b/migration/migration.c
index bb909781b7..6ac807ef3d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -3168,7 +3168,10 @@ static void migration_completion(MigrationState *s)
} else if (s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
trace_migration_completion_postcopy_end();
+ qemu_mutex_lock_iothread();
qemu_savevm_state_complete_postcopy(s->to_dst_file);
+ qemu_mutex_unlock_iothread();
+
trace_migration_completion_postcopy_end_after_complete();
} else if (s->state == MIGRATION_STATUS_CANCELLING) {
goto fail;
diff --git a/plugins/meson.build b/plugins/meson.build
index bfd5c9822a..aeb386ebae 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -2,9 +2,9 @@ plugin_ldflags = []
# Modules need more symbols than just those in plugins/qemu-plugins.symbols
if not enable_modules
if 'CONFIG_HAS_LD_DYNAMIC_LIST' in config_host
- plugin_ldflags = ['-Wl,--dynamic-list=' + (meson.build_root() / 'qemu-plugins-ld.symbols')]
+ plugin_ldflags = ['-Wl,--dynamic-list=' + (meson.project_build_root() / 'qemu-plugins-ld.symbols')]
elif 'CONFIG_HAS_LD_EXPORTED_SYMBOLS_LIST' in config_host
- plugin_ldflags = ['-Wl,-exported_symbols_list,' + (meson.build_root() / 'qemu-plugins-ld64.symbols')]
+ plugin_ldflags = ['-Wl,-exported_symbols_list,' + (meson.project_build_root() / 'qemu-plugins-ld64.symbols')]
endif
endif
diff --git a/scripts/mtest2make.py b/scripts/mtest2make.py
index ee072c0502..02c0453e67 100644
--- a/scripts/mtest2make.py
+++ b/scripts/mtest2make.py
@@ -60,11 +60,8 @@ def process_tests(test, targets, suites):
if test['workdir'] is not None:
print('.test.dir.%d := %s' % (i, shlex.quote(test['workdir'])))
- if 'depends' in test:
- deps = (targets.get(x, []) for x in test['depends'])
- deps = itertools.chain.from_iterable(deps)
- else:
- deps = ['all']
+ deps = (targets.get(x, []) for x in test['depends'])
+ deps = itertools.chain.from_iterable(deps)
print('.test.name.%d := %s' % (i, test['name']))
print('.test.driver.%d := %s' % (i, driver))
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index 6fd9360b74..c6d858ffb2 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -156,7 +156,8 @@ dectree_generated = custom_target(
'dectree_generated.h.inc',
output: 'dectree_generated.h.inc',
depends: [iset_py],
- command: ['env', 'PYTHONPATH=' + meson.current_build_dir(), files('dectree.py'), '@OUTPUT@'],
+ env: {'PYTHONPATH': meson.current_build_dir()},
+ command: [python, files('dectree.py'), '@OUTPUT@'],
)
hexagon_ss.add(dectree_generated)
diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c
index 0227cb5177..d8e6583171 100644
--- a/target/i386/sev-stub.c
+++ b/target/i386/sev-stub.c
@@ -81,3 +81,8 @@ sev_get_attestation_report(const char *mnonce, Error **errp)
error_setg(errp, "SEV is not available in this QEMU");
return NULL;
}
+
+bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
+{
+ g_assert_not_reached();
+}
diff --git a/target/i386/sev.c b/target/i386/sev.c
index fa7210473a..bcd9260fa4 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -23,6 +23,7 @@
#include "qemu/base64.h"
#include "qemu/module.h"
#include "qemu/uuid.h"
+#include "crypto/hash.h"
#include "sysemu/kvm.h"
#include "sev_i386.h"
#include "sysemu/sysemu.h"
@@ -83,6 +84,32 @@ typedef struct __attribute__((__packed__)) SevInfoBlock {
uint32_t reset_addr;
} SevInfoBlock;
+#define SEV_HASH_TABLE_RV_GUID "7255371f-3a3b-4b04-927b-1da6efa8d454"
+typedef struct QEMU_PACKED SevHashTableDescriptor {
+ /* SEV hash table area guest address */
+ uint32_t base;
+ /* SEV hash table area size (in bytes) */
+ uint32_t size;
+} SevHashTableDescriptor;
+
+/* hard code sha256 digest size */
+#define HASH_SIZE 32
+
+typedef struct QEMU_PACKED SevHashTableEntry {
+ QemuUUID guid;
+ uint16_t len;
+ uint8_t hash[HASH_SIZE];
+} SevHashTableEntry;
+
+typedef struct QEMU_PACKED SevHashTable {
+ QemuUUID guid;
+ uint16_t len;
+ SevHashTableEntry cmdline;
+ SevHashTableEntry initrd;
+ SevHashTableEntry kernel;
+ uint8_t padding[];
+} SevHashTable;
+
static SevGuestState *sev_guest;
static Error *sev_mig_blocker;
@@ -1071,6 +1098,116 @@ int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size)
return 0;
}
+static const QemuUUID sev_hash_table_header_guid = {
+ .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93,
+ 0xd4, 0x11, 0xfd, 0x21)
+};
+
+static const QemuUUID sev_kernel_entry_guid = {
+ .data = UUID_LE(0x4de79437, 0xabd2, 0x427f, 0xb8, 0x35, 0xd5, 0xb1,
+ 0x72, 0xd2, 0x04, 0x5b)
+};
+static const QemuUUID sev_initrd_entry_guid = {
+ .data = UUID_LE(0x44baf731, 0x3a2f, 0x4bd7, 0x9a, 0xf1, 0x41, 0xe2,
+ 0x91, 0x69, 0x78, 0x1d)
+};
+static const QemuUUID sev_cmdline_entry_guid = {
+ .data = UUID_LE(0x97d02dd8, 0xbd20, 0x4c94, 0xaa, 0x78, 0xe7, 0x71,
+ 0x4d, 0x36, 0xab, 0x2a)
+};
+
+/*
+ * Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
+ * which is included in SEV's initial memory measurement.
+ */
+bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
+{
+ uint8_t *data;
+ SevHashTableDescriptor *area;
+ SevHashTable *ht;
+ uint8_t cmdline_hash[HASH_SIZE];
+ uint8_t initrd_hash[HASH_SIZE];
+ uint8_t kernel_hash[HASH_SIZE];
+ uint8_t *hashp;
+ size_t hash_len = HASH_SIZE;
+ int aligned_len;
+
+ if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) {
+ error_setg(errp, "SEV: kernel specified but OVMF has no hash table guid");
+ return false;
+ }
+ area = (SevHashTableDescriptor *)data;
+
+ /*
+ * Calculate hash of kernel command-line with the terminating null byte. If
+ * the user doesn't supply a command-line via -append, the 1-byte "\0" will
+ * be used.
+ */
+ hashp = cmdline_hash;
+ if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256, ctx->cmdline_data,
+ ctx->cmdline_size, &hashp, &hash_len, errp) < 0) {
+ return false;
+ }
+ assert(hash_len == HASH_SIZE);
+
+ /*
+ * Calculate hash of initrd. If the user doesn't supply an initrd via
+ * -initrd, an empty buffer will be used (ctx->initrd_size == 0).
+ */
+ hashp = initrd_hash;
+ if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256, ctx->initrd_data,
+ ctx->initrd_size, &hashp, &hash_len, errp) < 0) {
+ return false;
+ }
+ assert(hash_len == HASH_SIZE);
+
+ /* Calculate hash of the kernel */
+ hashp = kernel_hash;
+ struct iovec iov[2] = {
+ { .iov_base = ctx->setup_data, .iov_len = ctx->setup_size },
+ { .iov_base = ctx->kernel_data, .iov_len = ctx->kernel_size }
+ };
+ if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256, iov, ARRAY_SIZE(iov),
+ &hashp, &hash_len, errp) < 0) {
+ return false;
+ }
+ assert(hash_len == HASH_SIZE);
+
+ /*
+ * Populate the hashes table in the guest's memory at the OVMF-designated
+ * area for the SEV hashes table
+ */
+ ht = qemu_map_ram_ptr(NULL, area->base);
+
+ ht->guid = sev_hash_table_header_guid;
+ ht->len = sizeof(*ht);
+
+ ht->cmdline.guid = sev_cmdline_entry_guid;
+ ht->cmdline.len = sizeof(ht->cmdline);
+ memcpy(ht->cmdline.hash, cmdline_hash, sizeof(ht->cmdline.hash));
+
+ ht->initrd.guid = sev_initrd_entry_guid;
+ ht->initrd.len = sizeof(ht->initrd);
+ memcpy(ht->initrd.hash, initrd_hash, sizeof(ht->initrd.hash));
+
+ ht->kernel.guid = sev_kernel_entry_guid;
+ ht->kernel.len = sizeof(ht->kernel);
+ memcpy(ht->kernel.hash, kernel_hash, sizeof(ht->kernel.hash));
+
+ /* When calling sev_encrypt_flash, the length has to be 16 byte aligned */
+ aligned_len = ROUND_UP(ht->len, 16);
+ if (aligned_len != ht->len) {
+ /* zero the excess data so the measurement can be reliably calculated */
+ memset(ht->padding, 0, aligned_len - ht->len);
+ }
+
+ if (sev_encrypt_flash((uint8_t *)ht, aligned_len, errp) < 0) {
+ return false;
+ }
+
+ return true;
+}
+
static void
sev_register_types(void)
{
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
index ae6d840478..2afe108069 100644
--- a/target/i386/sev_i386.h
+++ b/target/i386/sev_i386.h
@@ -28,6 +28,17 @@
#define SEV_POLICY_DOMAIN 0x10
#define SEV_POLICY_SEV 0x20
+typedef struct SevKernelLoaderContext {
+ char *setup_data;
+ size_t setup_size;
+ char *kernel_data;
+ size_t kernel_size;
+ char *initrd_data;
+ size_t initrd_size;
+ char *cmdline_data;
+ size_t cmdline_size;
+} SevKernelLoaderContext;
+
extern bool sev_es_enabled(void);
extern uint64_t sev_get_me_mask(void);
extern SevInfo *sev_get_info(void);
@@ -37,5 +48,6 @@ extern char *sev_get_launch_measurement(void);
extern SevCapability *sev_get_capabilities(Error **errp);
extern SevAttestationReport *
sev_get_attestation_report(const char *mnonce, Error **errp);
+extern bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp);
#endif
diff --git a/target/xtensa/cores.list b/target/xtensa/cores.list
new file mode 100644
index 0000000000..5772a00ab2
--- /dev/null
+++ b/target/xtensa/cores.list
@@ -0,0 +1,9 @@
+core-dc232b.c
+core-dc233c.c
+core-de212.c
+core-de233_fpu.c
+core-dsp3400.c
+core-fsf.c
+core-sample_controller.c
+core-test_kc705_be.c
+core-test_mmuhifi_c3.c
diff --git a/target/xtensa/import_core.sh b/target/xtensa/import_core.sh
index 396b264be9..df66d09393 100755
--- a/target/xtensa/import_core.sh
+++ b/target/xtensa/import_core.sh
@@ -66,3 +66,6 @@ static XtensaConfig $NAME __attribute__((unused)) = {
REGISTER_CORE($NAME)
EOF
+
+grep -qxf core-${NAME}.c "$BASE"/cores.list || \
+ echo core-${NAME}.c >> "$BASE"/cores.list
diff --git a/target/xtensa/meson.build b/target/xtensa/meson.build
index 7c4efa6c62..20bbf9b335 100644
--- a/target/xtensa/meson.build
+++ b/target/xtensa/meson.build
@@ -1,7 +1,7 @@
xtensa_ss = ss.source_set()
-xtensa_cores = run_command('sh', '-c', 'cd $MESON_SOURCE_ROOT/$MESON_SUBDIR ; ls -1 core-*.c')
-xtensa_ss.add(files(xtensa_cores.stdout().strip().split('\n')))
+xtensa_cores = fs.read('cores.list')
+xtensa_ss.add(files(xtensa_cores.strip().split('\n')))
xtensa_ss.add(files(
'cpu.c',
diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build
index 6187efbd58..df5acfd08b 100644
--- a/tests/qapi-schema/meson.build
+++ b/tests/qapi-schema/meson.build
@@ -1,5 +1,5 @@
test_env = environment()
-test_env.set('PYTHONPATH', meson.source_root() / 'scripts')
+test_env.set('PYTHONPATH', meson.project_source_root() / 'scripts')
test_env.set('PYTHONIOENCODING', 'utf-8')
schemas = [
@@ -248,7 +248,7 @@ if build_docs
# clutter up the build dir with the cache.
command: [SPHINX_ARGS,
'-b', 'text', '-E',
- '-c', meson.source_root() / 'docs',
+ '-c', meson.project_source_root() / 'docs',
'-D', 'master_doc=doc-good',
meson.current_source_dir(),
meson.current_build_dir()])
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 19444d4752..c9d8458062 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -275,7 +275,7 @@ foreach dir : target_dirs
qtest_env.set('QTEST_QEMU_IMG', './qemu-img')
test_deps += [qemu_img]
endif
- qtest_env.set('G_TEST_DBUS_DAEMON', meson.source_root() / 'tests/dbus-vmstate-daemon.sh')
+ qtest_env.set('G_TEST_DBUS_DAEMON', meson.project_source_root() / 'tests/dbus-vmstate-daemon.sh')
qtest_env.set('QTEST_QEMU_BINARY', './qemu-system-' + target_base)
if have_tools and have_vhost_user_blk_server
qtest_env.set('QTEST_QEMU_STORAGE_DAEMON_BINARY', './storage-daemon/qemu-storage-daemon')
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 5736d285b2..7c297d7e5c 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -43,7 +43,7 @@ tests = {
'test-keyval': [testqapi],
'test-logging': [],
'test-uuid': [],
- 'ptimer-test': ['ptimer-test-stubs.c', meson.source_root() / 'hw/core/ptimer.c'],
+ 'ptimer-test': ['ptimer-test-stubs.c', meson.project_source_root() / 'hw/core/ptimer.c'],
'test-qapi-util': [],
}
diff --git a/trace/meson.build b/trace/meson.build
index e401e7c415..b8f95de200 100644
--- a/trace/meson.build
+++ b/trace/meson.build
@@ -4,7 +4,7 @@ specific_ss.add(files('control-target.c'))
trace_events_files = []
dtrace = find_program('dtrace', required: 'CONFIG_TRACE_DTRACE' in config_host)
foreach dir : [ '.' ] + trace_events_subdirs
- trace_events_file = meson.source_root() / dir / 'trace-events'
+ trace_events_file = meson.project_source_root() / dir / 'trace-events'
trace_events_files += [ trace_events_file ]
group_name = dir == '.' ? 'root' : dir.underscorify()
group = '--group=' + group_name
@@ -70,7 +70,7 @@ foreach d : [
]
gen = custom_target(d[0],
output: d[0],
- input: meson.source_root() / 'trace-events',
+ input: meson.project_source_root() / 'trace-events',
command: [ tracetool, '--group=root', '--format=@0@'.format(d[1]), '@INPUT@', '@OUTPUT@' ],
depend_files: tracetool_depends)
specific_ss.add(when: 'CONFIG_TCG', if_true: gen)