From 1729404c62e1adae501feeaaf61b87262d52ae1b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 1 Oct 2015 12:59:08 +0200 Subject: nbd: switch from g_slice allocator to malloc Simplify memory allocation by sticking with a single API. GSlice is not that fast anyway (tcmalloc/jemalloc are better). Signed-off-by: Paolo Bonzini --- nbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nbd.c b/nbd.c index 07240bd..74859cb 100644 --- a/nbd.c +++ b/nbd.c @@ -1005,7 +1005,7 @@ static NBDRequest *nbd_request_get(NBDClient *client) client->nb_requests++; nbd_update_can_read(client); - req = g_slice_new0(NBDRequest); + req = g_new0(NBDRequest, 1); nbd_client_get(client); req->client = client; return req; @@ -1018,7 +1018,7 @@ static void nbd_request_put(NBDRequest *req) if (req->data) { qemu_vfree(req->data); } - g_slice_free(NBDRequest, req); + g_free(req); client->nb_requests--; nbd_update_can_read(client); -- cgit v1.1 From 633dccb458c4eaa40107cd7026737d804f90b6c0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 1 Oct 2015 12:59:01 +0200 Subject: scsi: switch from g_slice allocator to malloc Simplify memory allocation by sticking with a single API. GSlice is not that fast anyway (tcmalloc/jemalloc are better). Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-bus.c | 4 ++-- hw/scsi/virtio-scsi-dataplane.c | 10 +++++----- hw/scsi/virtio-scsi.c | 12 +++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index ffac8f4..d373c1b 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -558,7 +558,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, const int memset_off = offsetof(SCSIRequest, sense) + sizeof(req->sense); - req = g_slice_alloc(reqops->size); + req = g_malloc(reqops->size); memset((uint8_t *)req + memset_off, 0, reqops->size - memset_off); req->refcount = 1; req->bus = bus; @@ -1622,7 +1622,7 @@ void scsi_req_unref(SCSIRequest *req) } object_unref(OBJECT(req->dev)); object_unref(OBJECT(qbus->parent)); - g_slice_free1(req->ops->size, req); + g_free(req); } } diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 5575648..1248fd9 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -57,7 +57,7 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s, return NULL; } - r = g_slice_new(VirtIOSCSIVring); + r = g_new(VirtIOSCSIVring, 1); r->host_notifier = *virtio_queue_get_host_notifier(vq); r->guest_notifier = *virtio_queue_get_guest_notifier(vq); aio_set_event_notifier(s->ctx, &r->host_notifier, handler); @@ -73,7 +73,7 @@ static VirtIOSCSIVring *virtio_scsi_vring_init(VirtIOSCSI *s, fail_vring: aio_set_event_notifier(s->ctx, &r->host_notifier, NULL); k->set_host_notifier(qbus->parent, n, false); - g_slice_free(VirtIOSCSIVring, r); + g_free(r); return NULL; } @@ -182,18 +182,18 @@ static void virtio_scsi_vring_teardown(VirtIOSCSI *s) if (s->ctrl_vring) { vring_teardown(&s->ctrl_vring->vring, vdev, 0); - g_slice_free(VirtIOSCSIVring, s->ctrl_vring); + g_free(s->ctrl_vring); s->ctrl_vring = NULL; } if (s->event_vring) { vring_teardown(&s->event_vring->vring, vdev, 1); - g_slice_free(VirtIOSCSIVring, s->event_vring); + g_free(s->event_vring); s->event_vring = NULL; } if (s->cmd_vrings) { for (i = 0; i < vs->conf.num_queues && s->cmd_vrings[i]; i++) { vring_teardown(&s->cmd_vrings[i]->vring, vdev, 2 + i); - g_slice_free(VirtIOSCSIVring, s->cmd_vrings[i]); + g_free(s->cmd_vrings[i]); s->cmd_vrings[i] = NULL; } free(s->cmd_vrings); diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 1c33f14..20885fb 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -47,7 +47,7 @@ VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq) const size_t zero_skip = offsetof(VirtIOSCSIReq, elem) + sizeof(VirtQueueElement); - req = g_slice_alloc(sizeof(*req) + vs->cdb_size); + req = g_malloc(sizeof(*req) + vs->cdb_size); req->vq = vq; req->dev = s; qemu_sglist_init(&req->qsgl, DEVICE(s), 8, &address_space_memory); @@ -58,11 +58,9 @@ VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq) void virtio_scsi_free_req(VirtIOSCSIReq *req) { - VirtIOSCSICommon *vs = (VirtIOSCSICommon *)req->dev; - qemu_iovec_destroy(&req->resp_iov); qemu_sglist_destroy(&req->qsgl); - g_slice_free1(sizeof(*req) + vs->cdb_size, req); + g_free(req); } static void virtio_scsi_complete_req(VirtIOSCSIReq *req) @@ -250,7 +248,7 @@ static void virtio_scsi_cancel_notify(Notifier *notifier, void *data) if (--n->tmf_req->remaining == 0) { virtio_scsi_complete_req(n->tmf_req); } - g_slice_free(VirtIOSCSICancelNotifier, n); + g_free(n); } /* Return 0 if the request is ready to be completed and return to guest; @@ -301,7 +299,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) VirtIOSCSICancelNotifier *notifier; req->remaining = 1; - notifier = g_slice_new(VirtIOSCSICancelNotifier); + notifier = g_new(VirtIOSCSICancelNotifier, 1); notifier->tmf_req = req; notifier->notifier.notify = virtio_scsi_cancel_notify; scsi_req_cancel_async(r, ¬ifier->notifier); @@ -350,7 +348,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) VirtIOSCSICancelNotifier *notifier; req->remaining++; - notifier = g_slice_new(VirtIOSCSICancelNotifier); + notifier = g_new(VirtIOSCSICancelNotifier, 1); notifier->notifier.notify = virtio_scsi_cancel_notify; notifier->tmf_req = req; scsi_req_cancel_async(r, ¬ifier->notifier); -- cgit v1.1 From 8ef2eb8d2cad7400236d6b2c152bdb5506761b4d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 30 Sep 2015 19:21:10 +0200 Subject: megasas: fix megasas_get_sata_addr There are two bugs here. First, the 16-bit id loses the high 8 bits when shifted left by 24. Second, the address must be combined with an "or" or we just get zero. Signed-off-by: Paolo Bonzini --- hw/scsi/megasas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index a04369c..dcd724e 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -431,7 +431,7 @@ static uint64_t megasas_fw_time(void) static uint64_t megasas_get_sata_addr(uint16_t id) { uint64_t addr = (0x1221ULL << 48); - return addr & (id << 24); + return addr | ((uint64_t)id << 24); } /* -- cgit v1.1 From fec21036ff516d20721abc01ae7be99ae5bb0c7b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 4 Sep 2015 21:53:03 +0200 Subject: configure: Require Python 2.6 RHEL-6 and SLES-11 provide Python 2.6. It'll also work on OS X back to 10.6. Signed-off-by: Markus Armbruster Message-Id: <1441396383-17304-1-git-send-email-armbru@redhat.com> Reviewed-by: Peter Maydell Signed-off-by: Paolo Bonzini --- configure | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/configure b/configure index f08327e..913ae4a 100755 --- a/configure +++ b/configure @@ -1166,18 +1166,14 @@ fi # Note that if the Python conditional here evaluates True we will exit # with status 1 which is a shell 'false' value. -if ! $python -c 'import sys; sys.exit(sys.version_info < (2,4) or sys.version_info >= (3,))'; then - error_exit "Cannot use '$python', Python 2.4 or later is required." \ +if ! $python -c 'import sys; sys.exit(sys.version_info < (2,6) or sys.version_info >= (3,))'; then + error_exit "Cannot use '$python', Python 2.6 or later is required." \ "Note that Python 3 or later is not yet supported." \ "Use --python=/path/to/python to specify a supported Python." fi -# The -B switch was added in Python 2.6. -# If it is supplied, compiled files are not written. -# Use it for Python versions which support it. -if $python -B -c 'import sys; sys.exit(0)' 2>/dev/null; then - python="$python -B" -fi +# Suppress writing compiled files +python="$python -B" case "$cpu" in ppc) -- cgit v1.1 From 0a1c71cec63e95f9b8d0dc96d049d2daa00c5210 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 1 Oct 2015 15:29:48 +0100 Subject: exec.c: Don't call cpu_reload_memory_map() from cpu_exec_init() Currently we call cpu_reload_memory_map() from cpu_exec_init(), but this is not necessary: * KVM doesn't use the data structures maintained by cpu_reload_memory_map() (the TLB and cpu->memory_dispatch) * for TCG, we will call this function via tcg_commit() either as soon as tcg_cpu_address_space_init() registers the listener, or when the first MemoryRegion is added to the AddressSpace if the AS is empty when we register the listener The unnecessary call is awkward for adding support for multiple address spaces per CPU, so drop it. Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias Message-Id: <1443709790-25180-2-git-send-email-peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini --- exec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/exec.c b/exec.c index 7d90a52..ab5d8a8 100644 --- a/exec.c +++ b/exec.c @@ -601,7 +601,6 @@ void cpu_exec_init(CPUState *cpu, Error **errp) #ifndef CONFIG_USER_ONLY cpu->as = &address_space_memory; cpu->thread_id = qemu_get_thread_id(); - cpu_reload_memory_map(cpu); #endif #if defined(CONFIG_USER_ONLY) -- cgit v1.1 From 53f8a5e9e2633a4a3b6918c36aec725aa80f2887 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 1 Oct 2015 15:29:49 +0100 Subject: cpu-exec-common.c: Clarify comment about cpu_reload_memory_map()'s RCU operations The reason for cpu_reload_memory_map()'s RCU operations is not so much because the guest could make the critical section very long, but that it could have a critical section within which it made an arbitrary number of changes to the memory map and thus accumulate an unbounded amount of memory data structures awaiting reclamation. Clarify the comment to make this clearer. Signed-off-by: Peter Maydell Message-Id: <1443709790-25180-3-git-send-email-peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini --- cpu-exec-common.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/cpu-exec-common.c b/cpu-exec-common.c index 16d305b..b95b09a 100644 --- a/cpu-exec-common.c +++ b/cpu-exec-common.c @@ -42,13 +42,21 @@ void cpu_reload_memory_map(CPUState *cpu) AddressSpaceDispatch *d; if (qemu_in_vcpu_thread()) { - /* Do not let the guest prolong the critical section as much as it - * as it desires. + /* 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 + * critical section, we could potentially accumulate an unbounded + * collection of memory data structures awaiting reclamation. * - * Currently, this is prevented by the I/O thread's periodinc kicking - * of the VCPU thread (iothread_requesting_mutex, qemu_cpu_kick_thread) - * but this will go away once TCG's execution moves out of the global - * mutex. + * Because the only thing we're currently protecting with RCU is the + * memory data structures, it's sufficient to break the critical section + * in this callback, which we know will get called every time the + * memory map is rearranged. + * + * (If we add anything else in the system that uses RCU to protect + * its data structures, we will need to implement some other mechanism + * to force TCG CPUs to exit the critical section, at which point this + * part of this callback might become unnecessary.) * * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which * only protects cpu->as->dispatch. Since we reload it below, we can -- cgit v1.1 From 32857f4d5e165329c03d66000d666975d85f882a Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 1 Oct 2015 15:29:50 +0100 Subject: exec.c: Collect AddressSpace related fields into a CPUAddressSpace struct Gather up all the fields currently in CPUState which deal with the CPU's AddressSpace into a separate CPUAddressSpace struct. This paves the way for allowing the CPU to know about more than one AddressSpace. The rearrangement also allows us to make the MemoryListener a directly embedded object in the CPUAddressSpace (it could not be embedded in CPUState because 'struct MemoryListener' isn't defined for the user-only builds). This allows us to resolve the FIXME in tcg_commit() by going directly from the MemoryListener to the CPUAddressSpace. This patch extracts the actual update of the cached dispatch pointer from cpu_reload_memory_map() (which is renamed accordingly to cpu_reloading_memory_map() as it is only responsible for breaking cpu-exec.c's RCU critical section now). This lets us keep the definition of the CPUAddressSpace struct private to exec.c. Signed-off-by: Peter Maydell Message-Id: <1443709790-25180-4-git-send-email-peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini --- cpu-exec-common.c | 13 +++--------- exec.c | 56 +++++++++++++++++++++++++++++++++---------------- include/exec/exec-all.h | 2 +- include/qemu/typedefs.h | 1 + include/qom/cpu.h | 7 +++++-- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/cpu-exec-common.c b/cpu-exec-common.c index b95b09a..43edf36 100644 --- a/cpu-exec-common.c +++ b/cpu-exec-common.c @@ -37,10 +37,8 @@ void cpu_resume_from_signal(CPUState *cpu, void *puc) siglongjmp(cpu->jmp_env, 1); } -void cpu_reload_memory_map(CPUState *cpu) +void cpu_reloading_memory_map(void) { - AddressSpaceDispatch *d; - if (qemu_in_vcpu_thread()) { /* 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 @@ -59,17 +57,12 @@ void cpu_reload_memory_map(CPUState *cpu) * part of this callback might become unnecessary.) * * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which - * only protects cpu->as->dispatch. Since we reload it below, we can - * split the critical section. + * only protects cpu->as->dispatch. Since we know our caller is about + * to reload it, it's safe to split the critical section. */ rcu_read_unlock(); rcu_read_lock(); } - - /* The CPU and TLB are protected by the iothread lock. */ - d = atomic_rcu_read(&cpu->as->dispatch); - cpu->memory_dispatch = d; - tlb_flush(cpu, 1); } #endif diff --git a/exec.c b/exec.c index ab5d8a8..aad94a0 100644 --- a/exec.c +++ b/exec.c @@ -161,6 +161,21 @@ static void memory_map_init(void); static void tcg_commit(MemoryListener *listener); static MemoryRegion io_mem_watch; + +/** + * CPUAddressSpace: all the information a CPU needs about an AddressSpace + * @cpu: the CPU whose AddressSpace this is + * @as: the AddressSpace itself + * @memory_dispatch: its dispatch pointer (cached, RCU protected) + * @tcg_as_listener: listener for tracking changes to the AddressSpace + */ +struct CPUAddressSpace { + CPUState *cpu; + AddressSpace *as; + struct AddressSpaceDispatch *memory_dispatch; + MemoryListener tcg_as_listener; +}; + #endif #if !defined(CONFIG_USER_ONLY) @@ -431,7 +446,7 @@ address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, hwaddr *xlat, hwaddr *plen) { MemoryRegionSection *section; - section = address_space_translate_internal(cpu->memory_dispatch, + section = address_space_translate_internal(cpu->cpu_ases[0].memory_dispatch, addr, xlat, plen, false); assert(!section->mr->iommu_ops); @@ -537,13 +552,16 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) /* We only support one address space per cpu at the moment. */ assert(cpu->as == as); - if (cpu->tcg_as_listener) { - memory_listener_unregister(cpu->tcg_as_listener); - } else { - cpu->tcg_as_listener = g_new0(MemoryListener, 1); + if (cpu->cpu_ases) { + /* We've already registered the listener for our only AS */ + return; } - cpu->tcg_as_listener->commit = tcg_commit; - memory_listener_register(cpu->tcg_as_listener, as); + + cpu->cpu_ases = g_new0(CPUAddressSpace, 1); + cpu->cpu_ases[0].cpu = cpu; + cpu->cpu_ases[0].as = as; + cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit; + memory_listener_register(&cpu->cpu_ases[0].tcg_as_listener, as); } #endif @@ -2218,7 +2236,8 @@ static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as, MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index) { - AddressSpaceDispatch *d = atomic_rcu_read(&cpu->memory_dispatch); + CPUAddressSpace *cpuas = &cpu->cpu_ases[0]; + AddressSpaceDispatch *d = atomic_rcu_read(&cpuas->memory_dispatch); MemoryRegionSection *sections = d->map.sections; return sections[index & ~TARGET_PAGE_MASK].mr; @@ -2277,19 +2296,20 @@ static void mem_commit(MemoryListener *listener) static void tcg_commit(MemoryListener *listener) { - CPUState *cpu; + CPUAddressSpace *cpuas; + AddressSpaceDispatch *d; /* since each CPU stores ram addresses in its TLB cache, we must reset the modified entries */ - /* XXX: slow ! */ - CPU_FOREACH(cpu) { - /* FIXME: Disentangle the cpu.h circular files deps so we can - directly get the right CPU from listener. */ - if (cpu->tcg_as_listener != listener) { - continue; - } - cpu_reload_memory_map(cpu); - } + cpuas = container_of(listener, CPUAddressSpace, tcg_as_listener); + cpu_reloading_memory_map(); + /* The CPU and TLB are protected by the iothread lock. + * We reload the dispatch pointer now because cpu_reloading_memory_map() + * may have split the RCU critical section. + */ + d = atomic_rcu_read(&cpuas->as->dispatch); + cpuas->memory_dispatch = d; + tlb_flush(cpuas->cpu, 1); } void address_space_init_dispatch(AddressSpace *as) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index a63fd60..4e8afbf 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -85,7 +85,7 @@ void QEMU_NORETURN cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc); #if !defined(CONFIG_USER_ONLY) bool qemu_in_vcpu_thread(void); -void cpu_reload_memory_map(CPUState *cpu); +void cpu_reloading_memory_map(void); void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as); /* cputlb.c */ /** diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index ee1ce1d..d4a8f7a 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -16,6 +16,7 @@ typedef struct BusClass BusClass; typedef struct BusState BusState; typedef struct CharDriverState CharDriverState; typedef struct CompatProperty CompatProperty; +typedef struct CPUAddressSpace CPUAddressSpace; typedef struct DeviceState DeviceState; typedef struct DeviceListener DeviceListener; typedef struct DisplayChangeListener DisplayChangeListener; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index b613ff0..51a1323 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -234,6 +234,10 @@ struct kvm_run; * @can_do_io: Nonzero if memory-mapped IO is safe. Deterministic execution * requires that IO only be performed on the last instruction of a TB * so that interrupts take effect immediately. + * @cpu_ases: Pointer to array of CPUAddressSpaces (which define the + * AddressSpaces this CPU has) + * @as: Pointer to the first AddressSpace, for the convenience of targets which + * only have a single AddressSpace * @env_ptr: Pointer to subclass-specific CPUArchState field. * @current_tb: Currently executing TB. * @gdb_regs: Additional GDB registers. @@ -280,9 +284,8 @@ struct CPUState { QemuMutex work_mutex; struct qemu_work_item *queued_work_first, *queued_work_last; + CPUAddressSpace *cpu_ases; AddressSpace *as; - struct AddressSpaceDispatch *memory_dispatch; - MemoryListener *tcg_as_listener; void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; -- cgit v1.1 From 5b906129524d564d61760d04586d6c2301457ead Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 5 Oct 2015 14:45:55 +0200 Subject: checkpatch: allow open braces on typedef lines The style here seems to be split according to the maintainer, but traditionally open braces were placed on typedef lines. Suggested-by: Peter Maydell Signed-off-by: Paolo Bonzini --- scripts/checkpatch.pl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index b6d71ea..d51346a 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1704,11 +1704,6 @@ sub process { ERROR("open brace '{' following $1 go on the same line\n" . $hereprev); } -# ... however, open braces on typedef lines should be avoided. - if ($line =~ /^.\s*typedef\s+(enum|union|struct)(?:\s+$Ident\b)?.*[^;]$/) { - ERROR("typedefs should be separate from struct declaration\n" . $herecurr); - } - # missing space after union, struct or enum definition if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) { ERROR("missing space after $1 definition\n" . $herecurr); -- cgit v1.1 From 3a824b1552d68b708c161a900e2956a78d4ea466 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 2 Oct 2015 18:19:58 +0200 Subject: linux-headers: update from kvm/next linux-headers/linux/vhost.h is currently out of sync with Linux. Do not touch it in this update. Signed-off-by: Paolo Bonzini --- include/standard-headers/asm-x86/hyperv.h | 6 +++++ linux-headers/asm-arm64/kvm.h | 37 +++++++++++++++++++++++++++++-- linux-headers/linux/kvm.h | 12 ++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/standard-headers/asm-x86/hyperv.h b/include/standard-headers/asm-x86/hyperv.h index 99d311e..c37c14e 100644 --- a/include/standard-headers/asm-x86/hyperv.h +++ b/include/standard-headers/asm-x86/hyperv.h @@ -153,6 +153,12 @@ /* MSR used to provide vcpu index */ #define HV_X64_MSR_VP_INDEX 0x40000002 +/* MSR used to reset the guest OS. */ +#define HV_X64_MSR_RESET 0x40000003 + +/* MSR used to provide vcpu runtime in 100ns units */ +#define HV_X64_MSR_VP_RUNTIME 0x40000010 + /* MSR used to read the per-partition time reference counter */ #define HV_X64_MSR_TIME_REF_COUNT 0x40000020 diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h index c8abf25..d3714c0 100644 --- a/linux-headers/asm-arm64/kvm.h +++ b/linux-headers/asm-arm64/kvm.h @@ -53,14 +53,20 @@ struct kvm_regs { struct user_fpsimd_state fp_regs; }; -/* Supported Processor Types */ +/* + * Supported CPU Targets - Adding a new target type is not recommended, + * unless there are some special registers not supported by the + * genericv8 syreg table. + */ #define KVM_ARM_TARGET_AEM_V8 0 #define KVM_ARM_TARGET_FOUNDATION_V8 1 #define KVM_ARM_TARGET_CORTEX_A57 2 #define KVM_ARM_TARGET_XGENE_POTENZA 3 #define KVM_ARM_TARGET_CORTEX_A53 4 +/* Generic ARM v8 target */ +#define KVM_ARM_TARGET_GENERIC_V8 5 -#define KVM_ARM_NUM_TARGETS 5 +#define KVM_ARM_NUM_TARGETS 6 /* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */ #define KVM_ARM_DEVICE_TYPE_SHIFT 0 @@ -100,12 +106,39 @@ struct kvm_sregs { struct kvm_fpu { }; +/* + * See v8 ARM ARM D7.3: Debug Registers + * + * The architectural limit is 16 debug registers of each type although + * in practice there are usually less (see ID_AA64DFR0_EL1). + * + * Although the control registers are architecturally defined as 32 + * bits wide we use a 64 bit structure here to keep parity with + * KVM_GET/SET_ONE_REG behaviour which treats all system registers as + * 64 bit values. It also allows for the possibility of the + * architecture expanding the control registers without having to + * change the userspace ABI. + */ +#define KVM_ARM_MAX_DBG_REGS 16 struct kvm_guest_debug_arch { + __u64 dbg_bcr[KVM_ARM_MAX_DBG_REGS]; + __u64 dbg_bvr[KVM_ARM_MAX_DBG_REGS]; + __u64 dbg_wcr[KVM_ARM_MAX_DBG_REGS]; + __u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS]; }; struct kvm_debug_exit_arch { + __u32 hsr; + __u64 far; /* used for watchpoints */ }; +/* + * Architecture specific defines for kvm_guest_debug->control + */ + +#define KVM_GUESTDBG_USE_SW_BP (1 << 16) +#define KVM_GUESTDBG_USE_HW (1 << 17) + struct kvm_sync_regs { }; diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 683f713..dcc410e 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -183,6 +183,7 @@ struct kvm_s390_skeys { #define KVM_EXIT_EPR 23 #define KVM_EXIT_SYSTEM_EVENT 24 #define KVM_EXIT_S390_STSI 25 +#define KVM_EXIT_IOAPIC_EOI 26 /* For KVM_EXIT_INTERNAL_ERROR */ /* Emulate instruction failed. */ @@ -237,6 +238,7 @@ struct kvm_run { __u32 count; __u64 data_offset; /* relative to kvm_run start */ } io; + /* KVM_EXIT_DEBUG */ struct { struct kvm_debug_exit_arch arch; } debug; @@ -285,6 +287,7 @@ struct kvm_run { __u32 data; __u8 is_write; } dcr; + /* KVM_EXIT_INTERNAL_ERROR */ struct { __u32 suberror; /* Available with KVM_CAP_INTERNAL_ERROR_DATA: */ @@ -295,6 +298,7 @@ struct kvm_run { struct { __u64 gprs[32]; } osi; + /* KVM_EXIT_PAPR_HCALL */ struct { __u64 nr; __u64 ret; @@ -330,6 +334,10 @@ struct kvm_run { __u8 sel1; __u16 sel2; } s390_stsi; + /* KVM_EXIT_IOAPIC_EOI */ + struct { + __u8 vector; + } eoi; /* Fix the size of the union. */ char padding[256]; }; @@ -819,6 +827,10 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_DISABLE_QUIRKS 116 #define KVM_CAP_X86_SMM 117 #define KVM_CAP_MULTI_ADDRESS_SPACE 118 +#define KVM_CAP_GUEST_DEBUG_HW_BPS 119 +#define KVM_CAP_GUEST_DEBUG_HW_WPS 120 +#define KVM_CAP_SPLIT_IRQCHIP 121 +#define KVM_CAP_IOEVENTFD_ANY_LENGTH 122 #ifdef KVM_CAP_IRQ_ROUTING -- cgit v1.1 From 744b8a9440fa2bd78ae64861667337439e25a6dc Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Wed, 16 Sep 2015 12:59:42 +0300 Subject: target-i386/kvm: Hyper-V HV_X64_MSR_RESET support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HV_X64_MSR_RESET msr is used by Hyper-V based Windows guest to reset guest VM by hypervisor. This msr is stateless so no migration/fetch/update is required. This code checks cpu option "hv-reset" and support by kernel. If both conditions are met appropriate Hyper-V features cpuid bit is set. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Richard Henderson CC: Eduardo Habkost CC: "Andreas Färber" CC: Marcelo Tosatti Message-Id: <1442397584-16698-2-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- target-i386/cpu-qom.h | 1 + target-i386/cpu.c | 1 + target-i386/kvm.c | 12 ++++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index c35b624..ed8fd18 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -90,6 +90,7 @@ typedef struct X86CPU { int hyperv_spinlock_attempts; bool hyperv_time; bool hyperv_crash; + bool hyperv_reset; bool check_cpuid; bool enforce_cpuid; bool expose_kvm; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 05d7f26..230ecf4 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3140,6 +3140,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false), DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false), DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false), + DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false), DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false), DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 80d1a7e..401a2f3 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -82,6 +82,7 @@ static bool has_msr_hv_hypercall; static bool has_msr_hv_vapic; static bool has_msr_hv_tsc; static bool has_msr_hv_crash; +static bool has_msr_hv_reset; static bool has_msr_mtrr; static bool has_msr_xss; @@ -460,7 +461,8 @@ static bool hyperv_enabled(X86CPU *cpu) (hyperv_hypercall_available(cpu) || cpu->hyperv_time || cpu->hyperv_relaxed_timing || - cpu->hyperv_crash); + cpu->hyperv_crash || + cpu->hyperv_reset); } static Error *invtsc_mig_blocker; @@ -529,7 +531,9 @@ int kvm_arch_init_vcpu(CPUState *cs) if (cpu->hyperv_crash && has_msr_hv_crash) { c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE; } - + if (cpu->hyperv_reset && has_msr_hv_reset) { + c->eax |= HV_X64_MSR_RESET_AVAILABLE; + } c = &cpuid_data.entries[cpuid_i++]; c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; if (cpu->hyperv_relaxed_timing) { @@ -858,6 +862,10 @@ static int kvm_get_supported_msrs(KVMState *s) has_msr_hv_crash = true; continue; } + if (kvm_msr_list->indices[i] == HV_X64_MSR_RESET) { + has_msr_hv_reset = true; + continue; + } } } -- cgit v1.1 From 8c145d7ca9b4267d2ec1eabe801c6b2aee636f1f Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Wed, 16 Sep 2015 12:59:43 +0300 Subject: target-i386/kvm: set Hyper-V features cpuid bit HV_X64_MSR_VP_INDEX_AVAILABLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hyper-V features bit HV_X64_MSR_VP_INDEX_AVAILABLE value is based on cpu option "hv-vpindex" and kernel support of HV_X64_MSR_VP_INDEX. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Richard Henderson CC: Eduardo Habkost CC: "Andreas Färber" CC: Marcelo Tosatti Message-Id: <1442397584-16698-3-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- target-i386/cpu-qom.h | 1 + target-i386/cpu.c | 1 + target-i386/kvm.c | 11 ++++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index ed8fd18..8b5439b 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -91,6 +91,7 @@ typedef struct X86CPU { bool hyperv_time; bool hyperv_crash; bool hyperv_reset; + bool hyperv_vpindex; bool check_cpuid; bool enforce_cpuid; bool expose_kvm; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 230ecf4..741b94e 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3141,6 +3141,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false), DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false), DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false), + DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false), DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false), DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 401a2f3..4d5ff9a 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -83,6 +83,7 @@ static bool has_msr_hv_vapic; static bool has_msr_hv_tsc; static bool has_msr_hv_crash; static bool has_msr_hv_reset; +static bool has_msr_hv_vpindex; static bool has_msr_mtrr; static bool has_msr_xss; @@ -462,7 +463,8 @@ static bool hyperv_enabled(X86CPU *cpu) cpu->hyperv_time || cpu->hyperv_relaxed_timing || cpu->hyperv_crash || - cpu->hyperv_reset); + cpu->hyperv_reset || + cpu->hyperv_vpindex); } static Error *invtsc_mig_blocker; @@ -534,6 +536,9 @@ int kvm_arch_init_vcpu(CPUState *cs) if (cpu->hyperv_reset && has_msr_hv_reset) { c->eax |= HV_X64_MSR_RESET_AVAILABLE; } + if (cpu->hyperv_vpindex && has_msr_hv_vpindex) { + c->eax |= HV_X64_MSR_VP_INDEX_AVAILABLE; + } c = &cpuid_data.entries[cpuid_i++]; c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; if (cpu->hyperv_relaxed_timing) { @@ -866,6 +871,10 @@ static int kvm_get_supported_msrs(KVMState *s) has_msr_hv_reset = true; continue; } + if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_INDEX) { + has_msr_hv_vpindex = true; + continue; + } } } -- cgit v1.1 From 46eb8f98f2ce402e384d60ddd15020720994c7ca Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Wed, 16 Sep 2015 12:59:44 +0300 Subject: target-i386/kvm: Hyper-V HV_X64_MSR_VP_RUNTIME support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HV_X64_MSR_VP_RUNTIME msr used by guest to get "the time the virtual processor consumes running guest code, and the time the associated logical processor spends running hypervisor code on behalf of that guest." Calculation of that time is performed by task_cputime_adjusted() for vcpu task by KVM side. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Richard Henderson CC: Eduardo Habkost CC: "Andreas Färber" CC: Marcelo Tosatti Message-Id: <1442397584-16698-4-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- target-i386/cpu-qom.h | 1 + target-i386/cpu.c | 1 + target-i386/cpu.h | 1 + target-i386/kvm.c | 21 ++++++++++++++++++++- target-i386/machine.c | 20 ++++++++++++++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 8b5439b..9eab41b 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -92,6 +92,7 @@ typedef struct X86CPU { bool hyperv_crash; bool hyperv_reset; bool hyperv_vpindex; + bool hyperv_runtime; bool check_cpuid; bool enforce_cpuid; bool expose_kvm; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 741b94e..d2b0619 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3142,6 +3142,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false), DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false), DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false), + DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false), DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false), 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 54d9d50..a395b4b 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -911,6 +911,7 @@ typedef struct CPUX86State { uint64_t msr_hv_vapic; uint64_t msr_hv_tsc; uint64_t msr_hv_crash_params[HV_X64_MSR_CRASH_PARAMS]; + uint64_t msr_hv_runtime; /* exception/interrupt handling */ int error_code; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 4d5ff9a..65cd944 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -84,6 +84,7 @@ static bool has_msr_hv_tsc; static bool has_msr_hv_crash; static bool has_msr_hv_reset; static bool has_msr_hv_vpindex; +static bool has_msr_hv_runtime; static bool has_msr_mtrr; static bool has_msr_xss; @@ -464,7 +465,8 @@ static bool hyperv_enabled(X86CPU *cpu) cpu->hyperv_relaxed_timing || cpu->hyperv_crash || cpu->hyperv_reset || - cpu->hyperv_vpindex); + cpu->hyperv_vpindex || + cpu->hyperv_runtime); } static Error *invtsc_mig_blocker; @@ -539,6 +541,9 @@ int kvm_arch_init_vcpu(CPUState *cs) if (cpu->hyperv_vpindex && has_msr_hv_vpindex) { c->eax |= HV_X64_MSR_VP_INDEX_AVAILABLE; } + if (cpu->hyperv_runtime && has_msr_hv_runtime) { + c->eax |= HV_X64_MSR_VP_RUNTIME_AVAILABLE; + } c = &cpuid_data.entries[cpuid_i++]; c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; if (cpu->hyperv_relaxed_timing) { @@ -875,6 +880,10 @@ static int kvm_get_supported_msrs(KVMState *s) has_msr_hv_vpindex = true; continue; } + if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_RUNTIME) { + has_msr_hv_runtime = true; + continue; + } } } @@ -1420,6 +1429,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level) kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_CTL, HV_X64_MSR_CRASH_CTL_NOTIFY); } + if (has_msr_hv_runtime) { + kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME, + env->msr_hv_runtime); + } if (has_msr_mtrr) { kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype); kvm_msr_entry_set(&msrs[n++], @@ -1785,6 +1798,9 @@ static int kvm_get_msrs(X86CPU *cpu) msrs[n++].index = HV_X64_MSR_CRASH_P0 + j; } } + if (has_msr_hv_runtime) { + msrs[n++].index = HV_X64_MSR_VP_RUNTIME; + } if (has_msr_mtrr) { msrs[n++].index = MSR_MTRRdefType; msrs[n++].index = MSR_MTRRfix64K_00000; @@ -1938,6 +1954,9 @@ static int kvm_get_msrs(X86CPU *cpu) case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4: env->msr_hv_crash_params[index - HV_X64_MSR_CRASH_P0] = msrs[i].data; break; + case HV_X64_MSR_VP_RUNTIME: + env->msr_hv_runtime = 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 9fa0563..6737366 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -687,6 +687,25 @@ static const VMStateDescription vmstate_msr_hyperv_crash = { } }; +static bool hyperv_runtime_enable_needed(void *opaque) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + + return env->msr_hv_runtime != 0; +} + +static const VMStateDescription vmstate_msr_hyperv_runtime = { + .name = "cpu/msr_hyperv_runtime", + .version_id = 1, + .minimum_version_id = 1, + .needed = hyperv_runtime_enable_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64(env.msr_hv_runtime, X86CPU), + VMSTATE_END_OF_LIST() + } +}; + static bool avx512_needed(void *opaque) { X86CPU *cpu = opaque; @@ -869,6 +888,7 @@ VMStateDescription vmstate_x86_cpu = { &vmstate_msr_hyperv_vapic, &vmstate_msr_hyperv_time, &vmstate_msr_hyperv_crash, + &vmstate_msr_hyperv_runtime, &vmstate_avx512, &vmstate_xss, NULL -- cgit v1.1 From 88401cbc5b5730986fd5040425f5015a9cce9080 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 11 Aug 2015 10:52:46 +0200 Subject: exec: remove non-TCG stuff from exec-all.h header. The header is included from basically everywhere, thanks to cpu.h. It should be moved to the (TCG only) files that actually need it. As a start, remove non-TCG stuff. Signed-off-by: Paolo Bonzini --- include/exec/exec-all.h | 6 ------ include/exec/ram_addr.h | 1 + include/sysemu/cpus.h | 1 + include/sysemu/kvm.h | 4 ++++ 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 4e8afbf..9b93b9b 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -84,7 +84,6 @@ void QEMU_NORETURN cpu_loop_exit(CPUState *cpu); void QEMU_NORETURN cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc); #if !defined(CONFIG_USER_ONLY) -bool qemu_in_vcpu_thread(void); void cpu_reloading_memory_map(void); void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as); /* cputlb.c */ @@ -357,8 +356,6 @@ extern uintptr_t tci_tb_ptr; #if !defined(CONFIG_USER_ONLY) -void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align)); - struct MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index); @@ -408,7 +405,4 @@ extern int singlestep; extern CPUState *tcg_current_cpu; extern bool exit_request; -#if !defined(CONFIG_USER_ONLY) -void migration_bitmap_extend(ram_addr_t old, ram_addr_t new); -#endif #endif diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index c400a75..3360ac5 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -289,5 +289,6 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(unsigned long *dest, return num_dirty; } +void migration_bitmap_extend(ram_addr_t old, ram_addr_t new); #endif #endif diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 3f162a9..30ddd12 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -2,6 +2,7 @@ #define QEMU_CPUS_H /* cpus.c */ +bool qemu_in_vcpu_thread(void); void qemu_init_cpu_loop(void); void resume_all_vcpus(void); void pause_all_vcpus(void); diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 2a58b4d..52c57e2 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -210,6 +210,10 @@ int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset); int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr); int kvm_on_sigbus(int code, void *addr); +/* interface with exec.c */ + +void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align)); + /* internal API */ int kvm_ioctl(KVMState *s, int type, ...); -- cgit v1.1 From b232c7857aa36d144205134c725114541630b1c2 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Tue, 6 Oct 2015 14:30:57 +1100 Subject: kvm-all: Align to qemu_real_host_page_size in kvm_set_phys_mem As the comment in kvm_set_phys_mem() says, KVM works in page size chunks. However it uses hardcoded TARGET_PAGE_SIZE which is 4K on most platforms while actual host may use different page size, for example, PPC64 hosts use 64K system pages. This replaces static TARGET_PAGE_SIZE with run-time calculated qemu_real_host_page_size. Signed-off-by: Alexey Kardashevskiy Message-Id: <1444102257-17405-1-git-send-email-aik@ozlabs.ru> Signed-off-by: Paolo Bonzini --- kvm-all.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 0be4615..6f04fbb 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -642,15 +642,15 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, /* kvm works in page size chunks, but the function may be called with sub-page size and unaligned start address. Pad the start address to next and truncate size to previous page boundary. */ - delta = (TARGET_PAGE_SIZE - (start_addr & ~TARGET_PAGE_MASK)); - delta &= ~TARGET_PAGE_MASK; + delta = qemu_real_host_page_size - (start_addr & ~qemu_real_host_page_mask); + delta &= ~qemu_real_host_page_mask; if (delta > size) { return; } start_addr += delta; size -= delta; - size &= TARGET_PAGE_MASK; - if (!size || (start_addr & ~TARGET_PAGE_MASK)) { + size &= qemu_real_host_page_mask; + if (!size || (start_addr & ~qemu_real_host_page_mask)) { return; } -- cgit v1.1 From 3e5385fcf536fc4238eb87de55af8dd99089cad4 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Thu, 8 Oct 2015 10:05:24 +0200 Subject: checkpatch: port fix from kernel "## is not a valid modifier" checkpatch currently loops on fpu/softfloat.c Turns out this is fixed in the Linux version of checkpatch. So this is a port of Andy Whitcrofts fix from Linux, Original commit was commit 89a883530fe7 ("checkpatch: ## is not a valid modifier") As suggested by Peter Maydell for the QEMU version we drop the last "|" as there seems to be no need for that. (FWIW, the kernel discusion about that dried out: http://www.spinics.net/lists/kernel/msg1944421.html ) Cc: Andy Whitcroft Signed-off-by: Christian Borntraeger Message-Id: <1444291524-66569-1-git-send-email-borntraeger@de.ibm.com> Signed-off-by: Paolo Bonzini --- scripts/checkpatch.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index d51346a..b0f6e11 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1010,7 +1010,9 @@ sub possible { case| else| asm|__asm__| - do + do| + \#| + \#\# )(?:\s|$)| ^(?:typedef|struct|enum)\b )}x; -- cgit v1.1 From 566dd236e1e0bfe9d9bce326547f883d677cf30a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 22 Sep 2015 11:38:02 +0200 Subject: MAINTAINERS: add two devices to the e500 section Cc: Alexander Graf Cc: Scott Wood Signed-off-by: Paolo Bonzini --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9bde832..08896b7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -726,6 +726,8 @@ M: Scott Wood L: qemu-ppc@nongnu.org S: Supported F: hw/ppc/e500* +F: hw/pci-host/ppce500.c +F: hw/net/fsl_etsec/ Character devices M: Paolo Bonzini -- cgit v1.1 From c92451c2af29784c76527cc5484c33b4ce069d38 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 22 Sep 2015 11:36:48 +0200 Subject: MAINTAINERS: Add more Xen files Cc: Stefano Stabellini --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 08896b7..5c52ae0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -255,6 +255,12 @@ L: xen-devel@lists.xensource.com S: Supported F: xen-* F: */xen* +F: hw/char/xen_console.c +F: hw/display/xenfb.c +F: hw/net/xen_nic.c +F: hw/xen/ +F: hw/xenpv/ +F: include/hw/xen/ Hosts: ------ -- cgit v1.1 From 9b31bff02153cf86d4413c6289794175662f7c5c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 22 Sep 2015 11:42:50 +0200 Subject: MAINTAINERS: Add more pxa2xx files and boards Cc: Peter Maydell Cc: Andrzej Zaborowski Signed-off-by: Paolo Bonzini --- MAINTAINERS | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5c52ae0..f22f88f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -328,11 +328,6 @@ M: Peter Maydell S: Maintained F: hw/arm/integratorcp.c -Mainstone -L: qemu-devel@nongnu.org -S: Orphan -F: hw/arm/mainstone.c - Musicpal M: Jan Kiszka S: Maintained @@ -353,10 +348,14 @@ M: Peter Maydell S: Maintained F: hw/arm/realview* -Spitz +PXA2XX M: Andrzej Zaborowski S: Maintained +F: hw/arm/mainstone.c F: hw/arm/spitz.c +F: hw/arm/tosa.c +F: hw/arm/z2.c +F: hw/*/pxa2xx* Stellaris M: Peter Maydell -- cgit v1.1 From 062710000dbd9db81277156d9bdebd96b70cd1d2 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 22 Sep 2015 11:45:00 +0200 Subject: MAINTAINERS: Add maintainer for ARM PrimeCell and integrated devices Cc: Peter Maydell Signed-off-by: Paolo Bonzini --- MAINTAINERS | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index f22f88f..cb4666a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -292,6 +292,36 @@ F: hw/*/allwinner* F: include/hw/*/allwinner* F: hw/arm/cubieboard.c +ARM PrimeCell +M: Peter Maydell +S: Maintained +F: hw/char/pl011.c +F: hw/display/pl110* +F: hw/dma/pl080.c +F: hw/dma/pl330.c +F: hw/gpio/pl061.c +F: hw/input/pl050.c +F: hw/intc/pl190.c +F: hw/sd/pl181.c +F: hw/timer/pl031.c +F: include/hw/arm/primecell.h + +ARM cores +M: Peter Maydell +S: Maintained +F: hw/intc/arm* +F: hw/intc/gic_internal.h +F: hw/misc/a9scu.c +F: hw/misc/arm11scu.c +F: hw/timer/a9gtimer* +F: hw/timer/arm_* +F: include/hw/arm/arm.h +F: include/hw/intc/arm* +F: include/hw/misc/a9scu.h +F: include/hw/misc/arm11scu.h +F: include/hw/timer/a9gtimer.h +F: include/hw/timer/arm_mptimer.h + Exynos M: Evgeny Voevodin M: Maksim Kozlov -- cgit v1.1 From 5ea530491fe9ac56f75bc1833cc3fd7722b24efd Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 22 Sep 2015 11:49:41 +0200 Subject: MAINTAINERS: Add more devices to realview board Cc: Peter Maydell Signed-off-by: Paolo Bonzini --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index cb4666a..da26f99 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -377,6 +377,8 @@ Real View M: Peter Maydell S: Maintained F: hw/arm/realview* +F: hw/intc/realview_gic.c +F: include/hw/intc/realview_gic.h PXA2XX M: Andrzej Zaborowski -- cgit v1.1 From b77e7c8e99f9ac726c4eaa2fc3461fd886017dc0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 12 Oct 2015 15:35:16 +0200 Subject: qemu-sockets: fix conversion of ipv4/ipv6 JSON to QemuOpts The QemuOpts-based code treats "option not set" and "option set to false" the same way for the ipv4 and ipv6 options, because it is meant to handle only the ",ipv4" and ",ipv6" substrings in hand-crafted option parsers. When converting InetSocketAddress to QemuOpts, however, it is necessary to handle all three cases (not set, set to true, set to false). Currently we are not handling all cases correctly. The rules are: * if none or both options are absent, leave things as is * if the single present option is Y, the other should be N. This can be implemented by leaving things as is, or by setting the other option to N as done in this patch. * if the single present option is N, the other should be Y. This is handled by the "else if" branch of this patch. This ensures that the ipv4 option has an effect on Windows, where creating the socket with PF_UNSPEC makes an ipv6 socket. With this patch, ",ipv4" will result in a PF_INET socket instead. Reported-by: Sair, Umair Tested-by: Sair, Umair Reviewed-by: Daniel P. Berrange Signed-off-by: Paolo Bonzini --- util/qemu-sockets.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 2add83a..0a041a9 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -586,12 +586,15 @@ fail: static void inet_addr_to_opts(QemuOpts *opts, const InetSocketAddress *addr) { - bool ipv4 = addr->ipv4 || !addr->has_ipv4; - bool ipv6 = addr->ipv6 || !addr->has_ipv6; + bool ipv4 = addr->has_ipv4 && addr->ipv4; + bool ipv6 = addr->has_ipv6 && addr->ipv6; - if (!ipv4 || !ipv6) { + if (ipv4 || ipv6) { qemu_opt_set_bool(opts, "ipv4", ipv4, &error_abort); qemu_opt_set_bool(opts, "ipv6", ipv6, &error_abort); + } else if (addr->has_ipv4 || addr->has_ipv6) { + qemu_opt_set_bool(opts, "ipv4", !addr->has_ipv4, &error_abort); + qemu_opt_set_bool(opts, "ipv6", !addr->has_ipv6, &error_abort); } if (addr->has_to) { qemu_opt_set_number(opts, "to", addr->to, &error_abort); -- cgit v1.1 From 0a3c190098e1cb3daaa946cba6663467d1f4e857 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Mon, 12 Oct 2015 18:41:19 +0100 Subject: README: fill out some useful quickstart information The README file is usually the first thing consulted when a user or developer obtains a copy of the QEMU source. The current QEMU README is lacking immediately useful information and so not very friendly for first time encounters. It either redirects users to qemu-doc.html (which does not exist until they've actually compiled QEMU), or the website (which assumes the user has convenient internet access at time of reading). This fills out the README file as simple quick-start guide on the topics of building source, submitting patches, licensing and how to contact the QEMU community. It does not intend to be comprehensive, instead referring people to an appropriate web page to obtain more detailed information. The intent is to give users quick guidance to get them going in the right direction. Signed-off-by: Daniel P. Berrange Message-Id: <1444671679-17674-1-git-send-email-berrange@redhat.com> Reviewed-by: John Snow Signed-off-by: Paolo Bonzini --- README | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/README b/README index c7c990d..f38193f 100644 --- a/README +++ b/README @@ -1,3 +1,107 @@ -Read the documentation in qemu-doc.html or on http://wiki.qemu-project.org + QEMU README + =========== -- QEMU team +QEMU is a generic and open source machine & userspace emulator and +virtualizer. + +QEMU is capable of emulating a complete machine in software without any +need for hardware virtualization support. By using dynamic translation, +it achieves very good performance. QEMU can also integrate with the Xen +and KVM hypervisors to provide emulated hardware while allowing the +hypervisor to manage the CPU. With hypervisor support, QEMU can achieve +near native performance for CPUs. When QEMU emulates CPUs directly it is +capable of running operating systems made for one machine (e.g. an ARMv7 +board) on a different machine (e.g. an x86_64 PC board). + +QEMU is also capable of providing userspace API virtualization for Linux +and BSD kernel interfaces. This allows binaries compiled against one +architecture ABI (e.g. the Linux PPC64 ABI) to be run on a host using a +different architecture ABI (e.g. the Linux x86_64 ABI). This does not +involve any hardware emulation, simply CPU and syscall emulation. + +QEMU aims to fit into a variety of use cases. It can be invoked directly +by users wishing to have full control over its behaviour and settings. +It also aims to facilitate integration into higher level management +layers, by providing a stable command line interface and monitor API. +It is commonly invoked indirectly via the libvirt library when using +open source applications such as oVirt, OpenStack and virt-manager. + +QEMU as a whole is released under the GNU General Public License, +version 2. For full licensing details, consult the LICENSE file. + + +Building +======== + +QEMU is multi-platform software intended to be buildable on all modern +Linux platforms, OS-X, Win32 (via the Mingw64 toolchain) and a variety +of other UNIX targets. The simple steps to build QEMU are: + + mkdir build + cd build + ../configure + make + +Complete details of the process for building and configuring QEMU for +all supported host platforms can be found in the qemu-tech.html file. +Additional information can also be found online via the QEMU website: + + http://qemu-project.org/Hosts/Linux + http://qemu-project.org/Hosts/W32 + + +Submitting patches +================== + +The QEMU source code is maintained under the GIT version control system. + + git clone git://git.qemu-project.org/qemu.git + +When submitting patches, the preferred approach is to use 'git +format-patch' and/or 'git send-email' to format & send the mail to the +qemu-devel@nongnu.org mailing list. All patches submitted must contain +a 'Signed-off-by' line from the author. Patches should follow the +guidelines set out in the HACKING and CODING_STYLE files. + +Additional information on submitting patches can be found online via +the QEMU website + + http://qemu-project.org/Contribute/SubmitAPatch + http://qemu-project.org/Contribute/TrivialPatches + + +Bug reporting +============= + +The QEMU project uses Launchpad as its primary upstream bug tracker. Bugs +found when running code built from QEMU git or upstream released sources +should be reported via: + + https://bugs.launchpad.net/qemu/ + +If using QEMU via an operating system vendor pre-built binary package, it +is preferable to report bugs to the vendor's own bug tracker first. If +the bug is also known to affect latest upstream code, it can also be +reported via launchpad. + +For additional information on bug reporting consult: + + http://qemu-project.org/Contribute/ReportABug + + +Contact +======= + +The QEMU community can be contacted in a number of ways, with the two +main methods being email and IRC + + - qemu-devel@nongnu.org + http://lists.nongnu.org/mailman/listinfo/qemu-devel + - #qemu on irc.oftc.net + +Information on additional methods of contacting the community can be +found online via the QEMU website: + + http://qemu-project.org/Contribute/StartHere + +-- End -- cgit v1.1 From eaeba65304d9666309f246849adf1eff217b9868 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 14:54:05 +0200 Subject: qemu-char: cleanup qmp_chardev_add Use the usual idioms for error propagation. Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 56 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 653ea10..f51c0aa 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4214,6 +4214,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, { ChardevReturn *ret = g_new0(ChardevReturn, 1); CharDriverState *base, *chr = NULL; + Error *local_err = NULL; chr = qemu_chr_find(id); if (chr) { @@ -4224,22 +4225,22 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, switch (backend->kind) { case CHARDEV_BACKEND_KIND_FILE: - chr = qmp_chardev_open_file(backend->file, errp); + chr = qmp_chardev_open_file(backend->file, &local_err); break; case CHARDEV_BACKEND_KIND_SERIAL: - chr = qmp_chardev_open_serial(backend->serial, errp); + chr = qmp_chardev_open_serial(backend->serial, &local_err); break; case CHARDEV_BACKEND_KIND_PARALLEL: - chr = qmp_chardev_open_parallel(backend->parallel, errp); + chr = qmp_chardev_open_parallel(backend->parallel, &local_err); break; case CHARDEV_BACKEND_KIND_PIPE: chr = qemu_chr_open_pipe(backend->pipe); break; case CHARDEV_BACKEND_KIND_SOCKET: - chr = qmp_chardev_open_socket(backend->socket, errp); + chr = qmp_chardev_open_socket(backend->socket, &local_err); break; case CHARDEV_BACKEND_KIND_UDP: - chr = qmp_chardev_open_udp(backend->udp, errp); + chr = qmp_chardev_open_udp(backend->udp, &local_err); break; #ifdef HAVE_CHARDEV_TTY case CHARDEV_BACKEND_KIND_PTY: @@ -4252,7 +4253,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_MUX: base = qemu_chr_find(backend->mux->chardev); if (base == NULL) { - error_setg(errp, "mux: base chardev %s not found", + error_setg(&local_err, "mux: base chardev %s not found", backend->mux->chardev); break; } @@ -4290,11 +4291,11 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, break; case CHARDEV_BACKEND_KIND_RINGBUF: case CHARDEV_BACKEND_KIND_MEMORY: - chr = qemu_chr_open_ringbuf(backend->ringbuf, errp); + chr = qemu_chr_open_ringbuf(backend->ringbuf, &local_err); break; default: error_setg(errp, "unknown chardev backend (%d)", backend->kind); - break; + goto out_error; } /* @@ -4303,25 +4304,30 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, * error then. * TODO full conversion to Error API */ - if (chr == NULL && errp && !*errp) { - error_setg(errp, "Failed to create chardev"); - } - if (chr) { - chr->label = g_strdup(id); - chr->avail_connections = - (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1; - if (!chr->filename) { - chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]); - } - if (!chr->explicit_be_open) { - qemu_chr_be_event(chr, CHR_EVENT_OPENED); + if (chr == NULL) { + if (local_err) { + error_propagate(errp, local_err); + } else { + error_setg(errp, "Failed to create chardev"); } - QTAILQ_INSERT_TAIL(&chardevs, chr, next); - return ret; - } else { - g_free(ret); - return NULL; + goto out_error; + } + + chr->label = g_strdup(id); + chr->avail_connections = + (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1; + if (!chr->filename) { + chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]); } + if (!chr->explicit_be_open) { + qemu_chr_be_event(chr, CHR_EVENT_OPENED); + } + QTAILQ_INSERT_TAIL(&chardevs, chr, next); + return ret; + +out_error: + g_free(ret); + return NULL; } void qmp_chardev_remove(const char *id, Error **errp) -- cgit v1.1 From d809ab9521ace32a806cdf86ee7df40e1bf88443 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 12 Oct 2015 09:46:23 +0200 Subject: qemu-char: cleanup HAVE_CHARDEV_* Move the #ifdef up into qmp_chardev_add, and avoid duplicating the code that reports unavailable backends. Split HAVE_CHARDEV_TTY into HAVE_CHARDEV_SERIAL and HAVE_CHARDEV_PTY. Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index f51c0aa..7219d56 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1196,7 +1196,8 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) \ || defined(__GLIBC__) -#define HAVE_CHARDEV_TTY 1 +#define HAVE_CHARDEV_SERIAL 1 +#define HAVE_CHARDEV_PTY 1 typedef struct { GIOChannel *fd; @@ -1832,6 +1833,8 @@ static CharDriverState *qemu_chr_open_pp_fd(int fd) #else /* _WIN32 */ +#define HAVE_CHARDEV_SERIAL 1 + typedef struct { int max_size; HANDLE hcom, hrecv, hsend; @@ -4069,10 +4072,10 @@ static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp) return qemu_chr_open_fd(in, out); } +#ifdef HAVE_CHARDEV_SERIAL static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, Error **errp) { -#ifdef HAVE_CHARDEV_TTY int fd; fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); @@ -4081,16 +4084,12 @@ static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, } qemu_set_nonblock(fd); return qemu_chr_open_tty_fd(fd); -#else - error_setg(errp, "character device backend type 'serial' not supported"); - return NULL; -#endif } +#ifdef HAVE_CHARDEV_PARPORT static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, Error **errp) { -#ifdef HAVE_CHARDEV_PARPORT int fd; fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); @@ -4098,11 +4097,8 @@ static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, return NULL; } return qemu_chr_open_pp_fd(fd); -#else - error_setg(errp, "character device backend type 'parallel' not supported"); - return NULL; -#endif } +#endif #endif /* WIN32 */ @@ -4227,12 +4223,16 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_FILE: chr = qmp_chardev_open_file(backend->file, &local_err); break; +#ifdef HAVE_CHARDEV_SERIAL case CHARDEV_BACKEND_KIND_SERIAL: chr = qmp_chardev_open_serial(backend->serial, &local_err); break; +#endif +#ifdef HAVE_CHARDEV_PARPORT case CHARDEV_BACKEND_KIND_PARALLEL: chr = qmp_chardev_open_parallel(backend->parallel, &local_err); break; +#endif case CHARDEV_BACKEND_KIND_PIPE: chr = qemu_chr_open_pipe(backend->pipe); break; @@ -4242,7 +4242,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_UDP: chr = qmp_chardev_open_udp(backend->udp, &local_err); break; -#ifdef HAVE_CHARDEV_TTY +#ifdef HAVE_CHARDEV_PTY case CHARDEV_BACKEND_KIND_PTY: chr = qemu_chr_open_pty(id, ret); break; -- cgit v1.1 From 4ca172817a8c6df0145c16d80abdf04d53a56d92 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 14:55:59 +0200 Subject: qemu-char: add create to register_char_driver Having creation as a member of the CharDriver struct removes the need to export functions for qemu-char.c's usage. After the conversion, chardev backends implemented outside qemu-char.c will not need a stub creation function anymore. Ultimately all drivers will be converted. For now, support the case where cd->create == NULL. Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- backends/baum.c | 3 +- backends/msmouse.c | 3 +- backends/testdev.c | 3 +- include/sysemu/char.h | 4 +- qemu-char.c | 213 ++++++++++++++++++++++++++++---------------------- spice-qemu-char.c | 4 +- ui/console.c | 3 +- 7 files changed, 133 insertions(+), 100 deletions(-) diff --git a/backends/baum.c b/backends/baum.c index a17f625..e86a019 100644 --- a/backends/baum.c +++ b/backends/baum.c @@ -629,7 +629,8 @@ fail_handle: static void register_types(void) { - register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL); + register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL, + NULL); } type_init(register_types); diff --git a/backends/msmouse.c b/backends/msmouse.c index 0119110..d50ed47 100644 --- a/backends/msmouse.c +++ b/backends/msmouse.c @@ -79,7 +79,8 @@ CharDriverState *qemu_chr_open_msmouse(void) static void register_types(void) { - register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL); + register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL, + NULL); } type_init(register_types); diff --git a/backends/testdev.c b/backends/testdev.c index 1429152..43787f6 100644 --- a/backends/testdev.c +++ b/backends/testdev.c @@ -125,7 +125,8 @@ CharDriverState *chr_testdev_init(void) static void register_types(void) { - register_char_driver("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL); + register_char_driver("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL, + NULL); } type_init(register_types); diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 832b7fe..4b01a8c 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -345,7 +345,9 @@ bool chr_is_ringbuf(const CharDriverState *chr); QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); void register_char_driver(const char *name, ChardevBackendKind kind, - void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp)); + void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp), + CharDriverState *(*create)(const char *id, ChardevBackend *backend, + ChardevReturn *ret, Error **errp)); /* add an eventfd to the qemu devices that are polled */ CharDriverState *qemu_chr_open_eventfd(int eventfd); diff --git a/qemu-char.c b/qemu-char.c index 7219d56..a6411d6 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3644,12 +3644,16 @@ typedef struct CharDriver { const char *name; ChardevBackendKind kind; void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); + CharDriverState *(*create)(const char *id, ChardevBackend *backend, + ChardevReturn *ret, Error **errp); } CharDriver; static GSList *backends; void register_char_driver(const char *name, ChardevBackendKind kind, - void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp)) + void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp), + CharDriverState *(*create)(const char *id, ChardevBackend *backend, + ChardevReturn *ret, Error **errp)) { CharDriver *s; @@ -3657,6 +3661,7 @@ void register_char_driver(const char *name, ChardevBackendKind kind, s->name = g_strdup(name); s->kind = kind; s->parse = parse; + s->create = create; backends = g_slist_append(backends, s); } @@ -4211,6 +4216,8 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, ChardevReturn *ret = g_new0(ChardevReturn, 1); CharDriverState *base, *chr = NULL; Error *local_err = NULL; + GSList *i; + CharDriver *cd; chr = qemu_chr_find(id); if (chr) { @@ -4219,98 +4226,113 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, return NULL; } - switch (backend->kind) { - case CHARDEV_BACKEND_KIND_FILE: - chr = qmp_chardev_open_file(backend->file, &local_err); - break; + for (i = backends; i; i = i->next) { + cd = i->data; + + if (cd->kind == backend->kind && cd->create) { + chr = cd->create(id, backend, ret, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto out_error; + } + break; + } + } + + if (chr == NULL) { + switch (backend->kind) { + case CHARDEV_BACKEND_KIND_FILE: + chr = qmp_chardev_open_file(backend->file, &local_err); + break; #ifdef HAVE_CHARDEV_SERIAL - case CHARDEV_BACKEND_KIND_SERIAL: - chr = qmp_chardev_open_serial(backend->serial, &local_err); - break; + case CHARDEV_BACKEND_KIND_SERIAL: + chr = qmp_chardev_open_serial(backend->serial, &local_err); + break; #endif #ifdef HAVE_CHARDEV_PARPORT - case CHARDEV_BACKEND_KIND_PARALLEL: - chr = qmp_chardev_open_parallel(backend->parallel, &local_err); - break; + case CHARDEV_BACKEND_KIND_PARALLEL: + chr = qmp_chardev_open_parallel(backend->parallel, &local_err); + break; #endif - case CHARDEV_BACKEND_KIND_PIPE: - chr = qemu_chr_open_pipe(backend->pipe); - break; - case CHARDEV_BACKEND_KIND_SOCKET: - chr = qmp_chardev_open_socket(backend->socket, &local_err); - break; - case CHARDEV_BACKEND_KIND_UDP: - chr = qmp_chardev_open_udp(backend->udp, &local_err); - break; + case CHARDEV_BACKEND_KIND_PIPE: + chr = qemu_chr_open_pipe(backend->pipe); + break; + case CHARDEV_BACKEND_KIND_SOCKET: + chr = qmp_chardev_open_socket(backend->socket, &local_err); + break; + case CHARDEV_BACKEND_KIND_UDP: + chr = qmp_chardev_open_udp(backend->udp, &local_err); + break; #ifdef HAVE_CHARDEV_PTY - case CHARDEV_BACKEND_KIND_PTY: - chr = qemu_chr_open_pty(id, ret); - break; + case CHARDEV_BACKEND_KIND_PTY: + chr = qemu_chr_open_pty(id, ret); + break; #endif - case CHARDEV_BACKEND_KIND_NULL: - chr = qemu_chr_open_null(); - break; - case CHARDEV_BACKEND_KIND_MUX: - base = qemu_chr_find(backend->mux->chardev); - if (base == NULL) { - error_setg(&local_err, "mux: base chardev %s not found", - backend->mux->chardev); + case CHARDEV_BACKEND_KIND_NULL: + chr = qemu_chr_open_null(); + break; + case CHARDEV_BACKEND_KIND_MUX: + base = qemu_chr_find(backend->mux->chardev); + if (base == NULL) { + error_setg(&local_err, "mux: base chardev %s not found", + backend->mux->chardev); + break; + } + chr = qemu_chr_open_mux(base); + break; + case CHARDEV_BACKEND_KIND_MSMOUSE: + chr = qemu_chr_open_msmouse(); break; - } - chr = qemu_chr_open_mux(base); - break; - case CHARDEV_BACKEND_KIND_MSMOUSE: - chr = qemu_chr_open_msmouse(); - break; #ifdef CONFIG_BRLAPI - case CHARDEV_BACKEND_KIND_BRAILLE: - chr = chr_baum_init(); - break; + case CHARDEV_BACKEND_KIND_BRAILLE: + chr = chr_baum_init(); + break; #endif - case CHARDEV_BACKEND_KIND_TESTDEV: - chr = chr_testdev_init(); - break; - case CHARDEV_BACKEND_KIND_STDIO: - chr = qemu_chr_open_stdio(backend->stdio); - break; + case CHARDEV_BACKEND_KIND_TESTDEV: + chr = chr_testdev_init(); + break; + case CHARDEV_BACKEND_KIND_STDIO: + chr = qemu_chr_open_stdio(backend->stdio); + break; #ifdef _WIN32 - case CHARDEV_BACKEND_KIND_CONSOLE: - chr = qemu_chr_open_win_con(); - break; + case CHARDEV_BACKEND_KIND_CONSOLE: + chr = qemu_chr_open_win_con(); + break; #endif #ifdef CONFIG_SPICE - case CHARDEV_BACKEND_KIND_SPICEVMC: - chr = qemu_chr_open_spice_vmc(backend->spicevmc->type); - break; - case CHARDEV_BACKEND_KIND_SPICEPORT: - chr = qemu_chr_open_spice_port(backend->spiceport->fqdn); - break; + case CHARDEV_BACKEND_KIND_SPICEVMC: + chr = qemu_chr_open_spice_vmc(backend->spicevmc->type); + break; + case CHARDEV_BACKEND_KIND_SPICEPORT: + chr = qemu_chr_open_spice_port(backend->spiceport->fqdn); + break; #endif - case CHARDEV_BACKEND_KIND_VC: - chr = vc_init(backend->vc); - break; - case CHARDEV_BACKEND_KIND_RINGBUF: - case CHARDEV_BACKEND_KIND_MEMORY: - chr = qemu_chr_open_ringbuf(backend->ringbuf, &local_err); - break; - default: - error_setg(errp, "unknown chardev backend (%d)", backend->kind); - goto out_error; - } + case CHARDEV_BACKEND_KIND_VC: + chr = vc_init(backend->vc); + break; + case CHARDEV_BACKEND_KIND_RINGBUF: + case CHARDEV_BACKEND_KIND_MEMORY: + chr = qemu_chr_open_ringbuf(backend->ringbuf, &local_err); + break; + default: + error_setg(errp, "unknown chardev backend (%d)", backend->kind); + goto out_error; + } - /* - * Character backend open hasn't been fully converted to the Error - * API. Some opens fail without setting an error. Set a generic - * error then. - * TODO full conversion to Error API - */ - if (chr == NULL) { - if (local_err) { - error_propagate(errp, local_err); - } else { - error_setg(errp, "Failed to create chardev"); + /* + * Character backend open hasn't been fully converted to the Error + * API. Some opens fail without setting an error. Set a generic + * error then. + * TODO full conversion to Error API + */ + if (chr == NULL) { + if (local_err) { + error_propagate(errp, local_err); + } else { + error_setg(errp, "Failed to create chardev"); + } + goto out_error; } - goto out_error; } chr->label = g_strdup(id); @@ -4349,32 +4371,37 @@ void qmp_chardev_remove(const char *id, Error **errp) static void register_types(void) { - register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL); + register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, + NULL); register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, - qemu_chr_parse_socket); - register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp); + qemu_chr_parse_socket, NULL); + register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, + NULL); register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, - qemu_chr_parse_ringbuf); + qemu_chr_parse_ringbuf, NULL); register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, - qemu_chr_parse_file_out); + qemu_chr_parse_file_out, NULL); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, - qemu_chr_parse_stdio); + qemu_chr_parse_stdio, NULL); register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial); + qemu_chr_parse_serial, NULL); register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial); + qemu_chr_parse_serial, NULL); register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel); + qemu_chr_parse_parallel, NULL); register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel); - register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL); - register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL); + qemu_chr_parse_parallel, NULL); + register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, + NULL); + register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, + NULL); register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, - qemu_chr_parse_pipe); - register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux); + qemu_chr_parse_pipe, NULL); + register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, + NULL); /* Bug-compatibility: */ register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY, - qemu_chr_parse_ringbuf); + qemu_chr_parse_ringbuf, NULL); /* this must be done after machine init, since we register FEs with muxes * as part of realize functions like serial_isa_realizefn when -nographic * is specified diff --git a/spice-qemu-char.c b/spice-qemu-char.c index d41bb74..e4353ef 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -379,9 +379,9 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend, static void register_types(void) { register_char_driver("spicevmc", CHARDEV_BACKEND_KIND_SPICEVMC, - qemu_chr_parse_spice_vmc); + qemu_chr_parse_spice_vmc, NULL); register_char_driver("spiceport", CHARDEV_BACKEND_KIND_SPICEPORT, - qemu_chr_parse_spice_port); + qemu_chr_parse_spice_port, NULL); } type_init(register_types); diff --git a/ui/console.c b/ui/console.c index 31f0d35..aee6f21 100644 --- a/ui/console.c +++ b/ui/console.c @@ -2093,7 +2093,8 @@ static const TypeInfo qemu_console_info = { static void register_types(void) { type_register_static(&qemu_console_info); - register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc); + register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc, + NULL); } type_init(register_types); -- cgit v1.1 From fd5b036c5c6dc715bd06769a0023c6e1de2dadb4 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:06:02 +0200 Subject: qemu-char: convert file backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index a6411d6..13fd394 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4010,8 +4010,12 @@ QemuOptsList qemu_chardev_opts = { #ifdef _WIN32 -static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp) +static CharDriverState *qmp_chardev_open_file(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevFile *file = backend->file; HANDLE out; if (file->has_in) { @@ -4055,8 +4059,12 @@ static int qmp_chardev_open_file_source(char *src, int flags, return fd; } -static CharDriverState *qmp_chardev_open_file(ChardevFile *file, Error **errp) +static CharDriverState *qmp_chardev_open_file(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevFile *file = backend->file; int flags, in = -1, out; flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY; @@ -4242,7 +4250,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, if (chr == NULL) { switch (backend->kind) { case CHARDEV_BACKEND_KIND_FILE: - chr = qmp_chardev_open_file(backend->file, &local_err); + abort(); break; #ifdef HAVE_CHARDEV_SERIAL case CHARDEV_BACKEND_KIND_SERIAL: @@ -4380,7 +4388,7 @@ static void register_types(void) register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, qemu_chr_parse_ringbuf, NULL); register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, - qemu_chr_parse_file_out, NULL); + qemu_chr_parse_file_out, qmp_chardev_open_file); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, qemu_chr_parse_stdio, NULL); register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, -- cgit v1.1 From 6511d39679f296162a90e71685651717a29e78e5 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:08:05 +0200 Subject: qemu-char: convert serial backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 13fd394..8567580 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1886,7 +1886,7 @@ static void win_chr_close(CharDriverState *chr) qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } -static int win_chr_init(CharDriverState *chr, const char *filename) +static int win_chr_init(CharDriverState *chr, const char *filename, Error **errp) { WinCharState *s = chr->opaque; COMMCONFIG comcfg; @@ -1897,25 +1897,25 @@ static int win_chr_init(CharDriverState *chr, const char *filename) s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL); if (!s->hsend) { - fprintf(stderr, "Failed CreateEvent\n"); + error_setg(errp, "Failed CreateEvent"); goto fail; } s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL); if (!s->hrecv) { - fprintf(stderr, "Failed CreateEvent\n"); + error_setg(errp, "Failed CreateEvent"); goto fail; } s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if (s->hcom == INVALID_HANDLE_VALUE) { - fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError()); + error_setg(errp, "Failed CreateFile (%lu)", GetLastError()); s->hcom = NULL; goto fail; } if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) { - fprintf(stderr, "Failed SetupComm\n"); + error_setg(errp, "Failed SetupComm"); goto fail; } @@ -1926,23 +1926,23 @@ static int win_chr_init(CharDriverState *chr, const char *filename) CommConfigDialog(filename, NULL, &comcfg); if (!SetCommState(s->hcom, &comcfg.dcb)) { - fprintf(stderr, "Failed SetCommState\n"); + error_setg(errp, "Failed SetCommState"); goto fail; } if (!SetCommMask(s->hcom, EV_ERR)) { - fprintf(stderr, "Failed SetCommMask\n"); + error_setg(errp, "Failed SetCommMask"); goto fail; } cto.ReadIntervalTimeout = MAXDWORD; if (!SetCommTimeouts(s->hcom, &cto)) { - fprintf(stderr, "Failed SetCommTimeouts\n"); + error_setg(errp, "Failed SetCommTimeouts"); goto fail; } if (!ClearCommError(s->hcom, &err, &comstat)) { - fprintf(stderr, "Failed ClearCommError\n"); + error_setg(errp, "Failed ClearCommError"); goto fail; } qemu_add_polling_cb(win_chr_poll, chr); @@ -2047,7 +2047,8 @@ static int win_chr_poll(void *opaque) return 0; } -static CharDriverState *qemu_chr_open_win_path(const char *filename) +static CharDriverState *qemu_chr_open_win_path(const char *filename, + Error **errp) { CharDriverState *chr; WinCharState *s; @@ -2058,7 +2059,7 @@ static CharDriverState *qemu_chr_open_win_path(const char *filename) chr->chr_write = win_chr_write; chr->chr_close = win_chr_close; - if (win_chr_init(chr, filename) < 0) { + if (win_chr_init(chr, filename, errp) < 0) { g_free(s); g_free(chr); return NULL; @@ -3465,6 +3466,7 @@ static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend, backend->stdio->signal = qemu_opt_get_bool(opts, "signal", true); } +#ifdef HAVE_CHARDEV_SERIAL static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, Error **errp) { @@ -3477,6 +3479,7 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, backend->serial = g_new0(ChardevHostdev, 1); backend->serial->device = g_strdup(device); } +#endif static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, Error **errp) @@ -4032,10 +4035,13 @@ static CharDriverState *qmp_chardev_open_file(const char *id, return qemu_chr_open_win_file(out); } -static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, +static CharDriverState *qmp_chardev_open_serial(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { - return qemu_chr_open_win_path(serial->device); + ChardevHostdev *serial = backend->serial; + return qemu_chr_open_win_path(serial->device, errp); } static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, @@ -4086,9 +4092,12 @@ static CharDriverState *qmp_chardev_open_file(const char *id, } #ifdef HAVE_CHARDEV_SERIAL -static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, +static CharDriverState *qmp_chardev_open_serial(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { + ChardevHostdev *serial = backend->serial; int fd; fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); @@ -4098,6 +4107,7 @@ static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, qemu_set_nonblock(fd); return qemu_chr_open_tty_fd(fd); } +#endif #ifdef HAVE_CHARDEV_PARPORT static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, @@ -4252,11 +4262,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_FILE: abort(); break; -#ifdef HAVE_CHARDEV_SERIAL case CHARDEV_BACKEND_KIND_SERIAL: - chr = qmp_chardev_open_serial(backend->serial, &local_err); + abort(); break; -#endif #ifdef HAVE_CHARDEV_PARPORT case CHARDEV_BACKEND_KIND_PARALLEL: chr = qmp_chardev_open_parallel(backend->parallel, &local_err); @@ -4391,10 +4399,12 @@ static void register_types(void) qemu_chr_parse_file_out, qmp_chardev_open_file); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, qemu_chr_parse_stdio, NULL); +#if defined HAVE_CHARDEV_SERIAL register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial, NULL); + qemu_chr_parse_serial, qmp_chardev_open_serial); register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL, - qemu_chr_parse_serial, NULL); + qemu_chr_parse_serial, qmp_chardev_open_serial); +#endif register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL, qemu_chr_parse_parallel, NULL); register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, -- cgit v1.1 From 38bfb1a63d05d000f128ea740442955070d9ff57 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 12 Oct 2015 09:49:28 +0200 Subject: qemu-char: convert parallel backend to data-driven creation Conversion to Error * brings better error messages; before: qemu-system-x86_64: -chardev id=serial,backend=parallel,path=vl.c: Failed to create chardev After: qemu-system-x86_64: -chardev id=serial,backend=parallel,path=vl.c: not a parallel port: Inappropriate ioctl for device Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 8567580..ee6381b 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1753,12 +1753,13 @@ static void pp_close(CharDriverState *chr) qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } -static CharDriverState *qemu_chr_open_pp_fd(int fd) +static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp) { CharDriverState *chr; ParallelCharDriver *drv; if (ioctl(fd, PPCLAIM) < 0) { + error_setg_errno(errp, errno, "not a parallel port"); close(fd); return NULL; } @@ -1818,7 +1819,7 @@ static int pp_ioctl(CharDriverState *chr, int cmd, void *arg) return 0; } -static CharDriverState *qemu_chr_open_pp_fd(int fd) +static CharDriverState *qemu_chr_open_pp_fd(int fd, Error **errp) { CharDriverState *chr; @@ -3481,6 +3482,7 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, } #endif +#ifdef HAVE_CHARDEV_PARPORT static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, Error **errp) { @@ -3493,6 +3495,7 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, backend->parallel = g_new0(ChardevHostdev, 1); backend->parallel->device = g_strdup(device); } +#endif static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend, Error **errp) @@ -4044,13 +4047,6 @@ static CharDriverState *qmp_chardev_open_serial(const char *id, return qemu_chr_open_win_path(serial->device, errp); } -static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, - Error **errp) -{ - error_setg(errp, "character device backend type 'parallel' not supported"); - return NULL; -} - #else /* WIN32 */ static int qmp_chardev_open_file_source(char *src, int flags, @@ -4110,16 +4106,19 @@ static CharDriverState *qmp_chardev_open_serial(const char *id, #endif #ifdef HAVE_CHARDEV_PARPORT -static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, +static CharDriverState *qmp_chardev_open_parallel(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { + ChardevHostdev *parallel = backend->parallel; int fd; fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); if (fd < 0) { return NULL; } - return qemu_chr_open_pp_fd(fd); + return qemu_chr_open_pp_fd(fd, errp); } #endif @@ -4265,11 +4264,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_SERIAL: abort(); break; -#ifdef HAVE_CHARDEV_PARPORT case CHARDEV_BACKEND_KIND_PARALLEL: - chr = qmp_chardev_open_parallel(backend->parallel, &local_err); + abort(); break; -#endif case CHARDEV_BACKEND_KIND_PIPE: chr = qemu_chr_open_pipe(backend->pipe); break; @@ -4405,10 +4402,12 @@ static void register_types(void) register_char_driver("tty", CHARDEV_BACKEND_KIND_SERIAL, qemu_chr_parse_serial, qmp_chardev_open_serial); #endif +#ifdef HAVE_CHARDEV_PARPORT register_char_driver("parallel", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel, NULL); + qemu_chr_parse_parallel, qmp_chardev_open_parallel); register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, - qemu_chr_parse_parallel, NULL); + qemu_chr_parse_parallel, qmp_chardev_open_parallel); +#endif register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, NULL); register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, -- cgit v1.1 From 20cbe7a27980ef7e2ecd307cd210fc23b3f0762e Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:14:07 +0200 Subject: qemu-char: convert pipe backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index ee6381b..44a5a8d 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1078,18 +1078,17 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) return chr; } -static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) +static CharDriverState *qemu_chr_open_pipe(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevHostdev *opts = backend->pipe; int fd_in, fd_out; char filename_in[CHR_MAX_FILENAME_SIZE]; char filename_out[CHR_MAX_FILENAME_SIZE]; const char *filename = opts->device; - if (filename == NULL) { - fprintf(stderr, "chardev: pipe: no filename given\n"); - return NULL; - } - snprintf(filename_in, CHR_MAX_FILENAME_SIZE, "%s.in", filename); snprintf(filename_out, CHR_MAX_FILENAME_SIZE, "%s.out", filename); TFR(fd_in = qemu_open(filename_in, O_RDWR | O_BINARY)); @@ -1101,6 +1100,7 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) close(fd_out); TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY)); if (fd_in < 0) { + error_setg_file_open(errp, errno, filename); return NULL; } } @@ -2084,7 +2084,8 @@ static int win_chr_pipe_poll(void *opaque) return 0; } -static int win_chr_pipe_init(CharDriverState *chr, const char *filename) +static int win_chr_pipe_init(CharDriverState *chr, const char *filename, + Error **errp) { WinCharState *s = chr->opaque; OVERLAPPED ov; @@ -2096,12 +2097,12 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename) s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL); if (!s->hsend) { - fprintf(stderr, "Failed CreateEvent\n"); + error_setg(errp, "Failed CreateEvent"); goto fail; } s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL); if (!s->hrecv) { - fprintf(stderr, "Failed CreateEvent\n"); + error_setg(errp, "Failed CreateEvent"); goto fail; } @@ -2111,7 +2112,7 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename) PIPE_WAIT, MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL); if (s->hcom == INVALID_HANDLE_VALUE) { - fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError()); + error_setg(errp, "Failed CreateNamedPipe (%lu)", GetLastError()); s->hcom = NULL; goto fail; } @@ -2120,13 +2121,13 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename) ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ret = ConnectNamedPipe(s->hcom, &ov); if (ret) { - fprintf(stderr, "Failed ConnectNamedPipe\n"); + error_setg(errp, "Failed ConnectNamedPipe"); goto fail; } ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE); if (!ret) { - fprintf(stderr, "Failed GetOverlappedResult\n"); + error_setg(errp, "Failed GetOverlappedResult"); if (ov.hEvent) { CloseHandle(ov.hEvent); ov.hEvent = NULL; @@ -2147,8 +2148,12 @@ static int win_chr_pipe_init(CharDriverState *chr, const char *filename) } -static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) +static CharDriverState *qemu_chr_open_pipe(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevHostdev *opts = backend->pipe; const char *filename = opts->device; CharDriverState *chr; WinCharState *s; @@ -2159,7 +2164,7 @@ static CharDriverState *qemu_chr_open_pipe(ChardevHostdev *opts) chr->chr_write = win_chr_write; chr->chr_close = win_chr_close; - if (win_chr_pipe_init(chr, filename) < 0) { + if (win_chr_pipe_init(chr, filename, errp) < 0) { g_free(s); g_free(chr); return NULL; @@ -4268,7 +4273,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_PIPE: - chr = qemu_chr_open_pipe(backend->pipe); + abort(); break; case CHARDEV_BACKEND_KIND_SOCKET: chr = qmp_chardev_open_socket(backend->socket, &local_err); @@ -4413,7 +4418,7 @@ static void register_types(void) register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, NULL); register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, - qemu_chr_parse_pipe, NULL); + qemu_chr_parse_pipe, qemu_chr_open_pipe); register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, NULL); /* Bug-compatibility: */ -- cgit v1.1 From dbba8d1be3db5a52cfe200f219fbf8840d75cb14 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:15:53 +0200 Subject: qemu-char: convert socket backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 44a5a8d..d0de7ef 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4154,11 +4154,14 @@ static gboolean socket_reconnect_timeout(gpointer opaque) return false; } -static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock, +static CharDriverState *qmp_chardev_open_socket(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { CharDriverState *chr; TCPCharDriver *s; + ChardevSocket *sock = backend->socket; SocketAddress *addr = sock->addr; bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; bool is_listen = sock->has_server ? sock->server : true; @@ -4276,7 +4279,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_SOCKET: - chr = qmp_chardev_open_socket(backend->socket, &local_err); + abort(); break; case CHARDEV_BACKEND_KIND_UDP: chr = qmp_chardev_open_udp(backend->udp, &local_err); @@ -4392,7 +4395,7 @@ static void register_types(void) register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, NULL); register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, - qemu_chr_parse_socket, NULL); + qemu_chr_parse_socket, qmp_chardev_open_socket); register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, NULL); register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, -- cgit v1.1 From e79b80daa252ffb4bc5c84c836714eb45ab3bb68 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:17:20 +0200 Subject: qemu-char: convert UDP backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index d0de7ef..de4d9d8 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4223,9 +4223,12 @@ static CharDriverState *qmp_chardev_open_socket(const char *id, return chr; } -static CharDriverState *qmp_chardev_open_udp(ChardevUdp *udp, +static CharDriverState *qmp_chardev_open_udp(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { + ChardevUdp *udp = backend->udp; int fd; fd = socket_dgram(udp->remote, udp->local, errp); @@ -4282,7 +4285,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_UDP: - chr = qmp_chardev_open_udp(backend->udp, &local_err); + abort(); break; #ifdef HAVE_CHARDEV_PTY case CHARDEV_BACKEND_KIND_PTY: @@ -4397,7 +4400,7 @@ static void register_types(void) register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, qemu_chr_parse_socket, qmp_chardev_open_socket); register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, - NULL); + qmp_chardev_open_udp); register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, qemu_chr_parse_ringbuf, NULL); register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, -- cgit v1.1 From c2e75a432b907562cf93772b7d058d1ec8a8f8f1 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:23:42 +0200 Subject: qemu-char: convert pty backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index de4d9d8..15c1a15 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1390,7 +1390,9 @@ static void pty_chr_close(struct CharDriverState *chr) } static CharDriverState *qemu_chr_open_pty(const char *id, - ChardevReturn *ret) + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { CharDriverState *chr; PtyCharDriver *s; @@ -1399,6 +1401,7 @@ static CharDriverState *qemu_chr_open_pty(const char *id, master_fd = qemu_openpty_raw(&slave_fd, pty_name); if (master_fd < 0) { + error_setg_errno(errp, errno, "Failed to create PTY"); return NULL; } @@ -4287,11 +4290,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_UDP: abort(); break; -#ifdef HAVE_CHARDEV_PTY case CHARDEV_BACKEND_KIND_PTY: - chr = qemu_chr_open_pty(id, ret); + abort(); break; -#endif case CHARDEV_BACKEND_KIND_NULL: chr = qemu_chr_open_null(); break; @@ -4419,8 +4420,10 @@ static void register_types(void) register_char_driver("parport", CHARDEV_BACKEND_KIND_PARALLEL, qemu_chr_parse_parallel, qmp_chardev_open_parallel); #endif +#ifdef HAVE_CHARDEV_PTY register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, - NULL); + qemu_chr_open_pty); +#endif register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, NULL); register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, -- cgit v1.1 From 0d64992b5dfe099b170a0b19922833cc82745620 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:24:29 +0200 Subject: qemu-char: convert null backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 15c1a15..5bacee8 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -383,7 +383,10 @@ static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len) return len; } -static CharDriverState *qemu_chr_open_null(void) +static CharDriverState *qemu_chr_open_null(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { CharDriverState *chr; @@ -4294,7 +4297,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_NULL: - chr = qemu_chr_open_null(); + abort(); break; case CHARDEV_BACKEND_KIND_MUX: base = qemu_chr_find(backend->mux->chardev); @@ -4397,7 +4400,7 @@ void qmp_chardev_remove(const char *id, Error **errp) static void register_types(void) { register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, - NULL); + qemu_chr_open_null); register_char_driver("socket", CHARDEV_BACKEND_KIND_SOCKET, qemu_chr_parse_socket, qmp_chardev_open_socket); register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, -- cgit v1.1 From 3c0e5a4a845c9e2823c9060631eeefebabc2f093 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:27:24 +0200 Subject: qemu-char: convert mux backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 5bacee8..6f2202a 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -682,11 +682,20 @@ static GSource *mux_chr_add_watch(CharDriverState *s, GIOCondition cond) return d->drv->chr_add_watch(d->drv, cond); } -static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) +static CharDriverState *qemu_chr_open_mux(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { - CharDriverState *chr; + ChardevMux *mux = backend->mux; + CharDriverState *chr, *drv; MuxDriver *d; + drv = qemu_chr_find(mux->chardev); + if (drv == NULL) { + error_setg(errp, "mux: base chardev %s not found", mux->chardev); + return NULL; + } + chr = qemu_chr_alloc(); d = g_new0(MuxDriver, 1); @@ -4248,7 +4257,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, Error **errp) { ChardevReturn *ret = g_new0(ChardevReturn, 1); - CharDriverState *base, *chr = NULL; + CharDriverState *chr = NULL; Error *local_err = NULL; GSList *i; CharDriver *cd; @@ -4300,13 +4309,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_MUX: - base = qemu_chr_find(backend->mux->chardev); - if (base == NULL) { - error_setg(&local_err, "mux: base chardev %s not found", - backend->mux->chardev); - break; - } - chr = qemu_chr_open_mux(base); + abort(); break; case CHARDEV_BACKEND_KIND_MSMOUSE: chr = qemu_chr_open_msmouse(); @@ -4432,7 +4435,7 @@ static void register_types(void) register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, qemu_chr_parse_pipe, qemu_chr_open_pipe); register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, - NULL); + qemu_chr_open_mux); /* Bug-compatibility: */ register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY, qemu_chr_parse_ringbuf, NULL); -- cgit v1.1 From 96d885b93b47243d2fc6ee826abaa8c0017282c9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:29:15 +0200 Subject: qemu-char: convert msmouse backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- backends/msmouse.c | 7 +++++-- include/sysemu/char.h | 3 --- qemu-char.c | 2 +- stubs/Makefile.objs | 1 - stubs/chr-msmouse.c | 7 ------- 5 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 stubs/chr-msmouse.c diff --git a/backends/msmouse.c b/backends/msmouse.c index d50ed47..0126fa0 100644 --- a/backends/msmouse.c +++ b/backends/msmouse.c @@ -63,7 +63,10 @@ static void msmouse_chr_close (struct CharDriverState *chr) g_free (chr); } -CharDriverState *qemu_chr_open_msmouse(void) +static CharDriverState *qemu_chr_open_msmouse(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { CharDriverState *chr; @@ -80,7 +83,7 @@ CharDriverState *qemu_chr_open_msmouse(void) static void register_types(void) { register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL, - NULL); + qemu_chr_open_msmouse); } type_init(register_types); diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 4b01a8c..2fe8275 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -356,9 +356,6 @@ extern int term_escape_char; CharDriverState *qemu_char_get_next_serial(void); -/* msmouse */ -CharDriverState *qemu_chr_open_msmouse(void); - /* testdev.c */ CharDriverState *chr_testdev_init(void); diff --git a/qemu-char.c b/qemu-char.c index 6f2202a..64ca397 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4312,7 +4312,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_MSMOUSE: - chr = qemu_chr_open_msmouse(); + abort(); break; #ifdef CONFIG_BRLAPI case CHARDEV_BACKEND_KIND_BRAILLE: diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 85e4e81..63988ca 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -1,7 +1,6 @@ stub-obj-y += arch-query-cpu-def.o stub-obj-y += bdrv-commit-all.o stub-obj-y += chr-baum-init.o -stub-obj-y += chr-msmouse.o stub-obj-y += chr-testdev.o stub-obj-y += clock-warp.o stub-obj-y += cpu-get-clock.o diff --git a/stubs/chr-msmouse.c b/stubs/chr-msmouse.c deleted file mode 100644 index 812f8b0..0000000 --- a/stubs/chr-msmouse.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "qemu-common.h" -#include "sysemu/char.h" - -CharDriverState *qemu_chr_open_msmouse(void) -{ - return 0; -} -- cgit v1.1 From e47666b8d1f0a7043d53671587058b3ce539b09d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:31:26 +0200 Subject: qemu-char: convert braille backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- backends/baum.c | 16 +++++++++++----- include/sysemu/char.h | 3 --- qemu-char.c | 4 +--- stubs/Makefile.objs | 1 - stubs/chr-baum-init.c | 7 ------- 5 files changed, 12 insertions(+), 19 deletions(-) delete mode 100644 stubs/chr-baum-init.c diff --git a/backends/baum.c b/backends/baum.c index e86a019..723c658 100644 --- a/backends/baum.c +++ b/backends/baum.c @@ -561,7 +561,10 @@ static void baum_close(struct CharDriverState *chr) g_free(baum); } -CharDriverState *chr_baum_init(void) +static CharDriverState *chr_baum_init(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { BaumDriverState *baum; CharDriverState *chr; @@ -586,14 +589,16 @@ CharDriverState *chr_baum_init(void) baum->brlapi_fd = brlapi__openConnection(handle, NULL, NULL); if (baum->brlapi_fd == -1) { - brlapi_perror("baum_init: brlapi_openConnection"); + error_setg(errp, "brlapi__openConnection: %s", + brlapi_strerror(brlapi_error_location())); goto fail_handle; } baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum); if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) { - brlapi_perror("baum_init: brlapi_getDisplaySize"); + error_setg(errp, "brlapi__getDisplaySize: %s", + brlapi_strerror(brlapi_error_location())); goto fail; } @@ -609,7 +614,8 @@ CharDriverState *chr_baum_init(void) tty = BRLAPI_TTY_DEFAULT; if (brlapi__enterTtyMode(handle, tty, NULL) == -1) { - brlapi_perror("baum_init: brlapi_enterTtyMode"); + error_setg(errp, "brlapi__enterTtyMode: %s", + brlapi_strerror(brlapi_error_location())); goto fail; } @@ -630,7 +636,7 @@ fail_handle: static void register_types(void) { register_char_driver("braille", CHARDEV_BACKEND_KIND_BRAILLE, NULL, - NULL); + chr_baum_init); } type_init(register_types); diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 2fe8275..77415ec 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -359,9 +359,6 @@ CharDriverState *qemu_char_get_next_serial(void); /* testdev.c */ CharDriverState *chr_testdev_init(void); -/* baum.c */ -CharDriverState *chr_baum_init(void); - /* console.c */ typedef CharDriverState *(VcHandler)(ChardevVC *vc); diff --git a/qemu-char.c b/qemu-char.c index 64ca397..f2e3a35 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4314,11 +4314,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_MSMOUSE: abort(); break; -#ifdef CONFIG_BRLAPI case CHARDEV_BACKEND_KIND_BRAILLE: - chr = chr_baum_init(); + abort(); break; -#endif case CHARDEV_BACKEND_KIND_TESTDEV: chr = chr_testdev_init(); break; diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 63988ca..8cfa5a2 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -1,6 +1,5 @@ stub-obj-y += arch-query-cpu-def.o stub-obj-y += bdrv-commit-all.o -stub-obj-y += chr-baum-init.o stub-obj-y += chr-testdev.o stub-obj-y += clock-warp.o stub-obj-y += cpu-get-clock.o diff --git a/stubs/chr-baum-init.c b/stubs/chr-baum-init.c deleted file mode 100644 index f5cc6ce..0000000 --- a/stubs/chr-baum-init.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "qemu-common.h" -#include "sysemu/char.h" - -CharDriverState *chr_baum_init(void) -{ - return NULL; -} -- cgit v1.1 From 0498790173e462ac3a7e4e0f3608704b8382dd10 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:33:42 +0200 Subject: qemu-char: convert testdev backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- backends/testdev.c | 7 +++++-- include/sysemu/char.h | 3 --- qemu-char.c | 2 +- stubs/Makefile.objs | 1 - stubs/chr-testdev.c | 7 ------- 5 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 stubs/chr-testdev.c diff --git a/backends/testdev.c b/backends/testdev.c index 43787f6..26d5c73 100644 --- a/backends/testdev.c +++ b/backends/testdev.c @@ -108,7 +108,10 @@ static void testdev_close(struct CharDriverState *chr) g_free(testdev); } -CharDriverState *chr_testdev_init(void) +static CharDriverState *chr_testdev_init(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { TestdevCharState *testdev; CharDriverState *chr; @@ -126,7 +129,7 @@ CharDriverState *chr_testdev_init(void) static void register_types(void) { register_char_driver("testdev", CHARDEV_BACKEND_KIND_TESTDEV, NULL, - NULL); + chr_testdev_init); } type_init(register_types); diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 77415ec..5c28c16 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -356,9 +356,6 @@ extern int term_escape_char; CharDriverState *qemu_char_get_next_serial(void); -/* testdev.c */ -CharDriverState *chr_testdev_init(void); - /* console.c */ typedef CharDriverState *(VcHandler)(ChardevVC *vc); diff --git a/qemu-char.c b/qemu-char.c index f2e3a35..56bc7ed 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4318,7 +4318,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_TESTDEV: - chr = chr_testdev_init(); + abort(); break; case CHARDEV_BACKEND_KIND_STDIO: chr = qemu_chr_open_stdio(backend->stdio); diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 8cfa5a2..b5322a2 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -1,6 +1,5 @@ stub-obj-y += arch-query-cpu-def.o stub-obj-y += bdrv-commit-all.o -stub-obj-y += chr-testdev.o stub-obj-y += clock-warp.o stub-obj-y += cpu-get-clock.o stub-obj-y += cpu-get-icount.o diff --git a/stubs/chr-testdev.c b/stubs/chr-testdev.c deleted file mode 100644 index 23112a2..0000000 --- a/stubs/chr-testdev.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "qemu-common.h" -#include "sysemu/char.h" - -CharDriverState *chr_testdev_init(void) -{ - return 0; -} -- cgit v1.1 From 8c84b25d975870bbed2e089fe61e037c58a69854 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:40:28 +0200 Subject: qemu-char: convert stdio backend to data-driven creation The backend now always returns errors via the Error* argument. This avoids a double error message. Before: qemu-system-x86_64: -chardev stdio,id=base: cannot use stdio with -daemonize qemu-system-x86_64: -chardev stdio,id=base: Failed to create chardev After: qemu-system-x86_64: -chardev stdio,id=base: cannot use stdio with -daemonize Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 57 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 56bc7ed..faeffd4 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1168,19 +1168,23 @@ static void qemu_chr_close_stdio(struct CharDriverState *chr) fd_chr_close(chr); } -static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) +static CharDriverState *qemu_chr_open_stdio(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + ChardevStdio *opts = backend->stdio; CharDriverState *chr; struct sigaction act; if (is_daemonized()) { - error_report("cannot use stdio with -daemonize"); + error_setg(errp, "cannot use stdio with -daemonize"); return NULL; } if (stdio_in_use) { - error_report("cannot use stdio by multiple character devices"); - exit(1); + error_setg(errp, "cannot use stdio by multiple character devices"); + return NULL; } stdio_in_use = true; @@ -2341,7 +2345,10 @@ static void win_stdio_close(CharDriverState *chr) g_free(chr); } -static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) +static CharDriverState *qemu_chr_open_stdio(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { CharDriverState *chr; WinStdioCharState *stdio; @@ -2353,8 +2360,8 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE); if (stdio->hStdIn == INVALID_HANDLE_VALUE) { - fprintf(stderr, "cannot open stdio: invalid handle\n"); - exit(1); + error_setg(errp, "cannot open stdio: invalid handle"); + return NULL; } is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0; @@ -2366,25 +2373,30 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) if (is_console) { if (qemu_add_wait_object(stdio->hStdIn, win_stdio_wait_func, chr)) { - fprintf(stderr, "qemu_add_wait_object: failed\n"); + error_setg(errp, "qemu_add_wait_object: failed"); + goto err1; } } else { DWORD dwId; stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); stdio->hInputDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, - chr, 0, &dwId); - - if (stdio->hInputThread == INVALID_HANDLE_VALUE - || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE + if (stdio->hInputReadyEvent == INVALID_HANDLE_VALUE || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) { - fprintf(stderr, "cannot create stdio thread or event\n"); - exit(1); + error_setg(errp, "cannot create event"); + goto err2; } if (qemu_add_wait_object(stdio->hInputReadyEvent, win_stdio_thread_wait_func, chr)) { - fprintf(stderr, "qemu_add_wait_object: failed\n"); + error_setg(errp, "qemu_add_wait_object: failed"); + goto err2; + } + stdio->hInputThread = CreateThread(NULL, 0, win_stdio_thread, + chr, 0, &dwId); + + if (stdio->hInputThread == INVALID_HANDLE_VALUE) { + error_setg(errp, "cannot create stdio thread"); + goto err3; } } @@ -2402,6 +2414,15 @@ static CharDriverState *qemu_chr_open_stdio(ChardevStdio *opts) qemu_chr_fe_set_echo(chr, false); return chr; + +err3: + qemu_del_wait_object(stdio->hInputReadyEvent, NULL, NULL); +err2: + CloseHandle(stdio->hInputReadyEvent); + CloseHandle(stdio->hInputDoneEvent); +err1: + qemu_del_wait_object(stdio->hStdIn, NULL, NULL); + return NULL; } #endif /* !_WIN32 */ @@ -4321,7 +4342,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_STDIO: - chr = qemu_chr_open_stdio(backend->stdio); + abort(); break; #ifdef _WIN32 case CHARDEV_BACKEND_KIND_CONSOLE: @@ -4411,7 +4432,7 @@ static void register_types(void) register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, qemu_chr_parse_file_out, qmp_chardev_open_file); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, - qemu_chr_parse_stdio, NULL); + qemu_chr_parse_stdio, qemu_chr_open_stdio); #if defined HAVE_CHARDEV_SERIAL register_char_driver("serial", CHARDEV_BACKEND_KIND_SERIAL, qemu_chr_parse_serial, qmp_chardev_open_serial); -- cgit v1.1 From 122e5ed4412cadce2d44a5f636e4d1bfc67c534b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:42:04 +0200 Subject: qemu-char: convert console backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index faeffd4..b74d6aa 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2204,7 +2204,10 @@ static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out) return chr; } -static CharDriverState *qemu_chr_open_win_con(void) +static CharDriverState *qemu_chr_open_win_con(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE)); } @@ -4344,11 +4347,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_STDIO: abort(); break; -#ifdef _WIN32 case CHARDEV_BACKEND_KIND_CONSOLE: - chr = qemu_chr_open_win_con(); + abort(); break; -#endif #ifdef CONFIG_SPICE case CHARDEV_BACKEND_KIND_SPICEVMC: chr = qemu_chr_open_spice_vmc(backend->spicevmc->type); @@ -4449,8 +4450,10 @@ static void register_types(void) register_char_driver("pty", CHARDEV_BACKEND_KIND_PTY, NULL, qemu_chr_open_pty); #endif +#ifdef _WIN32 register_char_driver("console", CHARDEV_BACKEND_KIND_CONSOLE, NULL, - NULL); + qemu_chr_open_win_con); +#endif register_char_driver("pipe", CHARDEV_BACKEND_KIND_PIPE, qemu_chr_parse_pipe, qemu_chr_open_pipe); register_char_driver("mux", CHARDEV_BACKEND_KIND_MUX, qemu_chr_parse_mux, -- cgit v1.1 From 68145e178ac200a27b5f0ab342da80cf60ddd576 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:45:47 +0200 Subject: qemu-char: convert spice backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/ui/qemu-spice.h | 2 -- qemu-char.c | 6 ++---- spice-qemu-char.c | 21 ++++++++++++--------- stubs/Makefile.objs | 1 - stubs/qemu-chr-open-spice.c | 14 -------------- 5 files changed, 14 insertions(+), 30 deletions(-) delete mode 100644 stubs/qemu-chr-open-spice.c diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h index 0dff422..f9ce357 100644 --- a/include/ui/qemu-spice.h +++ b/include/ui/qemu-spice.h @@ -43,9 +43,7 @@ int qemu_spice_set_pw_expire(time_t expires); int qemu_spice_migrate_info(const char *hostname, int port, int tls_port, const char *subject); -CharDriverState *qemu_chr_open_spice_vmc(const char *type); #if SPICE_SERVER_VERSION >= 0x000c02 -CharDriverState *qemu_chr_open_spice_port(const char *name); void qemu_spice_register_ports(void); #else static inline CharDriverState *qemu_chr_open_spice_port(const char *name) diff --git a/qemu-char.c b/qemu-char.c index b74d6aa..02ec080 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4350,14 +4350,12 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, case CHARDEV_BACKEND_KIND_CONSOLE: abort(); break; -#ifdef CONFIG_SPICE case CHARDEV_BACKEND_KIND_SPICEVMC: - chr = qemu_chr_open_spice_vmc(backend->spicevmc->type); + abort(); break; case CHARDEV_BACKEND_KIND_SPICEPORT: - chr = qemu_chr_open_spice_port(backend->spiceport->fqdn); + abort(); break; -#endif case CHARDEV_BACKEND_KIND_VC: chr = vc_init(backend->vc); break; diff --git a/spice-qemu-char.c b/spice-qemu-char.c index e4353ef..a20fb5c 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -296,15 +296,14 @@ static CharDriverState *chr_open(const char *subtype, return chr; } -CharDriverState *qemu_chr_open_spice_vmc(const char *type) +static CharDriverState *qemu_chr_open_spice_vmc(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + const char *type = backend->spicevmc->type; const char **psubtype = spice_server_char_device_recognized_subtypes(); - if (type == NULL) { - fprintf(stderr, "spice-qemu-char: missing name parameter\n"); - print_allowed_subtypes(); - return NULL; - } for (; *psubtype != NULL; ++psubtype) { if (strcmp(type, *psubtype) == 0) { break; @@ -320,8 +319,12 @@ CharDriverState *qemu_chr_open_spice_vmc(const char *type) } #if SPICE_SERVER_VERSION >= 0x000c02 -CharDriverState *qemu_chr_open_spice_port(const char *name) +static CharDriverState *qemu_chr_open_spice_port(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, + Error **errp) { + const char *name = backend->spiceport->fqdn; CharDriverState *chr; SpiceCharDriver *s; @@ -379,9 +382,9 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend, static void register_types(void) { register_char_driver("spicevmc", CHARDEV_BACKEND_KIND_SPICEVMC, - qemu_chr_parse_spice_vmc, NULL); + qemu_chr_parse_spice_vmc, qemu_chr_open_spice_vmc); register_char_driver("spiceport", CHARDEV_BACKEND_KIND_SPICEPORT, - qemu_chr_parse_spice_port, NULL); + qemu_chr_parse_spice_port, qemu_chr_open_spice_port); } type_init(register_types); diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index b5322a2..6d4363d 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -20,7 +20,6 @@ stub-obj-y += mon-is-qmp.o stub-obj-y += mon-printf.o stub-obj-y += monitor-init.o stub-obj-y += notify-event.o -stub-obj-$(CONFIG_SPICE) += qemu-chr-open-spice.o stub-obj-y += qtest.o stub-obj-y += reset.o stub-obj-y += runstate-check.o diff --git a/stubs/qemu-chr-open-spice.c b/stubs/qemu-chr-open-spice.c deleted file mode 100644 index f1c4849..0000000 --- a/stubs/qemu-chr-open-spice.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "qemu-common.h" -#include "ui/qemu-spice.h" - -CharDriverState *qemu_chr_open_spice_vmc(const char *type) -{ - return NULL; -} - -#if SPICE_SERVER_VERSION >= 0x000c02 -CharDriverState *qemu_chr_open_spice_port(const char *name) -{ - return NULL; -} -#endif -- cgit v1.1 From fa19d02539a56ac20d03b2eef775be7ffcdd695a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:49:06 +0200 Subject: qemu-char: convert vc backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- include/sysemu/char.h | 5 ++--- qemu-char.c | 2 +- stubs/Makefile.objs | 1 - stubs/vc-init.c | 7 ------- ui/console.c | 10 ++++++---- ui/gtk.c | 2 +- 6 files changed, 10 insertions(+), 17 deletions(-) delete mode 100644 stubs/vc-init.c diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 5c28c16..edf7669 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -357,8 +357,7 @@ extern int term_escape_char; CharDriverState *qemu_char_get_next_serial(void); /* console.c */ -typedef CharDriverState *(VcHandler)(ChardevVC *vc); - +typedef CharDriverState *(VcHandler)(ChardevVC *vc, Error **errp); void register_vc_handler(VcHandler *handler); -CharDriverState *vc_init(ChardevVC *vc); + #endif diff --git a/qemu-char.c b/qemu-char.c index 02ec080..14cb253 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4357,7 +4357,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, abort(); break; case CHARDEV_BACKEND_KIND_VC: - chr = vc_init(backend->vc); + abort(); break; case CHARDEV_BACKEND_KIND_RINGBUF: case CHARDEV_BACKEND_KIND_MEMORY: diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 6d4363d..1862f84 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -27,7 +27,6 @@ stub-obj-y += set-fd-handler.o stub-obj-y += slirp.o stub-obj-y += sysbus.o stub-obj-y += uuid.o -stub-obj-y += vc-init.o stub-obj-y += vm-stop.o stub-obj-y += vmstate.o stub-obj-$(CONFIG_WIN32) += fd-register.o diff --git a/stubs/vc-init.c b/stubs/vc-init.c deleted file mode 100644 index 308dfa0..0000000 --- a/stubs/vc-init.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "qemu-common.h" -#include "sysemu/char.h" - -CharDriverState *vc_init(ChardevVC *vc) -{ - return 0; -} diff --git a/ui/console.c b/ui/console.c index aee6f21..cf649b2 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1962,7 +1962,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds) chr->init(chr); } -static CharDriverState *text_console_init(ChardevVC *vc) +static CharDriverState *text_console_init(ChardevVC *vc, Error **errp) { CharDriverState *chr; QemuConsole *s; @@ -1993,6 +1993,7 @@ static CharDriverState *text_console_init(ChardevVC *vc) if (!s) { g_free(chr); + error_setg(errp, "cannot create text console"); return NULL; } @@ -2012,9 +2013,10 @@ static CharDriverState *text_console_init(ChardevVC *vc) static VcHandler *vc_handler = text_console_init; -CharDriverState *vc_init(ChardevVC *vc) +static CharDriverState *vc_init(const char *id, ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { - return vc_handler(vc); + return vc_handler(backend->vc, errp); } void register_vc_handler(VcHandler *handler) @@ -2094,7 +2096,7 @@ static void register_types(void) { type_register_static(&qemu_console_info); register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc, - NULL); + vc_init); } type_init(register_types); diff --git a/ui/gtk.c b/ui/gtk.c index 2947838..47b37e1 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -1591,7 +1591,7 @@ static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static int nb_vcs; static CharDriverState *vcs[MAX_VCS]; -static CharDriverState *gd_vc_handler(ChardevVC *unused) +static CharDriverState *gd_vc_handler(ChardevVC *unused, Error **errp) { CharDriverState *chr; -- cgit v1.1 From 479f09a130f774b0275134b5c44081ea71fe00b3 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Sep 2015 15:51:14 +0200 Subject: qemu-char: convert ringbuf backend to data-driven creation Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 14cb253..6632018 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3222,9 +3222,12 @@ static void ringbuf_chr_close(struct CharDriverState *chr) chr->opaque = NULL; } -static CharDriverState *qemu_chr_open_ringbuf(ChardevRingbuf *opts, +static CharDriverState *qemu_chr_open_ringbuf(const char *id, + ChardevBackend *backend, + ChardevReturn *ret, Error **errp) { + ChardevRingbuf *opts = backend->ringbuf; CharDriverState *chr; RingBufCharDriver *d; @@ -4361,7 +4364,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, break; case CHARDEV_BACKEND_KIND_RINGBUF: case CHARDEV_BACKEND_KIND_MEMORY: - chr = qemu_chr_open_ringbuf(backend->ringbuf, &local_err); + abort(); break; default: error_setg(errp, "unknown chardev backend (%d)", backend->kind); @@ -4427,7 +4430,7 @@ static void register_types(void) register_char_driver("udp", CHARDEV_BACKEND_KIND_UDP, qemu_chr_parse_udp, qmp_chardev_open_udp); register_char_driver("ringbuf", CHARDEV_BACKEND_KIND_RINGBUF, - qemu_chr_parse_ringbuf, NULL); + qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); register_char_driver("file", CHARDEV_BACKEND_KIND_FILE, qemu_chr_parse_file_out, qmp_chardev_open_file); register_char_driver("stdio", CHARDEV_BACKEND_KIND_STDIO, @@ -4458,7 +4461,7 @@ static void register_types(void) qemu_chr_open_mux); /* Bug-compatibility: */ register_char_driver("memory", CHARDEV_BACKEND_KIND_MEMORY, - qemu_chr_parse_ringbuf, NULL); + qemu_chr_parse_ringbuf, qemu_chr_open_ringbuf); /* this must be done after machine init, since we register FEs with muxes * as part of realize functions like serial_isa_realizefn when -nographic * is specified -- cgit v1.1 From 1c3af0f4f04bd6e6729783a48bb51ca1eb5c3baf Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 12 Oct 2015 09:51:41 +0200 Subject: qemu-char: cleanup after completed conversion to cd->create All backends now return errors through Error*, so the "Failed to create chardev" placeholder error can only be reached if the backend is not available (and only from the chardev-add QMP command; instead, the -chardev command line option fails earlier). Reviewed-by: Eric Blake Signed-off-by: Paolo Bonzini --- qemu-char.c | 80 ++++--------------------------------------------------------- 1 file changed, 4 insertions(+), 76 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 6632018..13371c4 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4299,7 +4299,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, for (i = backends; i; i = i->next) { cd = i->data; - if (cd->kind == backend->kind && cd->create) { + if (cd->kind == backend->kind) { chr = cd->create(id, backend, ret, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -4310,81 +4310,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, } if (chr == NULL) { - switch (backend->kind) { - case CHARDEV_BACKEND_KIND_FILE: - abort(); - break; - case CHARDEV_BACKEND_KIND_SERIAL: - abort(); - break; - case CHARDEV_BACKEND_KIND_PARALLEL: - abort(); - break; - case CHARDEV_BACKEND_KIND_PIPE: - abort(); - break; - case CHARDEV_BACKEND_KIND_SOCKET: - abort(); - break; - case CHARDEV_BACKEND_KIND_UDP: - abort(); - break; - case CHARDEV_BACKEND_KIND_PTY: - abort(); - break; - case CHARDEV_BACKEND_KIND_NULL: - abort(); - break; - case CHARDEV_BACKEND_KIND_MUX: - abort(); - break; - case CHARDEV_BACKEND_KIND_MSMOUSE: - abort(); - break; - case CHARDEV_BACKEND_KIND_BRAILLE: - abort(); - break; - case CHARDEV_BACKEND_KIND_TESTDEV: - abort(); - break; - case CHARDEV_BACKEND_KIND_STDIO: - abort(); - break; - case CHARDEV_BACKEND_KIND_CONSOLE: - abort(); - break; - case CHARDEV_BACKEND_KIND_SPICEVMC: - abort(); - break; - case CHARDEV_BACKEND_KIND_SPICEPORT: - abort(); - break; - case CHARDEV_BACKEND_KIND_VC: - abort(); - break; - case CHARDEV_BACKEND_KIND_RINGBUF: - case CHARDEV_BACKEND_KIND_MEMORY: - abort(); - break; - default: - error_setg(errp, "unknown chardev backend (%d)", backend->kind); - goto out_error; - } - - /* - * Character backend open hasn't been fully converted to the Error - * API. Some opens fail without setting an error. Set a generic - * error then. - * TODO full conversion to Error API - */ - if (chr == NULL) { - if (local_err) { - error_propagate(errp, local_err); - } else { - error_setg(errp, "Failed to create chardev"); - } - goto out_error; - } + assert(!i); + error_setg(errp, "chardev backend not available"); + goto out_error; } chr->label = g_strdup(id); -- cgit v1.1 From 9bda456e419273199221625894003bf9307d8451 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Wed, 14 Oct 2015 18:46:44 +0300 Subject: doc/rcu: fix g_free_rcu() usage example The first argument of g_free_rcu() is a pointer to a structure. But foo_reclaim is used as a function name in the previous example along with &foo as a pointer to the structure being reclaimed. Make the example consistent with the previous one. Signed-off-by: Sergey Fedorov Message-Id: <1444837604-13712-1-git-send-email-serge.fdrv@gmail.com> Signed-off-by: Paolo Bonzini --- docs/rcu.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rcu.txt b/docs/rcu.txt index 21ecb81..2f70954 100644 --- a/docs/rcu.txt +++ b/docs/rcu.txt @@ -128,7 +128,7 @@ The core RCU API is small: the callback function is g_free, in particular, g_free_rcu can be used. In the above case, one could have written simply: - g_free_rcu(foo_reclaim, rcu); + g_free_rcu(&foo, rcu); typeof(*p) atomic_rcu_read(p); -- cgit v1.1 From 50bf31b9379cf88c4fe92ec477fdc56f89d1af94 Mon Sep 17 00:00:00 2001 From: Pavel Fedin Date: Thu, 15 Oct 2015 16:44:50 +0300 Subject: kvm: Make KVM_CAP_SIGNAL_MSI globally available This capability is useful to determine whether we can use KVM ITS emulation on ARM Signed-off-by: Pavel Fedin Message-Id: Signed-off-by: Paolo Bonzini --- include/sysemu/kvm.h | 9 +++++++++ kvm-all.c | 10 +++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 52c57e2..5fb22d2 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -52,6 +52,7 @@ extern bool kvm_msi_via_irqfd_allowed; extern bool kvm_gsi_routing_allowed; extern bool kvm_gsi_direct_mapping; extern bool kvm_readonly_mem_allowed; +extern bool kvm_direct_msi_allowed; #if defined CONFIG_KVM || !defined NEED_CPU_H #define kvm_enabled() (kvm_allowed) @@ -145,6 +146,13 @@ extern bool kvm_readonly_mem_allowed; */ #define kvm_readonly_mem_enabled() (kvm_readonly_mem_allowed) +/** + * kvm_direct_msi_enabled: + * + * Returns: true if KVM allows direct MSI injection. + */ +#define kvm_direct_msi_enabled() (kvm_direct_msi_allowed) + #else #define kvm_enabled() (0) #define kvm_irqchip_in_kernel() (false) @@ -157,6 +165,7 @@ extern bool kvm_readonly_mem_allowed; #define kvm_gsi_routing_allowed() (false) #define kvm_gsi_direct_mapping() (false) #define kvm_readonly_mem_enabled() (false) +#define kvm_direct_msi_enabled() (false) #endif struct kvm_run; diff --git a/kvm-all.c b/kvm-all.c index 6f04fbb..5519c02 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -93,7 +93,6 @@ struct KVMState uint32_t *used_gsi_bitmap; unsigned int gsi_count; QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; - bool direct_msi; #endif KVMMemoryListener memory_listener; }; @@ -111,6 +110,7 @@ bool kvm_gsi_direct_mapping; bool kvm_allowed; bool kvm_readonly_mem_allowed; bool kvm_vm_attributes_allowed; +bool kvm_direct_msi_allowed; static const KVMCapabilityInfo kvm_required_capabilites[] = { KVM_CAP_INFO(USER_MEMORY), @@ -979,7 +979,7 @@ void kvm_init_irq_routing(KVMState *s) s->irq_routes = g_malloc0(sizeof(*s->irq_routes)); s->nr_allocated_irq_routes = 0; - if (!s->direct_msi) { + if (!kvm_direct_msi_allowed) { for (i = 0; i < KVM_MSI_HASHTAB_SIZE; i++) { QTAILQ_INIT(&s->msi_hashtab[i]); } @@ -1113,7 +1113,7 @@ static int kvm_irqchip_get_virq(KVMState *s) * number can succeed even though a new route entry cannot be added. * When this happens, flush dynamic MSI entries to free IRQ route entries. */ - if (!s->direct_msi && s->irq_routes->nr == s->gsi_count) { + if (!kvm_direct_msi_allowed && s->irq_routes->nr == s->gsi_count) { kvm_flush_dynamic_msi_routes(s); } @@ -1150,7 +1150,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg) struct kvm_msi msi; KVMMSIRoute *route; - if (s->direct_msi) { + if (kvm_direct_msi_allowed) { msi.address_lo = (uint32_t)msg.address; msi.address_hi = msg.address >> 32; msi.data = le32_to_cpu(msg.data); @@ -1598,7 +1598,7 @@ static int kvm_init(MachineState *ms) #endif #ifdef KVM_CAP_IRQ_ROUTING - s->direct_msi = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) > 0); + kvm_direct_msi_allowed = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) > 0); #endif s->intx_set_mask = kvm_check_extension(s, KVM_CAP_PCI_2_3); -- cgit v1.1 From a05f686ff39c373384772b01f1b7fc71e7eb2500 Mon Sep 17 00:00:00 2001 From: Pavel Fedin Date: Thu, 15 Oct 2015 16:44:51 +0300 Subject: hw/pci: Introduce pci_requester_id() For GICv3 ITS implementation we are going to use requester IDs in KVM IRQ routing code. This patch introduces reusable convenient way to obtain this ID from the device pointer. The new function is now used in some places, where the same calculation was used. MemTxAttrs.stream_id also renamed to requester_id in order to better reflect semantics of the field. Signed-off-by: Pavel Fedin Reviewed-by: Michael S. Tsirkin Acked-by: Michael S. Tsirkin Message-Id: <5814bcb03a297f198e796b13ed9c35059c52f89b.1444916432.git.p.fedin@samsung.com> Signed-off-by: Paolo Bonzini --- hw/i386/kvm/pci-assign.c | 2 +- hw/pci/msi.c | 2 +- hw/pci/pcie_aer.c | 2 +- include/exec/memattrs.h | 4 ++-- include/hw/pci/pci.h | 5 +++++ 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index 44beee3..e48cae6 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -1483,7 +1483,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp) * error bits, leave the rest. */ status = pci_get_long(pci_dev->config + pos + PCI_X_STATUS); status &= ~(PCI_X_STATUS_BUS | PCI_X_STATUS_DEVFN); - status |= (pci_bus_num(pci_dev->bus) << 8) | pci_dev->devfn; + status |= pci_requester_id(pci_dev); status &= ~(PCI_X_STATUS_SPL_DISC | PCI_X_STATUS_UNX_SPL | PCI_X_STATUS_SPL_ERR); pci_set_long(pci_dev->config + pos + PCI_X_STATUS, status); diff --git a/hw/pci/msi.c b/hw/pci/msi.c index f9c0484..c1dd531 100644 --- a/hw/pci/msi.c +++ b/hw/pci/msi.c @@ -294,7 +294,7 @@ void msi_send_message(PCIDevice *dev, MSIMessage msg) { MemTxAttrs attrs = {}; - attrs.stream_id = (pci_bus_num(dev->bus) << 8) | dev->devfn; + attrs.requester_id = pci_requester_id(dev); address_space_stl_le(&dev->bus_master_as, msg.address, msg.data, attrs, NULL); } diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c index 46e0ad8..98d2c18 100644 --- a/hw/pci/pcie_aer.c +++ b/hw/pci/pcie_aer.c @@ -979,7 +979,7 @@ static int do_pcie_aer_inject_error(Monitor *mon, } } err.status = error_status; - err.source_id = (pci_bus_num(dev->bus) << 8) | dev->devfn; + err.source_id = pci_requester_id(dev); err.flags = 0; if (correctable) { diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h index f8537a8..e601061 100644 --- a/include/exec/memattrs.h +++ b/include/exec/memattrs.h @@ -35,8 +35,8 @@ typedef struct MemTxAttrs { unsigned int secure:1; /* Memory access is usermode (unprivileged) */ unsigned int user:1; - /* Stream ID (for MSI for example) */ - unsigned int stream_id:16; + /* Requester ID (for MSI for example) */ + unsigned int requester_id:16; } MemTxAttrs; /* Bus masters which don't specify any attributes will get this, diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 551cb3d..f5e7fd8 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -677,6 +677,11 @@ static inline uint32_t pci_config_size(const PCIDevice *d) return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE; } +static inline uint16_t pci_requester_id(PCIDevice *dev) +{ + return (pci_bus_num(dev->bus) << 8) | dev->devfn; +} + /* DMA access functions */ static inline AddressSpace *pci_get_address_space(PCIDevice *dev) { -- cgit v1.1 From dc9f06ca81e6e16d062ec382701142a3a2ab3f7d Mon Sep 17 00:00:00 2001 From: Pavel Fedin Date: Thu, 15 Oct 2015 16:44:52 +0300 Subject: kvm: Pass PCI device pointer to MSI routing functions In-kernel ITS emulation on ARM64 will require to supply requester IDs. These IDs can now be retrieved from the device pointer using new pci_requester_id() function. This patch adds pci_dev pointer to KVM GSI routing functions and makes callers passing it. x86 architecture does not use requester IDs, but hw/i386/kvm/pci-assign.c also made passing PCI device pointer instead of NULL for consistency with the rest of the code. Signed-off-by: Pavel Fedin Message-Id: Signed-off-by: Paolo Bonzini --- hw/i386/kvm/pci-assign.c | 9 +++++---- hw/vfio/pci.c | 11 ++++++----- hw/virtio/virtio-pci.c | 5 +++-- include/sysemu/kvm.h | 7 ++++--- kvm-all.c | 9 +++++---- kvm-stub.c | 5 +++-- target-arm/kvm.c | 2 +- target-i386/kvm.c | 2 +- target-mips/kvm.c | 2 +- target-ppc/kvm.c | 2 +- target-s390x/kvm.c | 2 +- 11 files changed, 31 insertions(+), 25 deletions(-) diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index e48cae6..0fd6923 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -979,7 +979,7 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev) MSIMessage msg = msi_get_message(pci_dev, 0); int virq; - virq = kvm_irqchip_add_msi_route(kvm_state, msg); + virq = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev); if (virq < 0) { perror("assigned_dev_update_msi: kvm_irqchip_add_msi_route"); return; @@ -1017,7 +1017,7 @@ static void assigned_dev_update_msi_msg(PCIDevice *pci_dev) } kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0], - msi_get_message(pci_dev, 0)); + msi_get_message(pci_dev, 0), pci_dev); } static bool assigned_dev_msix_masked(MSIXTableEntry *entry) @@ -1083,7 +1083,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) msg.address = entry->addr_lo | ((uint64_t)entry->addr_hi << 32); msg.data = entry->data; - r = kvm_irqchip_add_msi_route(kvm_state, msg); + r = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev); if (r < 0) { return r; } @@ -1602,7 +1602,8 @@ static void assigned_dev_msix_mmio_write(void *opaque, hwaddr addr, msg.data = entry->data; ret = kvm_irqchip_update_msi_route(kvm_state, - adev->msi_virq[i], msg); + adev->msi_virq[i], msg, + pdev); if (ret) { error_report("Error updating irq routing entry (%d)", ret); } diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index dcabb6d..8fadbcf 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -424,7 +424,7 @@ static void vfio_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector, return; } - virq = kvm_irqchip_add_msi_route(kvm_state, *msg); + virq = kvm_irqchip_add_msi_route(kvm_state, *msg, &vdev->pdev); if (virq < 0) { event_notifier_cleanup(&vector->kvm_interrupt); return; @@ -449,9 +449,10 @@ static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector) event_notifier_cleanup(&vector->kvm_interrupt); } -static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg) +static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg, + PCIDevice *pdev) { - kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg); + kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg, pdev); } static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, @@ -486,7 +487,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, if (!msg) { vfio_remove_kvm_msi_virq(vector); } else { - vfio_update_kvm_msi_virq(vector, *msg); + vfio_update_kvm_msi_virq(vector, *msg, pdev); } } else { vfio_add_kvm_msi_virq(vdev, vector, msg, true); @@ -760,7 +761,7 @@ static void vfio_update_msi(VFIOPCIDevice *vdev) } msg = msi_get_message(&vdev->pdev, i); - vfio_update_kvm_msi_virq(vector, msg); + vfio_update_kvm_msi_virq(vector, msg, &vdev->pdev); } } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index e5c406d..f55dd2b 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -590,7 +590,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, int ret; if (irqfd->users == 0) { - ret = kvm_irqchip_add_msi_route(kvm_state, msg); + ret = kvm_irqchip_add_msi_route(kvm_state, msg, &proxy->pci_dev); if (ret < 0) { return ret; } @@ -726,7 +726,8 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, if (proxy->vector_irqfd) { irqfd = &proxy->vector_irqfd[vector]; if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) { - ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg); + ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg, + &proxy->pci_dev); if (ret < 0) { return ret; } diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 5fb22d2..24657d8 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -326,7 +326,7 @@ int kvm_arch_on_sigbus(int code, void *addr); void kvm_arch_init_irq_routing(KVMState *s); int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, - uint64_t address, uint32_t data); + uint64_t address, uint32_t data, PCIDevice *dev); int kvm_arch_msi_data_to_gsi(uint32_t data); @@ -451,8 +451,9 @@ static inline void cpu_clean_state(CPUState *cpu) } } -int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg); -int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg); +int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev); +int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg, + PCIDevice *dev); void kvm_irqchip_release_virq(KVMState *s, int virq); int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter); diff --git a/kvm-all.c b/kvm-all.c index 5519c02..ab50a16 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1189,7 +1189,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg) return kvm_set_irq(s, route->kroute.gsi, 1); } -int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) +int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev) { struct kvm_irq_routing_entry kroute = {}; int virq; @@ -1213,7 +1213,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) kroute.u.msi.address_lo = (uint32_t)msg.address; kroute.u.msi.address_hi = msg.address >> 32; kroute.u.msi.data = le32_to_cpu(msg.data); - if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) { + if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data, dev)) { kvm_irqchip_release_virq(s, virq); return -EINVAL; } @@ -1224,7 +1224,8 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) return virq; } -int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) +int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg, + PCIDevice *dev) { struct kvm_irq_routing_entry kroute = {}; @@ -1242,7 +1243,7 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) kroute.u.msi.address_lo = (uint32_t)msg.address; kroute.u.msi.address_hi = msg.address >> 32; kroute.u.msi.data = le32_to_cpu(msg.data); - if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) { + if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data, dev)) { return -EINVAL; } diff --git a/kvm-stub.c b/kvm-stub.c index d9ad624..08bcc32 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -115,7 +115,7 @@ int kvm_on_sigbus(int code, void *addr) } #ifndef CONFIG_USER_ONLY -int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) +int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev) { return -ENOSYS; } @@ -128,7 +128,8 @@ void kvm_irqchip_release_virq(KVMState *s, int virq) { } -int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) +int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg, + PCIDevice *dev) { return -ENOSYS; } diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 6aadcd8..79ef4c6 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -605,7 +605,7 @@ int kvm_arm_vgic_probe(void) } int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, - uint64_t address, uint32_t data) + uint64_t address, uint32_t data, PCIDevice *dev) { return 0; } diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 65cd944..ee5bef9 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -2992,7 +2992,7 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id) } int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, - uint64_t address, uint32_t data) + uint64_t address, uint32_t data, PCIDevice *dev) { return 0; } diff --git a/target-mips/kvm.c b/target-mips/kvm.c index d287d42..12d7db3 100644 --- a/target-mips/kvm.c +++ b/target-mips/kvm.c @@ -678,7 +678,7 @@ int kvm_arch_get_registers(CPUState *cs) } int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, - uint64_t address, uint32_t data) + uint64_t address, uint32_t data, PCIDevice *dev) { return 0; } diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 7276299..38aa927 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -2483,7 +2483,7 @@ error_out: } int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, - uint64_t address, uint32_t data) + uint64_t address, uint32_t data, PCIDevice *dev) { return 0; } diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 5fdee1b..0305ffa 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -2208,7 +2208,7 @@ int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu) } int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, - uint64_t address, uint32_t data) + uint64_t address, uint32_t data, PCIDevice *dev) { S390PCIBusDevice *pbdev; uint32_t fid = data >> ZPCI_MSI_VEC_BITS; -- cgit v1.1 From 28143b409f698210d85165ca518235ac7e7c5ac5 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 15 Oct 2015 20:30:20 +0200 Subject: kvm: Move x86-specific functions into target-i386/kvm.c The functions for checking xcrs, xsave and pit_state2 are only used on x86, so they should reside in target-i386/kvm.c. Signed-off-by: Thomas Huth Message-Id: <1444933820-6968-1-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- include/sysemu/kvm.h | 2 -- kvm-all.c | 29 ----------------------------- kvm-stub.c | 5 ----- target-i386/kvm.c | 31 ++++++++++++++++++++++++++----- 4 files changed, 26 insertions(+), 41 deletions(-) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 24657d8..461ef65 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -191,8 +191,6 @@ int kvm_has_sync_mmu(void); int kvm_has_vcpu_events(void); int kvm_has_robust_singlestep(void); int kvm_has_debugregs(void); -int kvm_has_xsave(void); -int kvm_has_xcrs(void); int kvm_has_pit_state2(void); int kvm_has_many_ioeventfds(void); int kvm_has_gsi_routing(void); diff --git a/kvm-all.c b/kvm-all.c index ab50a16..c442838 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -77,8 +77,6 @@ struct KVMState #ifdef KVM_CAP_SET_GUEST_DEBUG struct kvm_sw_breakpoint_head kvm_sw_breakpoints; #endif - int pit_state2; - int xsave, xcrs; int many_ioeventfds; int intx_set_mask; /* The man page (and posix) say ioctl numbers are signed int, but @@ -1586,18 +1584,6 @@ static int kvm_init(MachineState *ms) s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS); #endif -#ifdef KVM_CAP_XSAVE - s->xsave = kvm_check_extension(s, KVM_CAP_XSAVE); -#endif - -#ifdef KVM_CAP_XCRS - s->xcrs = kvm_check_extension(s, KVM_CAP_XCRS); -#endif - -#ifdef KVM_CAP_PIT_STATE2 - s->pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2); -#endif - #ifdef KVM_CAP_IRQ_ROUTING kvm_direct_msi_allowed = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) > 0); #endif @@ -2063,21 +2049,6 @@ int kvm_has_debugregs(void) return kvm_state->debugregs; } -int kvm_has_xsave(void) -{ - return kvm_state->xsave; -} - -int kvm_has_xcrs(void) -{ - return kvm_state->xcrs; -} - -int kvm_has_pit_state2(void) -{ - return kvm_state->pit_state2; -} - int kvm_has_many_ioeventfds(void) { if (!kvm_enabled()) { diff --git a/kvm-stub.c b/kvm-stub.c index 08bcc32..a5051f7 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -67,11 +67,6 @@ int kvm_has_many_ioeventfds(void) return 0; } -int kvm_has_pit_state2(void) -{ - return 0; -} - void kvm_setup_guest_memory(void *start, size_t size) { } diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ee5bef9..010ac51 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -91,6 +91,15 @@ static bool has_msr_xss; static bool has_msr_architectural_pmu; static uint32_t num_architectural_pmu_counters; +static int has_xsave; +static int has_xcrs; +static int has_pit_state2; + +int kvm_has_pit_state2(void) +{ + return has_pit_state2; +} + bool kvm_has_smm(void) { return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM); @@ -766,7 +775,7 @@ int kvm_arch_init_vcpu(CPUState *cs) } } - if (kvm_has_xsave()) { + if (has_xsave) { env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave)); } @@ -934,6 +943,18 @@ int kvm_arch_init(MachineState *ms, KVMState *s) int ret; struct utsname utsname; +#ifdef KVM_CAP_XSAVE + has_xsave = kvm_check_extension(s, KVM_CAP_XSAVE); +#endif + +#ifdef KVM_CAP_XCRS + has_xcrs = kvm_check_extension(s, KVM_CAP_XCRS); +#endif + +#ifdef KVM_CAP_PIT_STATE2 + has_pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2); +#endif + ret = kvm_get_supported_msrs(s); if (ret < 0) { return ret; @@ -1142,7 +1163,7 @@ static int kvm_put_xsave(X86CPU *cpu) uint8_t *xmm, *ymmh, *zmmh; int i, r; - if (!kvm_has_xsave()) { + if (!has_xsave) { return kvm_put_fpu(cpu); } @@ -1196,7 +1217,7 @@ static int kvm_put_xcrs(X86CPU *cpu) CPUX86State *env = &cpu->env; struct kvm_xcrs xcrs = {}; - if (!kvm_has_xcrs()) { + if (!has_xcrs) { return 0; } @@ -1525,7 +1546,7 @@ static int kvm_get_xsave(X86CPU *cpu) const uint8_t *xmm, *ymmh, *zmmh; uint16_t cwd, swd, twd; - if (!kvm_has_xsave()) { + if (!has_xsave) { return kvm_get_fpu(cpu); } @@ -1584,7 +1605,7 @@ static int kvm_get_xcrs(X86CPU *cpu) int i, ret; struct kvm_xcrs xcrs; - if (!kvm_has_xcrs()) { + if (!has_xcrs) { return 0; } -- cgit v1.1 From 1c4a55dbed9a47fde9294f7de6c8bb060d874c88 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 16 Oct 2015 09:38:22 -0600 Subject: kvm: Allow the Hyper-V vendor ID to be specified According to Microsoft documentation, the signature in the standard hypervisor CPUID leaf at 0x40000000 identifies the Vendor ID and is for reporting and diagnostic purposes only. We can therefore allow the user to change it to whatever they want, within the 12 character limit. Add a new hv-vendor-id option to the -cpu flag to allow for this, ex: -cpu host,hv_time,hv-vendor-id=KeenlyKVM Link: http://msdn.microsoft.com/library/windows/hardware/hh975392 Signed-off-by: Alex Williamson Message-Id: <20151016153356.28104.48612.stgit@gimli.home> [Adjust error message to match the property name, use error_report. - Paolo] Signed-off-by: Paolo Bonzini --- target-i386/cpu-qom.h | 1 + target-i386/cpu.c | 1 + target-i386/kvm.c | 14 +++++++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 9eab41b..e3bfe9d 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -88,6 +88,7 @@ typedef struct X86CPU { bool hyperv_vapic; bool hyperv_relaxed_timing; int hyperv_spinlock_attempts; + char *hyperv_vendor_id; bool hyperv_time; bool hyperv_crash; bool hyperv_reset; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index d2b0619..5f53af2 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3149,6 +3149,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, 0), DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, 0), DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0), + DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id), DEFINE_PROP_END_OF_LIST() }; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 010ac51..64046cb 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -28,6 +28,7 @@ #include "exec/gdbstub.h" #include "qemu/host-utils.h" #include "qemu/config-file.h" +#include "qemu/error-report.h" #include "hw/i386/pc.h" #include "hw/i386/apic.h" #include "hw/i386/apic_internal.h" @@ -505,7 +506,18 @@ int kvm_arch_init_vcpu(CPUState *cs) if (hyperv_enabled(cpu)) { c = &cpuid_data.entries[cpuid_i++]; c->function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS; - memcpy(signature, "Microsoft Hv", 12); + if (!cpu->hyperv_vendor_id) { + memcpy(signature, "Microsoft Hv", 12); + } else { + size_t len = strlen(cpu->hyperv_vendor_id); + + if (len > 12) { + error_report("hv-vendor-id truncated to 12 characters"); + len = 12; + } + memset(signature, 0, 12); + memcpy(signature, cpu->hyperv_vendor_id, len); + } c->eax = HYPERV_CPUID_MIN; c->ebx = signature[0]; c->ecx = signature[1]; -- cgit v1.1