From fc1c8344e65807843ae8eaa25284e5277bdcd1eb Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Wed, 20 Jan 2021 01:02:55 -0500 Subject: [PATCH 01/46] fuzz: ignore address_space_map is_write flag We passed an is_write flag to the fuzz_dma_read_cb function to differentiate between the mapped DMA regions that need to be populated with fuzzed data, and those that don't. We simply passed through the address_space_map is_write parameter. The goal was to cut down on unnecessarily populating mapped DMA regions, when they are not read from. Unfortunately, nothing precludes code from reading from regions mapped with is_write=true. For example, see: https://lists.gnu.org/archive/html/qemu-devel/2021-01/msg04729.html This patch removes the is_write parameter to fuzz_dma_read_cb. As a result, we will fill all mapped DMA regions with fuzzed data, ignoring the specified transfer direction. Signed-off-by: Alexander Bulekov Reviewed-by: Darren Kenny Message-Id: <20210120060255.558535-1-alxndr@bu.edu> --- include/exec/memory.h | 8 +++----- include/exec/memory_ldst_cached.h.inc | 6 +++--- memory_ldst.c.inc | 8 ++++---- softmmu/memory.c | 5 ++--- softmmu/physmem.c | 4 ++-- tests/qtest/fuzz/generic_fuzz.c | 9 +++------ 6 files changed, 17 insertions(+), 23 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index c6ce74fb79..ecba90bfd8 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -45,13 +45,11 @@ DECLARE_OBJ_CHECKERS(IOMMUMemoryRegion, IOMMUMemoryRegionClass, #ifdef CONFIG_FUZZ void fuzz_dma_read_cb(size_t addr, size_t len, - MemoryRegion *mr, - bool is_write); + MemoryRegion *mr); #else static inline void fuzz_dma_read_cb(size_t addr, size_t len, - MemoryRegion *mr, - bool is_write) + MemoryRegion *mr) { /* Do Nothing */ } @@ -2506,7 +2504,7 @@ address_space_read_cached(MemoryRegionCache *cache, hwaddr addr, void *buf, hwaddr len) { assert(addr < cache->len && len <= cache->len - addr); - fuzz_dma_read_cb(cache->xlat + addr, len, cache->mrs.mr, false); + fuzz_dma_read_cb(cache->xlat + addr, len, cache->mrs.mr); if (likely(cache->ptr)) { memcpy(buf, cache->ptr + addr, len); return MEMTX_OK; diff --git a/include/exec/memory_ldst_cached.h.inc b/include/exec/memory_ldst_cached.h.inc index 01efad62de..7bc8790d34 100644 --- a/include/exec/memory_ldst_cached.h.inc +++ b/include/exec/memory_ldst_cached.h.inc @@ -28,7 +28,7 @@ static inline uint32_t ADDRESS_SPACE_LD_CACHED(l)(MemoryRegionCache *cache, hwaddr addr, MemTxAttrs attrs, MemTxResult *result) { assert(addr < cache->len && 4 <= cache->len - addr); - fuzz_dma_read_cb(cache->xlat + addr, 4, cache->mrs.mr, false); + fuzz_dma_read_cb(cache->xlat + addr, 4, cache->mrs.mr); if (likely(cache->ptr)) { return LD_P(l)(cache->ptr + addr); } else { @@ -40,7 +40,7 @@ static inline uint64_t ADDRESS_SPACE_LD_CACHED(q)(MemoryRegionCache *cache, hwaddr addr, MemTxAttrs attrs, MemTxResult *result) { assert(addr < cache->len && 8 <= cache->len - addr); - fuzz_dma_read_cb(cache->xlat + addr, 8, cache->mrs.mr, false); + fuzz_dma_read_cb(cache->xlat + addr, 8, cache->mrs.mr); if (likely(cache->ptr)) { return LD_P(q)(cache->ptr + addr); } else { @@ -52,7 +52,7 @@ static inline uint32_t ADDRESS_SPACE_LD_CACHED(uw)(MemoryRegionCache *cache, hwaddr addr, MemTxAttrs attrs, MemTxResult *result) { assert(addr < cache->len && 2 <= cache->len - addr); - fuzz_dma_read_cb(cache->xlat + addr, 2, cache->mrs.mr, false); + fuzz_dma_read_cb(cache->xlat + addr, 2, cache->mrs.mr); if (likely(cache->ptr)) { return LD_P(uw)(cache->ptr + addr); } else { diff --git a/memory_ldst.c.inc b/memory_ldst.c.inc index 2fed2de18e..b56e961967 100644 --- a/memory_ldst.c.inc +++ b/memory_ldst.c.inc @@ -42,7 +42,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL, MO_32 | devend_memop(endian), attrs); } else { /* RAM case */ - fuzz_dma_read_cb(addr, 4, mr, false); + fuzz_dma_read_cb(addr, 4, mr); ptr = qemu_map_ram_ptr(mr->ram_block, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: @@ -111,7 +111,7 @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL, MO_64 | devend_memop(endian), attrs); } else { /* RAM case */ - fuzz_dma_read_cb(addr, 8, mr, false); + fuzz_dma_read_cb(addr, 8, mr); ptr = qemu_map_ram_ptr(mr->ram_block, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: @@ -177,7 +177,7 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, r = memory_region_dispatch_read(mr, addr1, &val, MO_8, attrs); } else { /* RAM case */ - fuzz_dma_read_cb(addr, 1, mr, false); + fuzz_dma_read_cb(addr, 1, mr); ptr = qemu_map_ram_ptr(mr->ram_block, addr1); val = ldub_p(ptr); r = MEMTX_OK; @@ -215,7 +215,7 @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL, MO_16 | devend_memop(endian), attrs); } else { /* RAM case */ - fuzz_dma_read_cb(addr, 2, mr, false); + fuzz_dma_read_cb(addr, 2, mr); ptr = qemu_map_ram_ptr(mr->ram_block, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: diff --git a/softmmu/memory.c b/softmmu/memory.c index c0c814fbb9..23e8e33001 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -1440,7 +1440,7 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr, unsigned size = memop_size(op); MemTxResult r; - fuzz_dma_read_cb(addr, size, mr, false); + fuzz_dma_read_cb(addr, size, mr); if (!memory_region_access_valid(mr, addr, size, false, attrs)) { *pval = unassigned_mem_read(mr, addr, size); return MEMTX_DECODE_ERROR; @@ -3285,8 +3285,7 @@ void memory_region_init_rom_device(MemoryRegion *mr, #ifdef CONFIG_FUZZ void __attribute__((weak)) fuzz_dma_read_cb(size_t addr, size_t len, - MemoryRegion *mr, - bool is_write) + MemoryRegion *mr) { } #endif diff --git a/softmmu/physmem.c b/softmmu/physmem.c index 243c3097d3..96efaef97a 100644 --- a/softmmu/physmem.c +++ b/softmmu/physmem.c @@ -2839,7 +2839,7 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, stn_he_p(buf, l, val); } else { /* RAM case */ - fuzz_dma_read_cb(addr, len, mr, false); + fuzz_dma_read_cb(addr, len, mr); ram_ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false); memcpy(buf, ram_ptr, l); } @@ -3200,7 +3200,7 @@ void *address_space_map(AddressSpace *as, memory_region_ref(mr); *plen = flatview_extend_translation(fv, addr, len, mr, xlat, l, is_write, attrs); - fuzz_dma_read_cb(addr, *plen, mr, is_write); + fuzz_dma_read_cb(addr, *plen, mr); ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true); return ptr; diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c index be76d47d2d..deb74f15be 100644 --- a/tests/qtest/fuzz/generic_fuzz.c +++ b/tests/qtest/fuzz/generic_fuzz.c @@ -175,7 +175,7 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) * generic_fuzz(), avoiding potential race-conditions, which we don't have * a good way for reproducing right now. */ -void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write) +void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr) { /* Are we in the generic-fuzzer or are we using another fuzz-target? */ if (!qts_global) { @@ -187,14 +187,11 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write) * - We have no DMA patterns defined * - The length of the DMA read request is zero * - The DMA read is hitting an MR other than the machine's main RAM - * - The DMA request is not a read (what happens for a address_space_map - * with is_write=True? Can the device use the same pointer to do reads?) * - The DMA request hits past the bounds of our RAM */ if (dma_patterns->len == 0 || len == 0 || mr != current_machine->ram - || is_write || addr > current_machine->ram_size) { return; } @@ -213,12 +210,12 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write) double_fetch = true; if (addr < region.addr && avoid_double_fetches) { - fuzz_dma_read_cb(addr, region.addr - addr, mr, is_write); + fuzz_dma_read_cb(addr, region.addr - addr, mr); } if (addr + len > region.addr + region.size && avoid_double_fetches) { fuzz_dma_read_cb(region.addr + region.size, - addr + len - (region.addr + region.size), mr, is_write); + addr + len - (region.addr + region.size), mr); } return; } From d54d9b1d124bcea44293e25f3a45c593d798d2a8 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Wed, 20 Jan 2021 10:22:11 -0500 Subject: [PATCH 02/46] fuzz: refine the ide/ahci fuzzer configs Disks work differently depending on the x86 machine type (SATA vs PATA). Additionally, we should fuzz the atapi code paths, which might contain vulnerabilities such as CVE-2020-29443. This patch adds hard-disk and cdrom generic-fuzzer configs for both the pc (PATA) and q35 (SATA) machine types. Signed-off-by: Alexander Bulekov Acked-by: Thomas Huth Reviewed-by: Darren Kenny Message-Id: <20210120152211.109782-1-alxndr@bu.edu> --- tests/qtest/fuzz/generic_fuzz_configs.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h index 7fed035345..aa4c03f1ae 100644 --- a/tests/qtest/fuzz/generic_fuzz_configs.h +++ b/tests/qtest/fuzz/generic_fuzz_configs.h @@ -85,10 +85,28 @@ const generic_fuzz_config predefined_configs[] = { .objects = "intel-hda", },{ .name = "ide-hd", + .args = "-machine pc -nodefaults " + "-drive file=null-co://,if=none,format=raw,id=disk0 " + "-device ide-hd,drive=disk0", + .objects = "*ide*", + },{ + .name = "ide-atapi", + .args = "-machine pc -nodefaults " + "-drive file=null-co://,if=none,format=raw,id=disk0 " + "-device ide-cd,drive=disk0", + .objects = "*ide*", + },{ + .name = "ahci-hd", .args = "-machine q35 -nodefaults " "-drive file=null-co://,if=none,format=raw,id=disk0 " "-device ide-hd,drive=disk0", - .objects = "ahci*", + .objects = "*ahci*", + },{ + .name = "ahci-atapi", + .args = "-machine q35 -nodefaults " + "-drive file=null-co://,if=none,format=raw,id=disk0 " + "-device ide-cd,drive=disk0", + .objects = "*ahci*", },{ .name = "floppy", .args = "-machine pc -nodefaults -device floppy,id=floppy0 " From 92381157dd74c27b028d4a8e9349488e55b4c22d Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Sun, 17 Jan 2021 15:10:13 -0500 Subject: [PATCH 03/46] docs/fuzz: fix pre-meson path Signed-off-by: Alexander Bulekov Reviewed-by: Thomas Huth Message-Id: <20210117201014.271610-2-alxndr@bu.edu> --- docs/devel/fuzzing.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/devel/fuzzing.rst b/docs/devel/fuzzing.rst index 6096242d99..5f5200c843 100644 --- a/docs/devel/fuzzing.rst +++ b/docs/devel/fuzzing.rst @@ -119,7 +119,7 @@ Adding a new fuzzer Coverage over virtual devices can be improved by adding additional fuzzers. Fuzzers are kept in ``tests/qtest/fuzz/`` and should be added to -``tests/qtest/fuzz/Makefile.include`` +``tests/qtest/fuzz/meson.build`` Fuzzers can rely on both qtest and libqos to communicate with virtual devices. @@ -128,8 +128,7 @@ Fuzzers can rely on both qtest and libqos to communicate with virtual devices. 2. Write the fuzzing code using the libqtest/libqos API. See existing fuzzers for reference. -3. Register the fuzzer in ``tests/fuzz/Makefile.include`` by appending the - corresponding object to fuzz-obj-y +3. Add the fuzzer to ``tests/qtest/fuzz/meson.build``. Fuzzers can be more-or-less thought of as special qtest programs which can modify the qtest commands and/or qtest command arguments based on inputs From 61f90e0461984438ddd5064d1c03133f561dc848 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Sun, 17 Jan 2021 15:10:14 -0500 Subject: [PATCH 04/46] fuzz: log the arguments used to initialize QEMU This is useful for building reproducers. Instead checking the code or the QEMU_FUZZ_ARGS, the arguments are at the top of the crash log. Signed-off-by: Alexander Bulekov Reviewed-by: Thomas Huth Message-Id: <20210117201014.271610-3-alxndr@bu.edu> --- tests/qtest/fuzz/fuzz.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c index 238866a037..496d11a231 100644 --- a/tests/qtest/fuzz/fuzz.c +++ b/tests/qtest/fuzz/fuzz.c @@ -159,6 +159,8 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp) char *target_name; const char *bindir; char *datadir; + GString *cmd_line; + gchar *pretty_cmd_line; bool serialize = false; /* Initialize qgraph and modules */ @@ -217,7 +219,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp) } /* Run QEMU's softmmu main with the fuzz-target dependent arguments */ - GString *cmd_line = fuzz_target->get_init_cmdline(fuzz_target); + cmd_line = fuzz_target->get_init_cmdline(fuzz_target); g_string_append_printf(cmd_line, " %s -qtest /dev/null ", getenv("QTEST_LOG") ? "" : "-qtest-log none"); @@ -226,6 +228,13 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp) wordexp(cmd_line->str, &result, 0); g_string_free(cmd_line, true); + if (getenv("QTEST_LOG")) { + pretty_cmd_line = g_strjoinv(" ", result.we_wordv + 1); + printf("Starting %s with Arguments: %s\n", + result.we_wordv[0], pretty_cmd_line); + g_free(pretty_cmd_line); + } + qemu_init(result.we_wordc, result.we_wordv, NULL); /* re-enable the rcu atfork, which was previously disabled in qemu_init */ From 8630b43f115d9736cbe9782f453a300ac3ba5af5 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Sun, 17 Jan 2021 18:09:22 -0500 Subject: [PATCH 05/46] fuzz: enable dynamic args for generic-fuzz configs For some device configurations, it is useful to configure some resources, and adjust QEMU arguments at runtime, prior to fuzzing. This patch adds an "argfunc" to generic the generic_fuzz_config. When specified, it is responsible for configuring the resources and returning a string containing the corresponding QEMU arguments. This can be useful for targets that rely on e.g.: * a temporary qcow2 image * a temporary directory * an unused TCP port used to bind the VNC server Signed-off-by: Alexander Bulekov Reviewed-by: Thomas Huth Message-Id: <20210117230924.449676-2-alxndr@bu.edu> --- tests/qtest/fuzz/generic_fuzz.c | 10 +++++++++- tests/qtest/fuzz/generic_fuzz_configs.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c index deb74f15be..ee8c17a04c 100644 --- a/tests/qtest/fuzz/generic_fuzz.c +++ b/tests/qtest/fuzz/generic_fuzz.c @@ -933,12 +933,20 @@ static GString *generic_fuzz_cmdline(FuzzTarget *t) static GString *generic_fuzz_predefined_config_cmdline(FuzzTarget *t) { + gchar *args; const generic_fuzz_config *config; g_assert(t->opaque); config = t->opaque; setenv("QEMU_AVOID_DOUBLE_FETCH", "1", 1); - setenv("QEMU_FUZZ_ARGS", config->args, 1); + if (config->argfunc) { + args = config->argfunc(); + setenv("QEMU_FUZZ_ARGS", args, 1); + g_free(args); + } else { + g_assert_nonnull(config->args); + setenv("QEMU_FUZZ_ARGS", config->args, 1); + } setenv("QEMU_FUZZ_OBJECTS", config->objects, 1); return generic_fuzz_cmdline(t); } diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h index aa4c03f1ae..51e69c6e42 100644 --- a/tests/qtest/fuzz/generic_fuzz_configs.h +++ b/tests/qtest/fuzz/generic_fuzz_configs.h @@ -16,6 +16,7 @@ typedef struct generic_fuzz_config { const char *name, *args, *objects; + gchar* (*argfunc)(void); /* Result must be freeable by g_free() */ } generic_fuzz_config; const generic_fuzz_config predefined_configs[] = { From 3ca45fb4d26ba92e55f1dda651829fe46ab8f863 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Sun, 17 Jan 2021 18:09:23 -0500 Subject: [PATCH 06/46] docs/fuzz: add some information about OSS-Fuzz Signed-off-by: Alexander Bulekov Reviewed-by: Darren Kenny Message-Id: <20210117230924.449676-3-alxndr@bu.edu> --- docs/devel/fuzzing.rst | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/devel/fuzzing.rst b/docs/devel/fuzzing.rst index 5f5200c843..97797c4f8c 100644 --- a/docs/devel/fuzzing.rst +++ b/docs/devel/fuzzing.rst @@ -180,6 +180,36 @@ To ensure that these env variables have been configured correctly, we can use:: The output should contain a complete list of matched MemoryRegions. +OSS-Fuzz +-------- +QEMU is continuously fuzzed on `OSS-Fuzz` __(https://github.com/google/oss-fuzz). +By default, the OSS-Fuzz build will try to fuzz every fuzz-target. Since the +generic-fuzz target requires additional information provided in environment +variables, we pre-define some generic-fuzz configs in +``tests/qtest/fuzz/generic_fuzz_configs.h``. Each config must specify: + +- ``.name``: To identify the fuzzer config + +- ``.args`` OR ``.argfunc``: A string or pointer to a function returning a + string. These strings are used to specify the ``QEMU_FUZZ_ARGS`` + environment variable. ``argfunc`` is useful when the config relies on e.g. + a dynamically created temp directory, or a free tcp/udp port. + +- ``.objects``: A string that specifies the ``QEMU_FUZZ_OBJECTS`` environment + variable. + +To fuzz additional devices/device configuration on OSS-Fuzz, send patches for +either a new device-specific fuzzer or a new generic-fuzz config. + +Build details: + +- The Dockerfile that sets up the environment for building QEMU's + fuzzers on OSS-Fuzz can be fund in the OSS-Fuzz repository + __(https://github.com/google/oss-fuzz/blob/master/projects/qemu/Dockerfile) + +- The script responsible for building the fuzzers can be found in the + QEMU source tree at ``scripts/oss-fuzz/build.sh`` + Implementation Details / Fuzzer Lifecycle ----------------------------------------- From fff7111fb90e93b148b2196175fd656b2bfea4cd Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Sun, 17 Jan 2021 18:09:24 -0500 Subject: [PATCH 07/46] fuzz: add virtio-9p configurations for fuzzing virtio-9p devices are often used to expose a virtual-filesystem to the guest. There have been some bugs reported in this device, such as CVE-2018-19364, and CVE-2021-20181. We should fuzz this device This patch adds two virtio-9p configurations: * One with the widely used -fsdev local driver. This driver leaks some state in the form of files/directories created in the shared dir. * One with the synth driver. While it is not used in the real world, this driver won't leak leak state between fuzz inputs. Signed-off-by: Alexander Bulekov Reviewed-by: Darren Kenny Message-Id: <20210117230924.449676-4-alxndr@bu.edu> --- tests/qtest/fuzz/generic_fuzz_configs.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h index 51e69c6e42..5d599765c4 100644 --- a/tests/qtest/fuzz/generic_fuzz_configs.h +++ b/tests/qtest/fuzz/generic_fuzz_configs.h @@ -19,6 +19,16 @@ typedef struct generic_fuzz_config { gchar* (*argfunc)(void); /* Result must be freeable by g_free() */ } generic_fuzz_config; +static inline gchar *generic_fuzzer_virtio_9p_args(void){ + char tmpdir[] = "/tmp/qemu-fuzz.XXXXXX"; + g_assert_nonnull(mkdtemp(tmpdir)); + + return g_strdup_printf("-machine q35 -nodefaults " + "-device virtio-9p,fsdev=hshare,mount_tag=hshare " + "-fsdev local,id=hshare,path=%s,security_model=mapped-xattr," + "writeout=immediate,fmode=0600,dmode=0700", tmpdir); +} + const generic_fuzz_config predefined_configs[] = { { .name = "virtio-net-pci-slirp", @@ -60,6 +70,16 @@ const generic_fuzz_config predefined_configs[] = { .name = "virtio-mouse", .args = "-machine q35 -nodefaults -device virtio-mouse", .objects = "virtio*", + },{ + .name = "virtio-9p", + .argfunc = generic_fuzzer_virtio_9p_args, + .objects = "virtio*", + },{ + .name = "virtio-9p-synth", + .args = "-machine q35 -nodefaults " + "-device virtio-9p,fsdev=hshare,mount_tag=hshare " + "-fsdev synth,id=hshare", + .objects = "virtio*", },{ .name = "e1000", .args = "-M q35 -nodefaults " From 5ea9e9e239db83391a39c09f1de63c4099c20df5 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 25 Jan 2021 23:04:01 +0100 Subject: [PATCH 08/46] target/i386: do not set LM for 32-bit emulation "-cpu host/max" 32-bit targets by definition do not support long mode; therefore, the bit must be masked in the features supported by the accelerator. As a side effect, this avoids setting up the 0x80000008 CPUID leaf for qemu-system-i386 -cpu host which since commit 5a140b255d ("x86/cpu: Use max host physical address if -cpu max option is applied") would have printed this error: qemu-system-i386: phys-bits should be between 32 and 36 (but is 48) Reported-by: Nathan Chancellor Tested-by: Nathan Chancellor Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index ae89024d36..e775e9abb5 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5073,6 +5073,11 @@ static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, } else { return ~0; } +#ifndef TARGET_X86_64 + if (w == FEAT_8000_0001_EDX) { + r &= ~CPUID_EXT2_LM; + } +#endif if (migratable_only) { r &= x86_cpu_get_migratable_flags(w); } From 8db0b20415c129cf5e577a593a4a0372d90b7cc9 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Thu, 21 Jan 2021 11:15:04 -0500 Subject: [PATCH 09/46] machine: add missing doc for memory-backend option Add documentation for '-machine memory-backend' CLI option and how to use it. And document that x-use-canonical-path-for-ramblock-id, is considered to be stable to make sure it won't go away by accident. x- was intended for unstable/iternal properties, and not supposed to be stable option. However it's too late to rename (drop x-) it as it would mean that users will have to mantain both x-use-canonical-path-for-ramblock-id (for QEMU 5.0-5.2) versions and prefix-less for later versions. Signed-off-by: Igor Mammedov Message-Id: <20210121161504.1007247-1-imammedo@redhat.com> Signed-off-by: Paolo Bonzini --- backends/hostmem.c | 10 ++++++++++ qemu-options.hx | 26 +++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/backends/hostmem.c b/backends/hostmem.c index be0c3b079f..c6c1ff5b99 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -494,6 +494,16 @@ host_memory_backend_class_init(ObjectClass *oc, void *data) host_memory_backend_get_share, host_memory_backend_set_share); object_class_property_set_description(oc, "share", "Mark the memory as private to QEMU or shared"); + /* + * Do not delete/rename option. This option must be considered stable + * (as if it didn't have the 'x-' prefix including deprecation period) as + * long as 4.0 and older machine types exists. + * Option will be used by upper layers to override (disable) canonical path + * for ramblock-id set by compat properties on old machine types ( <= 4.0), + * to keep migration working when backend is used for main RAM with + * -machine memory-backend= option (main RAM historically used prefix-less + * ramblock-id). + */ object_class_property_add_bool(oc, "x-use-canonical-path-for-ramblock-id", host_memory_backend_get_use_canonical_path, host_memory_backend_set_use_canonical_path); diff --git a/qemu-options.hx b/qemu-options.hx index c09c4646e2..6c34c7050f 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -35,7 +35,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ " suppress-vmdesc=on|off disables self-describing migration (default=off)\n" " nvdimm=on|off controls NVDIMM support (default=off)\n" " memory-encryption=@var{} memory encryption object to use (default=none)\n" - " hmat=on|off controls ACPI HMAT support (default=off)\n", + " hmat=on|off controls ACPI HMAT support (default=off)\n" + " memory-backend='backend-id' specifies explicitly provided backend for main RAM (default=none)\n", QEMU_ARCH_ALL) SRST ``-machine [type=]name[,prop=value[,...]]`` @@ -96,6 +97,29 @@ SRST ``hmat=on|off`` Enables or disables ACPI Heterogeneous Memory Attribute Table (HMAT) support. The default is off. + + ``memory-backend='id'`` + An alternative to legacy ``-mem-path`` and ``mem-prealloc`` options. + Allows to use a memory backend as main RAM. + + For example: + :: + -object memory-backend-file,id=pc.ram,size=512M,mem-path=/hugetlbfs,prealloc=on,share=on + -machine memory-backend=pc.ram + -m 512M + + Migration compatibility note: + a) as backend id one shall use value of 'default-ram-id', advertised by + machine type (available via ``query-machines`` QMP command), if migration + to/from old QEMU (<5.0) is expected. + b) for machine types 4.0 and older, user shall + use ``x-use-canonical-path-for-ramblock-id=off`` backend option + if migration to/from old QEMU (<5.0) is expected. + For example: + :: + -object memory-backend-ram,id=pc.ram,size=512M,x-use-canonical-path-for-ramblock-id=off + -machine memory-backend=pc.ram + -m 512M ERST HXCOMM Deprecated by -machine From d7dedf428fefccc662f367745c21c0041f30a1d6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 26 Jan 2021 11:15:33 +0100 Subject: [PATCH 10/46] meson: accept either shared or static libraries if --disable-static Meson's "static" argument to cc.find_library is a tri-state. By default Meson *prefers* a shared library, which basically means using -l to look for it; instead, "static: false" *requires* a shared library. Of course, "static: true" requires a static library, which is all good for --enable-static builds. For --disable-static, "static: false" is rarely desirable; it does not match what the configure script used to do and the test is more complex (and harder to debug if it fails, which was reported by Peter Lieven for librbd). Reported-by: Peter Lieven Tested-by: Peter Lieven Signed-off-by: Paolo Bonzini --- docs/devel/build-system.rst | 2 +- meson.build | 79 +++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst index 31f4dced2a..69ce3087e3 100644 --- a/docs/devel/build-system.rst +++ b/docs/devel/build-system.rst @@ -100,7 +100,7 @@ In meson.build:: # Detect dependency sdl_image = dependency('SDL2_image', required: get_option('sdl_image'), method: 'pkg-config', - static: enable_static) + kwargs: static_kwargs) # Create config-host.h (if applicable) config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) diff --git a/meson.build b/meson.build index 2d8b433ff0..6d6537d74a 100644 --- a/meson.build +++ b/meson.build @@ -18,6 +18,9 @@ config_host = keyval.load(meson.current_build_dir() / 'config-host.mak') enable_modules = 'CONFIG_MODULES' in config_host enable_static = 'CONFIG_STATIC' in config_host +# Allow both shared and static libraries unless --enable-static +static_kwargs = enable_static ? {'static': true} : {} + # Temporary directory used for files created while # configure runs. Since it is in the build directory # we can safely blow away any previous version of it @@ -311,14 +314,14 @@ endif pixman = not_found if have_system or have_tools pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8', - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) endif pam = not_found if 'CONFIG_AUTH_PAM' in config_host pam = cc.find_library('pam') endif libaio = cc.find_library('aio', required: false) -zlib = dependency('zlib', required: true, static: enable_static) +zlib = dependency('zlib', required: true, kwargs: static_kwargs) linux_io_uring = not_found if 'CONFIG_LINUX_IO_URING' in config_host linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(), @@ -333,7 +336,7 @@ libnfs = not_found if not get_option('libnfs').auto() or have_block libnfs = dependency('libnfs', version: '>=1.9.3', required: get_option('libnfs'), - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) endif libattr_test = ''' @@ -354,7 +357,7 @@ if not get_option('attr').disabled() else libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'], required: get_option('attr'), - static: enable_static) + kwargs: static_kwargs) if libattr.found() and not \ cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR') libattr = not_found @@ -381,14 +384,14 @@ seccomp = not_found if not get_option('seccomp').auto() or have_system or have_tools seccomp = dependency('libseccomp', version: '>=2.3.0', required: get_option('seccomp'), - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) endif libcap_ng = not_found if not get_option('cap_ng').auto() or have_system or have_tools libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'], required: get_option('cap_ng'), - static: enable_static) + kwargs: static_kwargs) endif if libcap_ng.found() and not cc.links(''' #include @@ -409,7 +412,7 @@ if get_option('xkbcommon').auto() and not have_system and not have_tools xkbcommon = not_found else xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'), - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) endif vde = not_found if config_host.has_key('CONFIG_VDE') @@ -445,13 +448,13 @@ libiscsi = not_found if not get_option('libiscsi').auto() or have_block libiscsi = dependency('libiscsi', version: '>=1.9.0', required: get_option('libiscsi'), - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) endif zstd = not_found if not get_option('zstd').auto() or have_block zstd = dependency('libzstd', version: '>=1.4.0', required: get_option('zstd'), - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) endif gbm = not_found if 'CONFIG_GBM' in config_host @@ -468,14 +471,14 @@ if not get_option('curl').auto() or have_block curl = dependency('libcurl', version: '>=7.29.0', method: 'pkg-config', required: get_option('curl'), - static: enable_static) + kwargs: static_kwargs) endif libudev = not_found if targetos == 'linux' and (have_system or have_tools) libudev = dependency('libudev', method: 'pkg-config', required: get_option('libudev'), - static: enable_static) + kwargs: static_kwargs) endif mpathlibs = [libudev] @@ -511,17 +514,17 @@ if targetos == 'linux' and have_tools and not get_option('mpath').disabled() }''' libmpathpersist = cc.find_library('mpathpersist', required: get_option('mpath'), - static: enable_static) + kwargs: static_kwargs) if libmpathpersist.found() mpathlibs += libmpathpersist if enable_static mpathlibs += cc.find_library('devmapper', required: get_option('mpath'), - static: enable_static) + kwargs: static_kwargs) endif mpathlibs += cc.find_library('multipath', required: get_option('mpath'), - static: enable_static) + kwargs: static_kwargs) foreach lib: mpathlibs if not lib.found() mpathlibs = [] @@ -571,7 +574,7 @@ if have_system and not get_option('curses').disabled() curses = dependency(curses_dep, required: false, method: 'pkg-config', - static: enable_static) + kwargs: static_kwargs) endif endforeach msg = get_option('curses').enabled() ? 'curses library not found' : '' @@ -596,7 +599,7 @@ if have_system and not get_option('curses').disabled() foreach curses_libname : curses_libname_list libcurses = cc.find_library(curses_libname, required: false, - static: enable_static) + kwargs: static_kwargs) if libcurses.found() if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses) curses = declare_dependency(compile_args: curses_compile_args, @@ -647,7 +650,7 @@ brlapi = not_found if not get_option('brlapi').auto() or have_system brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'], required: get_option('brlapi'), - static: enable_static) + kwargs: static_kwargs) if brlapi.found() and not cc.links(''' #include #include @@ -663,7 +666,7 @@ endif sdl = not_found if not get_option('sdl').auto() or (have_system and not cocoa.found()) - sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static) + sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs) sdl_image = not_found endif if sdl.found() @@ -671,7 +674,7 @@ if sdl.found() sdl = declare_dependency(compile_args: '-Wno-undef', dependencies: sdl) sdl_image = dependency('SDL2_image', required: get_option('sdl_image'), - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) else if get_option('sdl_image').enabled() error('sdl-image required, but SDL was @0@'.format( @@ -683,10 +686,10 @@ endif rbd = not_found if not get_option('rbd').auto() or have_block librados = cc.find_library('rados', required: get_option('rbd'), - static: enable_static) + kwargs: static_kwargs) librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'], required: get_option('rbd'), - static: enable_static) + kwargs: static_kwargs) if librados.found() and librbd.found() and cc.links(''' #include #include @@ -705,7 +708,7 @@ glusterfs_iocb_has_stat = false if not get_option('glusterfs').auto() or have_block glusterfs = dependency('glusterfs-api', version: '>=3', required: get_option('glusterfs'), - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) if glusterfs.found() glusterfs_ftruncate_has_stat = cc.links(''' #include @@ -744,7 +747,7 @@ libbzip2 = not_found if not get_option('bzip2').auto() or have_block libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'], required: get_option('bzip2'), - static: enable_static) + kwargs: static_kwargs) if libbzip2.found() and not cc.links(''' #include int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2) @@ -761,7 +764,7 @@ liblzfse = not_found if not get_option('lzfse').auto() or have_block liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'], required: get_option('lzfse'), - static: enable_static) + kwargs: static_kwargs) endif if liblzfse.found() and not cc.links(''' #include @@ -798,12 +801,12 @@ if not get_option('gtk').auto() or (have_system and not cocoa.found()) gtk = dependency('gtk+-3.0', version: '>=3.22.0', method: 'pkg-config', required: get_option('gtk'), - static: enable_static) + kwargs: static_kwargs) if gtk.found() gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0', method: 'pkg-config', required: false, - static: enable_static) + kwargs: static_kwargs) gtk = declare_dependency(dependencies: [gtk, gtkx11]) endif endif @@ -816,7 +819,7 @@ endif x11 = not_found if gtkx11.found() or 'lm32-softmmu' in target_dirs x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(), - static: enable_static) + kwargs: static_kwargs) endif vnc = not_found png = not_found @@ -825,12 +828,12 @@ sasl = not_found if get_option('vnc').enabled() vnc = declare_dependency() # dummy dependency png = dependency('libpng', required: get_option('vnc_png'), - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'), - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'], required: get_option('vnc_sasl'), - static: enable_static) + kwargs: static_kwargs) if sasl.found() sasl = declare_dependency(dependencies: sasl, compile_args: '-DSTRUCT_IOVEC_DEFINED') @@ -841,7 +844,7 @@ snappy = not_found if not get_option('snappy').auto() or have_system snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'], required: get_option('snappy'), - static: enable_static) + kwargs: static_kwargs) endif if snappy.found() and not cc.links(''' #include @@ -858,7 +861,7 @@ lzo = not_found if not get_option('lzo').auto() or have_system lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'], required: get_option('lzo'), - static: enable_static) + kwargs: static_kwargs) endif if lzo.found() and not cc.links(''' #include @@ -893,7 +896,7 @@ u2f = not_found if have_system u2f = dependency('u2f-emu', required: get_option('u2f'), method: 'pkg-config', - static: enable_static) + kwargs: static_kwargs) endif usbredir = not_found if 'CONFIG_USB_REDIR' in config_host @@ -920,7 +923,7 @@ if 'CONFIG_TASN1' in config_host link_args: config_host['TASN1_LIBS'].split()) endif keyutils = dependency('libkeyutils', required: false, - method: 'pkg-config', static: enable_static) + method: 'pkg-config', kwargs: static_kwargs) has_gettid = cc.has_function('gettid') @@ -979,7 +982,7 @@ endif fuse = dependency('fuse3', required: get_option('fuse'), version: '>=3.1', method: 'pkg-config', - static: enable_static) + kwargs: static_kwargs) fuse_lseek = not_found if not get_option('fuse_lseek').disabled() @@ -1367,7 +1370,7 @@ capstone_opt = get_option('capstone') if capstone_opt in ['enabled', 'auto', 'system'] have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile') capstone = dependency('capstone', version: '>=4.0', - static: enable_static, method: 'pkg-config', + kwargs: static_kwargs, method: 'pkg-config', required: capstone_opt == 'system' or capstone_opt == 'enabled' and not have_internal) if capstone.found() @@ -1477,7 +1480,7 @@ if have_system slirp_opt = get_option('slirp') if slirp_opt in ['enabled', 'auto', 'system'] have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build') - slirp = dependency('slirp', static: enable_static, + slirp = dependency('slirp', kwargs: static_kwargs, method: 'pkg-config', required: slirp_opt == 'system' or slirp_opt == 'enabled' and not have_internal) @@ -1556,7 +1559,7 @@ fdt_opt = get_option('fdt') if have_system if fdt_opt in ['enabled', 'auto', 'system'] have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt') - fdt = cc.find_library('fdt', static: enable_static, + fdt = cc.find_library('fdt', kwargs: static_kwargs, required: fdt_opt == 'system' or fdt_opt == 'enabled' and not have_internal) if fdt.found() and cc.links(''' From c518d6c2bffdef9d98177dba7f25d5cb4193822e Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 26 Jan 2021 11:20:35 +0100 Subject: [PATCH 11/46] meson: honor --enable-rbd if cc.links test fails If the link test failed, compilation proceeded with RBD disabled, even if --enable-rbd was used on the configure command line. Fix that. Signed-off-by: Paolo Bonzini --- meson.build | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/meson.build b/meson.build index 6d6537d74a..5bd22f431a 100644 --- a/meson.build +++ b/meson.build @@ -690,15 +690,21 @@ if not get_option('rbd').auto() or have_block librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'], required: get_option('rbd'), kwargs: static_kwargs) - if librados.found() and librbd.found() and cc.links(''' - #include - #include - int main(void) { - rados_t cluster; - rados_create(&cluster, NULL); - return 0; - }''', dependencies: [librbd, librados]) - rbd = declare_dependency(dependencies: [librbd, librados]) + if librados.found() and librbd.found() + if cc.links(''' + #include + #include + int main(void) { + rados_t cluster; + rados_create(&cluster, NULL); + return 0; + }''', dependencies: [librbd, librados]) + rbd = declare_dependency(dependencies: [librbd, librados]) + elif get_option('rbd').enabled() + error('could not link librados') + else + warning('could not link librados, disabling') + endif endif endif From 5447089c2b3b084b51670af36fc86ee3979e04be Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Tue, 26 Jan 2021 14:24:56 -0600 Subject: [PATCH 12/46] x86/cpu: Populate SVM CPUID feature bits Newer AMD CPUs will add CPUID_0x8000000A_EDX[28] bit, which indicates that SVM instructions (VMRUN/VMSAVE/VMLOAD) will trigger #VMEXIT before CPU checking their EAX against reserved memory regions. This change will allow the hypervisor to avoid intercepting #GP and emulating SVM instructions. KVM turns on this CPUID bit for nested VMs. In order to support it, let us populate this bit, along with other SVM feature bits, in FEAT_SVM. Signed-off-by: Wei Huang Message-Id: <20210126202456.589932-1-wei.huang2@amd.com> Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 6 +++--- target/i386/cpu.h | 24 ++++++++++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index e775e9abb5..ff25ad6f6c 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -926,11 +926,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { "npt", "lbrv", "svm-lock", "nrip-save", "tsc-scale", "vmcb-clean", "flushbyasid", "decodeassists", NULL, NULL, "pause-filter", NULL, - "pfthreshold", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, + "pfthreshold", "avic", NULL, "v-vmsave-vmload", + "vgif", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "svme-addr-chk", NULL, NULL, NULL, }, .cpuid = { .eax = 0x8000000A, .reg = R_EDX, }, .tcg_features = TCG_SVM_FEATURES, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index d23a5b340a..b39ec505de 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -670,16 +670,20 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_EXT3_PERFCORE (1U << 23) #define CPUID_EXT3_PERFNB (1U << 24) -#define CPUID_SVM_NPT (1U << 0) -#define CPUID_SVM_LBRV (1U << 1) -#define CPUID_SVM_SVMLOCK (1U << 2) -#define CPUID_SVM_NRIPSAVE (1U << 3) -#define CPUID_SVM_TSCSCALE (1U << 4) -#define CPUID_SVM_VMCBCLEAN (1U << 5) -#define CPUID_SVM_FLUSHASID (1U << 6) -#define CPUID_SVM_DECODEASSIST (1U << 7) -#define CPUID_SVM_PAUSEFILTER (1U << 10) -#define CPUID_SVM_PFTHRESHOLD (1U << 12) +#define CPUID_SVM_NPT (1U << 0) +#define CPUID_SVM_LBRV (1U << 1) +#define CPUID_SVM_SVMLOCK (1U << 2) +#define CPUID_SVM_NRIPSAVE (1U << 3) +#define CPUID_SVM_TSCSCALE (1U << 4) +#define CPUID_SVM_VMCBCLEAN (1U << 5) +#define CPUID_SVM_FLUSHASID (1U << 6) +#define CPUID_SVM_DECODEASSIST (1U << 7) +#define CPUID_SVM_PAUSEFILTER (1U << 10) +#define CPUID_SVM_PFTHRESHOLD (1U << 12) +#define CPUID_SVM_AVIC (1U << 13) +#define CPUID_SVM_V_VMSAVE_VMLOAD (1U << 15) +#define CPUID_SVM_VGIF (1U << 16) +#define CPUID_SVM_SVME_ADDR_CHK (1U << 28) /* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */ #define CPUID_7_0_EBX_FSGSBASE (1U << 0) From 487a1d13baf46dd72b95f8919d6d40e938fd25c3 Mon Sep 17 00:00:00 2001 From: Qiuhao Li Date: Thu, 28 Jan 2021 11:59:28 +0800 Subject: [PATCH 13/46] fuzz: fix wrong index in clear_bits Signed-off-by: Qiuhao Li Message-Id: Signed-off-by: Paolo Bonzini --- scripts/oss-fuzz/minimize_qtest_trace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/oss-fuzz/minimize_qtest_trace.py b/scripts/oss-fuzz/minimize_qtest_trace.py index 4cba96dee2..20825768c2 100755 --- a/scripts/oss-fuzz/minimize_qtest_trace.py +++ b/scripts/oss-fuzz/minimize_qtest_trace.py @@ -261,7 +261,7 @@ def clear_bits(newtrace, outpath): data_try = hex(int("".join(data_bin_list), 2)) # It seems qtest only accepts padded hex-values. if len(data_try) % 2 == 1: - data_try = data_try[:2] + "0" + data_try[2:-1] + data_try = data_try[:2] + "0" + data_try[2:] newtrace[i] = "{prefix} {data_try}\n".format( prefix=prefix, From e0f7fc588d735f23b36fdaf16b6c81f804348cb0 Mon Sep 17 00:00:00 2001 From: Stefan Reiter Date: Thu, 28 Jan 2021 15:58:01 +0100 Subject: [PATCH 14/46] docs: don't install corresponding man page if guest agent is disabled No sense outputting the qemu-ga and qemu-ga-ref man pages when the guest agent binary itself is disabled. This mirrors behaviour from before the meson switch. Signed-off-by: Stefan Reiter Message-Id: <20210128145801.14384-1-s.reiter@proxmox.com> Signed-off-by: Paolo Bonzini --- docs/meson.build | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/meson.build b/docs/meson.build index bb14eaebd3..f84306ba7e 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -46,9 +46,11 @@ if build_docs meson.source_root() / 'docs/sphinx/qmp_lexer.py', qapi_gen_depends ] + have_ga = have_tools and config_host.has_key('CONFIG_GUEST_AGENT') + man_pages = { - 'qemu-ga.8': (have_tools ? 'man8' : ''), - 'qemu-ga-ref.7': 'man7', + 'qemu-ga.8': (have_ga ? 'man8' : ''), + 'qemu-ga-ref.7': (have_ga ? 'man7' : ''), 'qemu-qmp-ref.7': 'man7', 'qemu-storage-daemon-qmp-ref.7': (have_tools ? 'man7' : ''), 'qemu-img.1': (have_tools ? 'man1' : ''), From dec2bb14b8c4824c4d1da9df91b4dbe1bd89cf04 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Thu, 17 Dec 2020 17:00:39 +0200 Subject: [PATCH 15/46] virtio-scsi: don't uninitialize queues that we didn't initialize Count number of queues that we initialized and only deinitialize these that we initialized successfully. Signed-off-by: Maxim Levitsky Message-Id: <20201217150040.906961-3-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini --- hw/scsi/virtio-scsi-dataplane.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index b995bab3a2..2c83a0ab1f 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -126,6 +126,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev) { int i; int rc; + int vq_init_count = 0; BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); @@ -153,17 +154,22 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev) if (rc) { goto fail_vrings; } + + vq_init_count++; rc = virtio_scsi_vring_init(s, vs->event_vq, 1, virtio_scsi_data_plane_handle_event); if (rc) { goto fail_vrings; } + + vq_init_count++; for (i = 0; i < vs->conf.num_queues; i++) { rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2, virtio_scsi_data_plane_handle_cmd); if (rc) { goto fail_vrings; } + vq_init_count++; } s->dataplane_starting = false; @@ -174,7 +180,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev) fail_vrings: aio_wait_bh_oneshot(s->ctx, virtio_scsi_dataplane_stop_bh, s); aio_context_release(s->ctx); - for (i = 0; i < vs->conf.num_queues + 2; i++) { + for (i = 0; i < vq_init_count; i++) { virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false); virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i); } From e34e47eb28c0b8119be2e958450763701b38ac3a Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Thu, 17 Dec 2020 17:00:40 +0200 Subject: [PATCH 16/46] event_notifier: handle initialization failure better Add 'initialized' field and use it to avoid touching event notifiers which are either not initialized or if their initialization failed. This is somewhat a hack, but it seems the less intrusive way to make virtio code deal with event notifiers that failed initialization. Signed-off-by: Maxim Levitsky Message-Id: <20201217150040.906961-4-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini --- include/qemu/event_notifier.h | 1 + util/event_notifier-posix.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/qemu/event_notifier.h b/include/qemu/event_notifier.h index 3380b662f3..b79add035d 100644 --- a/include/qemu/event_notifier.h +++ b/include/qemu/event_notifier.h @@ -24,6 +24,7 @@ struct EventNotifier { #else int rfd; int wfd; + bool initialized; #endif }; diff --git a/util/event_notifier-posix.c b/util/event_notifier-posix.c index 00d93204f9..5b2110e861 100644 --- a/util/event_notifier-posix.c +++ b/util/event_notifier-posix.c @@ -29,6 +29,7 @@ void event_notifier_init_fd(EventNotifier *e, int fd) { e->rfd = fd; e->wfd = fd; + e->initialized = true; } #endif @@ -68,6 +69,7 @@ int event_notifier_init(EventNotifier *e, int active) if (active) { event_notifier_set(e); } + e->initialized = true; return 0; fail: @@ -78,12 +80,18 @@ fail: void event_notifier_cleanup(EventNotifier *e) { + if (!e->initialized) { + return; + } + if (e->rfd != e->wfd) { close(e->rfd); } + e->rfd = -1; close(e->wfd); e->wfd = -1; + e->initialized = false; } int event_notifier_get_fd(const EventNotifier *e) @@ -96,6 +104,10 @@ int event_notifier_set(EventNotifier *e) static const uint64_t value = 1; ssize_t ret; + if (!e->initialized) { + return -1; + } + do { ret = write(e->wfd, &value, sizeof(value)); } while (ret < 0 && errno == EINTR); @@ -113,6 +125,10 @@ int event_notifier_test_and_clear(EventNotifier *e) ssize_t len; char buffer[512]; + if (!e->initialized) { + return 0; + } + /* Drain the notify pipe. For eventfd, only 8 bytes will be read. */ value = 0; do { From 51909241d26fe6fe18a08def93ccc8273f61a8b3 Mon Sep 17 00:00:00 2001 From: David Greenaway Date: Thu, 14 Jan 2021 17:39:58 +1100 Subject: [PATCH 17/46] target/i386: Fix decoding of certain BMI instructions This patch fixes a translation bug for a subset of x86 BMI instructions such as the following: c4 e2 f9 f7 c0 shlxq %rax, %rax, %rax Currently, these incorrectly generate an undefined instruction exception when SSE is disabled via CR4, while instructions like "shrxq" work fine. The problem appears to be related to BMI instructions encoded using VEX and with a mandatory prefix of "0x66" (data). Instructions with this data prefix (such as shlxq) are currently rejected. Instructions with other mandatory prefixes (such as shrxq) translate as expected. This patch removes the incorrect check in "gen_sse" that causes the exception to be generated. For the non-BMI cases, the check is redundant: prefixes are already checked at line 3696. Buglink: https://bugs.launchpad.net/qemu/+bug/1748296 Signed-off-by: David Greenaway Message-Id: <20210114063958.1508050-1-dgreenaway@google.com> Signed-off-by: Paolo Bonzini --- target/i386/tcg/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 6a4c31f933..af1faf9342 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -3075,7 +3075,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b, } if (is_xmm && !(s->flags & HF_OSFXSR_MASK) - && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) { + && (b != 0x38 && b != 0x3a)) { goto unknown_op; } if (b == 0x0e) { From e7e7bdababeefff10736c6adf410c66d2f0d46fe Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 27 Jan 2021 09:28:49 +0100 Subject: [PATCH 18/46] target/i86: implement PKS Protection Keys for Supervisor-mode pages is a simple extension of the PKU feature that QEMU already implements. For supervisor-mode pages, protection key restrictions come from a new MSR. The MSR has no XSAVE state associated to it. PKS is only respected in long mode. However, in principle it is possible to set the MSR even outside long mode, and in fact even the XSAVE state for PKRU could be set outside long mode using XRSTOR. So do not limit the migration subsections for PKRU and PKRS to long mode. Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 4 ++-- target/i386/cpu.h | 5 +++++ target/i386/helper.c | 3 +++ target/i386/machine.c | 24 ++++++++++++++++++++---- target/i386/tcg/excp_helper.c | 32 ++++++++++++++++++++------------ target/i386/tcg/misc_helper.c | 14 ++++++++++++++ 6 files changed, 64 insertions(+), 18 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index ff25ad6f6c..0b0d65c21c 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -667,7 +667,7 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, CPUID_7_0_EBX_RDSEED */ #define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \ /* CPUID_7_0_ECX_OSPKE is dynamic */ \ - CPUID_7_0_ECX_LA57) + CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS) #define TCG_7_0_EDX_FEATURES 0 #define TCG_7_1_EAX_FEATURES 0 #define TCG_APM_FEATURES 0 @@ -964,7 +964,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { "la57", NULL, NULL, NULL, NULL, NULL, "rdpid", NULL, NULL, "cldemote", NULL, "movdiri", - "movdir64b", NULL, NULL, NULL, + "movdir64b", NULL, NULL, "pks", }, .cpuid = { .eax = 7, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index b39ec505de..cc5a26f35b 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -247,6 +247,7 @@ typedef enum X86Seg { #define CR4_SMEP_MASK (1U << 20) #define CR4_SMAP_MASK (1U << 21) #define CR4_PKE_MASK (1U << 22) +#define CR4_PKS_MASK (1U << 24) #define DR6_BD (1 << 13) #define DR6_BS (1 << 14) @@ -357,6 +358,7 @@ typedef enum X86Seg { #define MSR_IA32_TSX_CTRL 0x122 #define MSR_IA32_TSCDEADLINE 0x6e0 +#define MSR_IA32_PKRS 0x6e1 #define FEATURE_CONTROL_LOCKED (1<<0) #define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) @@ -772,6 +774,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_ECX_MOVDIRI (1U << 27) /* Move 64 Bytes as Direct Store Instruction */ #define CPUID_7_0_ECX_MOVDIR64B (1U << 28) +/* Protection Keys for Supervisor-mode Pages */ +#define CPUID_7_0_ECX_PKS (1U << 31) /* AVX512 Neural Network Instructions */ #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) @@ -1487,6 +1491,7 @@ typedef struct CPUX86State { uint64_t msr_smi_count; uint32_t pkru; + uint32_t pkrs; uint32_t tsx_ctrl; uint64_t spec_ctrl; diff --git a/target/i386/helper.c b/target/i386/helper.c index 6bb0c53182..618ad1c409 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -194,6 +194,9 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) { new_cr4 &= ~CR4_PKE_MASK; } + if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS)) { + new_cr4 &= ~CR4_PKS_MASK; + } env->cr[4] = new_cr4; env->hflags = hflags; diff --git a/target/i386/machine.c b/target/i386/machine.c index 1614e8c2f8..3768a753af 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -980,7 +980,6 @@ static const VMStateDescription vmstate_umwait = { } }; -#ifdef TARGET_X86_64 static bool pkru_needed(void *opaque) { X86CPU *cpu = opaque; @@ -999,7 +998,25 @@ static const VMStateDescription vmstate_pkru = { VMSTATE_END_OF_LIST() } }; -#endif + +static bool pkrs_needed(void *opaque) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + + return env->pkrs != 0; +} + +static const VMStateDescription vmstate_pkrs = { + .name = "cpu/pkrs", + .version_id = 1, + .minimum_version_id = 1, + .needed = pkrs_needed, + .fields = (VMStateField[]){ + VMSTATE_UINT32(env.pkrs, X86CPU), + VMSTATE_END_OF_LIST() + } +}; static bool tsc_khz_needed(void *opaque) { @@ -1480,9 +1497,8 @@ VMStateDescription vmstate_x86_cpu = { &vmstate_umwait, &vmstate_tsc_khz, &vmstate_msr_smi_count, -#ifdef TARGET_X86_64 &vmstate_pkru, -#endif + &vmstate_pkrs, &vmstate_spec_ctrl, &vmstate_mcg_ext_ctl, &vmstate_msr_intel_pt, diff --git a/target/i386/tcg/excp_helper.c b/target/i386/tcg/excp_helper.c index a0f44431fe..b7d6259e4a 100644 --- a/target/i386/tcg/excp_helper.c +++ b/target/i386/tcg/excp_helper.c @@ -361,6 +361,7 @@ static int handle_mmu_fault(CPUState *cs, vaddr addr, int size, uint64_t rsvd_mask = PG_HI_RSVD_MASK; uint32_t page_offset; target_ulong vaddr; + uint32_t pkr; is_user = mmu_idx == MMU_USER_IDX; #if defined(DEBUG_MMU) @@ -588,21 +589,28 @@ do_check_protect_pse36: !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) { prot |= PAGE_EXEC; } - if ((env->cr[4] & CR4_PKE_MASK) && (env->hflags & HF_LMA_MASK) && - (ptep & PG_USER_MASK) && env->pkru) { - uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT; - uint32_t pkru_ad = (env->pkru >> pk * 2) & 1; - uint32_t pkru_wd = (env->pkru >> pk * 2) & 2; - uint32_t pkru_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - if (pkru_ad) { - pkru_prot &= ~(PAGE_READ | PAGE_WRITE); - } else if (pkru_wd && (is_user || env->cr[0] & CR0_WP_MASK)) { - pkru_prot &= ~PAGE_WRITE; + if (!(env->hflags & HF_LMA_MASK)) { + pkr = 0; + } else if (ptep & PG_USER_MASK) { + pkr = env->cr[4] & CR4_PKE_MASK ? env->pkru : 0; + } else { + pkr = env->cr[4] & CR4_PKS_MASK ? env->pkrs : 0; + } + if (pkr) { + uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT; + uint32_t pkr_ad = (pkr >> pk * 2) & 1; + uint32_t pkr_wd = (pkr >> pk * 2) & 2; + uint32_t pkr_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + + if (pkr_ad) { + pkr_prot &= ~(PAGE_READ | PAGE_WRITE); + } else if (pkr_wd && (is_user || env->cr[0] & CR0_WP_MASK)) { + pkr_prot &= ~PAGE_WRITE; } - prot &= pkru_prot; - if ((pkru_prot & (1 << is_write1)) == 0) { + prot &= pkr_prot; + if ((pkr_prot & (1 << is_write1)) == 0) { assert(is_write1 != 2); error_code |= PG_ERROR_PK_MASK; goto do_fault_protect; diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c index 0bd6c95749..f02e4fd400 100644 --- a/target/i386/tcg/misc_helper.c +++ b/target/i386/tcg/misc_helper.c @@ -244,6 +244,7 @@ void helper_rdmsr(CPUX86State *env) void helper_wrmsr(CPUX86State *env) { uint64_t val; + CPUState *cs = env_cpu(env); cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC()); @@ -296,6 +297,13 @@ void helper_wrmsr(CPUX86State *env) case MSR_PAT: env->pat = val; break; + case MSR_IA32_PKRS: + if (val & 0xFFFFFFFF00000000ull) { + goto error; + } + env->pkrs = val; + tlb_flush(cs); + break; case MSR_VM_HSAVE_PA: env->vm_hsave = val; break; @@ -399,6 +407,9 @@ void helper_wrmsr(CPUX86State *env) /* XXX: exception? */ break; } + return; +error: + raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); } void helper_rdmsr(CPUX86State *env) @@ -430,6 +441,9 @@ void helper_rdmsr(CPUX86State *env) case MSR_PAT: val = env->pat; break; + case MSR_IA32_PKRS: + val = env->pkrs; + break; case MSR_VM_HSAVE_PA: val = env->vm_hsave; break; From e9a16e3846d7962a12a9af17163311bc17262ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 25 Jan 2021 15:45:28 +0100 Subject: [PATCH 19/46] configure: Improve TCI feature description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Users might want to enable all features, without realizing some features have negative effect. Mention the TCI feature is slow and experimental, hoping it will be selected knowingly. Suggested-by: Thomas Huth Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20210125144530.2837481-3-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- configure | 2 +- meson_options.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index a34f91171d..ca2cf50773 100755 --- a/configure +++ b/configure @@ -1764,7 +1764,7 @@ Advanced options (experts only): --with-trace-file=NAME Full PATH,NAME of file to store traces Default:trace- --disable-slirp disable SLIRP userspace network connectivity - --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI) + --enable-tcg-interpreter enable TCI (TCG with bytecode interpreter, experimental and slow) --enable-malloc-trim enable libc malloc_trim() for memory optimization --oss-lib path to OSS library --cpu=CPU Build for host CPU [$cpu] diff --git a/meson_options.txt b/meson_options.txt index 95f1079829..675a9c500a 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -40,7 +40,7 @@ option('xen_pci_passthrough', type: 'feature', value: 'auto', option('tcg', type: 'feature', value: 'auto', description: 'TCG support') option('tcg_interpreter', type: 'boolean', value: false, - description: 'TCG bytecode interpreter (TCI)') + description: 'TCG with bytecode interpreter (experimental and slow)') option('cfi', type: 'boolean', value: 'false', description: 'Control-Flow Integrity (CFI)') option('cfi_debug', type: 'boolean', value: 'false', From 39687aca6a72e08ea09652bb45073d09a65d8023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 25 Jan 2021 15:45:29 +0100 Subject: [PATCH 20/46] meson: Explicit TCG backend used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Thomas Huth Reviewed-by: Stefan Weil Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20210125144530.2837481-4-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- meson.build | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 5bd22f431a..3a13ba3307 100644 --- a/meson.build +++ b/meson.build @@ -227,7 +227,7 @@ tcg_arch = config_host['ARCH'] if not get_option('tcg').disabled() if cpu not in supported_cpus if get_option('tcg_interpreter') - warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu)) + warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu)) else error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu)) endif @@ -2509,8 +2509,12 @@ if have_system endif summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')} if config_all.has_key('CONFIG_TCG') + if get_option('tcg_interpreter') + summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, experimental and slow)'} + else + summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} + endif summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')} - summary_info += {'TCG interpreter': tcg_arch == 'tci'} endif summary_info += {'target list': ' '.join(target_dirs)} if have_system From fa2f7b0b9b7d1087bd09f8e086c6403515bbdd3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 25 Jan 2021 15:45:30 +0100 Subject: [PATCH 21/46] meson: Warn when TCI is selected but TCG backend is available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some new users get confused with 'TCG' and 'TCI', and enable TCI support expecting to enable TCG. Emit a warning when native TCG backend is available on the host architecture, mentioning this is a suboptimal configuration. Reviewed-by: Thomas Huth Suggested-by: Daniel Berrangé Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20210125144530.2837481-5-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- meson.build | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/meson.build b/meson.build index 3a13ba3307..4cc3ebb827 100644 --- a/meson.build +++ b/meson.build @@ -231,6 +231,13 @@ if not get_option('tcg').disabled() else error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu)) endif + elif get_option('tcg_interpreter') + warning('Use of the TCG interpretor is not recommended on this host') + warning('architecture. There is a native TCG execution backend available') + warning('which provides substantially better performance and reliability.') + warning('It is strongly recommended to remove the --enable-tcg-interpreter') + warning('configuration option on this architecture to use the native') + warning('backend.') endif if get_option('tcg_interpreter') tcg_arch = 'tci' From f77147cd4de8c726f89b2702f7a9d0c9711d8875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:31 +0100 Subject: [PATCH 22/46] tests/meson: Only build softfloat objects if TCG is selected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested-by: Paolo Bonzini Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Reviewed-by: Alex Bennée Message-Id: <20210122204441.2145197-3-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- tests/meson.build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/meson.build b/tests/meson.build index 29ebaba48d..6f1ff926d2 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -276,7 +276,9 @@ test('decodetree', sh, workdir: meson.current_source_dir() / 'decode', suite: 'decodetree') -subdir('fp') +if 'CONFIG_TCG' in config_all + subdir('fp') +endif if not get_option('tcg').disabled() if 'CONFIG_PLUGIN' in config_host From 6d21d60a2a9261f5ac36b68398a2a8e23814a9b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:32 +0100 Subject: [PATCH 23/46] pc-bios/meson: Only install EDK2 blob firmwares with system emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Message-Id: <20210122204441.2145197-4-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- pc-bios/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/pc-bios/meson.build b/pc-bios/meson.build index af95c5d1f1..f2b32598af 100644 --- a/pc-bios/meson.build +++ b/pc-bios/meson.build @@ -12,6 +12,7 @@ if install_edk2_blobs foreach f : fds custom_target(f, + build_by_default: have_system, output: f, input: '@0@.bz2'.format(f), capture: true, From f285bd3fdcbfaa73e8af0f60371a745e124da804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:34 +0100 Subject: [PATCH 24/46] meson: Restrict block subsystem processing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid generating module_block.h and block-gen.c if we are not going to use them. Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Message-Id: <20210122204441.2145197-6-philmd@redhat.com> [Extend to nearby files and directories. - Paolo] Signed-off-by: Paolo Bonzini --- meson.build | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/meson.build b/meson.build index 4cc3ebb827..0ca73d0102 100644 --- a/meson.build +++ b/meson.build @@ -1877,29 +1877,31 @@ subdir('libdecnumber') subdir('target') subdir('dump') -block_ss.add(files( - 'block.c', - 'blockjob.c', - 'job.c', - 'qemu-io-cmds.c', -)) -block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c')) +if have_block + block_ss.add(files( + 'block.c', + 'blockjob.c', + 'job.c', + 'qemu-io-cmds.c', + )) + block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c')) -subdir('nbd') -subdir('scsi') -subdir('block') + subdir('nbd') + subdir('scsi') + subdir('block') -blockdev_ss.add(files( - 'blockdev.c', - 'blockdev-nbd.c', - 'iothread.c', - 'job-qmp.c', -), gnutls) + blockdev_ss.add(files( + 'blockdev.c', + 'blockdev-nbd.c', + 'iothread.c', + 'job-qmp.c', + ), gnutls) -# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, -# os-win32.c does not -blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c')) -softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')]) + # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, + # os-win32.c does not + blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c')) + softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')]) +endif common_ss.add(files('cpus-common.c')) From 69ff4d0a45eb940c880d26527939a6da68d21193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:35 +0100 Subject: [PATCH 25/46] meson: Merge trace_events_subdirs array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The trace_events_subdirs array is split in two different locations, merge it as one. Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Reviewed-by: Claudio Fontana Message-Id: <20210122204441.2145197-7-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- meson.build | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/meson.build b/meson.build index 0ca73d0102..da21812064 100644 --- a/meson.build +++ b/meson.build @@ -1744,7 +1744,20 @@ trace_events_subdirs = [ 'accel/kvm', 'accel/tcg', 'crypto', + 'hw/core', + 'qapi', + 'qom', 'monitor', + 'target/arm', + 'target/hppa', + 'target/i386', + 'target/i386/kvm', + 'target/mips', + 'target/ppc', + 'target/riscv', + 'target/s390x', + 'target/sparc', + 'util', ] if have_user trace_events_subdirs += [ 'linux-user' ] @@ -1817,21 +1830,6 @@ if have_system 'ui', ] endif -trace_events_subdirs += [ - 'hw/core', - 'qapi', - 'qom', - 'target/arm', - 'target/hppa', - 'target/i386', - 'target/i386/kvm', - 'target/mips', - 'target/ppc', - 'target/riscv', - 'target/s390x', - 'target/sparc', - 'util', -] vhost_user = not_found if 'CONFIG_VHOST_USER' in config_host From 8985db2659897391ad1be5e560a7f34c825fd97e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:36 +0100 Subject: [PATCH 26/46] meson: Restrict some trace event directories to user/system emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Message-Id: <20210122204441.2145197-8-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- meson.build | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/meson.build b/meson.build index da21812064..d6eb880b89 100644 --- a/meson.build +++ b/meson.build @@ -1741,22 +1741,10 @@ target_softmmu_arch = {} # TODO: add each directory to the subdirs from its own meson.build, once # we have those trace_events_subdirs = [ - 'accel/kvm', - 'accel/tcg', 'crypto', - 'hw/core', 'qapi', 'qom', 'monitor', - 'target/arm', - 'target/hppa', - 'target/i386', - 'target/i386/kvm', - 'target/mips', - 'target/ppc', - 'target/riscv', - 'target/s390x', - 'target/sparc', 'util', ] if have_user @@ -1773,6 +1761,7 @@ if have_block endif if have_system trace_events_subdirs += [ + 'accel/kvm', 'audio', 'backends', 'backends/tpm', @@ -1830,6 +1819,21 @@ if have_system 'ui', ] endif +if have_system or have_user + trace_events_subdirs += [ + 'accel/tcg', + 'hw/core', + 'target/arm', + 'target/hppa', + 'target/i386', + 'target/i386/kvm', + 'target/mips', + 'target/ppc', + 'target/riscv', + 'target/s390x', + 'target/sparc', + ] +endif vhost_user = not_found if 'CONFIG_VHOST_USER' in config_host From 957b31f6c537c74efeb221953b803ee0dd1c379a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:37 +0100 Subject: [PATCH 27/46] meson: Restrict emulation code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Message-Id: <20210122204441.2145197-9-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- meson.build | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index d6eb880b89..e3ef660670 100644 --- a/meson.build +++ b/meson.build @@ -1867,16 +1867,18 @@ libqemuutil = static_library('qemuutil', qemuutil = declare_dependency(link_with: libqemuutil, sources: genh + version_res) -decodetree = generator(find_program('scripts/decodetree.py'), - output: 'decode-@BASENAME@.c.inc', - arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) +if have_system or have_user + decodetree = generator(find_program('scripts/decodetree.py'), + output: 'decode-@BASENAME@.c.inc', + arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) + subdir('libdecnumber') + subdir('target') +endif subdir('audio') subdir('io') subdir('chardev') subdir('fsdev') -subdir('libdecnumber') -subdir('target') subdir('dump') if have_block From 9b45a025edbb6ddeeee04e071ac9c4b17c507b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:38 +0100 Subject: [PATCH 28/46] qapi/meson: Restrict qdev code to system-mode emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Beside a CPU device, user-mode emulation doesn't access anything else from qdev subsystem. Tools don't need anything from qdev. Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Message-Id: <20210122204441.2145197-10-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- MAINTAINERS | 1 + qapi/meson.build | 6 +++++- stubs/meson.build | 2 ++ stubs/qdev.c | 23 +++++++++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 stubs/qdev.c diff --git a/MAINTAINERS b/MAINTAINERS index 8d8b0bf966..ca74617cc3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2539,6 +2539,7 @@ F: qapi/qom.json F: qapi/qdev.json F: scripts/coccinelle/qom-parent-type.cocci F: softmmu/qdev-monitor.c +F: stubs/qdev.c F: qom/ F: tests/check-qom-interface.c F: tests/check-qom-proplist.c diff --git a/qapi/meson.build b/qapi/meson.build index ab68e7900e..2839871b47 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -35,7 +35,6 @@ qapi_all_modules = [ 'misc-target', 'net', 'pragma', - 'qdev', 'pci', 'qom', 'rdma', @@ -49,6 +48,11 @@ qapi_all_modules = [ 'ui', 'yank', ] +if have_system + qapi_all_modules += [ + 'qdev', + ] +endif qapi_storage_daemon_modules = [ 'block-core', diff --git a/stubs/meson.build b/stubs/meson.build index 1a656cd070..a054d5877f 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -53,4 +53,6 @@ endif if have_system stub_ss.add(files('semihost.c')) stub_ss.add(files('xen-hw-stub.c')) +else + stub_ss.add(files('qdev.c')) endif diff --git a/stubs/qdev.c b/stubs/qdev.c new file mode 100644 index 0000000000..92e6143134 --- /dev/null +++ b/stubs/qdev.c @@ -0,0 +1,23 @@ +/* + * QOM stubs + * + * Copyright (c) 2021 Red Hat, Inc. + * + * Author: + * Philippe Mathieu-Daudé + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/qapi-events-qdev.h" + +void qapi_event_send_device_deleted(bool has_device, + const char *device, + const char *path) +{ + /* Nothing to do. */ +} From 1935e0e4e09bcff8059ab17d2ce36fb1fbb70628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:39 +0100 Subject: [PATCH 29/46] qapi/meson: Remove QMP from user-mode emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Message-Id: <20210122204441.2145197-11-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- qapi/meson.build | 10 +++++++--- tests/meson.build | 7 ++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/qapi/meson.build b/qapi/meson.build index 2839871b47..b301a46f04 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -4,14 +4,18 @@ util_ss.add(files( 'qapi-dealloc-visitor.c', 'qapi-util.c', 'qapi-visit-core.c', - 'qmp-dispatch.c', - 'qmp-event.c', - 'qmp-registry.c', 'qobject-input-visitor.c', 'qobject-output-visitor.c', 'string-input-visitor.c', 'string-output-visitor.c', )) +if have_system or have_tools + util_ss.add(files( + 'qmp-dispatch.c', + 'qmp-event.c', + 'qmp-registry.c', + )) +endif qapi_all_modules = [ 'acpi', diff --git a/tests/meson.build b/tests/meson.build index 6f1ff926d2..7d7da6a636 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -86,7 +86,6 @@ tests = { 'test-qobject-input-visitor': [testqapi], 'test-string-input-visitor': [testqapi], 'test-string-output-visitor': [testqapi], - 'test-qmp-event': [testqapi], 'test-opts-visitor': [testqapi], 'test-visitor-serialization': [testqapi], 'test-bitmap': [], @@ -117,6 +116,12 @@ tests = { 'test-qapi-util': [], } +if have_system or have_tools + tests += { + 'test-qmp-event': [testqapi], + } +endif + test_deps = { 'test-qht-par': qht_bench, } From 7fdb383d04deb13ace83419188327742daa1967e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:40 +0100 Subject: [PATCH 30/46] qapi/meson: Restrict system-mode specific modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Message-Id: <20210122204441.2145197-12-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- qapi/meson.build | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qapi/meson.build b/qapi/meson.build index b301a46f04..7aca8d5048 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -18,8 +18,6 @@ if have_system or have_tools endif qapi_all_modules = [ - 'acpi', - 'audio', 'authz', 'block', 'block-core', @@ -39,14 +37,10 @@ qapi_all_modules = [ 'misc-target', 'net', 'pragma', - 'pci', 'qom', - 'rdma', 'replay', - 'rocker', 'run-state', 'sockets', - 'tpm', 'trace', 'transaction', 'ui', @@ -54,7 +48,13 @@ qapi_all_modules = [ ] if have_system qapi_all_modules += [ + 'acpi', + 'audio', 'qdev', + 'pci', + 'rdma', + 'rocker', + 'tpm', ] endif From c2651c0eaa1920f6478b4d371ad13c5e1409cccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:41 +0100 Subject: [PATCH 31/46] qapi/meson: Restrict UI module to system emulation and tools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Message-Id: <20210122204441.2145197-13-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- qapi/meson.build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qapi/meson.build b/qapi/meson.build index 7aca8d5048..0652569bc4 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -43,7 +43,6 @@ qapi_all_modules = [ 'sockets', 'trace', 'transaction', - 'ui', 'yank', ] if have_system @@ -57,6 +56,11 @@ if have_system 'tpm', ] endif +if have_system or have_tools + qapi_all_modules += [ + 'ui', + ] +endif qapi_storage_daemon_modules = [ 'block-core', From 38e0b7904eca7cd32f8953c33701e1f226ecc3fe Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 29 Jan 2021 09:43:54 +0100 Subject: [PATCH 32/46] accel/kvm/kvm-all: Fix wrong return code handling in dirty log code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kvm_vm_ioctl() wrapper already returns -errno if the ioctl itself returned -1, so the callers of kvm_vm_ioctl() should not check for -1 but for a value < 0 instead. This problem has been fixed once already in commit b533f658a98325d0e4 but that commit missed that the ENOENT error code is not fatal for this ioctl, so the commit has been reverted in commit 50212d6346f33d6e since the problem occurred close to a pending release at that point in time. The plan was to fix it properly after the release, but it seems like this has been forgotten. So let's do it now finally instead. Resolves: https://bugs.launchpad.net/qemu/+bug/1294227 Signed-off-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210129084354.42928-1-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- accel/kvm/kvm-all.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index e72a19aaf8..47516913b7 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -644,16 +644,19 @@ static int kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml, d.dirty_bitmap = mem->dirty_bmap; d.slot = mem->slot | (kml->as_id << 16); - if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) { - DPRINTF("ioctl failed %d\n", errno); - ret = -1; + ret = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d); + if (ret == -ENOENT) { + /* kernel does not have dirty bitmap in this slot */ + ret = 0; + } else if (ret < 0) { + error_report("ioctl KVM_GET_DIRTY_LOG failed: %d", errno); goto out; + } else { + subsection.offset_within_region += slot_offset; + subsection.size = int128_make64(slot_size); + kvm_get_dirty_pages_log_range(&subsection, d.dirty_bitmap); } - subsection.offset_within_region += slot_offset; - subsection.size = int128_make64(slot_size); - kvm_get_dirty_pages_log_range(&subsection, d.dirty_bitmap); - slot_offset += slot_size; start_addr += slot_size; size -= slot_size; @@ -750,8 +753,8 @@ static int kvm_log_clear_one_slot(KVMSlot *mem, int as_id, uint64_t start, d.num_pages = bmap_npages; d.slot = mem->slot | (as_id << 16); - if (kvm_vm_ioctl(s, KVM_CLEAR_DIRTY_LOG, &d) == -1) { - ret = -errno; + ret = kvm_vm_ioctl(s, KVM_CLEAR_DIRTY_LOG, &d); + if (ret < 0 && ret != -ENOENT) { error_report("%s: KVM_CLEAR_DIRTY_LOG failed, slot=%d, " "start=0x%"PRIx64", size=0x%"PRIx32", errno=%d", __func__, d.slot, (uint64_t)d.first_page, From 189012fcd7babafd937c4cabd5c3231be6e85fdc Mon Sep 17 00:00:00 2001 From: Pavel Dovgalyuk Date: Mon, 1 Feb 2021 10:05:27 +0300 Subject: [PATCH 33/46] replay: fix replay of the interrupts Sometimes interrupt event comes at the same time with the virtual timers. In this case replay tries to proceed the timers, because deadline for them is zero. This patch allows processing interrupts and exceptions by entering the vCPU execution loop, when deadline is zero, but checkpoint associated with virtual timers is not ready to be replayed. Signed-off-by: Pavel Dovgalyuk Message-Id: <161216312794.2030770.1709657858900983160.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- accel/tcg/tcg-accel-ops-icount.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/accel/tcg/tcg-accel-ops-icount.c b/accel/tcg/tcg-accel-ops-icount.c index 87762b469c..13b8fbeb69 100644 --- a/accel/tcg/tcg-accel-ops-icount.c +++ b/accel/tcg/tcg-accel-ops-icount.c @@ -81,7 +81,13 @@ void icount_handle_deadline(void) int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, QEMU_TIMER_ATTR_ALL); - if (deadline == 0) { + /* + * Instructions, interrupts, and exceptions are processed in cpu-exec. + * Don't interrupt cpu thread, when these events are waiting + * (i.e., there is no checkpoint) + */ + if (deadline == 0 + && (replay_mode != REPLAY_MODE_PLAY || replay_has_checkpoint())) { icount_notify_aio_contexts(); } } From 4b956a399969c0c497a48ba469b7c674b0eb51bd Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Sun, 31 Jan 2021 14:34:34 +0000 Subject: [PATCH 34/46] pc-bios/descriptors: fix paths in json files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before the change /usr/share/qemu/firmware/50-edk2-x86_64-secure.json contained the relative path: "filename": "share/qemu/edk2-x86_64-secure-code.fd", "filename": "share/qemu/edk2-i386-vars.fd", After then change the paths are absolute: "filename": "/usr/share/qemu/edk2-x86_64-secure-code.fd", "filename": "/usr/share/qemu/edk2-i386-vars.fd", The regression appeared in qemu-5.2.0 (seems to be related to meson port). CC: Paolo Bonzini CC: "Marc-André Lureau" CC: "Philippe Mathieu-Daudé" Bug: https://bugs.gentoo.org/766743 Bug: https://bugs.launchpad.net/qemu/+bug/1913012 Signed-off-by: Jannik Glückert Signed-off-by: Sergei Trofimovich Message-Id: <20210131143434.2513363-1-slyfox@gentoo.org> Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini --- pc-bios/descriptors/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pc-bios/descriptors/meson.build b/pc-bios/descriptors/meson.build index ac6ec66b00..29efa16d99 100644 --- a/pc-bios/descriptors/meson.build +++ b/pc-bios/descriptors/meson.build @@ -9,7 +9,7 @@ if install_edk2_blobs ] configure_file(input: files(f), output: f, - configuration: {'DATADIR': qemu_datadir}, + configuration: {'DATADIR': get_option('prefix') / qemu_datadir}, install: get_option('install_blobs'), install_dir: qemu_datadir / 'firmware') endforeach From 54550d886e5bb4148c0765c639fa04a44f3e5d8d Mon Sep 17 00:00:00 2001 From: Pavel Dovgalyuk Date: Wed, 3 Feb 2021 09:00:12 +0300 Subject: [PATCH 35/46] replay: rng-builtin support This patch enables using rng-builtin with record/replay by making the callbacks deterministic. Signed-off-by: Pavel Dovgalyuk Message-Id: <161233201286.170686.7858208964037376305.stgit@pasha-ThinkPad-X280> Signed-off-by: Paolo Bonzini --- backends/rng-builtin.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/rng-builtin.c b/backends/rng-builtin.c index f38dff117d..f367eb665c 100644 --- a/backends/rng-builtin.c +++ b/backends/rng-builtin.c @@ -10,6 +10,7 @@ #include "qemu/main-loop.h" #include "qemu/guest-random.h" #include "qom/object.h" +#include "sysemu/replay.h" OBJECT_DECLARE_SIMPLE_TYPE(RngBuiltin, RNG_BUILTIN) @@ -37,7 +38,7 @@ static void rng_builtin_request_entropy(RngBackend *b, RngRequest *req) { RngBuiltin *s = RNG_BUILTIN(b); - qemu_bh_schedule(s->bh); + replay_bh_schedule_event(s->bh); } static void rng_builtin_init(Object *obj) From 33c38f8ca1e09b9f77cf263404d423e076c19177 Mon Sep 17 00:00:00 2001 From: Utkarsh Tripathi Date: Thu, 31 Dec 2020 13:13:04 +0000 Subject: [PATCH 36/46] cpu-throttle: Remove timer_mod() from cpu_throttle_set() During migrations, after each iteration, cpu_throttle_set() is called, which irrespective of input, re-arms the timer according to value of new_throttle_pct. This causes cpu_throttle_thread() to be delayed in getting scheduled and consqeuntly lets guest run for more time than what the throttle value should allow. This leads to spikes in guest throughput at high cpu-throttle percentage whenever cpu_throttle_set() is called. A solution would be not to modify the timer immediately in cpu_throttle_set(), instead, only modify throttle_percentage so that the throttle would automatically adjust to the required percentage when cpu_throttle_timer_tick() is invoked. Manually tested the patch using following configuration: Guest: Centos7 (3.10.0-123.el7.x86_64) Total Memory - 64GB , CPUs - 16 Tool used - stress (1.0.4) Workload - stress --vm 32 --vm-bytes 1G --vm-keep Migration Parameters: Network Bandwidth - 500MBPS cpu-throttle-initial - 99 Results: With timer_mod(): fails to converge, continues indefinitely Without timer_mod(): converges in 249 sec Signed-off-by: Utkarsh Tripathi Message-Id: <1609420384-119407-1-git-send-email-utkarsh.tripathi@nutanix.com> Signed-off-by: Paolo Bonzini --- softmmu/cpu-throttle.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/softmmu/cpu-throttle.c b/softmmu/cpu-throttle.c index 2ec4b8e0bc..8c2144ab95 100644 --- a/softmmu/cpu-throttle.c +++ b/softmmu/cpu-throttle.c @@ -90,14 +90,21 @@ static void cpu_throttle_timer_tick(void *opaque) void cpu_throttle_set(int new_throttle_pct) { + /* + * boolean to store whether throttle is already active or not, + * before modifying throttle_percentage + */ + bool throttle_active = cpu_throttle_active(); + /* Ensure throttle percentage is within valid range */ new_throttle_pct = MIN(new_throttle_pct, CPU_THROTTLE_PCT_MAX); new_throttle_pct = MAX(new_throttle_pct, CPU_THROTTLE_PCT_MIN); qatomic_set(&throttle_percentage, new_throttle_pct); - timer_mod(throttle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT) + - CPU_THROTTLE_TIMESLICE_NS); + if (!throttle_active) { + cpu_throttle_timer_tick(NULL); + } } void cpu_throttle_stop(void) From 520f26fc6d17b71a43eaf620e834b3bdf316f3d3 Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Tue, 11 Aug 2020 17:11:25 +0530 Subject: [PATCH 37/46] hw/pci-host: add pci-intack write method Add pci-intack mmio write method to avoid NULL pointer dereference issue. Reported-by: Lei Sun Reviewed-by: Li Qiang Reviewed-by: Peter Maydell Signed-off-by: Prasad J Pandit Message-Id: <20200811114133.672647-2-ppandit@redhat.com> Signed-off-by: Paolo Bonzini --- hw/pci-host/prep.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index 0469db8c1d..0a9162fba9 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -27,6 +27,7 @@ #include "qemu-common.h" #include "qemu/datadir.h" #include "qemu/units.h" +#include "qemu/log.h" #include "qapi/error.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" @@ -121,8 +122,15 @@ static uint64_t raven_intack_read(void *opaque, hwaddr addr, return pic_read_irq(isa_pic); } +static void raven_intack_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__); +} + static const MemoryRegionOps raven_intack_ops = { .read = raven_intack_read, + .write = raven_intack_write, .valid = { .max_access_size = 1, }, From 4f2a5202a05fc1612954804a2482f07bff105ea2 Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Tue, 11 Aug 2020 17:11:26 +0530 Subject: [PATCH 38/46] pci-host: designware: add pcie-msi read method Add pcie-msi mmio read method to avoid NULL pointer dereference issue. Reported-by: Lei Sun Reviewed-by: Li Qiang Reviewed-by: Peter Maydell Signed-off-by: Prasad J Pandit Message-Id: <20200811114133.672647-3-ppandit@redhat.com> Signed-off-by: Paolo Bonzini --- hw/pci-host/designware.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c index f9fb97a3e3..bde3a343a2 100644 --- a/hw/pci-host/designware.c +++ b/hw/pci-host/designware.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/module.h" +#include "qemu/log.h" #include "hw/pci/msi.h" #include "hw/pci/pci_bridge.h" #include "hw/pci/pci_host.h" @@ -63,6 +64,23 @@ designware_pcie_root_to_host(DesignwarePCIERoot *root) return DESIGNWARE_PCIE_HOST(bus->parent); } +static uint64_t designware_pcie_root_msi_read(void *opaque, hwaddr addr, + unsigned size) +{ + /* + * Attempts to read from the MSI address are undefined in + * the PCI specifications. For this hardware, the datasheet + * specifies that a read from the magic address is simply not + * intercepted by the MSI controller, and will go out to the + * AHB/AXI bus like any other PCI-device-initiated DMA read. + * This is not trivial to implement in QEMU, so since + * well-behaved guests won't ever ask a PCI device to DMA from + * this address we just log the missing functionality. + */ + qemu_log_mask(LOG_UNIMP, "%s not implemented\n", __func__); + return 0; +} + static void designware_pcie_root_msi_write(void *opaque, hwaddr addr, uint64_t val, unsigned len) { @@ -77,6 +95,7 @@ static void designware_pcie_root_msi_write(void *opaque, hwaddr addr, } static const MemoryRegionOps designware_pci_host_msi_ops = { + .read = designware_pcie_root_msi_read, .write = designware_pcie_root_msi_write, .endianness = DEVICE_LITTLE_ENDIAN, .valid = { From 24202d2b561c3b4c48bd28383c8c34b4ac66c2bf Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Tue, 11 Aug 2020 17:11:27 +0530 Subject: [PATCH 39/46] vfio: add quirk device write method Add vfio quirk device mmio write method to avoid NULL pointer dereference issue. Reported-by: Lei Sun Reviewed-by: Li Qiang Reviewed-by: Peter Maydell Acked-by: Alex Williamson Signed-off-by: Prasad J Pandit Message-Id: <20200811114133.672647-4-ppandit@redhat.com> Signed-off-by: Paolo Bonzini --- hw/vfio/pci-quirks.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c index fc8d63c850..c5c4c61d01 100644 --- a/hw/vfio/pci-quirks.c +++ b/hw/vfio/pci-quirks.c @@ -14,6 +14,7 @@ #include CONFIG_DEVICES #include "exec/memop.h" #include "qemu/units.h" +#include "qemu/log.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "qemu/module.h" @@ -264,8 +265,15 @@ static uint64_t vfio_ati_3c3_quirk_read(void *opaque, return data; } +static void vfio_ati_3c3_quirk_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid access\n", __func__); +} + static const MemoryRegionOps vfio_ati_3c3_quirk = { .read = vfio_ati_3c3_quirk_read, + .write = vfio_ati_3c3_quirk_write, .endianness = DEVICE_LITTLE_ENDIAN, }; From f867cebaedbc9c43189f102e4cdfdff05e88df7f Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Tue, 11 Aug 2020 17:11:28 +0530 Subject: [PATCH 40/46] prep: add ppc-parity write method Add ppc-parity mmio write method to avoid NULL pointer dereference issue. Reported-by: Lei Sun Acked-by: David Gibson Signed-off-by: Prasad J Pandit Reviewed-by: Li Qiang Message-Id: <20200811114133.672647-5-ppandit@redhat.com> Signed-off-by: Paolo Bonzini --- hw/ppc/prep_systemio.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c index 4e48ef245c..b2bd783248 100644 --- a/hw/ppc/prep_systemio.c +++ b/hw/ppc/prep_systemio.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "hw/irq.h" #include "hw/isa/isa.h" #include "hw/qdev-properties.h" @@ -235,8 +236,15 @@ static uint64_t ppc_parity_error_readl(void *opaque, hwaddr addr, return val; } +static void ppc_parity_error_writel(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid access\n", __func__); +} + static const MemoryRegionOps ppc_parity_error_ops = { .read = ppc_parity_error_readl, + .write = ppc_parity_error_writel, .valid = { .min_access_size = 4, .max_access_size = 4, From b5bf601f364e1a14ca4c3276f88dfec024acf613 Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Tue, 11 Aug 2020 17:11:29 +0530 Subject: [PATCH 41/46] nvram: add nrf51_soc flash read method Add nrf51_soc mmio read method to avoid NULL pointer dereference issue. Reported-by: Lei Sun Reviewed-by: Peter Maydell Signed-off-by: Prasad J Pandit Reviewed-by: Li Qiang Message-Id: <20200811114133.672647-6-ppandit@redhat.com> Signed-off-by: Paolo Bonzini --- hw/nvram/nrf51_nvm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/nvram/nrf51_nvm.c b/hw/nvram/nrf51_nvm.c index f2283c1a8d..7b3460d52d 100644 --- a/hw/nvram/nrf51_nvm.c +++ b/hw/nvram/nrf51_nvm.c @@ -273,6 +273,15 @@ static const MemoryRegionOps io_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static uint64_t flash_read(void *opaque, hwaddr offset, unsigned size) +{ + /* + * This is a rom_device MemoryRegion which is always in + * romd_mode (we never put it in MMIO mode), so reads always + * go directly to RAM and never come here. + */ + g_assert_not_reached(); +} static void flash_write(void *opaque, hwaddr offset, uint64_t value, unsigned int size) @@ -300,6 +309,7 @@ static void flash_write(void *opaque, hwaddr offset, uint64_t value, static const MemoryRegionOps flash_ops = { + .read = flash_read, .write = flash_write, .valid.min_access_size = 4, .valid.max_access_size = 4, From 921604e175b8ec06c39503310e7b3ec1e3eafe9e Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Tue, 11 Aug 2020 17:11:30 +0530 Subject: [PATCH 42/46] spapr_pci: add spapr msi read method Add spapr msi mmio read method to avoid NULL pointer dereference issue. Reported-by: Lei Sun Acked-by: David Gibson Reviewed-by: Li Qiang Signed-off-by: Prasad J Pandit Message-Id: <20200811114133.672647-7-ppandit@redhat.com> Signed-off-by: Paolo Bonzini --- hw/ppc/spapr_pci.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 76d7c91e9c..b89f810034 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -53,6 +53,7 @@ #include "sysemu/hostmem.h" #include "sysemu/numa.h" #include "hw/ppc/spapr_numa.h" +#include "qemu/log.h" /* Copied from the kernel arch/powerpc/platforms/pseries/msi.c */ #define RTAS_QUERY_FN 0 @@ -739,6 +740,12 @@ static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin) return route; } +static uint64_t spapr_msi_read(void *opaque, hwaddr addr, unsigned size) +{ + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid access\n", __func__); + return 0; +} + /* * MSI/MSIX memory region implementation. * The handler handles both MSI and MSIX. @@ -756,8 +763,11 @@ static void spapr_msi_write(void *opaque, hwaddr addr, } static const MemoryRegionOps spapr_msi_ops = { - /* There is no .read as the read result is undefined by PCI spec */ - .read = NULL, + /* + * .read result is undefined by PCI spec. + * define .read method to avoid assert failure in memory_region_init_io + */ + .read = spapr_msi_read, .write = spapr_msi_write, .endianness = DEVICE_LITTLE_ENDIAN }; From 2c9fb3b784000c1df32231e1c2464bb2e3fc4620 Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Tue, 11 Aug 2020 17:11:31 +0530 Subject: [PATCH 43/46] tz-ppc: add dummy read/write methods Add tz-ppc-dummy mmio read/write methods to avoid assert failure during initialisation. Reviewed-by: Peter Maydell Signed-off-by: Prasad J Pandit Reviewed-by: Li Qiang Message-Id: <20200811114133.672647-8-ppandit@redhat.com> Signed-off-by: Paolo Bonzini --- hw/misc/tz-ppc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/misc/tz-ppc.c b/hw/misc/tz-ppc.c index 6431257b52..36495c68e7 100644 --- a/hw/misc/tz-ppc.c +++ b/hw/misc/tz-ppc.c @@ -196,7 +196,21 @@ static bool tz_ppc_dummy_accepts(void *opaque, hwaddr addr, g_assert_not_reached(); } +static uint64_t tz_ppc_dummy_read(void *opaque, hwaddr addr, unsigned size) +{ + g_assert_not_reached(); +} + +static void tz_ppc_dummy_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + g_assert_not_reached(); +} + static const MemoryRegionOps tz_ppc_dummy_ops = { + /* define r/w methods to avoid assert failure in memory_region_init_io */ + .read = tz_ppc_dummy_read, + .write = tz_ppc_dummy_write, .valid.accepts = tz_ppc_dummy_accepts, }; From 735754aaa15a6ed46db51fd731e88331c446ea54 Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Tue, 11 Aug 2020 17:11:32 +0530 Subject: [PATCH 44/46] imx7-ccm: add digprog mmio write method Add digprog mmio write method to avoid assert failure during initialisation. Reviewed-by: Li Qiang Signed-off-by: Prasad J Pandit Message-Id: <20200811114133.672647-9-ppandit@redhat.com> Signed-off-by: Paolo Bonzini --- hw/misc/imx7_ccm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c index 02fc1ae8d0..075159e497 100644 --- a/hw/misc/imx7_ccm.c +++ b/hw/misc/imx7_ccm.c @@ -131,8 +131,16 @@ static const struct MemoryRegionOps imx7_set_clr_tog_ops = { }, }; +static void imx7_digprog_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + qemu_log_mask(LOG_GUEST_ERROR, + "Guest write to read-only ANALOG_DIGPROG register\n"); +} + static const struct MemoryRegionOps imx7_digprog_ops = { .read = imx7_set_clr_tog_read, + .write = imx7_digprog_write, .endianness = DEVICE_NATIVE_ENDIAN, .impl = { .min_access_size = 4, From 6aa4228bd68cb251ccb5f802c015b494c6a10f19 Mon Sep 17 00:00:00 2001 From: Chenyi Qiang Date: Fri, 5 Feb 2021 16:33:24 +0800 Subject: [PATCH 45/46] target/i386: Add support for save/load IA32_PKRS MSR PKS introduces MSR IA32_PKRS(0x6e1) to manage the supervisor protection key rights. Page access and writes can be managed via the MSR update without TLB flushes when permissions change. Add the support to save/load IA32_PKRS MSR in guest. Signed-off-by: Chenyi Qiang Message-Id: <20210205083325.13880-2-chenyi.qiang@intel.com> Signed-off-by: Paolo Bonzini --- target/i386/kvm/kvm.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 4788139128..e97f841757 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -113,6 +113,7 @@ static bool has_msr_vmx_vmfunc; static bool has_msr_ucode_rev; static bool has_msr_vmx_procbased_ctls2; static bool has_msr_perf_capabs; +static bool has_msr_pkrs; static uint32_t has_architectural_pmu_version; static uint32_t num_architectural_pmu_gp_counters; @@ -2087,6 +2088,9 @@ static int kvm_get_supported_msrs(KVMState *s) case MSR_IA32_VMX_PROCBASED_CTLS2: has_msr_vmx_procbased_ctls2 = true; break; + case MSR_IA32_PKRS: + has_msr_pkrs = true; + break; } } } @@ -2814,6 +2818,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level) if (has_msr_smi_count) { kvm_msr_entry_add(cpu, MSR_SMI_COUNT, env->msr_smi_count); } + if (has_msr_pkrs) { + kvm_msr_entry_add(cpu, MSR_IA32_PKRS, env->pkrs); + } if (has_msr_bndcfgs) { kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, env->msr_bndcfgs); } @@ -3205,6 +3212,9 @@ static int kvm_get_msrs(X86CPU *cpu) if (has_msr_feature_control) { kvm_msr_entry_add(cpu, MSR_IA32_FEATURE_CONTROL, 0); } + if (has_msr_pkrs) { + kvm_msr_entry_add(cpu, MSR_IA32_PKRS, 0); + } if (has_msr_bndcfgs) { kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, 0); } @@ -3475,6 +3485,9 @@ static int kvm_get_msrs(X86CPU *cpu) case MSR_IA32_UMWAIT_CONTROL: env->umwait = msrs[i].data; break; + case MSR_IA32_PKRS: + env->pkrs = msrs[i].data; + break; default: if (msrs[i].index >= MSR_MC0_CTL && msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) { From 52a44ad2b92ba4cd81c2b271cd5e4a2d820e91fc Mon Sep 17 00:00:00 2001 From: Chenyi Qiang Date: Fri, 5 Feb 2021 16:33:25 +0800 Subject: [PATCH 46/46] target/i386: Expose VMX entry/exit load pkrs control bits Expose the VMX exit/entry load pkrs control bits in VMX_TRUE_EXIT_CTLS/VMX_TRUE_ENTRY_CTLS MSRs to guest, which supports the PKS in nested VM. Signed-off-by: Chenyi Qiang Message-Id: <20210205083325.13880-3-chenyi.qiang@intel.com> Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 4 ++-- target/i386/cpu.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 0b0d65c21c..9c3d2d60b7 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1215,7 +1215,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { "vmx-exit-save-efer", "vmx-exit-load-efer", "vmx-exit-save-preemption-timer", "vmx-exit-clear-bndcfgs", NULL, "vmx-exit-clear-rtit-ctl", NULL, NULL, - NULL, NULL, NULL, NULL, + NULL, "vmx-exit-load-pkrs", NULL, NULL, }, .msr = { .index = MSR_IA32_VMX_TRUE_EXIT_CTLS, @@ -1230,7 +1230,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { NULL, "vmx-entry-ia32e-mode", NULL, NULL, NULL, "vmx-entry-load-perf-global-ctrl", "vmx-entry-load-pat", "vmx-entry-load-efer", "vmx-entry-load-bndcfgs", NULL, "vmx-entry-load-rtit-ctl", NULL, - NULL, NULL, NULL, NULL, + NULL, NULL, "vmx-entry-load-pkrs", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index cc5a26f35b..8d599bb5b8 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -973,6 +973,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define VMX_VM_EXIT_CLEAR_BNDCFGS 0x00800000 #define VMX_VM_EXIT_PT_CONCEAL_PIP 0x01000000 #define VMX_VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000 +#define VMX_VM_EXIT_LOAD_IA32_PKRS 0x20000000 #define VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS 0x00000004 #define VMX_VM_ENTRY_IA32E_MODE 0x00000200 @@ -984,6 +985,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define VMX_VM_ENTRY_LOAD_BNDCFGS 0x00010000 #define VMX_VM_ENTRY_PT_CONCEAL_PIP 0x00020000 #define VMX_VM_ENTRY_LOAD_IA32_RTIT_CTL 0x00040000 +#define VMX_VM_ENTRY_LOAD_IA32_PKRS 0x00400000 /* Supported Hyper-V Enlightenments */ #define HYPERV_FEAT_RELAXED 0