From 8e46bbf362458fc3e4638a53249248a1ee40b912 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Thu, 6 Feb 2014 11:24:33 +0100 Subject: memory_region_present: return false if address is not found in child MemoryRegion Windows XP shows COM2 port as non functional in "Device Manager" although no COM2 port backing device is present in QEMU. This regression is really due to 3bb28b7208b349e7a1b326e3c6ef9efac1d462bf? memory: Provide separate handling of unassigned io ports accesses That is caused by the fact that QEMU reports to OSPM that device is present by setting 5th bit in PII4XPM.pci_conf[0x67] register when COM2 doesn't exist. It happens due to memory_region_present(io_as, 0x2f8) returning false positive since 0x2f8 address eventually translates into catchall io_as address space. Fix memory_region_present(parent, addr) by returning true only if addr maps into a MemoryRegion within parent (excluding parent itself), to match its doc comment. While at it fix copy/paste error in memory_region_present() doc comment. Note: this is a temporary hack: we really need better handling for unassigned regions, we should avoid fallback regions since they are bad for performance (breaking radix tree assumption that the data structure is sparsely populated); for memory we need to fix this to implement PCI master abort properly, anyway. Cc: Jan Kiszka Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/exec/memory.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/exec/memory.h b/include/exec/memory.h index 9101fc3a55..c084db2d9d 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -836,13 +836,13 @@ void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset); /** - * memory_region_present: translate an address/size relative to a - * MemoryRegion into a #MemoryRegionSection. + * memory_region_present: checks if an address relative to a @parent + * translates into #MemoryRegion within @parent * * Answer whether a #MemoryRegion within @parent covers the address * @addr. * - * @parent: a MemoryRegion within which @addr is a relative address + * @parent: a #MemoryRegion within which @addr is a relative address * @addr: the area within @parent to be searched */ bool memory_region_present(MemoryRegion *parent, hwaddr addr); -- cgit v1.2.3-55-g7522 From 8f480de0c91a18d550721f8d9af969ebfbda0793 Mon Sep 17 00:00:00 2001 From: Dr. David Alan Gilbert Date: Thu, 30 Jan 2014 10:20:31 +0000 Subject: Add 'debug-threads' suboption to --name Add flag storage to qemu-thread-* to store the namethreads flag Signed-off-by: Dr. David Alan Gilbert Acked-by: Michael S. Tsirkin Reviewed-by: Laszlo Ersek --- include/qemu/thread.h | 1 + qemu-options.hx | 7 +++++-- util/qemu-thread-posix.c | 7 +++++++ util/qemu-thread-win32.c | 8 ++++++++ vl.c | 9 +++++++++ 5 files changed, 30 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 3e32c6531c..bf1e110a38 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -59,5 +59,6 @@ void *qemu_thread_join(QemuThread *thread); void qemu_thread_get_self(QemuThread *thread); bool qemu_thread_is_self(QemuThread *thread); void qemu_thread_exit(void *retval); +void qemu_thread_naming(bool enable); #endif diff --git a/qemu-options.hx b/qemu-options.hx index 56e5fdf1e0..068da2df09 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -328,9 +328,11 @@ possible drivers and properties, use @code{-device help} and ETEXI DEF("name", HAS_ARG, QEMU_OPTION_name, - "-name string1[,process=string2]\n" + "-name string1[,process=string2][,debug-threads=on|off]\n" " set the name of the guest\n" - " string1 sets the window title and string2 the process name (on Linux)\n", + " string1 sets the window title and string2 the process name (on Linux)\n" + " When debug-threads is enabled, individual threads are given a separate name (on Linux)\n" + " NOTE: The thread names are for debugging and not a stable API.\n", QEMU_ARCH_ALL) STEXI @item -name @var{name} @@ -339,6 +341,7 @@ Sets the @var{name} of the guest. This name will be displayed in the SDL window caption. The @var{name} will also be used for the VNC server. Also optionally set the top visible process name in Linux. +Naming of individual threads can also be enabled on Linux to aid debugging. ETEXI DEF("uuid", HAS_ARG, QEMU_OPTION_uuid, diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 37dd298631..0fa6c81c0a 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -27,6 +27,13 @@ #include "qemu/thread.h" #include "qemu/atomic.h" +static bool name_threads; + +void qemu_thread_naming(bool enable) +{ + name_threads = enable; +} + static void error_exit(int err, const char *msg) { fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err)); diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index 27a5217769..e42cb77f91 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -16,6 +16,14 @@ #include #include +static bool name_threads; + +void qemu_thread_naming(bool enable) +{ + /* But note we don't actually name them on Windows yet */ + name_threads = enable; +} + static void error_exit(int err, const char *msg) { char *pstr; diff --git a/vl.c b/vl.c index 44b5ad3b39..c8a5bfa959 100644 --- a/vl.c +++ b/vl.c @@ -495,6 +495,12 @@ static QemuOptsList qemu_name_opts = { .name = "process", .type = QEMU_OPT_STRING, .help = "Sets the name of the QEMU process, as shown in top etc", + }, { + .name = "debug-threads", + .type = QEMU_OPT_BOOL, + .help = "When enabled, name the individual threads; defaults off.\n" + "NOTE: The thread names are for debugging and not a\n" + "stable API.", }, { /* End of list */ } }, @@ -954,6 +960,9 @@ static void parse_name(QemuOpts *opts) { const char *proc_name; + if (qemu_opt_get(opts, "debug-threads")) { + qemu_thread_naming(qemu_opt_get_bool(opts, "debug-threads", false)); + } qemu_name = qemu_opt_get(opts, "guest"); proc_name = qemu_opt_get(opts, "process"); -- cgit v1.2.3-55-g7522 From 4900116e6f0edef6877c0e8a9ca19957d47765c9 Mon Sep 17 00:00:00 2001 From: Dr. David Alan Gilbert Date: Thu, 30 Jan 2014 10:20:32 +0000 Subject: Add a 'name' parameter to qemu_thread_create If enabled, set the thread name at creation (on GNU systems with pthread_set_np) Fix up all the callers with a thread name Signed-off-by: Dr. David Alan Gilbert Acked-by: Michael S. Tsirkin Reviewed-by: Laszlo Ersek --- cpus.c | 25 ++++++++++++++++++++----- hw/block/dataplane/virtio-blk.c | 2 +- hw/usb/ccid-card-emulated.c | 8 ++++---- include/qemu/thread.h | 2 +- libcacard/vscclient.c | 2 +- migration.c | 2 +- thread-pool.c | 2 +- ui/vnc-jobs.c | 3 ++- util/compatfd.c | 3 ++- util/qemu-thread-posix.c | 9 +++++++-- util/qemu-thread-win32.c | 2 +- 11 files changed, 41 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/cpus.c b/cpus.c index 945d85b326..b6421fd2a8 100644 --- a/cpus.c +++ b/cpus.c @@ -1117,8 +1117,13 @@ void resume_all_vcpus(void) } } +/* For temporary buffers for forming a name */ +#define VCPU_THREAD_NAME_SIZE 16 + static void qemu_tcg_init_vcpu(CPUState *cpu) { + char thread_name[VCPU_THREAD_NAME_SIZE]; + tcg_cpu_address_space_init(cpu, cpu->as); /* share a single thread for all cpus with TCG */ @@ -1127,8 +1132,10 @@ static void qemu_tcg_init_vcpu(CPUState *cpu) cpu->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(cpu->halt_cond); tcg_halt_cond = cpu->halt_cond; - qemu_thread_create(cpu->thread, qemu_tcg_cpu_thread_fn, cpu, - QEMU_THREAD_JOINABLE); + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qemu_tcg_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); #ifdef _WIN32 cpu->hThread = qemu_thread_get_handle(cpu->thread); #endif @@ -1144,11 +1151,15 @@ static void qemu_tcg_init_vcpu(CPUState *cpu) static void qemu_kvm_start_vcpu(CPUState *cpu) { + char thread_name[VCPU_THREAD_NAME_SIZE]; + cpu->thread = g_malloc0(sizeof(QemuThread)); cpu->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(cpu->halt_cond); - qemu_thread_create(cpu->thread, qemu_kvm_cpu_thread_fn, cpu, - QEMU_THREAD_JOINABLE); + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); } @@ -1156,10 +1167,14 @@ static void qemu_kvm_start_vcpu(CPUState *cpu) static void qemu_dummy_start_vcpu(CPUState *cpu) { + char thread_name[VCPU_THREAD_NAME_SIZE]; + cpu->thread = g_malloc0(sizeof(QemuThread)); cpu->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(cpu->halt_cond); - qemu_thread_create(cpu->thread, qemu_dummy_cpu_thread_fn, cpu, + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qemu_dummy_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 2237edb4eb..d1c7ad4574 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -358,7 +358,7 @@ static void start_data_plane_bh(void *opaque) qemu_bh_delete(s->start_bh); s->start_bh = NULL; - qemu_thread_create(&s->thread, data_plane_thread, + qemu_thread_create(&s->thread, "data_plane", data_plane_thread, s, QEMU_THREAD_JOINABLE); } diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c index aa913df853..7213c8909c 100644 --- a/hw/usb/ccid-card-emulated.c +++ b/hw/usb/ccid-card-emulated.c @@ -546,10 +546,10 @@ static int emulated_initfn(CCIDCardState *base) printf("%s: failed to initialize vcard\n", EMULATED_DEV_NAME); return -1; } - qemu_thread_create(&card->event_thread_id, event_thread, card, - QEMU_THREAD_JOINABLE); - qemu_thread_create(&card->apdu_thread_id, handle_apdu_thread, card, - QEMU_THREAD_JOINABLE); + qemu_thread_create(&card->event_thread_id, "ccid/event", event_thread, + card, QEMU_THREAD_JOINABLE); + qemu_thread_create(&card->apdu_thread_id, "ccid/apdu", handle_apdu_thread, + card, QEMU_THREAD_JOINABLE); return 0; } diff --git a/include/qemu/thread.h b/include/qemu/thread.h index bf1e110a38..f7e3b9b290 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -52,7 +52,7 @@ void qemu_event_reset(QemuEvent *ev); void qemu_event_wait(QemuEvent *ev); void qemu_event_destroy(QemuEvent *ev); -void qemu_thread_create(QemuThread *thread, +void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void *), void *arg, int mode); void *qemu_thread_join(QemuThread *thread); diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c index 24f7088ecf..3477ab3e1b 100644 --- a/libcacard/vscclient.c +++ b/libcacard/vscclient.c @@ -269,7 +269,7 @@ on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0); /* launch the event_thread. This will trigger reader adds for all the * existing readers */ - qemu_thread_create(&thread_id, event_thread, NULL, 0); + qemu_thread_create(&thread_id, "vsc/event", event_thread, NULL, 0); return 0; } diff --git a/migration.c b/migration.c index 14235b280a..00f465ea46 100644 --- a/migration.c +++ b/migration.c @@ -695,6 +695,6 @@ void migrate_fd_connect(MigrationState *s) /* Notify before starting migration thread */ notifier_list_notify(&migration_state_notifiers, s); - qemu_thread_create(&s->thread, migration_thread, s, + qemu_thread_create(&s->thread, "migration", migration_thread, s, QEMU_THREAD_JOINABLE); } diff --git a/thread-pool.c b/thread-pool.c index 3735fd34bc..fbdd3ffa3a 100644 --- a/thread-pool.c +++ b/thread-pool.c @@ -140,7 +140,7 @@ static void do_spawn_thread(ThreadPool *pool) pool->new_threads--; pool->pending_threads++; - qemu_thread_create(&t, worker_thread, pool, QEMU_THREAD_DETACHED); + qemu_thread_create(&t, "worker", worker_thread, pool, QEMU_THREAD_DETACHED); } static void spawn_thread_bh_fn(void *opaque) diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index 2d3fce8155..3f3c47b9a5 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -333,7 +333,8 @@ void vnc_start_worker_thread(void) return ; q = vnc_queue_init(); - qemu_thread_create(&q->thread, vnc_worker_thread, q, QEMU_THREAD_DETACHED); + qemu_thread_create(&q->thread, "vnc_worker", vnc_worker_thread, q, + QEMU_THREAD_DETACHED); queue = q; /* Set global queue */ } diff --git a/util/compatfd.c b/util/compatfd.c index 430a41c855..341ada638f 100644 --- a/util/compatfd.c +++ b/util/compatfd.c @@ -88,7 +88,8 @@ static int qemu_signalfd_compat(const sigset_t *mask) memcpy(&info->mask, mask, sizeof(*mask)); info->fd = fds[1]; - qemu_thread_create(&thread, sigwait_compat, info, QEMU_THREAD_DETACHED); + qemu_thread_create(&thread, "signalfd_compat", sigwait_compat, info, + QEMU_THREAD_DETACHED); return fds[0]; } diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 0fa6c81c0a..45113b464d 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -394,8 +394,7 @@ void qemu_event_wait(QemuEvent *ev) } } - -void qemu_thread_create(QemuThread *thread, +void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void*), void *arg, int mode) { @@ -421,6 +420,12 @@ void qemu_thread_create(QemuThread *thread, if (err) error_exit(err, __func__); +#ifdef _GNU_SOURCE + if (name_threads) { + pthread_setname_np(thread->thread, name); + } +#endif + pthread_sigmask(SIG_SETMASK, &oldset, NULL); pthread_attr_destroy(&attr); diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index e42cb77f91..b9c957b6a0 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -333,7 +333,7 @@ void *qemu_thread_join(QemuThread *thread) return ret; } -void qemu_thread_create(QemuThread *thread, +void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void *), void *arg, int mode) { -- cgit v1.2.3-55-g7522