diff options
| -rw-r--r-- | blockdev.c | 4 | ||||
| -rw-r--r-- | bsd-user/mmap.c | 13 | ||||
| -rw-r--r-- | bsd-user/qemu.h | 2 | ||||
| -rw-r--r-- | cpu-exec-common.c | 2 | ||||
| -rw-r--r-- | cpus.c | 2 | ||||
| -rw-r--r-- | qapi/block-core.json | 95 | ||||
| -rw-r--r-- | replay/replay.c | 2 | ||||
| -rw-r--r-- | tests/qemu-iotests/139 | 8 | ||||
| -rwxr-xr-x | tests/qemu-iotests/141 | 4 | ||||
| -rwxr-xr-x | tests/qemu-iotests/147 | 2 | ||||
| -rw-r--r-- | ui/console.c | 18 | ||||
| -rw-r--r-- | user-exec.c | 18 |
12 files changed, 77 insertions, 93 deletions
diff --git a/blockdev.c b/blockdev.c index c5b2c2c209..040c152512 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2835,7 +2835,7 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict) bs = bdrv_find_node(id); if (bs) { - qmp_x_blockdev_del(id, &local_err); + qmp_blockdev_del(id, &local_err); if (local_err) { error_report_err(local_err); } @@ -3900,7 +3900,7 @@ fail: visit_free(v); } -void qmp_x_blockdev_del(const char *node_name, Error **errp) +void qmp_blockdev_del(const char *node_name, Error **errp) { AioContext *aio_context; BlockDriverState *bs; diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 1ad018a127..7f2018ede0 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -24,8 +24,7 @@ //#define DEBUG_MMAP -#if defined(CONFIG_USE_NPTL) -pthread_mutex_t mmap_mutex; +static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER; static int __thread mmap_lock_count; void mmap_lock(void) @@ -62,16 +61,6 @@ void mmap_fork_end(int child) else pthread_mutex_unlock(&mmap_mutex); } -#else -/* We aren't threadsafe to start with, so no need to worry about locking. */ -void mmap_lock(void) -{ -} - -void mmap_unlock(void) -{ -} -#endif /* NOTE: all the constants are the HOST ones, but addresses are target. */ int target_mprotect(abi_ulong start, abi_ulong len, int prot) diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index 2b2b9184e0..b550cee0cb 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -209,10 +209,8 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, abi_ulong new_addr); int target_msync(abi_ulong start, abi_ulong len, int flags); extern unsigned long last_brk; -#if defined(CONFIG_USE_NPTL) void mmap_fork_start(void); void mmap_fork_end(int child); -#endif /* main.c */ extern unsigned long x86_stack_size; diff --git a/cpu-exec-common.c b/cpu-exec-common.c index 0504a9457b..e81da276bb 100644 --- a/cpu-exec-common.c +++ b/cpu-exec-common.c @@ -35,7 +35,7 @@ void cpu_loop_exit_noexc(CPUState *cpu) #if defined(CONFIG_SOFTMMU) void cpu_reloading_memory_map(void) { - if (qemu_in_vcpu_thread()) { + if (qemu_in_vcpu_thread() && current_cpu->running) { /* The guest can in theory prolong the RCU critical section as long * as it feels like. The major problem with this is that because it * can do multiple reconfigurations of the memory map within the diff --git a/cpus.c b/cpus.c index 167d9615e1..68fdbc40b9 100644 --- a/cpus.c +++ b/cpus.c @@ -209,7 +209,7 @@ void qemu_tcg_configure(QemuOpts *opts, Error **errp) if (!check_tcg_memory_orders_compatible()) { error_report("Guest expects a stronger memory ordering " "than the host provides"); - error_printf("This may cause strange/hard to debug errors"); + error_printf("This may cause strange/hard to debug errors\n"); } mttcg_enabled = true; } diff --git a/qapi/block-core.json b/qapi/block-core.json index 78eb8fb5aa..4e8e4e36a1 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2053,7 +2053,7 @@ # @ignore: Ignore the request # @unmap: Forward as an unmap request # -# Since: 1.7 +# Since: 2.9 ## { 'enum': 'BlockdevDiscardOptions', 'data': [ 'ignore', 'unmap' ] } @@ -2082,7 +2082,7 @@ # @threads: Use qemu's thread pool # @native: Use native AIO backend (only Linux and Windows) # -# Since: 1.7 +# Since: 2.9 ## { 'enum': 'BlockdevAioOptions', 'data': [ 'threads', 'native' ] } @@ -2097,7 +2097,7 @@ # @no-flush: ignore any flush requests for the device (default: # false) # -# Since: 1.7 +# Since: 2.9 ## { 'struct': 'BlockdevCacheOptions', 'data': { '*direct': 'bool', @@ -2108,18 +2108,7 @@ # # Drivers that are supported in block device operations. # -# @host_device: Since 2.1 -# @host_cdrom: Since 2.1 -# @gluster: Since 2.7 -# @nbd: Since 2.8 -# @nfs: Since 2.8 -# @replication: Since 2.8 -# @ssh: Since 2.8 -# @iscsi: Since 2.9 -# @rbd: Since 2.9 -# @sheepdog: Since 2.9 -# -# Since: 2.0 +# Since: 2.9 ## { 'enum': 'BlockdevDriver', 'data': [ 'blkdebug', 'blkverify', 'bochs', 'cloop', @@ -2137,7 +2126,7 @@ # @filename: path to the image file # @aio: AIO backend (default: threads) (since: 2.8) # -# Since: 1.7 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsFile', 'data': { 'filename': 'str', @@ -2153,7 +2142,7 @@ # requests. Default to zero which completes requests immediately. # (Since 2.4) # -# Since: 2.2 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsNull', 'data': { '*size': 'int', '*latency-ns': 'uint64' } } @@ -2173,7 +2162,7 @@ # (since 2.4) # @rw: whether to allow write operations (default: false) # -# Since: 1.7 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsVVFAT', 'data': { 'dir': 'str', '*fat-type': 'int', '*floppy': 'bool', @@ -2187,7 +2176,7 @@ # # @file: reference to or definition of the data source block device # -# Since: 1.7 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsGenericFormat', 'data': { 'file': 'BlockdevRef' } } @@ -2201,7 +2190,7 @@ # the decryption key (since 2.6). Mandatory except when # doing a metadata-only probe of the image. # -# Since: 2.6 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsLUKS', 'base': 'BlockdevOptionsGenericFormat', @@ -2219,7 +2208,7 @@ # allowed to pass an empty string here in order to disable the # default backing file. # -# Since: 1.7 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsGenericCOWFormat', 'base': 'BlockdevOptionsGenericFormat', @@ -2240,7 +2229,7 @@ # # @all: Perform all available overlap checks # -# Since: 2.2 +# Since: 2.9 ## { 'enum': 'Qcow2OverlapCheckMode', 'data': [ 'none', 'constant', 'cached', 'all' ] } @@ -2255,7 +2244,7 @@ # @template: Specifies a template mode which can be adjusted using the other # flags, defaults to 'cached' # -# Since: 2.2 +# Since: 2.9 ## { 'struct': 'Qcow2OverlapCheckFlags', 'data': { '*template': 'Qcow2OverlapCheckMode', @@ -2279,7 +2268,7 @@ # # @mode: named mode which chooses a specific set of flags # -# Since: 2.2 +# Since: 2.9 ## { 'alternate': 'Qcow2OverlapChecks', 'data': { 'flags': 'Qcow2OverlapCheckFlags', @@ -2320,7 +2309,7 @@ # caches. The interval is in seconds. The default value # is 0 and it disables this feature (since 2.5) # -# Since: 1.7 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsQcow2', 'base': 'BlockdevOptionsGenericCOWFormat', @@ -2347,7 +2336,7 @@ # # TODO: Expose the host_key_check option in QMP # -# Since: 2.8 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsSsh', 'data': { 'server': 'InetSocketAddress', @@ -2360,7 +2349,7 @@ # # Trigger events supported by blkdebug. # -# Since: 2.0 +# Since: 2.9 ## { 'enum': 'BlkdebugEvent', 'prefix': 'BLKDBG', 'data': [ 'l1_update', 'l1_grow_alloc_table', 'l1_grow_write_table', @@ -2400,7 +2389,7 @@ # # @immediately: fail immediately; defaults to false # -# Since: 2.0 +# Since: 2.9 ## { 'struct': 'BlkdebugInjectErrorOptions', 'data': { 'event': 'BlkdebugEvent', @@ -2423,7 +2412,7 @@ # @new_state: the state identifier blkdebug is supposed to assume if # this event is triggered # -# Since: 2.0 +# Since: 2.9 ## { 'struct': 'BlkdebugSetStateOptions', 'data': { 'event': 'BlkdebugEvent', @@ -2446,7 +2435,7 @@ # # @set-state: array of state-change descriptions # -# Since: 2.0 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsBlkdebug', 'data': { 'image': 'BlockdevRef', @@ -2464,7 +2453,7 @@ # # @raw: raw image used for verification # -# Since: 2.0 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsBlkverify', 'data': { 'test': 'BlockdevRef', @@ -2479,7 +2468,7 @@ # # @fifo: read only from the first child that has not failed # -# Since: 2.2 +# Since: 2.9 ## { 'enum': 'QuorumReadPattern', 'data': [ 'quorum', 'fifo' ] } @@ -2501,7 +2490,7 @@ # @read-pattern: choose read pattern and set to quorum by default # (Since 2.2) # -# Since: 2.0 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsQuorum', 'data': { '*blkverify': 'bool', @@ -2526,7 +2515,7 @@ # # @logfile: libgfapi log file (default /dev/stderr) (Since 2.8) # -# Since: 2.7 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsGluster', 'data': { 'volume': 'str', @@ -2657,7 +2646,7 @@ # # @secondary: Secondary mode, receive the vm's state from primary QEMU. # -# Since: 2.8 +# Since: 2.9 ## { 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ] } @@ -2672,7 +2661,7 @@ # node who owns the replication node chain. Must not be given in # primary mode. # -# Since: 2.8 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsReplication', 'base': 'BlockdevOptionsGenericFormat', @@ -2686,7 +2675,7 @@ # # @inet: TCP transport # -# Since: 2.8 +# Since: 2.9 ## { 'enum': 'NFSTransport', 'data': [ 'inet' ] } @@ -2700,7 +2689,7 @@ # # @host: host address for NFS server # -# Since: 2.8 +# Since: 2.9 ## { 'struct': 'NFSServer', 'data': { 'type': 'NFSTransport', @@ -2735,7 +2724,7 @@ # @debug: set the NFS debug level (max 2) (defaults # to libnfs default) # -# Since: 2.8 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsNfs', 'data': { 'server': 'NFSServer', @@ -2754,7 +2743,7 @@ # # @filename: path to the image file # -# Since: 1.7 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsCurl', 'data': { 'filename': 'str' } } @@ -2770,7 +2759,7 @@ # # @tls-creds: TLS credentials ID # -# Since: 2.8 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsNbd', 'data': { 'server': 'SocketAddress', @@ -2785,7 +2774,7 @@ # @offset: position where the block device starts # @size: the assumed size of the device # -# Since: 2.8 +# Since: 2.9 ## { 'struct': 'BlockdevOptionsRaw', 'base': 'BlockdevOptionsGenericFormat', @@ -2809,7 +2798,7 @@ # # Remaining options are determined by the block driver. # -# Since: 1.7 +# Since: 2.9 ## { 'union': 'BlockdevOptions', 'base': { 'driver': 'BlockdevDriver', @@ -2866,7 +2855,7 @@ # empty string means that no block device should be # referenced. # -# Since: 1.7 +# Since: 2.9 ## { 'alternate': 'BlockdevRef', 'data': { 'definition': 'BlockdevOptions', @@ -2879,11 +2868,7 @@ # BlockBackend will be created; otherwise, @node-name is mandatory at the top # level and no BlockBackend will be created. # -# Note: This command is still a work in progress. It doesn't support all -# block drivers among other things. Stay away from it unless you want -# to help with its development. -# -# Since: 1.7 +# Since: 2.9 # # Example: # @@ -2929,7 +2914,7 @@ { 'command': 'blockdev-add', 'data': 'BlockdevOptions', 'boxed': true } ## -# @x-blockdev-del: +# @blockdev-del: # # Deletes a block device that has been added using blockdev-add. # The command will fail if the node is attached to a device or is @@ -2937,11 +2922,7 @@ # # @node-name: Name of the graph node to delete. # -# Note: This command is still a work in progress and is considered -# experimental. Stay away from it unless you want to help with its -# development. -# -# Since: 2.5 +# Since: 2.9 # # Example: # @@ -2957,13 +2938,13 @@ # } # <- { "return": {} } # -# -> { "execute": "x-blockdev-del", +# -> { "execute": "blockdev-del", # "arguments": { "node-name": "node0" } # } # <- { "return": {} } # ## -{ 'command': 'x-blockdev-del', 'data': { 'node-name': 'str' } } +{ 'command': 'blockdev-del', 'data': { 'node-name': 'str' } } ## # @blockdev-open-tray: diff --git a/replay/replay.c b/replay/replay.c index 78e2a7e570..9e0724e756 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -22,7 +22,7 @@ /* Current version of the replay mechanism. Increase it when file format changes. */ -#define REPLAY_VERSION 0xe02005 +#define REPLAY_VERSION 0xe02006 /* Size of replay log header */ #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139 index 6d98e4f879..175d8f0008 100644 --- a/tests/qemu-iotests/139 +++ b/tests/qemu-iotests/139 @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Test cases for the QMP 'x-blockdev-del' command +# Test cases for the QMP 'blockdev-del' command # # Copyright (C) 2015 Igalia, S.L. # Author: Alberto Garcia <berto@igalia.com> @@ -79,7 +79,7 @@ class TestBlockdevDel(iotests.QMPTestCase): # Delete a BlockDriverState def delBlockDriverState(self, node, expect_error = False): self.checkBlockDriverState(node) - result = self.vm.qmp('x-blockdev-del', node_name = node) + result = self.vm.qmp('blockdev-del', node_name = node) if expect_error: self.assert_qmp(result, 'error/class', 'GenericError') else: @@ -173,7 +173,7 @@ class TestBlockdevDel(iotests.QMPTestCase): self.wait_until_completed(id) # Add a BlkDebug node - # Note that the purpose of this is to test the x-blockdev-del + # Note that the purpose of this is to test the blockdev-del # sanity checks, not to create a usable blkdebug drive def addBlkDebug(self, debug, node): self.checkBlockDriverState(node, False) @@ -191,7 +191,7 @@ class TestBlockdevDel(iotests.QMPTestCase): self.checkBlockDriverState(debug) # Add a BlkVerify node - # Note that the purpose of this is to test the x-blockdev-del + # Note that the purpose of this is to test the blockdev-del # sanity checks, not to create a usable blkverify drive def addBlkVerify(self, blkverify, test, raw): self.checkBlockDriverState(test, False) diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141 index 6d8f0a1a84..27fb1cc92c 100755 --- a/tests/qemu-iotests/141 +++ b/tests/qemu-iotests/141 @@ -65,7 +65,7 @@ test_blockjob() # We want this to return an error because the block job is still running _send_qemu_cmd $QEMU_HANDLE \ - "{'execute': 'x-blockdev-del', + "{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}" \ 'error' | _filter_generated_node_ids @@ -75,7 +75,7 @@ test_blockjob() "$3" _send_qemu_cmd $QEMU_HANDLE \ - "{'execute': 'x-blockdev-del', + "{'execute': 'blockdev-del', 'arguments': {'node-name': 'drv0'}}" \ 'return' } diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147 index 45469c911e..cca75c562c 100755 --- a/tests/qemu-iotests/147 +++ b/tests/qemu-iotests/147 @@ -57,7 +57,7 @@ class NBDBlockdevAddBase(iotests.QMPTestCase): filename) break - result = self.vm.qmp('x-blockdev-del', node_name='nbd-blockdev') + result = self.vm.qmp('blockdev-del', node_name='nbd-blockdev') self.assert_qmp(result, 'return', {}) diff --git a/ui/console.c b/ui/console.c index 937c950840..419b098c11 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1576,17 +1576,22 @@ bool dpy_gfx_check_format(QemuConsole *con, } /* - * Safe DPY refresh for TCG guests. This runs when the TCG vCPUs are - * quiescent so we can avoid races between dirty page tracking for - * direct frame-buffer access by the guest. + * Safe DPY refresh for TCG guests. We use the exclusive mechanism to + * ensure the TCG vCPUs are quiescent so we can avoid races between + * dirty page tracking for direct frame-buffer access by the guest. * * This is a temporary stopgap until we've fixed the dirty tracking * races in display adapters. */ -static void do_safe_dpy_refresh(CPUState *cpu, run_on_cpu_data opaque) +static void do_safe_dpy_refresh(DisplayChangeListener *dcl) { - DisplayChangeListener *dcl = opaque.host_ptr; + qemu_mutex_unlock_iothread(); + start_exclusive(); + qemu_mutex_lock_iothread(); dcl->ops->dpy_refresh(dcl); + qemu_mutex_unlock_iothread(); + end_exclusive(); + qemu_mutex_lock_iothread(); } static void dpy_refresh(DisplayState *s) @@ -1596,8 +1601,7 @@ static void dpy_refresh(DisplayState *s) QLIST_FOREACH(dcl, &s->listeners, next) { if (dcl->ops->dpy_refresh) { if (tcg_enabled()) { - async_safe_run_on_cpu(first_cpu, do_safe_dpy_refresh, - RUN_ON_CPU_HOST_PTR(dcl)); + do_safe_dpy_refresh(dcl); } else { dcl->ops->dpy_refresh(dcl); } diff --git a/user-exec.c b/user-exec.c index 6db075884d..a8f95fa1e1 100644 --- a/user-exec.c +++ b/user-exec.c @@ -57,10 +57,23 @@ static void cpu_exit_tb_from_sighandler(CPUState *cpu, sigset_t *old_set) static inline int handle_cpu_signal(uintptr_t pc, unsigned long address, int is_write, sigset_t *old_set) { - CPUState *cpu; + CPUState *cpu = current_cpu; CPUClass *cc; int ret; + /* For synchronous signals we expect to be coming from the vCPU + * thread (so current_cpu should be valid) and either from running + * code or during translation which can fault as we cross pages. + * + * If neither is true then something has gone wrong and we should + * abort rather than try and restart the vCPU execution. + */ + if (!cpu || !cpu->running) { + printf("qemu:%s received signal outside vCPU context @ pc=0x%" + PRIxPTR "\n", __func__, pc); + abort(); + } + #if defined(DEBUG_SIGNAL) printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", pc, address, is_write, *(unsigned long *)old_set); @@ -83,7 +96,7 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address, * currently executing TB was modified and must be exited * immediately. */ - cpu_exit_tb_from_sighandler(current_cpu, old_set); + cpu_exit_tb_from_sighandler(cpu, old_set); g_assert_not_reached(); default: g_assert_not_reached(); @@ -94,7 +107,6 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address, are still valid segv ones */ address = h2g_nocheck(address); - cpu = current_cpu; cc = CPU_GET_CLASS(cpu); /* see if it is an MMU fault */ g_assert(cc->handle_mmu_fault); |