From 181ce1d05c6d4f1c80f0e7ebb41e489c2b541edf Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Wed, 18 Apr 2018 09:50:44 +0200 Subject: [PATCH 01/29] configure: recognize more rpmbuild macros Extend the list of recognized, but ignored options from rpms %configure macro. This fixes build on hosts running SUSE Linux. Cc: qemu-stable@nongnu.org Signed-off-by: Olaf Hering Message-Id: <20180418075045.27393-1-olaf@aepfle.de> Signed-off-by: Paolo Bonzini --- configure | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure b/configure index 1443422e83..83a6080bf8 100755 --- a/configure +++ b/configure @@ -964,6 +964,8 @@ for opt do ;; --firmwarepath=*) firmwarepath="$optarg" ;; + --host=*|--build=*|\ + --disable-dependency-tracking|\ --sbindir=*|--sharedstatedir=*|\ --oldincludedir=*|--datarootdir=*|--infodir=*|--localedir=*|\ --htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*) From f056158d694d2adc63ff120ca71c73ae8b14426c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 23 Apr 2018 10:45:18 +0200 Subject: [PATCH 02/29] cpus: Fix event order on resume of stopped guest When resume of a stopped guest immediately runs into block device errors, the BLOCK_IO_ERROR event is sent before the RESUME event. Reproducer: 1. Create a scratch image $ dd if=/dev/zero of=scratch.img bs=1M count=100 Size doesn't actually matter. 2. Prepare blkdebug configuration: $ cat >blkdebug.conf < ' Issue QMP command 'qmp_capabilities': QMP> { "execute": "qmp_capabilities" } 5. Boot the guest. 6. In the guest, write to the scratch disk, e.g. like this: # dd if=/dev/zero of=/dev/vdb count=1 Do double-check the device specified with of= is actually the scratch device! 7. Issue QMP command 'cont': QMP> { "execute": "cont" } After step 6, I get a BLOCK_IO_ERROR event followed by a STOP event. Good. After step 7, I get BLOCK_IO_ERROR, then RESUME, then STOP. Not so good; I'd expect RESUME, then BLOCK_IO_ERROR, then STOP. The funny event order confuses libvirt: virsh -r domstate DOMAIN --reason reports "paused (unknown)" rather than "paused (I/O error)". The culprit is vm_prepare_start(). /* Ensure that a STOP/RESUME pair of events is emitted if a * vmstop request was pending. The BLOCK_IO_ERROR event, for * example, according to documentation is always followed by * the STOP event. */ if (runstate_is_running()) { qapi_event_send_stop(&error_abort); res = -1; } else { replay_enable_events(); cpu_enable_ticks(); runstate_set(RUN_STATE_RUNNING); vm_state_notify(1, RUN_STATE_RUNNING); } /* We are sending this now, but the CPUs will be resumed shortly later */ qapi_event_send_resume(&error_abort); return res; When resuming a stopped guest, we take the else branch before we get to sending RESUME. vm_state_notify() runs virtio_vmstate_change(), among other things. This restarts I/O, triggering the BLOCK_IO_ERROR event. Reshuffle vm_prepare_start() to send the RESUME event earlier. Fixes RHBZ 1566153. Cc: Paolo Bonzini Signed-off-by: Markus Armbruster Message-Id: <20180423084518.2426-1-armbru@redhat.com> Signed-off-by: Paolo Bonzini --- cpus.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cpus.c b/cpus.c index 5bcd3ecf38..be3a4eb27a 100644 --- a/cpus.c +++ b/cpus.c @@ -2043,7 +2043,6 @@ int vm_stop(RunState state) int vm_prepare_start(void) { RunState requested; - int res = 0; qemu_vmstop_requested(&requested); if (runstate_is_running() && requested == RUN_STATE__MAX) { @@ -2057,17 +2056,18 @@ int vm_prepare_start(void) */ if (runstate_is_running()) { qapi_event_send_stop(&error_abort); - res = -1; - } else { - replay_enable_events(); - cpu_enable_ticks(); - runstate_set(RUN_STATE_RUNNING); - vm_state_notify(1, RUN_STATE_RUNNING); + qapi_event_send_resume(&error_abort); + return -1; } /* We are sending this now, but the CPUs will be resumed shortly later */ qapi_event_send_resume(&error_abort); - return res; + + replay_enable_events(); + cpu_enable_ticks(); + runstate_set(RUN_STATE_RUNNING); + vm_state_notify(1, RUN_STATE_RUNNING); + return 0; } void vm_start(void) From 54961aac190df28d311802364d19e18d5cda8bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Wed, 25 Apr 2018 15:18:28 +0200 Subject: [PATCH 03/29] cpus: tcg: fix never exiting loop on unplug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 9b0605f9837b ("cpus: tcg: unregister thread with RCU, fix exiting of loop on unplug") changed the exit condition of the loop in the vCPU thread function but forgot to remove the beginning 'while (1)' statement. The resulting code : while (1) { ... } while (!cpu->unplug || cpu_can_run(cpu)); is a sequence of two distinct two while() loops, the first not exiting in case of an unplug event. Remove the first while (1) to fix CPU unplug. Signed-off-by: Cédric Le Goater Message-Id: <20180425131828.15604-1-clg@kaod.org> Cc: qemu-stable@nongnu.org Fixes: 9b0605f9837b68fd56c7fc7c96a3a1a3b983687d Signed-off-by: Paolo Bonzini Signed-off-by: Cédric Le Goater --- cpus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index be3a4eb27a..d1f16296de 100644 --- a/cpus.c +++ b/cpus.c @@ -1648,7 +1648,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) /* process any pending work */ cpu->exit_request = 1; - while (1) { + do { if (cpu_can_run(cpu)) { int r; qemu_mutex_unlock_iothread(); From 82870f3c0295d36c342942b4757b2b1ddd55ab19 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Wed, 25 Apr 2018 15:01:03 +0800 Subject: [PATCH 04/29] checkpatch.pl: add common glib defines to typelist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise it can warn this: ERROR: space prohibited between function name and open parenthesis '(' When with things like this: typedef gboolean (*it_tree_iterator)(ITValue start, ITValue end); CC: Paolo Bonzini CC: "Daniel P. Berrangé" CC: Vladimir Sementsov-Ogievskiy CC: Fam Zheng Signed-off-by: Peter Xu Message-Id: <20180425070103.23723-1-peterx@redhat.com> Reviewed-by: Stefan Hajnoczi Reviewed-by: Markus Armbruster Signed-off-by: Paolo Bonzini --- scripts/checkpatch.pl | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 5b8735defb..e73b4efcfb 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -265,8 +265,36 @@ our @typeList = ( qr{${Ident}_handler_fn}, qr{target_(?:u)?long}, qr{hwaddr}, + # external libraries qr{xml${Ident}}, qr{xendevicemodel_handle}, + # Glib definitions + qr{gchar}, + qr{gshort}, + qr{glong}, + qr{gint}, + qr{gboolean}, + qr{guchar}, + qr{gushort}, + qr{gulong}, + qr{guint}, + qr{gfloat}, + qr{gdouble}, + qr{gpointer}, + qr{gconstpointer}, + qr{gint8}, + qr{guint8}, + qr{gint16}, + qr{guint16}, + qr{gint32}, + qr{guint32}, + qr{gint64}, + qr{guint64}, + qr{gsize}, + qr{gssize}, + qr{goffset}, + qr{gintptr}, + qr{guintptr}, ); # This can be modified by sub possible. Since it can be empty, be careful From 770dec2627b085457280490ac0543def97396fef Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 30 Apr 2018 11:44:17 +0200 Subject: [PATCH 05/29] qom: allow object_get_canonical_path_component without parent Just return NULL; any callers that cause a change in behavior would have caused an assertion failure before, so this is safe. Signed-off-by: Paolo Bonzini --- include/qom/object.h | 1 + qom/object.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index 96ce81bc5e..a0c78c76f7 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1302,6 +1302,7 @@ Object *object_get_internal_root(void); * * Returns: The final component in the object's canonical path. The canonical * path is the path within the composition tree starting from the root. + * %NULL if the object doesn't have a parent (and thus a canonical path). */ gchar *object_get_canonical_path_component(Object *obj); diff --git a/qom/object.c b/qom/object.c index 76a89af99b..0fc972030e 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1644,8 +1644,9 @@ gchar *object_get_canonical_path_component(Object *obj) ObjectProperty *prop = NULL; GHashTableIter iter; - g_assert(obj); - g_assert(obj->parent != NULL); + if (obj->parent == NULL) { + return NULL; + } g_hash_table_iter_init(&iter, obj->parent->properties); while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&prop)) { From 29de4ec164ba2ceac4983ffd08491ea98ca8f8af Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 30 Apr 2018 11:48:18 +0200 Subject: [PATCH 06/29] memdev: remove "id" property The "id" property is unnecessary and can be replaced simply with object_get_canonical_path_component. This patch mostly undoes commit e1ff3c67e8 ("monitor: fix qmp/hmp query-memdev not reporting IDs of memory backends", 2017-01-12). Signed-off-by: Paolo Bonzini --- backends/hostmem.c | 26 -------------------------- include/sysemu/hostmem.h | 1 - numa.c | 2 +- qom/object_interfaces.c | 6 ------ 4 files changed, 1 insertion(+), 34 deletions(-) diff --git a/backends/hostmem.c b/backends/hostmem.c index 6a0c474222..3627e61584 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -369,24 +369,6 @@ host_memory_backend_can_be_deleted(UserCreatable *uc) } } -static char *get_id(Object *o, Error **errp) -{ - HostMemoryBackend *backend = MEMORY_BACKEND(o); - - return g_strdup(backend->id); -} - -static void set_id(Object *o, const char *str, Error **errp) -{ - HostMemoryBackend *backend = MEMORY_BACKEND(o); - - if (backend->id) { - error_setg(errp, "cannot change property value"); - return; - } - backend->id = g_strdup(str); -} - static bool host_memory_backend_get_share(Object *o, Error **errp) { HostMemoryBackend *backend = MEMORY_BACKEND(o); @@ -434,18 +416,11 @@ host_memory_backend_class_init(ObjectClass *oc, void *data) &HostMemPolicy_lookup, host_memory_backend_get_policy, host_memory_backend_set_policy, &error_abort); - object_class_property_add_str(oc, "id", get_id, set_id, &error_abort); object_class_property_add_bool(oc, "share", host_memory_backend_get_share, host_memory_backend_set_share, &error_abort); } -static void host_memory_backend_finalize(Object *o) -{ - HostMemoryBackend *backend = MEMORY_BACKEND(o); - g_free(backend->id); -} - static const TypeInfo host_memory_backend_info = { .name = TYPE_MEMORY_BACKEND, .parent = TYPE_OBJECT, @@ -454,7 +429,6 @@ static const TypeInfo host_memory_backend_info = { .class_init = host_memory_backend_class_init, .instance_size = sizeof(HostMemoryBackend), .instance_init = host_memory_backend_init, - .instance_finalize = host_memory_backend_finalize, .interfaces = (InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { } diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h index bc36899bb8..5beb0ef8ab 100644 --- a/include/sysemu/hostmem.h +++ b/include/sysemu/hostmem.h @@ -52,7 +52,6 @@ struct HostMemoryBackend { Object parent; /* protected */ - char *id; uint64_t size; bool merge, dump; bool prealloc, force_prealloc, is_mapped, share; diff --git a/numa.c b/numa.c index 70b150e73a..aac22a9612 100644 --- a/numa.c +++ b/numa.c @@ -580,7 +580,7 @@ static int query_memdev(Object *obj, void *opaque) m->value = g_malloc0(sizeof(*m->value)); - m->value->id = object_property_get_str(obj, "id", NULL); + m->value->id = object_get_canonical_path_component(obj); m->value->has_id = !!m->value->id; m->value->size = object_property_get_uint(obj, "size", diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c index 980ffc2ada..72b97a8bed 100644 --- a/qom/object_interfaces.c +++ b/qom/object_interfaces.c @@ -65,12 +65,6 @@ Object *user_creatable_add_type(const char *type, const char *id, assert(qdict); obj = object_new(type); - if (object_property_find(obj, "id", NULL)) { - object_property_set_str(obj, id, "id", &local_err); - if (local_err) { - goto out; - } - } visit_start_struct(v, NULL, NULL, 0, &local_err); if (local_err) { goto out; From 4269c82bf72f7e171a03a09b9264b0db76ae0050 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sun, 4 Mar 2018 23:31:47 +0100 Subject: [PATCH 07/29] exec: move memory access declarations to a common header, inline *_phys functions For now, this reduces the text size very slightly due to the newly-added inlining: text size before: 9301965 text size after: 9300645 Later, however, the declarations in include/exec/memory_ldst.inc.h will be reused for the MemoryRegionCache slow path functions. Signed-off-by: Paolo Bonzini --- include/exec/cpu-all.h | 69 +++++-------- include/exec/memory.h | 151 ++++++++-------------------- include/exec/memory_ldst.inc.h | 71 +++++++++++++ include/exec/memory_ldst_phys.inc.h | 147 +++++++++++++++++++++++++++ memory_ldst.inc.c | 126 ----------------------- 5 files changed, 288 insertions(+), 276 deletions(-) create mode 100644 include/exec/memory_ldst.inc.h create mode 100644 include/exec/memory_ldst_phys.inc.h diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index f4fa94e966..173edd1fb4 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -168,51 +168,36 @@ extern unsigned long reserved_va; #else #include "exec/hwaddr.h" -uint32_t lduw_phys(AddressSpace *as, hwaddr addr); -uint32_t ldl_phys(AddressSpace *as, hwaddr addr); -uint64_t ldq_phys(AddressSpace *as, hwaddr addr); -void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val); -void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val); -uint32_t address_space_lduw(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_ldl(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint64_t address_space_ldq(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stw(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stl(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stq(AddressSpace *as, hwaddr addr, uint64_t val, - MemTxAttrs attrs, MemTxResult *result); +#define SUFFIX +#define ARG1 as +#define ARG1_DECL AddressSpace *as +#define TARGET_ENDIANNESS +#include "exec/memory_ldst.inc.h" -uint32_t lduw_phys_cached(MemoryRegionCache *cache, hwaddr addr); -uint32_t ldl_phys_cached(MemoryRegionCache *cache, hwaddr addr); -uint64_t ldq_phys_cached(MemoryRegionCache *cache, hwaddr addr); -void stl_phys_notdirty_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); -void stw_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); -void stl_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); -void stq_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val); +#define SUFFIX _cached +#define ARG1 cache +#define ARG1_DECL MemoryRegionCache *cache +#define TARGET_ENDIANNESS +#include "exec/memory_ldst.inc.h" -uint32_t address_space_lduw_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_ldl_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint64_t address_space_ldq_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stl_notdirty_cached(MemoryRegionCache *cache, hwaddr addr, - uint32_t val, MemTxAttrs attrs, MemTxResult *result); -void address_space_stw_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stl_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stq_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val, - MemTxAttrs attrs, MemTxResult *result); +static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val) +{ + address_space_stl_notdirty(as, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +#define SUFFIX +#define ARG1 as +#define ARG1_DECL AddressSpace *as +#define TARGET_ENDIANNESS +#include "exec/memory_ldst_phys.inc.h" + +#define SUFFIX _cached +#define ARG1 cache +#define ARG1_DECL MemoryRegionCache *cache +#define TARGET_ENDIANNESS +#include "exec/memory_ldst_phys.inc.h" #endif /* page related stuff */ diff --git a/include/exec/memory.h b/include/exec/memory.h index 31eae0a640..ca361bc409 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1676,49 +1676,16 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, * @result: location to write the success/failure of the transaction; * if NULL, this information is discarded */ -uint32_t address_space_ldub(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_lduw_le(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_lduw_be(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_ldl_le(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_ldl_be(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint64_t address_space_ldq_le(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint64_t address_space_ldq_be(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stb(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stw_le(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stw_be(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stl_le(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stl_be(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stq_le(AddressSpace *as, hwaddr addr, uint64_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stq_be(AddressSpace *as, hwaddr addr, uint64_t val, - MemTxAttrs attrs, MemTxResult *result); -uint32_t ldub_phys(AddressSpace *as, hwaddr addr); -uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr); -uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr); -uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr); -uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr); -uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr); -uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr); -void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val); -void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val); +#define SUFFIX +#define ARG1 as +#define ARG1_DECL AddressSpace *as +#include "exec/memory_ldst.inc.h" + +#define SUFFIX +#define ARG1 as +#define ARG1_DECL AddressSpace *as +#include "exec/memory_ldst_phys.inc.h" struct MemoryRegionCache { hwaddr xlat; @@ -1728,6 +1695,40 @@ struct MemoryRegionCache { #define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .as = NULL }) +/* address_space_ld*_cached: load from a cached #MemoryRegion + * address_space_st*_cached: store into a cached #MemoryRegion + * + * These functions perform a load or store of the byte, word, + * longword or quad to the specified address. The address is + * a physical address in the AddressSpace, but it must lie within + * a #MemoryRegion that was mapped with address_space_cache_init. + * + * The _le suffixed functions treat the data as little endian; + * _be indicates big endian; no suffix indicates "same endianness + * as guest CPU". + * + * The "guest CPU endianness" accessors are deprecated for use outside + * target-* code; devices should be CPU-agnostic and use either the LE + * or the BE accessors. + * + * @cache: previously initialized #MemoryRegionCache to be accessed + * @addr: address within the address space + * @val: data value, for stores + * @attrs: memory transaction attributes + * @result: location to write the success/failure of the transaction; + * if NULL, this information is discarded + */ + +#define SUFFIX _cached +#define ARG1 cache +#define ARG1_DECL MemoryRegionCache *cache +#include "exec/memory_ldst.inc.h" + +#define SUFFIX _cached +#define ARG1 cache +#define ARG1_DECL MemoryRegionCache *cache +#include "exec/memory_ldst_phys.inc.h" + /* address_space_cache_init: prepare for repeated access to a physical * memory region * @@ -1772,72 +1773,6 @@ void address_space_cache_invalidate(MemoryRegionCache *cache, */ void address_space_cache_destroy(MemoryRegionCache *cache); -/* address_space_ld*_cached: load from a cached #MemoryRegion - * address_space_st*_cached: store into a cached #MemoryRegion - * - * These functions perform a load or store of the byte, word, - * longword or quad to the specified address. The address is - * a physical address in the AddressSpace, but it must lie within - * a #MemoryRegion that was mapped with address_space_cache_init. - * - * The _le suffixed functions treat the data as little endian; - * _be indicates big endian; no suffix indicates "same endianness - * as guest CPU". - * - * The "guest CPU endianness" accessors are deprecated for use outside - * target-* code; devices should be CPU-agnostic and use either the LE - * or the BE accessors. - * - * @cache: previously initialized #MemoryRegionCache to be accessed - * @addr: address within the address space - * @val: data value, for stores - * @attrs: memory transaction attributes - * @result: location to write the success/failure of the transaction; - * if NULL, this information is discarded - */ -uint32_t address_space_ldub_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_lduw_le_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_lduw_be_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_ldl_le_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint32_t address_space_ldl_be_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint64_t address_space_ldq_le_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -uint64_t address_space_ldq_be_cached(MemoryRegionCache *cache, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stb_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stw_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stw_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stl_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stl_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stq_le_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val, - MemTxAttrs attrs, MemTxResult *result); -void address_space_stq_be_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val, - MemTxAttrs attrs, MemTxResult *result); - -uint32_t ldub_phys_cached(MemoryRegionCache *cache, hwaddr addr); -uint32_t lduw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr); -uint32_t lduw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr); -uint32_t ldl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr); -uint32_t ldl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr); -uint64_t ldq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr); -uint64_t ldq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr); -void stb_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); -void stw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); -void stw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); -void stl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); -void stl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); -void stq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val); -void stq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val); /* address_space_get_iotlb_entry: translate an address into an IOTLB * entry. Should be called from an RCU critical section. */ diff --git a/include/exec/memory_ldst.inc.h b/include/exec/memory_ldst.inc.h new file mode 100644 index 0000000000..272c20f02e --- /dev/null +++ b/include/exec/memory_ldst.inc.h @@ -0,0 +1,71 @@ +/* + * Physical memory access templates + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2015 Linaro, Inc. + * Copyright (c) 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifdef TARGET_ENDIANNESS +extern uint32_t glue(address_space_lduw, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern uint32_t glue(address_space_ldl, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern uint64_t glue(address_space_ldq, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stw, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stl, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stq, SUFFIX)(ARG1_DECL, + hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result); +#else +extern uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern uint32_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern uint32_t glue(address_space_ldl_le, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern uint64_t glue(address_space_ldq_le, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stb, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stw_le, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stw_be, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stl_le, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stl_be, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stq_le, SUFFIX)(ARG1_DECL, + hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result); +extern void glue(address_space_stq_be, SUFFIX)(ARG1_DECL, + hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result); +#endif + +#undef ARG1_DECL +#undef ARG1 +#undef SUFFIX +#undef TARGET_ENDIANNESS diff --git a/include/exec/memory_ldst_phys.inc.h b/include/exec/memory_ldst_phys.inc.h new file mode 100644 index 0000000000..91f72973cb --- /dev/null +++ b/include/exec/memory_ldst_phys.inc.h @@ -0,0 +1,147 @@ +/* + * Physical memory access templates + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2015 Linaro, Inc. + * Copyright (c) 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifdef TARGET_ENDIANNESS +static inline uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldl, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldq, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_lduw, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stl, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stw, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) +{ + glue(address_space_stq, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} +#else +static inline uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldl_le, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint32_t glue(ldl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldl_be, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint64_t glue(ldq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldq_le, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldq_be, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldub, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_lduw_le, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_lduw_be, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stl_le, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stl_be, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stb, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stw_le, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stw_be, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) +{ + glue(address_space_stq_le, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static inline void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) +{ + glue(address_space_stq_be, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} +#endif + +#undef ARG1_DECL +#undef ARG1 +#undef SUFFIX +#undef TARGET_ENDIANNESS diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c index 5dbff9cef8..25d6125747 100644 --- a/memory_ldst.inc.c +++ b/memory_ldst.inc.c @@ -95,24 +95,6 @@ uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL, DEVICE_BIG_ENDIAN); } -uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_ldl, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_ldl_le, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint32_t glue(ldl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_ldl_be, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - /* warning: addr must be aligned */ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result, @@ -189,24 +171,6 @@ uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL, DEVICE_BIG_ENDIAN); } -uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_ldq, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint64_t glue(ldq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_ldq_le, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_ldq_be, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result) { @@ -241,12 +205,6 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, return val; } -uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_ldub, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - /* warning: addr must be aligned */ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result, @@ -323,24 +281,6 @@ uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL, DEVICE_BIG_ENDIAN); } -uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_lduw, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_lduw_le, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) -{ - return glue(address_space_lduw_be, SUFFIX)(ARG1, addr, - MEMTXATTRS_UNSPECIFIED, NULL); -} - /* warning: addr must be aligned. The ram page is not masked as dirty and the code inside is not invalidated. It is useful if the dirty bits are used to track modified PTEs */ @@ -380,12 +320,6 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL, RCU_READ_UNLOCK(); } -void glue(stl_phys_notdirty, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stl_notdirty, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - /* warning: addr must be aligned */ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val, MemTxAttrs attrs, @@ -460,24 +394,6 @@ void glue(address_space_stl_be, SUFFIX)(ARG1_DECL, result, DEVICE_BIG_ENDIAN); } -void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stl, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stl_le, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stl_be, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - void glue(address_space_stb, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) { @@ -509,12 +425,6 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL, RCU_READ_UNLOCK(); } -void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stb, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - /* warning: addr must be aligned */ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val, MemTxAttrs attrs, @@ -589,24 +499,6 @@ void glue(address_space_stw_be, SUFFIX)(ARG1_DECL, DEVICE_BIG_ENDIAN); } -void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stw, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stw_le, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) -{ - glue(address_space_stw_be, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result, enum device_endian endian) @@ -680,24 +572,6 @@ void glue(address_space_stq_be, SUFFIX)(ARG1_DECL, DEVICE_BIG_ENDIAN); } -void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) -{ - glue(address_space_stq, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) -{ - glue(address_space_stq_le, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - -void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) -{ - glue(address_space_stq_be, SUFFIX)(ARG1, addr, val, - MEMTXATTRS_UNSPECIFIED, NULL); -} - #undef ARG1_DECL #undef ARG1 #undef SUFFIX From ad2804d9e47df2dab642a253502b5ceef233f450 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 17 Apr 2018 11:39:35 +0200 Subject: [PATCH 08/29] exec: small changes to flatview_do_translate Prepare for extracting the IOMMU part to a separate function. Mostly cosmetic; the only semantic change is that, if there is more than one cascaded IOMMU and the second one fails to translate, *plen_out is now adjusted according to the page mask of the first IOMMU. Reviewed-by: Peter Xu Signed-off-by: Paolo Bonzini --- exec.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/exec.c b/exec.c index c7fcefa851..8354cdcaf2 100644 --- a/exec.c +++ b/exec.c @@ -476,6 +476,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x * would tell. It can be @NULL if we don't care about it. * @is_write: whether the translation operation is for write * @is_mmio: whether this can be MMIO, set true if it can + * @target_as: the address space targeted by the IOMMU * * This function is called from RCU critical section */ @@ -495,14 +496,14 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv, hwaddr page_mask = (hwaddr)(-1); hwaddr plen = (hwaddr)(-1); - if (plen_out) { - plen = *plen_out; + if (!plen_out) { + plen_out = &plen; } for (;;) { section = address_space_translate_internal( - flatview_to_dispatch(fv), addr, &addr, - &plen, is_mmio); + flatview_to_dispatch(fv), addr, xlat, + plen_out, is_mmio); iommu_mr = memory_region_get_iommu(section->mr); if (!iommu_mr) { @@ -510,35 +511,29 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv, } imrc = memory_region_get_iommu_class_nocheck(iommu_mr); + addr = *xlat; iotlb = imrc->translate(iommu_mr, addr, is_write ? IOMMU_WO : IOMMU_RO); - addr = ((iotlb.translated_addr & ~iotlb.addr_mask) - | (addr & iotlb.addr_mask)); - page_mask &= iotlb.addr_mask; - plen = MIN(plen, (addr | iotlb.addr_mask) - addr + 1); if (!(iotlb.perm & (1 << is_write))) { goto translate_fail; } + addr = ((iotlb.translated_addr & ~iotlb.addr_mask) + | (addr & iotlb.addr_mask)); + page_mask &= iotlb.addr_mask; + *plen_out = MIN(*plen_out, (addr | iotlb.addr_mask) - addr + 1); fv = address_space_to_flatview(iotlb.target_as); *target_as = iotlb.target_as; } - *xlat = addr; - - if (page_mask == (hwaddr)(-1)) { - /* Not behind an IOMMU, use default page size. */ - page_mask = ~TARGET_PAGE_MASK; - } - if (page_mask_out) { + if (page_mask == (hwaddr)(-1)) { + /* Not behind an IOMMU, use default page size. */ + page_mask = ~TARGET_PAGE_MASK; + } *page_mask_out = page_mask; } - if (plen_out) { - *plen_out = plen; - } - return *section; translate_fail: From a411c84b561baa94b28165c52f21c33517ee8f59 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 3 Mar 2018 17:24:04 +0100 Subject: [PATCH 09/29] exec: extract address_space_translate_iommu, fix page_mask corner case This will be used to process IOMMUs in a MemoryRegionCache. This includes a small bugfix, in that the returned page_mask is now correctly -1 if the IOMMU memory region maps the entire address space directly. Previously, address_space_get_iotlb_entry would return ~TARGET_PAGE_MASK. Reviewed-by: Peter Xu Signed-off-by: Paolo Bonzini --- exec.c | 110 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 35 deletions(-) diff --git a/exec.c b/exec.c index 8354cdcaf2..5f98106d33 100644 --- a/exec.c +++ b/exec.c @@ -461,6 +461,70 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x return section; } +/** + * address_space_translate_iommu - translate an address through an IOMMU + * memory region and then through the target address space. + * + * @iommu_mr: the IOMMU memory region that we start the translation from + * @addr: the address to be translated through the MMU + * @xlat: the translated address offset within the destination memory region. + * It cannot be %NULL. + * @plen_out: valid read/write length of the translated address. It + * cannot be %NULL. + * @page_mask_out: page mask for the translated address. This + * should only be meaningful for IOMMU translated + * addresses, since there may be huge pages that this bit + * would tell. It can be %NULL if we don't care about it. + * @is_write: whether the translation operation is for write + * @is_mmio: whether this can be MMIO, set true if it can + * @target_as: the address space targeted by the IOMMU + * + * This function is called from RCU critical section. It is the common + * part of flatview_do_translate and address_space_translate_cached. + */ +static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iommu_mr, + hwaddr *xlat, + hwaddr *plen_out, + hwaddr *page_mask_out, + bool is_write, + bool is_mmio, + AddressSpace **target_as) +{ + MemoryRegionSection *section; + hwaddr page_mask = (hwaddr)-1; + + do { + hwaddr addr = *xlat; + IOMMUMemoryRegionClass *imrc = memory_region_get_iommu_class_nocheck(iommu_mr); + IOMMUTLBEntry iotlb = imrc->translate(iommu_mr, addr, is_write ? + IOMMU_WO : IOMMU_RO); + + if (!(iotlb.perm & (1 << is_write))) { + goto unassigned; + } + + addr = ((iotlb.translated_addr & ~iotlb.addr_mask) + | (addr & iotlb.addr_mask)); + page_mask &= iotlb.addr_mask; + *plen_out = MIN(*plen_out, (addr | iotlb.addr_mask) - addr + 1); + *target_as = iotlb.target_as; + + section = address_space_translate_internal( + address_space_to_dispatch(iotlb.target_as), addr, xlat, + plen_out, is_mmio); + + iommu_mr = memory_region_get_iommu(section->mr); + } while (unlikely(iommu_mr)); + + if (page_mask_out) { + *page_mask_out = page_mask; + } + return *section; + +unassigned: + return (MemoryRegionSection) { .mr = &io_mem_unassigned }; +} + /** * flatview_do_translate - translate an address in FlatView * @@ -489,55 +553,31 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv, bool is_mmio, AddressSpace **target_as) { - IOMMUTLBEntry iotlb; MemoryRegionSection *section; IOMMUMemoryRegion *iommu_mr; - IOMMUMemoryRegionClass *imrc; - hwaddr page_mask = (hwaddr)(-1); hwaddr plen = (hwaddr)(-1); if (!plen_out) { plen_out = &plen; } - for (;;) { - section = address_space_translate_internal( - flatview_to_dispatch(fv), addr, xlat, - plen_out, is_mmio); + section = address_space_translate_internal( + flatview_to_dispatch(fv), addr, xlat, + plen_out, is_mmio); - iommu_mr = memory_region_get_iommu(section->mr); - if (!iommu_mr) { - break; - } - imrc = memory_region_get_iommu_class_nocheck(iommu_mr); - - addr = *xlat; - iotlb = imrc->translate(iommu_mr, addr, is_write ? - IOMMU_WO : IOMMU_RO); - if (!(iotlb.perm & (1 << is_write))) { - goto translate_fail; - } - - addr = ((iotlb.translated_addr & ~iotlb.addr_mask) - | (addr & iotlb.addr_mask)); - page_mask &= iotlb.addr_mask; - *plen_out = MIN(*plen_out, (addr | iotlb.addr_mask) - addr + 1); - fv = address_space_to_flatview(iotlb.target_as); - *target_as = iotlb.target_as; + iommu_mr = memory_region_get_iommu(section->mr); + if (unlikely(iommu_mr)) { + return address_space_translate_iommu(iommu_mr, xlat, + plen_out, page_mask_out, + is_write, is_mmio, + target_as); } - if (page_mask_out) { - if (page_mask == (hwaddr)(-1)) { - /* Not behind an IOMMU, use default page size. */ - page_mask = ~TARGET_PAGE_MASK; - } - *page_mask_out = page_mask; + /* Not behind an IOMMU, use default page size. */ + *page_mask_out = ~TARGET_PAGE_MASK; } return *section; - -translate_fail: - return (MemoryRegionSection) { .mr = &io_mem_unassigned }; } /* Called from RCU critical section */ From 48564041a73adbbff52834f9edbe3806fceefab7 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sun, 18 Mar 2018 18:26:36 +0100 Subject: [PATCH 10/29] exec: reintroduce MemoryRegion caching MemoryRegionCache was reverted to "normal" address_space_* operations for 2.9, due to lack of support for IOMMUs. Reinstate the optimizations, caching only the IOMMU translation at address_cache_init but not the IOMMU lookup and target AddressSpace translation are not cached; now that MemoryRegionCache supports IOMMUs, it becomes more widely applicable too. The inlined fast path is defined in memory_ldst_cached.inc.h, while the slow path uses memory_ldst.inc.c as before. The smaller fast path causes a little code size reduction in MemoryRegionCache users: hw/virtio/virtio.o text size before: 32373 hw/virtio/virtio.o text size after: 31941 Signed-off-by: Paolo Bonzini --- exec.c | 121 +++++++++++++++++++++++--- include/exec/cpu-all.h | 6 +- include/exec/memory-internal.h | 3 + include/exec/memory.h | 58 ++++++++++-- include/exec/memory_ldst_cached.inc.h | 108 +++++++++++++++++++++++ memory.c | 4 +- 6 files changed, 280 insertions(+), 20 deletions(-) create mode 100644 include/exec/memory_ldst_cached.inc.h diff --git a/exec.c b/exec.c index 5f98106d33..ffa1099547 100644 --- a/exec.c +++ b/exec.c @@ -3641,33 +3641,130 @@ int64_t address_space_cache_init(MemoryRegionCache *cache, hwaddr len, bool is_write) { - cache->len = len; - cache->as = as; - cache->xlat = addr; - return len; + AddressSpaceDispatch *d; + hwaddr l; + MemoryRegion *mr; + + assert(len > 0); + + l = len; + cache->fv = address_space_get_flatview(as); + d = flatview_to_dispatch(cache->fv); + cache->mrs = *address_space_translate_internal(d, addr, &cache->xlat, &l, true); + + mr = cache->mrs.mr; + memory_region_ref(mr); + if (memory_access_is_direct(mr, is_write)) { + l = flatview_extend_translation(cache->fv, addr, len, mr, + cache->xlat, l, is_write); + cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true); + } else { + cache->ptr = NULL; + } + + cache->len = l; + cache->is_write = is_write; + return l; } void address_space_cache_invalidate(MemoryRegionCache *cache, hwaddr addr, hwaddr access_len) { + assert(cache->is_write); + if (likely(cache->ptr)) { + invalidate_and_set_dirty(cache->mrs.mr, addr + cache->xlat, access_len); + } } void address_space_cache_destroy(MemoryRegionCache *cache) { - cache->as = NULL; + if (!cache->mrs.mr) { + return; + } + + if (xen_enabled()) { + xen_invalidate_map_cache_entry(cache->ptr); + } + memory_region_unref(cache->mrs.mr); + flatview_unref(cache->fv); + cache->mrs.mr = NULL; + cache->fv = NULL; +} + +/* Called from RCU critical section. This function has the same + * semantics as address_space_translate, but it only works on a + * predefined range of a MemoryRegion that was mapped with + * address_space_cache_init. + */ +static inline MemoryRegion *address_space_translate_cached( + MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat, + hwaddr *plen, bool is_write) +{ + MemoryRegionSection section; + MemoryRegion *mr; + IOMMUMemoryRegion *iommu_mr; + AddressSpace *target_as; + + assert(!cache->ptr); + *xlat = addr + cache->xlat; + + mr = cache->mrs.mr; + iommu_mr = memory_region_get_iommu(mr); + if (!iommu_mr) { + /* MMIO region. */ + return mr; + } + + section = address_space_translate_iommu(iommu_mr, xlat, plen, + NULL, is_write, true, + &target_as); + return section.mr; +} + +/* Called from RCU critical section. address_space_read_cached uses this + * out of line function when the target is an MMIO or IOMMU region. + */ +void +address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr, + void *buf, int len) +{ + hwaddr addr1, l; + MemoryRegion *mr; + + l = len; + mr = address_space_translate_cached(cache, addr, &addr1, &l, false); + flatview_read_continue(cache->fv, + addr, MEMTXATTRS_UNSPECIFIED, buf, len, + addr1, l, mr); +} + +/* Called from RCU critical section. address_space_write_cached uses this + * out of line function when the target is an MMIO or IOMMU region. + */ +void +address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr, + const void *buf, int len) +{ + hwaddr addr1, l; + MemoryRegion *mr; + + l = len; + mr = address_space_translate_cached(cache, addr, &addr1, &l, true); + flatview_write_continue(cache->fv, + addr, MEMTXATTRS_UNSPECIFIED, buf, len, + addr1, l, mr); } #define ARG1_DECL MemoryRegionCache *cache #define ARG1 cache -#define SUFFIX _cached -#define TRANSLATE(addr, ...) \ - address_space_translate(cache->as, cache->xlat + (addr), __VA_ARGS__) -#define IS_DIRECT(mr, is_write) true -#define MAP_RAM(mr, ofs) qemu_map_ram_ptr((mr)->ram_block, ofs) +#define SUFFIX _cached_slow +#define TRANSLATE(...) address_space_translate_cached(cache, __VA_ARGS__) +#define IS_DIRECT(mr, is_write) memory_access_is_direct(mr, is_write) +#define MAP_RAM(mr, ofs) (cache->ptr + (ofs - cache->xlat)) #define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len) -#define RCU_READ_LOCK() rcu_read_lock() -#define RCU_READ_UNLOCK() rcu_read_unlock() +#define RCU_READ_LOCK() ((void)0) +#define RCU_READ_UNLOCK() ((void)0) #include "memory_ldst.inc.c" /* virtual memory access for debug (includes writing to ROM) */ diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 173edd1fb4..a635f532f9 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -175,7 +175,7 @@ extern unsigned long reserved_va; #define TARGET_ENDIANNESS #include "exec/memory_ldst.inc.h" -#define SUFFIX _cached +#define SUFFIX _cached_slow #define ARG1 cache #define ARG1_DECL MemoryRegionCache *cache #define TARGET_ENDIANNESS @@ -193,6 +193,10 @@ static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val #define TARGET_ENDIANNESS #include "exec/memory_ldst_phys.inc.h" +/* Inline fast path for direct RAM access. */ +#define ENDIANNESS +#include "exec/memory_ldst_cached.inc.h" + #define SUFFIX _cached #define ARG1 cache #define ARG1_DECL MemoryRegionCache *cache diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 6a5ee42d36..58399b9318 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -31,6 +31,9 @@ static inline AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as) return flatview_to_dispatch(address_space_to_flatview(as)); } +FlatView *address_space_get_flatview(AddressSpace *as); +void flatview_unref(FlatView *view); + extern const MemoryRegionOps unassigned_mem_ops; bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr, diff --git a/include/exec/memory.h b/include/exec/memory.h index ca361bc409..525619a5f4 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1688,12 +1688,16 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, #include "exec/memory_ldst_phys.inc.h" struct MemoryRegionCache { + void *ptr; hwaddr xlat; hwaddr len; - AddressSpace *as; + FlatView *fv; + MemoryRegionSection mrs; + bool is_write; }; -#define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .as = NULL }) +#define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .mrs.mr = NULL }) + /* address_space_ld*_cached: load from a cached #MemoryRegion * address_space_st*_cached: store into a cached #MemoryRegion @@ -1719,11 +1723,40 @@ struct MemoryRegionCache { * if NULL, this information is discarded */ -#define SUFFIX _cached +#define SUFFIX _cached_slow #define ARG1 cache #define ARG1_DECL MemoryRegionCache *cache #include "exec/memory_ldst.inc.h" +/* Inline fast path for direct RAM access. */ +static inline uint8_t address_space_ldub_cached(MemoryRegionCache *cache, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + assert(addr < cache->len); + if (likely(cache->ptr)) { + return ldub_p(cache->ptr + addr); + } else { + return address_space_ldub_cached_slow(cache, addr, attrs, result); + } +} + +static inline void address_space_stb_cached(MemoryRegionCache *cache, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + assert(addr < cache->len); + if (likely(cache->ptr)) { + stb_p(cache->ptr + addr, val); + } else { + address_space_stb_cached_slow(cache, addr, val, attrs, result); + } +} + +#define ENDIANNESS _le +#include "exec/memory_ldst_cached.inc.h" + +#define ENDIANNESS _be +#include "exec/memory_ldst_cached.inc.h" + #define SUFFIX _cached #define ARG1 cache #define ARG1_DECL MemoryRegionCache *cache @@ -1860,6 +1893,13 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, MemoryRegion *mr); void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr); +/* Internal functions, part of the implementation of address_space_read_cached + * and address_space_write_cached. */ +void address_space_read_cached_slow(MemoryRegionCache *cache, + hwaddr addr, void *buf, int len); +void address_space_write_cached_slow(MemoryRegionCache *cache, + hwaddr addr, const void *buf, int len); + static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) { if (is_write) { @@ -1928,7 +1968,11 @@ address_space_read_cached(MemoryRegionCache *cache, hwaddr addr, void *buf, int len) { assert(addr < cache->len && len <= cache->len - addr); - address_space_read(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len); + if (likely(cache->ptr)) { + memcpy(buf, cache->ptr + addr, len); + } else { + address_space_read_cached_slow(cache, addr, buf, len); + } } /** @@ -1944,7 +1988,11 @@ address_space_write_cached(MemoryRegionCache *cache, hwaddr addr, void *buf, int len) { assert(addr < cache->len && len <= cache->len - addr); - address_space_write(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len); + if (likely(cache->ptr)) { + memcpy(cache->ptr + addr, buf, len); + } else { + address_space_write_cached_slow(cache, addr, buf, len); + } } #endif diff --git a/include/exec/memory_ldst_cached.inc.h b/include/exec/memory_ldst_cached.inc.h new file mode 100644 index 0000000000..fd4bbb40e7 --- /dev/null +++ b/include/exec/memory_ldst_cached.inc.h @@ -0,0 +1,108 @@ +/* + * Memory access templates for MemoryRegionCache + * + * Copyright (c) 2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#define ADDRESS_SPACE_LD_CACHED(size) \ + glue(glue(address_space_ld, size), glue(ENDIANNESS, _cached)) +#define ADDRESS_SPACE_LD_CACHED_SLOW(size) \ + glue(glue(address_space_ld, size), glue(ENDIANNESS, _cached_slow)) +#define LD_P(size) \ + glue(glue(ld, size), glue(ENDIANNESS, _p)) + +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); + if (likely(cache->ptr)) { + return LD_P(l)(cache->ptr + addr); + } else { + return ADDRESS_SPACE_LD_CACHED_SLOW(l)(cache, addr, attrs, result); + } +} + +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); + if (likely(cache->ptr)) { + return LD_P(q)(cache->ptr + addr); + } else { + return ADDRESS_SPACE_LD_CACHED_SLOW(q)(cache, addr, attrs, result); + } +} + +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); + if (likely(cache->ptr)) { + return LD_P(uw)(cache->ptr + addr); + } else { + return ADDRESS_SPACE_LD_CACHED_SLOW(uw)(cache, addr, attrs, result); + } +} + +#undef ADDRESS_SPACE_LD_CACHED +#undef ADDRESS_SPACE_LD_CACHED_SLOW +#undef LD_P + +#define ADDRESS_SPACE_ST_CACHED(size) \ + glue(glue(address_space_st, size), glue(ENDIANNESS, _cached)) +#define ADDRESS_SPACE_ST_CACHED_SLOW(size) \ + glue(glue(address_space_st, size), glue(ENDIANNESS, _cached_slow)) +#define ST_P(size) \ + glue(glue(st, size), glue(ENDIANNESS, _p)) + +static inline void ADDRESS_SPACE_ST_CACHED(l)(MemoryRegionCache *cache, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + assert(addr < cache->len && 4 <= cache->len - addr); + if (likely(cache->ptr)) { + ST_P(l)(cache->ptr + addr, val); + } else { + ADDRESS_SPACE_ST_CACHED_SLOW(l)(cache, addr, val, attrs, result); + } +} + +static inline void ADDRESS_SPACE_ST_CACHED(w)(MemoryRegionCache *cache, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + assert(addr < cache->len && 2 <= cache->len - addr); + if (likely(cache->ptr)) { + ST_P(w)(cache->ptr + addr, val); + } else { + ADDRESS_SPACE_ST_CACHED_SLOW(w)(cache, addr, val, attrs, result); + } +} + +static inline void ADDRESS_SPACE_ST_CACHED(q)(MemoryRegionCache *cache, + hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result) +{ + assert(addr < cache->len && 8 <= cache->len - addr); + if (likely(cache->ptr)) { + ST_P(q)(cache->ptr + addr, val); + } else { + ADDRESS_SPACE_ST_CACHED_SLOW(q)(cache, addr, val, attrs, result); + } +} + +#undef ADDRESS_SPACE_ST_CACHED +#undef ADDRESS_SPACE_ST_CACHED_SLOW +#undef ST_P + +#undef ENDIANNESS diff --git a/memory.c b/memory.c index e70b64b8b9..fc7f9b782b 100644 --- a/memory.c +++ b/memory.c @@ -298,7 +298,7 @@ static bool flatview_ref(FlatView *view) return atomic_fetch_inc_nonzero(&view->ref) > 0; } -static void flatview_unref(FlatView *view) +void flatview_unref(FlatView *view) { if (atomic_fetch_dec(&view->ref) == 1) { trace_flatview_destroy_rcu(view, view->root); @@ -822,7 +822,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as, } } -static FlatView *address_space_get_flatview(AddressSpace *as) +FlatView *address_space_get_flatview(AddressSpace *as) { FlatView *view; From d820fa5b62d2ae2311702bf307f1b91dc338fd25 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Thu, 12 Apr 2018 13:34:44 +0800 Subject: [PATCH 11/29] qemu-thread: always keep the posix wrapper layer We will conditionally have a wrapper layer depending on whether the host has the PTHREAD_SETNAME capability. It complicates stuff. Let's keep the wrapper there; we opt out the pthread_setname_np() call only. Signed-off-by: Peter Xu Message-Id: <20180412053444.17801-1-peterx@redhat.com> Reviewed-by: Fam Zheng Signed-off-by: Paolo Bonzini --- util/qemu-thread-posix.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index b789cf32e9..a1c34ba6f2 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -482,7 +482,6 @@ static void __attribute__((constructor)) qemu_thread_atexit_init(void) } -#ifdef CONFIG_PTHREAD_SETNAME_NP typedef struct { void *(*start_routine)(void *); void *arg; @@ -495,16 +494,18 @@ static void *qemu_thread_start(void *args) void *(*start_routine)(void *) = qemu_thread_args->start_routine; void *arg = qemu_thread_args->arg; +#ifdef CONFIG_PTHREAD_SETNAME_NP /* Attempt to set the threads name; note that this is for debug, so * we're not going to fail if we can't set it. */ - pthread_setname_np(pthread_self(), qemu_thread_args->name); + if (name_threads && qemu_thread_args->name) { + pthread_setname_np(pthread_self(), qemu_thread_args->name); + } +#endif g_free(qemu_thread_args->name); g_free(qemu_thread_args); return start_routine(arg); } -#endif - void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void*), @@ -513,6 +514,7 @@ void qemu_thread_create(QemuThread *thread, const char *name, sigset_t set, oldset; int err; pthread_attr_t attr; + QemuThreadArgs *qemu_thread_args; err = pthread_attr_init(&attr); if (err) { @@ -527,22 +529,13 @@ void qemu_thread_create(QemuThread *thread, const char *name, sigfillset(&set); pthread_sigmask(SIG_SETMASK, &set, &oldset); -#ifdef CONFIG_PTHREAD_SETNAME_NP - if (name_threads) { - QemuThreadArgs *qemu_thread_args; - qemu_thread_args = g_new0(QemuThreadArgs, 1); - qemu_thread_args->name = g_strdup(name); - qemu_thread_args->start_routine = start_routine; - qemu_thread_args->arg = arg; + qemu_thread_args = g_new0(QemuThreadArgs, 1); + qemu_thread_args->name = g_strdup(name); + qemu_thread_args->start_routine = start_routine; + qemu_thread_args->arg = arg; - err = pthread_create(&thread->thread, &attr, - qemu_thread_start, qemu_thread_args); - } else -#endif - { - err = pthread_create(&thread->thread, &attr, - start_routine, arg); - } + err = pthread_create(&thread->thread, &attr, + qemu_thread_start, qemu_thread_args); if (err) error_exit(err, __func__); From 7afcfd32a65688401cba337eb99f65dc24d9750e Mon Sep 17 00:00:00 2001 From: Roman Kagan Date: Fri, 13 Apr 2018 17:33:54 +0300 Subject: [PATCH 12/29] update-linux-headers: drop hyperv.h As of mainline linux commit 5a485803221777013944cbd1a7cd5c62efba3ffa "x86/hyper-v: move hyperv.h out of uapi" by Vitaly Kuznetsov, no linux uapi header includes it, so we no longer need to create a stub for it. Cc: Vitaly Kuznetsov Signed-off-by: Roman Kagan Message-Id: <20180413143354.17614-1-rkagan@virtuozzo.com> Signed-off-by: Paolo Bonzini --- scripts/update-linux-headers.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index 5b1d8dcdf4..b65c03f0ae 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -118,9 +118,6 @@ for arch in $ARCHLIST; do cp "$tmpdir/include/asm/unistd-common.h" "$output/linux-headers/asm-arm/" fi if [ $arch = x86 ]; then - cat <<-EOF >"$output/include/standard-headers/asm-x86/hyperv.h" - /* this is a temporary placeholder until kvm_para.h stops including it */ -EOF cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/" cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/" cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/" @@ -144,9 +141,6 @@ else cp "$linux/COPYING" "$output/linux-headers" fi -cat <$output/linux-headers/asm-x86/hyperv.h -#include "standard-headers/asm-x86/hyperv.h" -EOF cat <$output/linux-headers/linux/virtio_config.h #include "standard-headers/linux/virtio_config.h" EOF From 20efc49ed625585809401d8293ad9267927a6a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 16 Apr 2018 12:17:41 +0100 Subject: [PATCH 13/29] accel: use g_strsplit for parsing accelerator names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of re-using the get_opt_name() method from QemuOpts to split a string on ':', just use g_strsplit(). Signed-off-by: Daniel P. Berrangé Message-Id: <20180416111743.8473-2-berrange@redhat.com> Signed-off-by: Paolo Bonzini Signed-off-by: Daniel P. Berrangé --- accel/accel.c | 16 +++++++--------- include/qemu/option.h | 1 - util/qemu-option.c | 3 ++- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/accel/accel.c b/accel/accel.c index 9cfab115d0..966b2d8f53 100644 --- a/accel/accel.c +++ b/accel/accel.c @@ -70,8 +70,8 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms) void configure_accelerator(MachineState *ms) { - const char *accel, *p; - char buf[10]; + const char *accel; + char **accel_list, **tmp; int ret; bool accel_initialised = false; bool init_failed = false; @@ -83,13 +83,10 @@ void configure_accelerator(MachineState *ms) accel = "tcg"; } - p = accel; - while (!accel_initialised && *p != '\0') { - if (*p == ':') { - p++; - } - p = get_opt_name(buf, sizeof(buf), p, ':'); - acc = accel_find(buf); + accel_list = g_strsplit(accel, ":", 0); + + for (tmp = accel_list; !accel_initialised && tmp && *tmp; tmp++) { + acc = accel_find(*tmp); if (!acc) { continue; } @@ -107,6 +104,7 @@ void configure_accelerator(MachineState *ms) accel_initialised = true; } } + g_strfreev(accel_list); if (!accel_initialised) { if (!init_failed) { diff --git a/include/qemu/option.h b/include/qemu/option.h index 306fdb5f7a..1cfe5cbc2d 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -28,7 +28,6 @@ #include "qemu/queue.h" -const char *get_opt_name(char *buf, int buf_size, const char *p, char delim); const char *get_opt_value(char *buf, int buf_size, const char *p); void parse_option_size(const char *name, const char *value, diff --git a/util/qemu-option.c b/util/qemu-option.c index d0756fda58..baca40fb94 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -49,7 +49,8 @@ * The return value is the position of the delimiter/zero byte after the option * name in p. */ -const char *get_opt_name(char *buf, int buf_size, const char *p, char delim) +static const char *get_opt_name(char *buf, int buf_size, const char *p, + char delim) { char *q; From e652714f98f22e8882e88e3d563b025c5b00feec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 16 Apr 2018 12:17:42 +0100 Subject: [PATCH 14/29] opts: don't silently truncate long parameter keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing QemuOpts parsing code uses a fixed size 128 byte buffer for storing the parameter keys. If a key exceeded this size it was silently truncate and no error reported to the user. This behaviour was reasonable & harmless because traditionally the key names are all statically declared, and it was known that no code was declaring a key longer than 127 bytes. This assumption, however, ceased to be valid once the block layer added support for dot-separate compound keys. This syntax allows for keys that can be arbitrarily long, limited only by the number of block drivers you can stack up. With this usage, silently truncating the key name can never lead to correct behaviour. Hopefully such truncation would turn into an error, when the block code then tried to extract options later, but there's no guarantee that will happen. It is conceivable that an option specified by the user may be truncated and then ignored. This could have serious consequences, possibly even leading to security problems if the ignored option set a security relevant parameter. If the operating system didn't limit the user's argv when spawning QEMU, the code should honour whatever length arguments were given without imposing its own length restrictions. This patch thus changes the code to use a heap allocated buffer for storing the keys during parsing, lifting the arbitrary length restriction. Signed-off-by: Daniel P. Berrangé Message-Id: <20180416111743.8473-3-berrange@redhat.com> Signed-off-by: Paolo Bonzini Signed-off-by: Daniel P. Berrangé --- tests/test-qemu-opts.c | 18 ----------------- util/qemu-option.c | 44 +++++++++++++++++++++--------------------- 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c index 77dd72b403..7092e216f7 100644 --- a/tests/test-qemu-opts.c +++ b/tests/test-qemu-opts.c @@ -459,8 +459,6 @@ static void test_opts_parse(void) { Error *err = NULL; QemuOpts *opts; - char long_key[129]; - char *params; /* Nothing */ opts = qemu_opts_parse(&opts_list_03, "", false, &error_abort); @@ -471,22 +469,6 @@ static void test_opts_parse(void) g_assert_cmpuint(opts_count(opts), ==, 1); g_assert_cmpstr(qemu_opt_get(opts, ""), ==, "val"); - /* Long key */ - memset(long_key, 'a', 127); - long_key[127] = 'z'; - long_key[128] = 0; - params = g_strdup_printf("%s=v", long_key); - opts = qemu_opts_parse(&opts_list_03, params + 1, NULL, &error_abort); - g_assert_cmpuint(opts_count(opts), ==, 1); - g_assert_cmpstr(qemu_opt_get(opts, long_key + 1), ==, "v"); - - /* Overlong key gets truncated */ - opts = qemu_opts_parse(&opts_list_03, params, NULL, &error_abort); - g_assert(opts_count(opts) == 1); - long_key[127] = 0; - g_assert_cmpstr(qemu_opt_get(opts, long_key), ==, "v"); - g_free(params); - /* Multiple keys, last one wins */ opts = qemu_opts_parse(&opts_list_03, "a=1,b=2,,x,a=3", false, &error_abort); diff --git a/util/qemu-option.c b/util/qemu-option.c index baca40fb94..fa1a9f17fc 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -43,27 +43,23 @@ * first byte of the option name) * * The option name is delimited by delim (usually , or =) or the string end - * and is copied into buf. If the option name is longer than buf_size, it is - * truncated. buf is always zero terminated. + * and is copied into option. The caller is responsible for free'ing option + * when no longer required. * * The return value is the position of the delimiter/zero byte after the option * name in p. */ -static const char *get_opt_name(char *buf, int buf_size, const char *p, - char delim) +static const char *get_opt_name(const char *p, char **option, char delim) { - char *q; + char *offset = strchr(p, delim); - q = buf; - while (*p != '\0' && *p != delim) { - if (q && (q - buf) < buf_size - 1) - *q++ = *p; - p++; + if (offset) { + *option = g_strndup(p, offset - p); + return offset; + } else { + *option = g_strdup(p); + return p + strlen(p); } - if (q) - *q = '\0'; - - return p; } /* @@ -758,7 +754,8 @@ void qemu_opts_print(QemuOpts *opts, const char *separator) static void opts_do_parse(QemuOpts *opts, const char *params, const char *firstname, bool prepend, Error **errp) { - char option[128], value[1024]; + char *option = NULL; + char value[1024]; const char *p,*pe,*pc; Error *local_err = NULL; @@ -769,11 +766,11 @@ static void opts_do_parse(QemuOpts *opts, const char *params, /* found "foo,more" */ if (p == params && firstname) { /* implicitly named first option */ - pstrcpy(option, sizeof(option), firstname); + option = g_strdup(firstname); p = get_opt_value(value, sizeof(value), p); } else { /* option without value, probably a flag */ - p = get_opt_name(option, sizeof(option), p, ','); + p = get_opt_name(p, &option, ','); if (strncmp(option, "no", 2) == 0) { memmove(option, option+2, strlen(option+2)+1); pstrcpy(value, sizeof(value), "off"); @@ -783,10 +780,8 @@ static void opts_do_parse(QemuOpts *opts, const char *params, } } else { /* found "foo=bar,more" */ - p = get_opt_name(option, sizeof(option), p, '='); - if (*p != '=') { - break; - } + p = get_opt_name(p, &option, '='); + assert(*p == '='); p++; p = get_opt_value(value, sizeof(value), p); } @@ -795,13 +790,18 @@ static void opts_do_parse(QemuOpts *opts, const char *params, opt_set(opts, option, value, prepend, &local_err); if (local_err) { error_propagate(errp, local_err); - return; + goto cleanup; } } if (*p != ',') { break; } + g_free(option); + option = NULL; } + + cleanup: + g_free(option); } /** From 950c4e6c94b15cd0d8b63891dddd7a8dbf458e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Mon, 16 Apr 2018 12:17:43 +0100 Subject: [PATCH 15/29] opts: don't silently truncate long option values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing QemuOpts parsing code uses a fixed size 1024 byte buffer for storing the option values. If a value exceeded this size it was silently truncated and no error reported to the user. Long option values is not a common scenario, but it is conceivable that they will happen. eg if the user has a very deeply nested filesystem it would be possible to come up with a disk path that was > 1024 bytes. Most of the time if such data was silently truncated, the user would get an error about opening a non-existant disk. If they're unlucky though, QEMU might use a completely different disk image from another VM, which could be considered a security issue. Another example program was in using the -smbios command line arg with very large data blobs. In this case the silent truncation will be providing semantically incorrect data to the guest OS for SMBIOS tables. If the operating system didn't limit the user's argv when spawning QEMU, the code should honour whatever length arguments were given without imposing its own length restrictions. This patch thus changes the code to use a heap allocated buffer for storing the values during parsing, lifting the arbitrary length restriction. Signed-off-by: Daniel P. Berrangé Message-Id: <20180416111743.8473-4-berrange@redhat.com> Signed-off-by: Paolo Bonzini Signed-off-by: Daniel P. Berrangé --- hw/i386/multiboot.c | 33 +++++++----- include/qemu/option.h | 2 +- util/qemu-option.c | 113 ++++++++++++++++++++++-------------------- 3 files changed, 82 insertions(+), 66 deletions(-) diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index 5bc0a2cddb..7a2953e26f 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -291,12 +291,16 @@ int load_multiboot(FWCfgState *fw_cfg, cmdline_len = strlen(kernel_filename) + 1; cmdline_len += strlen(kernel_cmdline) + 1; if (initrd_filename) { - const char *r = initrd_filename; + const char *r = get_opt_value(initrd_filename, NULL); cmdline_len += strlen(r) + 1; mbs.mb_mods_avail = 1; - while (*(r = get_opt_value(NULL, 0, r))) { - mbs.mb_mods_avail++; - r++; + while (1) { + mbs.mb_mods_avail++; + r = get_opt_value(r, NULL); + if (!*r) { + break; + } + r++; } } @@ -313,7 +317,8 @@ int load_multiboot(FWCfgState *fw_cfg, if (initrd_filename) { const char *next_initrd; - char not_last, tmpbuf[strlen(initrd_filename) + 1]; + char not_last; + char *one_file = NULL; mbs.offset_mods = mbs.mb_buf_size; @@ -322,24 +327,26 @@ int load_multiboot(FWCfgState *fw_cfg, int mb_mod_length; uint32_t offs = mbs.mb_buf_size; - next_initrd = get_opt_value(tmpbuf, sizeof(tmpbuf), initrd_filename); + next_initrd = get_opt_value(initrd_filename, &one_file); not_last = *next_initrd; /* if a space comes after the module filename, treat everything after that as parameters */ - hwaddr c = mb_add_cmdline(&mbs, tmpbuf); - if ((next_space = strchr(tmpbuf, ' '))) + hwaddr c = mb_add_cmdline(&mbs, one_file); + next_space = strchr(one_file, ' '); + if (next_space) { *next_space = '\0'; - mb_debug("multiboot loading module: %s", tmpbuf); - mb_mod_length = get_image_size(tmpbuf); + } + mb_debug("multiboot loading module: %s", one_file); + mb_mod_length = get_image_size(one_file); if (mb_mod_length < 0) { - error_report("Failed to open file '%s'", tmpbuf); + error_report("Failed to open file '%s'", one_file); exit(1); } mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_mod_length + mbs.mb_buf_size); mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size); - load_image(tmpbuf, (unsigned char *)mbs.mb_buf + offs); + load_image(one_file, (unsigned char *)mbs.mb_buf + offs); mb_add_mod(&mbs, mbs.mb_buf_phys + offs, mbs.mb_buf_phys + offs + mb_mod_length, c); @@ -347,6 +354,8 @@ int load_multiboot(FWCfgState *fw_cfg, (char *)mbs.mb_buf + offs, (char *)mbs.mb_buf + offs + mb_mod_length, c); initrd_filename = next_initrd+1; + g_free(one_file); + one_file = NULL; } while (not_last); } diff --git a/include/qemu/option.h b/include/qemu/option.h index 1cfe5cbc2d..3dfb4493cc 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -28,7 +28,7 @@ #include "qemu/queue.h" -const char *get_opt_value(char *buf, int buf_size, const char *p); +const char *get_opt_value(const char *p, char **value); void parse_option_size(const char *name, const char *value, uint64_t *ret, Error **errp); diff --git a/util/qemu-option.c b/util/qemu-option.c index fa1a9f17fc..58d1c23893 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -70,25 +70,37 @@ static const char *get_opt_name(const char *p, char **option, char delim) * delimiter is fixed to be comma which starts a new option. To specify an * option value that contains commas, double each comma. */ -const char *get_opt_value(char *buf, int buf_size, const char *p) +const char *get_opt_value(const char *p, char **value) { - char *q; + size_t capacity = 0, length; + const char *offset; - q = buf; - while (*p != '\0') { - if (*p == ',') { - if (*(p + 1) != ',') - break; - p++; + *value = NULL; + while (1) { + offset = strchr(p, ','); + if (!offset) { + offset = p + strlen(p); } - if (q && (q - buf) < buf_size - 1) - *q++ = *p; - p++; - } - if (q) - *q = '\0'; - return p; + length = offset - p; + if (*offset != '\0' && *(offset + 1) == ',') { + length++; + } + if (value) { + *value = g_renew(char, *value, capacity + length + 1); + strncpy(*value + capacity, p, length); + (*value)[capacity + length] = '\0'; + } + capacity += length; + if (*offset == '\0' || + *(offset + 1) != ',') { + break; + } + + p += (offset - p) + 2; + } + + return offset; } static void parse_option_bool(const char *name, const char *value, bool *ret, @@ -162,50 +174,43 @@ void parse_option_size(const char *name, const char *value, bool has_help_option(const char *param) { - size_t buflen = strlen(param) + 1; - char *buf = g_malloc(buflen); const char *p = param; bool result = false; - while (*p) { - p = get_opt_value(buf, buflen, p); + while (*p && !result) { + char *value; + + p = get_opt_value(p, &value); if (*p) { p++; } - if (is_help_option(buf)) { - result = true; - goto out; - } + result = is_help_option(value); + g_free(value); } -out: - g_free(buf); return result; } -bool is_valid_option_list(const char *param) +bool is_valid_option_list(const char *p) { - size_t buflen = strlen(param) + 1; - char *buf = g_malloc(buflen); - const char *p = param; - bool result = true; + char *value = NULL; + bool result = false; while (*p) { - p = get_opt_value(buf, buflen, p); - if (*p && !*++p) { - result = false; + p = get_opt_value(p, &value); + if ((*p && !*++p) || + (!*value || *value == ',')) { goto out; } - if (!*buf || *buf == ',') { - result = false; - goto out; - } + g_free(value); + value = NULL; } + result = true; out: - g_free(buf); + g_free(value); return result; } @@ -487,7 +492,7 @@ int qemu_opt_unset(QemuOpts *opts, const char *name) } } -static void opt_set(QemuOpts *opts, const char *name, const char *value, +static void opt_set(QemuOpts *opts, const char *name, char *value, bool prepend, Error **errp) { QemuOpt *opt; @@ -496,6 +501,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value, desc = find_desc_by_name(opts->list->desc, name); if (!desc && !opts_accepts_any(opts)) { + g_free(value); error_setg(errp, QERR_INVALID_PARAMETER, name); return; } @@ -509,8 +515,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value, QTAILQ_INSERT_TAIL(&opts->head, opt, next); } opt->desc = desc; - opt->str = g_strdup(value); - assert(opt->str); + opt->str = value; qemu_opt_parse(opt, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -521,7 +526,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value, void qemu_opt_set(QemuOpts *opts, const char *name, const char *value, Error **errp) { - opt_set(opts, name, value, false, errp); + opt_set(opts, name, g_strdup(value), false, errp); } void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val, @@ -755,7 +760,7 @@ static void opts_do_parse(QemuOpts *opts, const char *params, const char *firstname, bool prepend, Error **errp) { char *option = NULL; - char value[1024]; + char *value = NULL; const char *p,*pe,*pc; Error *local_err = NULL; @@ -767,15 +772,15 @@ static void opts_do_parse(QemuOpts *opts, const char *params, if (p == params && firstname) { /* implicitly named first option */ option = g_strdup(firstname); - p = get_opt_value(value, sizeof(value), p); + p = get_opt_value(p, &value); } else { /* option without value, probably a flag */ p = get_opt_name(p, &option, ','); if (strncmp(option, "no", 2) == 0) { memmove(option, option+2, strlen(option+2)+1); - pstrcpy(value, sizeof(value), "off"); + value = g_strdup("off"); } else { - pstrcpy(value, sizeof(value), "on"); + value = g_strdup("on"); } } } else { @@ -783,11 +788,12 @@ static void opts_do_parse(QemuOpts *opts, const char *params, p = get_opt_name(p, &option, '='); assert(*p == '='); p++; - p = get_opt_value(value, sizeof(value), p); + p = get_opt_value(p, &value); } if (strcmp(option, "id") != 0) { /* store and parse */ opt_set(opts, option, value, prepend, &local_err); + value = NULL; if (local_err) { error_propagate(errp, local_err); goto cleanup; @@ -797,11 +803,13 @@ static void opts_do_parse(QemuOpts *opts, const char *params, break; } g_free(option); - option = NULL; + g_free(value); + option = value = NULL; } cleanup: g_free(option); + g_free(value); } /** @@ -820,7 +828,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params, bool permit_abbrev, bool defaults, Error **errp) { const char *firstname; - char value[1024], *id = NULL; + char *id = NULL; const char *p; QemuOpts *opts; Error *local_err = NULL; @@ -829,11 +837,9 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params, firstname = permit_abbrev ? list->implied_opt_name : NULL; if (strncmp(params, "id=", 3) == 0) { - get_opt_value(value, sizeof(value), params+3); - id = value; + get_opt_value(params + 3, &id); } else if ((p = strstr(params, ",id=")) != NULL) { - get_opt_value(value, sizeof(value), p+4); - id = value; + get_opt_value(p + 4, &id); } /* @@ -845,6 +851,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params, */ assert(!defaults || list->merge_lists); opts = qemu_opts_create(list, id, !defaults, &local_err); + g_free(id); if (opts == NULL) { error_propagate(errp, local_err); return NULL; From bf3175b49952628f96d72d1247d8bb3aa5c2466c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 27 Apr 2018 15:11:26 +0200 Subject: [PATCH 16/29] target/i386: sev: fix memory leaks Reported by Coverity. Signed-off-by: Paolo Bonzini --- target/i386/sev.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/target/i386/sev.c b/target/i386/sev.c index c01167143f..2395171acf 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -430,7 +430,8 @@ static int sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain, size_t *cert_chain_len) { - guchar *pdh_data, *cert_chain_data; + guchar *pdh_data = NULL; + guchar *cert_chain_data = NULL; struct sev_user_data_pdh_cert_export export = {}; int err, r; @@ -471,8 +472,9 @@ e_free: SevCapability * sev_get_capabilities(void) { - SevCapability *cap; - guchar *pdh_data, *cert_chain_data; + SevCapability *cap = NULL; + guchar *pdh_data = NULL; + guchar *cert_chain_data = NULL; size_t pdh_len = 0, cert_chain_len = 0; uint32_t ebx; int fd; @@ -486,7 +488,7 @@ sev_get_capabilities(void) if (sev_get_pdh_info(fd, &pdh_data, &pdh_len, &cert_chain_data, &cert_chain_len)) { - return NULL; + goto out; } cap = g_new0(SevCapability, 1); @@ -502,9 +504,9 @@ sev_get_capabilities(void) */ cap->reduced_phys_bits = 1; +out: g_free(pdh_data); g_free(cert_chain_data); - close(fd); return cap; } @@ -530,7 +532,7 @@ sev_launch_start(SEVState *s) { gsize sz; int ret = 1; - int fw_error; + int fw_error, rc; QSevGuestInfo *sev = s->sev_info; struct kvm_sev_launch_start *start; guchar *session = NULL, *dh_cert = NULL; @@ -543,7 +545,7 @@ sev_launch_start(SEVState *s) &error_abort); if (sev->session_file) { if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) { - return 1; + goto out; } start->session_uaddr = (unsigned long)session; start->session_len = sz; @@ -551,18 +553,18 @@ sev_launch_start(SEVState *s) if (sev->dh_cert_file) { if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) { - return 1; + goto out; } start->dh_uaddr = (unsigned long)dh_cert; start->dh_len = sz; } trace_kvm_sev_launch_start(start->policy, session, dh_cert); - ret = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error); - if (ret < 0) { + rc = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error); + if (rc < 0) { error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'", __func__, ret, fw_error, fw_error_to_str(fw_error)); - return 1; + goto out; } object_property_set_int(OBJECT(sev), start->handle, "handle", @@ -570,12 +572,13 @@ sev_launch_start(SEVState *s) sev_set_guest_state(SEV_STATE_LAUNCH_UPDATE); s->handle = start->handle; s->policy = start->policy; + ret = 0; +out: g_free(start); g_free(session); g_free(dh_cert); - - return 0; + return ret; } static int @@ -712,7 +715,7 @@ sev_guest_init(const char *id) uint32_t host_cbitpos; struct sev_user_data_status status = {}; - s = g_new0(SEVState, 1); + sev_state = s = g_new0(SEVState, 1); s->sev_info = lookup_sev_guest_info(id); if (!s->sev_info) { error_report("%s: '%s' is not a valid '%s' object", @@ -720,7 +723,6 @@ sev_guest_init(const char *id) goto err; } - sev_state = s; s->state = SEV_STATE_UNINIT; host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL); From 454012997e0818e371750893c87c28c155ef14e3 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 4 May 2018 17:13:10 +0200 Subject: [PATCH 17/29] qemu-options: Mark -virtioconsole as deprecated The qemu-doc already states that this option is only maintained for backward compatibility and "-device virtconsole" should be used instead. So let's take the next step and mark this option officially as deprecated. Reviewed-by: Markus Armbruster Signed-off-by: Thomas Huth Message-Id: <1525446790-16139-1-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- qemu-doc.texi | 5 +++++ qemu-options.hx | 5 +---- vl.c | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/qemu-doc.texi b/qemu-doc.texi index 0ed0f19e6b..4add403bf1 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2931,6 +2931,11 @@ The @code{-localtime} option has been replaced by @code{-rtc base=localtime}. The @code{-startdate} option has been replaced by @code{-rtc base=@var{date}}. +@subsection -virtioconsole (since 2.13.0) + +Option @option{-virtioconsole} has been replaced by +@option{-device virtconsole}. + @section qemu-img command line arguments @subsection convert -s (since 2.0.0) diff --git a/qemu-options.hx b/qemu-options.hx index c611766390..091ded6e0c 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3675,10 +3675,7 @@ STEXI @item -virtioconsole @var{c} @findex -virtioconsole Set virtio console. - -This option is maintained for backward compatibility. - -Please use @code{-device virtconsole} for the new way of invocation. +This option is deprecated, please use @option{-device virtconsole} instead. ETEXI DEF("show-cursor", 0, QEMU_OPTION_show_cursor, \ diff --git a/vl.c b/vl.c index 12e31d1aa9..b928e3e439 100644 --- a/vl.c +++ b/vl.c @@ -3587,6 +3587,8 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_virtiocon: + warn_report("This option is deprecated, " + "use '-device virtconsole' instead"); add_device_config(DEV_VIRTCON, optarg); default_virtcon = 0; if (strncmp(optarg, "mon:", 4) == 0) { From 281b95231d79a7a7ecc93a51ebb8e68b1ce7f1e5 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 4 May 2018 19:01:06 +0200 Subject: [PATCH 18/29] qemu-options: Remove remainders of the -tdf option The -tdf options has been removed with d07aa197c5a1556449361a0cbb5108e2, but apparently I forgot to remove the corresponding two lines from qemu-options.hx, so this option is still "available" and just silently ignored. Kill it now for good. Reviewed-by: Markus Armbruster Signed-off-by: Thomas Huth Message-Id: <1525453270-23074-2-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- qemu-options.hx | 3 --- 1 file changed, 3 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 091ded6e0c..50c906c85b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3921,9 +3921,6 @@ DEF("no-kvm-pit-reinjection", 0, QEMU_OPTION_no_kvm_pit_reinjection, HXCOMM Deprecated by -machine kernel_irqchip=on|off property DEF("no-kvm-irqchip", 0, QEMU_OPTION_no_kvm_irqchip, "", QEMU_ARCH_I386) -HXCOMM Deprecated (ignored) -DEF("tdf", 0, QEMU_OPTION_tdf,"", QEMU_ARCH_ALL) - DEF("msg", HAS_ARG, QEMU_OPTION_msg, "-msg timestamp[=on|off]\n" " change the format of messages\n" From 1217d6ca2bf28c0febe1bd7d5b3fa912bbf6af2a Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 4 May 2018 19:01:07 +0200 Subject: [PATCH 19/29] qemu-options: Bail out on unsupported options instead of silently ignoring them The dangling remainder of the -tdf option revealed a deficiency in our option parsing: Options that have been declared, but are not supported in the switch-case statement in vl.c and not handled in the OS-specifc os_parse_cmd_args() functions are currently silently ignored. We should rather tell the users that they specified something that we can not handle, so let's print an error message and exit instead. Reported-by: Markus Armbruster Signed-off-by: Thomas Huth Message-Id: <1525453270-23074-3-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- include/qemu-common.h | 2 +- os-posix.c | 6 +++++- os-win32.c | 4 ++-- vl.c | 5 ++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/qemu-common.h b/include/qemu-common.h index 8a4f63c9de..85f4749aef 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -137,7 +137,7 @@ char *qemu_find_file(int type, const char *name); /* OS specific functions */ void os_setup_early_signal_handling(void); char *os_find_datadir(void); -void os_parse_cmd_args(int index, const char *optarg); +int os_parse_cmd_args(int index, const char *optarg); #include "qemu/module.h" diff --git a/os-posix.c b/os-posix.c index 24eb7007dc..9ce6f74513 100644 --- a/os-posix.c +++ b/os-posix.c @@ -165,7 +165,7 @@ static bool os_parse_runas_uid_gid(const char *optarg) * Parse OS specific command line options. * return 0 if option handled, -1 otherwise */ -void os_parse_cmd_args(int index, const char *optarg) +int os_parse_cmd_args(int index, const char *optarg) { switch (index) { #ifdef CONFIG_SLIRP @@ -199,7 +199,11 @@ void os_parse_cmd_args(int index, const char *optarg) fips_set_state(true); break; #endif + default: + return -1; } + + return 0; } static void change_process_uid(void) diff --git a/os-win32.c b/os-win32.c index 586a7c7d49..0674f94b57 100644 --- a/os-win32.c +++ b/os-win32.c @@ -93,9 +93,9 @@ void os_set_line_buffering(void) * Parse OS specific command line options. * return 0 if option handled, -1 otherwise */ -void os_parse_cmd_args(int index, const char *optarg) +int os_parse_cmd_args(int index, const char *optarg) { - return; + return -1; } int qemu_create_pidfile(const char *filename) diff --git a/vl.c b/vl.c index b928e3e439..a23acb2861 100644 --- a/vl.c +++ b/vl.c @@ -4033,7 +4033,10 @@ int main(int argc, char **argv, char **envp) } break; default: - os_parse_cmd_args(popt->index, optarg); + if (os_parse_cmd_args(popt->index, optarg)) { + error_report("Option not supported in this build"); + exit(1); + } } } } From ec910caba92ea6db882a3b3d2d992caea6a1c160 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 4 May 2018 19:01:08 +0200 Subject: [PATCH 20/29] qemu-options: Remove deprecated -no-kvm-pit-reinjection Deprecated since the beginning when it was added for compatibility with the ancient qemu-kvm fork of QEMU, and it even printed out the deprecation warning since right from the start (i.e. QEMU v1.3.0), so it's really time to remove this now. Reviewed-by: Markus Armbruster Signed-off-by: Thomas Huth Message-Id: <1525453270-23074-4-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- qemu-doc.texi | 5 ----- qemu-options.hx | 4 ---- vl.c | 12 ------------ 3 files changed, 21 deletions(-) diff --git a/qemu-doc.texi b/qemu-doc.texi index 4add403bf1..85a7a397d9 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2786,11 +2786,6 @@ which is the default. @section System emulator command line arguments -@subsection -no-kvm-pit-reinjection (since 1.3.0) - -The ``-no-kvm-pit-reinjection'' argument is now a -synonym for setting ``-global kvm-pit.lost_tick_policy=discard''. - @subsection -no-kvm-irqchip (since 1.3.0) The ``-no-kvm-irqchip'' argument is now a synonym for diff --git a/qemu-options.hx b/qemu-options.hx index 50c906c85b..dfff698a93 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3914,10 +3914,6 @@ ETEXI HXCOMM Deprecated by -machine accel=tcg property DEF("no-kvm", 0, QEMU_OPTION_no_kvm, "", QEMU_ARCH_I386) -HXCOMM Deprecated by kvm-pit driver properties -DEF("no-kvm-pit-reinjection", 0, QEMU_OPTION_no_kvm_pit_reinjection, - "", QEMU_ARCH_I386) - HXCOMM Deprecated by -machine kernel_irqchip=on|off property DEF("no-kvm-irqchip", 0, QEMU_OPTION_no_kvm_irqchip, "", QEMU_ARCH_I386) diff --git a/vl.c b/vl.c index a23acb2861..23d55a42f7 100644 --- a/vl.c +++ b/vl.c @@ -3696,18 +3696,6 @@ int main(int argc, char **argv, char **envp) olist = qemu_find_opts("machine"); qemu_opts_parse_noisily(olist, "accel=tcg", false); break; - case QEMU_OPTION_no_kvm_pit_reinjection: { - static GlobalProperty kvm_pit_lost_tick_policy = { - .driver = "kvm-pit", - .property = "lost_tick_policy", - .value = "discard", - }; - - warn_report("deprecated, replaced by " - "-global kvm-pit.lost_tick_policy=discard"); - qdev_prop_register_global(&kvm_pit_lost_tick_policy); - break; - } case QEMU_OPTION_accel: accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"), optarg, true); From d8ab6cb7985e6151b9dd0025aa8a9ee998bdc958 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 4 May 2018 19:01:09 +0200 Subject: [PATCH 21/29] qemu-options: Remove deprecated -no-kvm-irqchip We've never documented this option in our qemu-doc, so apart from the users that already used the old qemu-kvm fork before, most users should not be aware of this option at all. It's been marked as deprecated in the source code for a long time already, and officially marked as deprecated in the documentation since QEMU v2.10, so it should be fine to remove this now. Reviewed-by: Markus Armbruster Signed-off-by: Thomas Huth Message-Id: <1525453270-23074-5-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- qemu-doc.texi | 5 ----- qemu-options.hx | 3 --- vl.c | 5 ----- 3 files changed, 13 deletions(-) diff --git a/qemu-doc.texi b/qemu-doc.texi index 85a7a397d9..bde542b065 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -2786,11 +2786,6 @@ which is the default. @section System emulator command line arguments -@subsection -no-kvm-irqchip (since 1.3.0) - -The ``-no-kvm-irqchip'' argument is now a synonym for -setting ``-machine kernel_irqchip=off''. - @subsection -no-kvm (since 1.3.0) The ``-no-kvm'' argument is now a synonym for setting diff --git a/qemu-options.hx b/qemu-options.hx index dfff698a93..b2fefd12b6 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3914,9 +3914,6 @@ ETEXI HXCOMM Deprecated by -machine accel=tcg property DEF("no-kvm", 0, QEMU_OPTION_no_kvm, "", QEMU_ARCH_I386) -HXCOMM Deprecated by -machine kernel_irqchip=on|off property -DEF("no-kvm-irqchip", 0, QEMU_OPTION_no_kvm_irqchip, "", QEMU_ARCH_I386) - DEF("msg", HAS_ARG, QEMU_OPTION_msg, "-msg timestamp[=on|off]\n" " change the format of messages\n" diff --git a/vl.c b/vl.c index 23d55a42f7..b9f6b42779 100644 --- a/vl.c +++ b/vl.c @@ -3138,11 +3138,6 @@ int main(int argc, char **argv, char **envp) exit(1); } switch(popt->index) { - case QEMU_OPTION_no_kvm_irqchip: { - olist = qemu_find_opts("machine"); - qemu_opts_parse_noisily(olist, "kernel_irqchip=off", false); - break; - } case QEMU_OPTION_cpu: /* hw initialization will check this */ cpu_model = optarg; From 45b47130f4b7b53eb1437e8301bfeb4e73490413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Fri, 4 May 2018 17:00:24 +0100 Subject: [PATCH 22/29] qemu-doc: provide details of supported build platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe the policy the project uses to decide which OS are supported as build platforms. This will: - Allow maintainers to determine when the minimum version of a 3rd party piece of software can be increased without negatively impacting supported platforms. - Allow tailoring of CI environments to match the intended supported build platforms. Signed-off-by: Daniel P. Berrangé Message-Id: <20180504160026.14017-2-berrange@redhat.com> Signed-off-by: Paolo Bonzini Signed-off-by: Daniel P. Berrangé --- qemu-doc.texi | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/qemu-doc.texi b/qemu-doc.texi index bde542b065..715bd336b4 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -39,6 +39,7 @@ * QEMU User space emulator:: * Implementation notes:: * Deprecated features:: +* Supported build platforms:: * License:: * Index:: @end menu @@ -2976,6 +2977,73 @@ The ``xlnx-zcu102'' machine has the same features and capabilites in QEMU. In order to prevent QEMU from automatically opening an image's backing chain, use ``"backing": null'' instead. +@node Supported build platforms +@appendix Supported build platforms + +QEMU aims to support building and executing on multiple host OS platforms. +This appendix outlines which platforms are the major build targets. These +platforms are used as the basis for deciding upon the minimum required +versions of 3rd party software QEMU depends on. The supported platforms +are the targets for automated testing performed by the project when patches +are submitted for review, and tested before and after merge. + +If a platform is not listed here, it does not imply that QEMU won't work. +If an unlisted platform has comparable software versions to a listed platform, +there is every expectation that it will work. Bug reports are welcome for +problems encountered on unlisted platforms unless they are clearly older +vintage than what is described here. + +Note that when considering software versions shipped in distros as support +targets, QEMU considers only the version number, and assumes the features in +that distro match the upstream release with the same version. In other words, +if a distro backports extra features to the software in their distro, QEMU +upstream code will not add explicit support for those backports, unless the +feature is auto-detectable in a manner that works for the upstream releases +too. + +The Repology site @url{https://repology.org} is a useful resource to identify +currently shipped versions of software in various operating systems, though +it does not cover all distros listed below. + +@section Linux OS + +For distributions with frequent, short-lifetime releases, the project will +aim to support all versions that are not end of life by their respective +vendors. For the purposes of identifying supported software versions, the +project will look at Fedora, Ubuntu, and openSUSE distros. Other short- +lifetime distros will be assumed to ship similar software versions. + +For distributions with long-lifetime releases, the project will aim to support +the most recent major version at all times. Support for the previous major +version will be dropped 2 years after the new major version is released. For +the purposes of identifying supported software versions, the project will look +at RHEL, Debian, Ubuntu LTS, and SLES distros. Other long-lifetime distros will +be assumed to ship similar software versions. + +@section Windows + +The project supports building with current versions of the MinGW toolchain, +hosted on Linux. + +@section macOS + +The project supports building with the two most recent versions of macOS, with +the current homebrew package set available. + +@section FreeBSD + +The project aims to support the all the versions which are not end of life. + +@section NetBSD + +The project aims to support the most recent major version at all times. Support +for the previous major version will be dropped 2 years after the new major +version is released. + +@section OpenBSD + +The project aims to support the all the versions which are not end of life. + @node License @appendix License From ba6a4fd95de1e0a85bfbe43330448f16486e2181 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Wed, 11 Apr 2018 13:50:36 +0200 Subject: [PATCH 23/29] i386/kvm: add support for Hyper-V reenlightenment MSRs KVM recently gained support for Hyper-V Reenlightenment MSRs which are required to make KVM-on-Hyper-V enable TSC page clocksource to its guests when INVTSC is not passed to it (and it is not passed by default in Qemu as it effectively blocks migration). Signed-off-by: Vitaly Kuznetsov Message-Id: <20180411115036.31832-2-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 4 +++- target/i386/cpu.h | 4 ++++ target/i386/hyperv-proto.h | 9 ++++++++- target/i386/kvm.c | 39 +++++++++++++++++++++++++++++++++++++- target/i386/machine.c | 24 +++++++++++++++++++++++ 5 files changed, 77 insertions(+), 3 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index a20fe26573..b0a1c629a3 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -416,7 +416,8 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { NULL /* hv_vpindex_access */, NULL /* hv_msr_reset_access */, NULL /* hv_msr_stats_access */, NULL /* hv_reftsc_access */, NULL /* hv_msr_idle_access */, NULL /* hv_msr_frequency_access */, - NULL, NULL, NULL, NULL, + NULL /* hv_msr_debug_access */, NULL /* hv_msr_reenlightenment_access */, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -4770,6 +4771,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false), DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false), DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false), + DEFINE_PROP_BOOL("hv-reenlightenment", X86CPU, hyperv_reenlightenment, false), DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true), DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 1b219fafc4..b58b779bff 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1174,6 +1174,9 @@ typedef struct CPUX86State { uint64_t msr_hv_synic_sint[HV_SINT_COUNT]; uint64_t msr_hv_stimer_config[HV_STIMER_COUNT]; uint64_t msr_hv_stimer_count[HV_STIMER_COUNT]; + uint64_t msr_hv_reenlightenment_control; + uint64_t msr_hv_tsc_emulation_control; + uint64_t msr_hv_tsc_emulation_status; uint64_t msr_rtit_ctrl; uint64_t msr_rtit_status; @@ -1297,6 +1300,7 @@ struct X86CPU { bool hyperv_synic; bool hyperv_stimer; bool hyperv_frequencies; + bool hyperv_reenlightenment; bool check_cpuid; bool enforce_cpuid; bool expose_kvm; diff --git a/target/i386/hyperv-proto.h b/target/i386/hyperv-proto.h index cb4d7f2b7a..93352ebd2a 100644 --- a/target/i386/hyperv-proto.h +++ b/target/i386/hyperv-proto.h @@ -35,7 +35,7 @@ #define HV_RESET_AVAILABLE (1u << 7) #define HV_REFERENCE_TSC_AVAILABLE (1u << 9) #define HV_ACCESS_FREQUENCY_MSRS (1u << 11) - +#define HV_ACCESS_REENLIGHTENMENTS_CONTROL (1u << 13) /* * HV_CPUID_FEATURES.EDX bits @@ -129,6 +129,13 @@ #define HV_X64_MSR_CRASH_CTL 0x40000105 #define HV_CRASH_CTL_NOTIFY (1ull << 63) +/* + * Reenlightenment notification MSRs + */ +#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106 +#define HV_X64_MSR_TSC_EMULATION_CONTROL 0x40000107 +#define HV_X64_MSR_TSC_EMULATION_STATUS 0x40000108 + /* * Hypercall status code */ diff --git a/target/i386/kvm.c b/target/i386/kvm.c index 6c49954e68..d6666a4b19 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -90,6 +90,7 @@ static bool has_msr_hv_runtime; static bool has_msr_hv_synic; static bool has_msr_hv_stimer; static bool has_msr_hv_frequencies; +static bool has_msr_hv_reenlightenment; static bool has_msr_xss; static bool has_msr_spec_ctrl; static bool has_msr_smi_count; @@ -583,7 +584,8 @@ static bool hyperv_enabled(X86CPU *cpu) cpu->hyperv_vpindex || cpu->hyperv_runtime || cpu->hyperv_synic || - cpu->hyperv_stimer); + cpu->hyperv_stimer || + cpu->hyperv_reenlightenment); } static int kvm_arch_set_tsc_khz(CPUState *cs) @@ -669,6 +671,16 @@ static int hyperv_handle_properties(CPUState *cs) } env->features[FEAT_HYPERV_EDX] |= HV_GUEST_CRASH_MSR_AVAILABLE; } + if (cpu->hyperv_reenlightenment) { + if (!has_msr_hv_reenlightenment) { + fprintf(stderr, + "Hyper-V Reenlightenment MSRs " + "(requested by 'hv-reenlightenment' cpu flag) " + "are not supported by kernel\n"); + return -ENOSYS; + } + env->features[FEAT_HYPERV_EAX] |= HV_ACCESS_REENLIGHTENMENTS_CONTROL; + } env->features[FEAT_HYPERV_EDX] |= HV_CPU_DYNAMIC_PARTITIONING_AVAILABLE; if (cpu->hyperv_reset) { if (!has_msr_hv_reset) { @@ -1215,6 +1227,9 @@ static int kvm_get_supported_msrs(KVMState *s) case HV_X64_MSR_TSC_FREQUENCY: has_msr_hv_frequencies = true; break; + case HV_X64_MSR_REENLIGHTENMENT_CONTROL: + has_msr_hv_reenlightenment = true; + break; case MSR_IA32_SPEC_CTRL: has_msr_spec_ctrl = true; break; @@ -1778,6 +1793,14 @@ static int kvm_put_msrs(X86CPU *cpu, int level) kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, env->msr_hv_tsc); } + if (cpu->hyperv_reenlightenment) { + kvm_msr_entry_add(cpu, HV_X64_MSR_REENLIGHTENMENT_CONTROL, + env->msr_hv_reenlightenment_control); + kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_CONTROL, + env->msr_hv_tsc_emulation_control); + kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_STATUS, + env->msr_hv_tsc_emulation_status); + } } if (cpu->hyperv_vapic) { kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE, @@ -2140,6 +2163,11 @@ static int kvm_get_msrs(X86CPU *cpu) if (cpu->hyperv_time) { kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, 0); } + if (cpu->hyperv_reenlightenment) { + kvm_msr_entry_add(cpu, HV_X64_MSR_REENLIGHTENMENT_CONTROL, 0); + kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_CONTROL, 0); + kvm_msr_entry_add(cpu, HV_X64_MSR_TSC_EMULATION_STATUS, 0); + } if (has_msr_hv_crash) { int j; @@ -2397,6 +2425,15 @@ static int kvm_get_msrs(X86CPU *cpu) env->msr_hv_stimer_count[(index - HV_X64_MSR_STIMER0_COUNT)/2] = msrs[i].data; break; + case HV_X64_MSR_REENLIGHTENMENT_CONTROL: + env->msr_hv_reenlightenment_control = msrs[i].data; + break; + case HV_X64_MSR_TSC_EMULATION_CONTROL: + env->msr_hv_tsc_emulation_control = msrs[i].data; + break; + case HV_X64_MSR_TSC_EMULATION_STATUS: + env->msr_hv_tsc_emulation_status = msrs[i].data; + break; case MSR_MTRRdefType: env->mtrr_deftype = msrs[i].data; break; diff --git a/target/i386/machine.c b/target/i386/machine.c index bd2d82e91b..fd99c0bbb4 100644 --- a/target/i386/machine.c +++ b/target/i386/machine.c @@ -713,6 +713,29 @@ static const VMStateDescription vmstate_msr_hyperv_stimer = { } }; +static bool hyperv_reenlightenment_enable_needed(void *opaque) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + + return env->msr_hv_reenlightenment_control != 0 || + env->msr_hv_tsc_emulation_control != 0 || + env->msr_hv_tsc_emulation_status != 0; +} + +static const VMStateDescription vmstate_msr_hyperv_reenlightenment = { + .name = "cpu/msr_hyperv_reenlightenment", + .version_id = 1, + .minimum_version_id = 1, + .needed = hyperv_reenlightenment_enable_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64(env.msr_hv_reenlightenment_control, X86CPU), + VMSTATE_UINT64(env.msr_hv_tsc_emulation_control, X86CPU), + VMSTATE_UINT64(env.msr_hv_tsc_emulation_status, X86CPU), + VMSTATE_END_OF_LIST() + } +}; + static bool avx512_needed(void *opaque) { X86CPU *cpu = opaque; @@ -1005,6 +1028,7 @@ VMStateDescription vmstate_x86_cpu = { &vmstate_msr_hyperv_runtime, &vmstate_msr_hyperv_synic, &vmstate_msr_hyperv_stimer, + &vmstate_msr_hyperv_reenlightenment, &vmstate_avx512, &vmstate_xss, &vmstate_tsc_khz, From 8a99e9a30ca8c93082d9032627c5d522ff66e664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 15 Apr 2018 20:05:19 -0300 Subject: [PATCH 24/29] configure: Really use local libfdt if the system one is too old MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QEMU requires libfdt version >= 1.4.2. If the host has an older libfdt installed, the configure script will use a (git cloned) local version. Example with Debian 8: $ dpkg-query --showformat='${Version}\n' --show libfdt-dev 1.4.0+dfsg-1 $ ./configure [...] fdt support yes # from git submodule 'dtc' If this case occurs, the linker will have 2 different libfdt available in the library search path. The default behavior is to search the system path first, then the local path. Even if the configure script noticed the libfdt is too old and clone a more recent locally, when linking the system library is selected first, and the link process eventually fails: LINK mips64el-softmmu/qemu-system-mips64el ../hw/core/loader-fit.o: In function `load_fit': /root/src/github.com/philmd/qemu/hw/core/loader-fit.c:278: undefined reference to `fdt_first_subnode' /root/src/github.com/philmd/qemu/hw/core/loader-fit.c:286: undefined reference to `fdt_next_subnode' /root/src/github.com/philmd/qemu/hw/core/loader-fit.c:277: undefined reference to `fdt_first_subnode' collect2: error: ld returned 1 exit status Makefile:201: recipe for target 'qemu-system-mips64el' failed make[1]: *** [qemu-system-mips64el] Error 1 QEMU already uses a kludge to enforce local CFLAGS before system ones for libpixman and libfdt, add a similar kludge for the LDFLAGS to enforce using the local libfdt. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20180415230522.24404-2-f4bug@amsat.org> Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth --- configure | 6 +++++- rules.mak | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 83a6080bf8..e25e0d9494 100755 --- a/configure +++ b/configure @@ -3804,7 +3804,8 @@ EOF symlink "$source_path/dtc/scripts" "dtc/scripts" fi fdt_cflags="-I\$(SRC_PATH)/dtc/libfdt" - fdt_libs="-L\$(BUILD_DIR)/dtc/libfdt $fdt_libs" + fdt_ldflags="-L\$(BUILD_DIR)/dtc/libfdt" + fdt_libs="$fdt_libs" elif test "$fdt" = "yes" ; then # Not a git build & no libfdt found, prompt for system install error_exit "DTC (libfdt) version >= 1.4.2 not present." \ @@ -5746,6 +5747,7 @@ echo_version() { # prepend pixman and ftd flags after all config tests are done QEMU_CFLAGS="$pixman_cflags $fdt_cflags $QEMU_CFLAGS" +QEMU_LDFLAGS="$fdt_ldflags $QEMU_LDFLAGS" libs_softmmu="$pixman_libs $libs_softmmu" echo "Install prefix $prefix" @@ -5776,6 +5778,7 @@ echo "ARFLAGS $ARFLAGS" echo "CFLAGS $CFLAGS" echo "QEMU_CFLAGS $QEMU_CFLAGS" echo "LDFLAGS $LDFLAGS" +echo "QEMU_LDFLAGS $QEMU_LDFLAGS" echo "make $make" echo "install $install" echo "python $python" @@ -6710,6 +6713,7 @@ else fi echo "LDFLAGS=$LDFLAGS" >> $config_host_mak echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak +echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak echo "LD_REL_FLAGS=$LD_REL_FLAGS" >> $config_host_mak echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak echo "LIBS+=$LIBS" >> $config_host_mak diff --git a/rules.mak b/rules.mak index 93a07027b0..04c7f74d07 100644 --- a/rules.mak +++ b/rules.mak @@ -73,7 +73,7 @@ expand-objs = $(strip $(sort $(filter %.o,$1)) \ # must link with the C++ compiler, not the plain C compiler. LINKPROG = $(or $(CXX),$(CC)) -LINK = $(call quiet-command, $(LINKPROG) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \ +LINK = $(call quiet-command, $(LINKPROG) $(QEMU_LDFLAGS) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ \ $(call process-archive-undefs, $1) \ $(version-obj-y) $(call extract-libs,$1) $(LIBS),"LINK","$(TARGET_DIR)$@") From e3971d612abd8a11b15e95add672fc993f65db2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 15 Apr 2018 20:05:20 -0300 Subject: [PATCH 25/29] configure: Display if libfdt is from system or git MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The configure script outputs "yes" regardless which libfdt is used: ./configure [...] fdt support yes Sometimes you can have both system and local git version available, change the configure script to display which library got selected: debian8$ dpkg-query --showformat='${Version}\n' --show libfdt-dev 1.4.0+dfsg-1 debian8$ ./configure [...] fdt support git Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20180415230522.24404-3-f4bug@amsat.org> Signed-off-by: Paolo Bonzini --- configure | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/configure b/configure index e25e0d9494..49cdf12449 100755 --- a/configure +++ b/configure @@ -3789,15 +3789,14 @@ int main(void) { fdt_first_subnode(0, 0); return 0; } EOF if compile_prog "" "$fdt_libs" ; then # system DTC is good - use it - fdt=yes + fdt=system else # have GIT checkout, so activate dtc submodule if test -e "${source_path}/.git" ; then git_submodules="${git_submodules} dtc" fi if test -d "${source_path}/dtc/libfdt" || test -e "${source_path}/.git" ; then - fdt=yes - dtc_internal="yes" + fdt=git mkdir -p dtc if [ "$pwd_is_source_path" != "y" ] ; then symlink "$source_path/dtc/Makefile" "dtc/Makefile" @@ -6338,7 +6337,7 @@ fi if test "$preadv" = "yes" ; then echo "CONFIG_PREADV=y" >> $config_host_mak fi -if test "$fdt" = "yes" ; then +if test "$fdt" != "no" ; then echo "CONFIG_FDT=y" >> $config_host_mak fi if test "$membarrier" = "yes" ; then @@ -7140,7 +7139,7 @@ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak done # for target in $targets -if [ "$dtc_internal" = "yes" ]; then +if [ "$fdt" = "git" ]; then echo "config-host.h: subdir-dtc" >> $config_host_mak fi if [ "$capstone" = "git" -o "$capstone" = "internal" ]; then From 03d92e26532cba48eb511633c41ec81555fb40ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 15 Apr 2018 20:05:21 -0300 Subject: [PATCH 26/29] shippable: Remove Debian 8 libfdt kludge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This kludge was added in a825ca06137, but a cleaner and more generic fix is now available (see ##COMMIT_CONFIGURE_LIBFDT_LDFLAGS_SHA##). Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20180415230522.24404-4-f4bug@amsat.org> Signed-off-by: Paolo Bonzini --- .shippable.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.shippable.yml b/.shippable.yml index 60f2ce9218..f74a3de3ff 100644 --- a/.shippable.yml +++ b/.shippable.yml @@ -35,13 +35,5 @@ build: options: "-e HOME=/root" ci: - unset CC - # some targets require newer up to date packages, for example TARGET_LIST matching - # aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu) - # see the configure script: - # error_exit "DTC (libfdt) version >= 1.4.2 not present. Your options:" - # " (1) Preferred: Install the DTC (libfdt) devel package" - # " (2) Fetch the DTC submodule, using:" - # " git submodule update --init dtc" - - dpkg --compare-versions `dpkg-query --showformat='${Version}' --show libfdt-dev` ge 1.4.2 || git submodule update --init dtc - ./configure ${QEMU_CONFIGURE_OPTS} --target-list=${TARGET_LIST} - make -j$(($(getconf _NPROCESSORS_ONLN) + 1)) From 814e1110d51f287f5616ffc04b788f6477519560 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 15 Apr 2018 20:05:22 -0300 Subject: [PATCH 27/29] build: Silence dtc directory creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align with other mkdir calls. Signed-off-by: Jan Kiszka Reviewed-by: Philippe Mathieu-Daudé Message-Id: <0dd4c8f5-d60e-e564-652f-cd0101f6ee68@web.de> Message-Id: <20180415230522.24404-5-f4bug@amsat.org> Signed-off-by: Paolo Bonzini --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d71dd5bea4..35554b5bef 100644 --- a/Makefile +++ b/Makefile @@ -485,7 +485,7 @@ subdir-dtc: .git-submodule-status dtc/libfdt dtc/tests $(call quiet-command,$(MAKE) $(DTC_MAKE_ARGS) CPPFLAGS="$(DTC_CPPFLAGS)" CFLAGS="$(DTC_CFLAGS)" LDFLAGS="$(LDFLAGS)" ARFLAGS="$(ARFLAGS)" CC="$(CC)" AR="$(AR)" LD="$(LD)" $(SUBDIR_MAKEFLAGS) libfdt/libfdt.a,) dtc/%: .git-submodule-status - mkdir -p $@ + @mkdir -p $@ # Overriding CFLAGS causes us to lose defines added in the sub-makefile. # Not overriding CFLAGS leads to mis-matches between compilation modes. From 3ff333effa319df6178f138d9cf32e3937419790 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 27 Apr 2018 14:05:15 +0200 Subject: [PATCH 28/29] pc-dimm: fix error messages if no slots were defined If no slots were defined we try to allocate an empty bitmap, which fails. Signed-off-by: David Hildenbrand Reviewed-by: Marcel Apfelbaum Reviewed-by: Thomas Huth Message-Id: <20180427120515.24067-1-david@redhat.com> Signed-off-by: Paolo Bonzini --- hw/mem/pc-dimm.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 0119c68e01..12da89d562 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -118,9 +118,16 @@ static int pc_dimm_slot2bitmap(Object *obj, void *opaque) int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp) { - unsigned long *bitmap = bitmap_new(max_slots); + unsigned long *bitmap; int slot = 0; + if (max_slots <= 0) { + error_setg(errp, "no slots where allocated, please specify " + "the 'slots' option"); + return slot; + } + + bitmap = bitmap_new(max_slots); object_child_foreach(qdev_get_machine(), pc_dimm_slot2bitmap, bitmap); /* check if requested slot is not occupied */ From 5b27a92dcc5afb11d38c7fe0a637d5d64d31108a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 4 May 2018 11:52:55 +0200 Subject: [PATCH 29/29] rename included C files to foo.inc.c, remove osdep.h osdep.h is only needed for files that are compiled directly. Remove it from included C source files, and rename them to *.inc.c so that scripts/clean-includes knows to skip them. Cc: Eric Blake Cc: Michael S. Tsirkin Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini --- target/cris/translate.c | 2 +- .../{translate_v10.c => translate_v10.inc.c} | 0 target/mips/translate.c | 2 +- ...{translate_init.c => translate_init.inc.c} | 0 target/ppc/int_helper.c | 2 +- .../ppc/{mfrom_table.c => mfrom_table.inc.c} | 0 target/ppc/translate.c | 2 +- ...{translate_init.c => translate_init.inc.c} | 1 - ui/vnc-enc-zrle.c | 22 +++++++++---------- ...enc-zrle-template.c => vnc-enc-zrle.inc.c} | 0 10 files changed, 15 insertions(+), 16 deletions(-) rename target/cris/{translate_v10.c => translate_v10.inc.c} (100%) rename target/mips/{translate_init.c => translate_init.inc.c} (100%) rename target/ppc/{mfrom_table.c => mfrom_table.inc.c} (100%) rename target/ppc/{translate_init.c => translate_init.inc.c} (99%) rename ui/{vnc-enc-zrle-template.c => vnc-enc-zrle.inc.c} (100%) diff --git a/target/cris/translate.c b/target/cris/translate.c index f51a731db9..ce1ee7a45f 100644 --- a/target/cris/translate.c +++ b/target/cris/translate.c @@ -3047,7 +3047,7 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc) return insn_len; } -#include "translate_v10.c" +#include "translate_v10.inc.c" /* * Delay slots on QEMU/CRIS. diff --git a/target/cris/translate_v10.c b/target/cris/translate_v10.inc.c similarity index 100% rename from target/cris/translate_v10.c rename to target/cris/translate_v10.inc.c diff --git a/target/mips/translate.c b/target/mips/translate.c index d05ee67e63..26f5404bae 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -20499,7 +20499,7 @@ void mips_tcg_init(void) "fcr31"); } -#include "translate_init.c" +#include "translate_init.inc.c" void cpu_mips_realize_env(CPUMIPSState *env) { diff --git a/target/mips/translate_init.c b/target/mips/translate_init.inc.c similarity index 100% rename from target/mips/translate_init.c rename to target/mips/translate_init.inc.c diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 35bdf09773..1607a7a42b 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -379,7 +379,7 @@ target_ulong helper_divso(CPUPPCState *env, target_ulong arg1, target_ulong helper_602_mfrom(target_ulong arg) { if (likely(arg < 602)) { -#include "mfrom_table.c" +#include "mfrom_table.inc.c" return mfrom_ROM_table[arg]; } else { return 0; diff --git a/target/ppc/mfrom_table.c b/target/ppc/mfrom_table.inc.c similarity index 100% rename from target/ppc/mfrom_table.c rename to target/ppc/mfrom_table.inc.c diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 2a4140f420..257badf149 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6991,7 +6991,7 @@ GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \ }; #include "helper_regs.h" -#include "translate_init.c" +#include "translate_init.inc.c" /*****************************************************************************/ /* Misc PowerPC helpers */ diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.inc.c similarity index 99% rename from target/ppc/translate_init.c rename to target/ppc/translate_init.inc.c index a72be6d121..a0b3f184b2 100644 --- a/target/ppc/translate_init.c +++ b/target/ppc/translate_init.inc.c @@ -18,7 +18,6 @@ * License along with this library; if not, see . */ -#include "qemu/osdep.h" #include "disas/bfd.h" #include "exec/gdbstub.h" #include "kvm_ppc.h" diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c index fd63d4f688..7493a84723 100644 --- a/ui/vnc-enc-zrle.c +++ b/ui/vnc-enc-zrle.c @@ -199,56 +199,56 @@ static void zrle_write_u8(VncState *vs, uint8_t value) #define ZRLE_BPP 8 #define ZYWRLE_ENDIAN ENDIAN_NO -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZRLE_BPP #define ZRLE_BPP 15 #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_LITTLE -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_BIG -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZRLE_BPP #define ZRLE_BPP 16 #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_LITTLE -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_BIG -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZRLE_BPP #define ZRLE_BPP 32 #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_LITTLE -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_BIG -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #define ZRLE_COMPACT_PIXEL 24a #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_LITTLE -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_BIG -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZRLE_COMPACT_PIXEL #define ZRLE_COMPACT_PIXEL 24b #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_LITTLE -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZYWRLE_ENDIAN #define ZYWRLE_ENDIAN ENDIAN_BIG -#include "vnc-enc-zrle-template.c" +#include "vnc-enc-zrle.inc.c" #undef ZRLE_COMPACT_PIXEL #undef ZRLE_BPP diff --git a/ui/vnc-enc-zrle-template.c b/ui/vnc-enc-zrle.inc.c similarity index 100% rename from ui/vnc-enc-zrle-template.c rename to ui/vnc-enc-zrle.inc.c