[Qemu-devel] [PATCH 05/15] memory: introduce life_ops to MemoryRegion
From: Liu Ping Fan The types of referred object by MemoryRegion are variable, ex, another mr, DeviceState, or other struct defined by drivers. So the refer/unrefer may be different by drivers. Using this ops, we can mange the backend object. Signed-off-by: Liu Ping Fan --- hw/ide/piix.c |6 ++-- hw/pckbd.c|6 +++- hw/serial.c |2 +- ioport.c |3 +- memory.c | 69 - memory.h | 16 + 6 files changed, 94 insertions(+), 8 deletions(-) diff --git a/hw/ide/piix.c b/hw/ide/piix.c index f5a74c2..bdd70b1 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -93,11 +93,11 @@ static void bmdma_setup_bar(PCIIDEState *d) for(i = 0;i < 2; i++) { BMDMAState *bm = &d->bmdma[i]; -memory_region_init_io(&bm->extra_io, &piix_bmdma_ops, bm, +memory_region_init_io_ext(&bm->extra_io, &piix_bmdma_ops, NULL, bm, "piix-bmdma", 4); memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io); -memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm, - "bmdma", 4); +memory_region_init_io_ext(&bm->addr_ioport, &bmdma_addr_ioport_ops, + NULL, bm, "bmdma", 4); memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport); } } diff --git a/hw/pckbd.c b/hw/pckbd.c index 69857ba..de3c46d 100644 --- a/hw/pckbd.c +++ b/hw/pckbd.c @@ -485,10 +485,12 @@ static int i8042_initfn(ISADevice *dev) isa_init_irq(dev, &s->irq_kbd, 1); isa_init_irq(dev, &s->irq_mouse, 12); -memory_region_init_io(isa_s->io + 0, &i8042_data_ops, s, "i8042-data", 1); +memory_region_init_io_ext(isa_s->io + 0, &i8042_data_ops, NULL, s, +"i8042-data", 1); isa_register_ioport(dev, isa_s->io + 0, 0x60); -memory_region_init_io(isa_s->io + 1, &i8042_cmd_ops, s, "i8042-cmd", 1); +memory_region_init_io_ext(isa_s->io + 1, &i8042_cmd_ops, NULL, s, +"i8042-cmd", 1); isa_register_ioport(dev, isa_s->io + 1, 0x64); s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); diff --git a/hw/serial.c b/hw/serial.c index a421d1e..e992c6a 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -794,7 +794,7 @@ static int serial_isa_initfn(ISADevice *dev) serial_init_core(s); qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3); -memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8); +memory_region_init_io_ext(&s->io, &serial_io_ops, NULL, s, "serial", 8); isa_register_ioport(dev, &s->io, isa->iobase); return 0; } diff --git a/ioport.c b/ioport.c index 6e4ca0d..768e271 100644 --- a/ioport.c +++ b/ioport.c @@ -384,7 +384,8 @@ static void portio_list_add_1(PortioList *piolist, * Use an alias so that the callback is called with an absolute address, * rather than an offset relative to to start + off_low. */ -memory_region_init_io(region, ops, piolist->opaque, piolist->name, +memory_region_init_io_ext(region, ops, NULL, piolist->opaque, + piolist->name, INT64_MAX); memory_region_init_alias(alias, piolist->name, region, start + off_low, off_high - off_low); diff --git a/memory.c b/memory.c index 5986532..80c7529 100644 --- a/memory.c +++ b/memory.c @@ -19,6 +19,7 @@ #include "bitops.h" #include "kvm.h" #include +#include "hw/qdev.h" #define WANT_EXEC_OBSOLETE #include "exec-obsolete.h" @@ -799,6 +800,7 @@ static bool memory_region_wrong_endianness(MemoryRegion *mr) #endif } +static MemoryRegionLifeOps nops; void memory_region_init(MemoryRegion *mr, const char *name, uint64_t size) @@ -809,6 +811,7 @@ void memory_region_init(MemoryRegion *mr, if (size == UINT64_MAX) { mr->size = int128_2_64(); } +mr->life_ops = &nops; mr->addr = 0; mr->subpage = false; mr->enabled = true; @@ -931,6 +934,66 @@ static void memory_region_dispatch_write(MemoryRegion *mr, memory_region_write_accessor, mr); } +static void mr_object_get(MemoryRegion *mr) +{ +object_dynamic_cast_assert(OBJECT(mr->opaque), TYPE_DEVICE); +object_ref(OBJECT(mr->opaque)); +} + +static void mr_object_put(MemoryRegion *mr) +{ +object_unref(OBJECT(mr->opaque)); +} + +static MemoryRegionLifeOps obj_ops = { +.get = mr_object_get, +.put = mr_object_put, +}; + +static void mr_alias_get(MemoryRegion *mr) +{ +} + +static void mr_alias_put(MemoryRegion *mr) +{ +} + +static MemoryRegionLifeOps alias_ops = { +.get = mr_alias_get, +.put = mr_alias_put, +}; + +static void mr_nop_get(MemoryRegion *mr) +{ +} + +static void mr_nop_put(MemoryRegion *mr) +{ +} + +static MemoryRegionLifeOps nops = { +.get = mr_nop_get, +.put = mr_nop_put, +}; + +void memory_region_
[Qemu-devel] [PATCH 12/15] qdev: using devtree lock to protect device's accessing
From: Liu Ping Fan lock: qemu_device_tree_mutex competitors: --device_del(destruction of device will be postphoned until unplug ack from guest), --pci hot-unplug --iteration (qdev_reset_all) --device_add Signed-off-by: Liu Ping Fan --- hw/pci-hotplug.c |4 hw/qdev-monitor.c | 17 - hw/qdev.c |2 ++ 3 files changed, 22 insertions(+), 1 deletions(-) diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index e7fb780..33a9dfe 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -265,9 +265,11 @@ static int pci_device_hot_remove(Monitor *mon, const char *pci_addr) return -1; } +qemu_lock_devtree(); d = pci_find_device(pci_find_root_bus(dom), bus, PCI_DEVFN(slot, 0)); if (!d) { monitor_printf(mon, "slot %d empty\n", slot); +qemu_unlock_devtree(); return -1; } @@ -275,9 +277,11 @@ static int pci_device_hot_remove(Monitor *mon, const char *pci_addr) if (error_is_set(&local_err)) { monitor_printf(mon, "%s\n", error_get_pretty(local_err)); error_free(local_err); +qemu_unlock_devtree(); return -1; } +qemu_unlock_devtree(); return 0; } diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index 7915b45..2d47fe0 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -429,14 +429,18 @@ DeviceState *qdev_device_add(QemuOpts *opts) /* find bus */ path = qemu_opt_get(opts, "bus"); + +qemu_lock_devtree(); if (path != NULL) { bus = qbus_find(path); if (!bus) { +qemu_unlock_devtree(); return NULL; } if (strcmp(object_get_typename(OBJECT(bus)), k->bus_type) != 0) { qerror_report(QERR_BAD_BUS_FOR_DEVICE, driver, object_get_typename(OBJECT(bus))); +qemu_unlock_devtree(); return NULL; } } else { @@ -444,11 +448,13 @@ DeviceState *qdev_device_add(QemuOpts *opts) if (!bus) { qerror_report(QERR_NO_BUS_FOR_DEVICE, driver, k->bus_type); +qemu_unlock_devtree(); return NULL; } } if (qdev_hotplug && !bus->allow_hotplug) { qerror_report(QERR_BUS_NO_HOTPLUG, bus->name); +qemu_unlock_devtree(); return NULL; } @@ -466,6 +472,7 @@ DeviceState *qdev_device_add(QemuOpts *opts) } if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) { qdev_free(qdev); +qemu_unlock_devtree(); return NULL; } if (qdev->id) { @@ -478,6 +485,8 @@ DeviceState *qdev_device_add(QemuOpts *opts) OBJECT(qdev), NULL); g_free(name); } +qemu_unlock_devtree(); + if (qdev_init(qdev) < 0) { qerror_report(QERR_DEVICE_INIT_FAILED, driver); return NULL; @@ -600,13 +609,19 @@ void qmp_device_del(const char *id, Error **errp) { DeviceState *dev; +/* protect against unplug ack from guest, where we really remove device + * from system + */ +qemu_lock_devtree(); dev = qdev_find_recursive(sysbus_get_default(), id); if (NULL == dev) { error_set(errp, QERR_DEVICE_NOT_FOUND, id); +qemu_unlock_devtree(); return; } - +/* Just remove from system, and drop refcnt there*/ qdev_unplug(dev, errp); +qemu_unlock_devtree(); } void qdev_machine_init(void) diff --git a/hw/qdev.c b/hw/qdev.c index af54467..17525fe 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -230,7 +230,9 @@ static int qbus_reset_one(BusState *bus, void *opaque) void qdev_reset_all(DeviceState *dev) { +qemu_lock_devtree(); qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL); +qemu_unlock_devtree(); } void qbus_reset_all_fn(void *opaque) -- 1.7.4.4
[Qemu-devel] [PATCH 09/15] memory: prepare flatview and radix-tree for rcu style access
From: Liu Ping Fan Flatview and radix view are all under the protection of pointer. And this make sure the change of them seem to be atomic! The mr accessed by radix-tree leaf or flatview will be reclaimed after the prev PhysMap not in use any longer Signed-off-by: Liu Ping Fan --- exec.c | 303 +++--- hw/vhost.c |2 +- hw/xen_pt.c |2 +- kvm-all.c |2 +- memory.c| 92 ++- memory.h|9 ++- vl.c|1 + xen-all.c |2 +- 8 files changed, 286 insertions(+), 127 deletions(-) diff --git a/exec.c b/exec.c index 01b91b0..97addb9 100644 --- a/exec.c +++ b/exec.c @@ -24,6 +24,7 @@ #include #endif +#include "qemu/atomic.h" #include "qemu-common.h" #include "cpu.h" #include "tcg.h" @@ -35,6 +36,8 @@ #include "qemu-timer.h" #include "memory.h" #include "exec-memory.h" +#include "qemu-thread.h" +#include "qemu/reclaimer.h" #if defined(CONFIG_USER_ONLY) #include #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) @@ -184,25 +187,17 @@ static void *l1_map[V_L1_SIZE]; #if !defined(CONFIG_USER_ONLY) -static MemoryRegionSection *phys_sections; -static unsigned phys_sections_nb, phys_sections_nb_alloc; static uint16_t phys_section_unassigned; static uint16_t phys_section_notdirty; static uint16_t phys_section_rom; static uint16_t phys_section_watch; - -/* Simple allocator for PhysPageEntry nodes */ -static PhysPageEntry (*phys_map_nodes)[L2_SIZE]; -static unsigned phys_map_nodes_nb, phys_map_nodes_nb_alloc; - #define PHYS_MAP_NODE_NIL (((uint16_t)~0) >> 1) -/* This is a multi-level map on the physical address space. - The bottom level has pointers to MemoryRegionSections. */ -static PhysPageEntry phys_map = { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 }; - +static QemuMutex cur_map_lock; +static PhysMap *cur_map; QemuMutex mem_map_lock; +static PhysMap *next_map; static void io_mem_init(void); static void memory_map_init(void); @@ -383,41 +378,38 @@ static inline PageDesc *page_find(tb_page_addr_t index) #if !defined(CONFIG_USER_ONLY) -static void phys_map_node_reserve(unsigned nodes) +static void phys_map_node_reserve(PhysMap *map, unsigned nodes) { -if (phys_map_nodes_nb + nodes > phys_map_nodes_nb_alloc) { +if (map->phys_map_nodes_nb + nodes > map->phys_map_nodes_nb_alloc) { typedef PhysPageEntry Node[L2_SIZE]; -phys_map_nodes_nb_alloc = MAX(phys_map_nodes_nb_alloc * 2, 16); -phys_map_nodes_nb_alloc = MAX(phys_map_nodes_nb_alloc, - phys_map_nodes_nb + nodes); -phys_map_nodes = g_renew(Node, phys_map_nodes, - phys_map_nodes_nb_alloc); +map->phys_map_nodes_nb_alloc = MAX(map->phys_map_nodes_nb_alloc * 2, +16); +map->phys_map_nodes_nb_alloc = MAX(map->phys_map_nodes_nb_alloc, + map->phys_map_nodes_nb + nodes); +map->phys_map_nodes = g_renew(Node, map->phys_map_nodes, + map->phys_map_nodes_nb_alloc); } } -static uint16_t phys_map_node_alloc(void) +static uint16_t phys_map_node_alloc(PhysMap *map) { unsigned i; uint16_t ret; -ret = phys_map_nodes_nb++; +ret = map->phys_map_nodes_nb++; assert(ret != PHYS_MAP_NODE_NIL); -assert(ret != phys_map_nodes_nb_alloc); +assert(ret != map->phys_map_nodes_nb_alloc); for (i = 0; i < L2_SIZE; ++i) { -phys_map_nodes[ret][i].is_leaf = 0; -phys_map_nodes[ret][i].ptr = PHYS_MAP_NODE_NIL; +map->phys_map_nodes[ret][i].is_leaf = 0; +map->phys_map_nodes[ret][i].ptr = PHYS_MAP_NODE_NIL; } return ret; } -static void phys_map_nodes_reset(void) -{ -phys_map_nodes_nb = 0; -} - - -static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t *index, -target_phys_addr_t *nb, uint16_t leaf, +static void phys_page_set_level(PhysMap *map, PhysPageEntry *lp, +target_phys_addr_t *index, +target_phys_addr_t *nb, +uint16_t leaf, int level) { PhysPageEntry *p; @@ -425,8 +417,8 @@ static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t *index, target_phys_addr_t step = (target_phys_addr_t)1 << (level * L2_BITS); if (!lp->is_leaf && lp->ptr == PHYS_MAP_NODE_NIL) { -lp->ptr = phys_map_node_alloc(); -p = phys_map_nodes[lp->ptr]; +lp->ptr = phys_map_node_alloc(map); +p = map->phys_map_nodes[lp->ptr]; if (level == 0) { for (i = 0; i < L2_SIZE; i++) { p[i].is_leaf = 1; @@ -434,7 +426,7 @@ static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t *index, } } } else { -p = phys_ma
[Qemu-devel] [PATCH 04/15] memory: MemoryRegion topology must be stable when updating
From: Liu Ping Fan Using mem_map_lock to protect among updaters. So we can get the intact snapshot of mem topology -- FlatView & radix-tree. Signed-off-by: Liu Ping Fan --- exec.c |3 +++ memory.c | 22 ++ memory.h |2 ++ 3 files changed, 27 insertions(+), 0 deletions(-) diff --git a/exec.c b/exec.c index 8244d54..0e29ef9 100644 --- a/exec.c +++ b/exec.c @@ -210,6 +210,8 @@ static unsigned phys_map_nodes_nb, phys_map_nodes_nb_alloc; The bottom level has pointers to MemoryRegionSections. */ static PhysPageEntry phys_map = { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 }; +QemuMutex mem_map_lock; + static void io_mem_init(void); static void memory_map_init(void); @@ -637,6 +639,7 @@ void cpu_exec_init_all(void) #if !defined(CONFIG_USER_ONLY) memory_map_init(); io_mem_init(); +qemu_mutex_init(&mem_map_lock); #endif } diff --git a/memory.c b/memory.c index aab4a31..5986532 100644 --- a/memory.c +++ b/memory.c @@ -761,7 +761,9 @@ void memory_region_transaction_commit(void) assert(memory_region_transaction_depth); --memory_region_transaction_depth; if (!memory_region_transaction_depth && memory_region_update_pending) { +qemu_mutex_lock(&mem_map_lock); memory_region_update_topology(NULL); +qemu_mutex_unlock(&mem_map_lock); } } @@ -1069,8 +1071,10 @@ void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) { uint8_t mask = 1 << client; +qemu_mutex_lock(&mem_map_lock); mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask); memory_region_update_topology(mr); +qemu_mutex_unlock(&mem_map_lock); } bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr, @@ -1103,8 +1107,10 @@ void memory_region_sync_dirty_bitmap(MemoryRegion *mr) void memory_region_set_readonly(MemoryRegion *mr, bool readonly) { if (mr->readonly != readonly) { +qemu_mutex_lock(&mem_map_lock); mr->readonly = readonly; memory_region_update_topology(mr); +qemu_mutex_unlock(&mem_map_lock); } } @@ -1112,7 +1118,9 @@ void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable) { if (mr->readable != readable) { mr->readable = readable; +qemu_mutex_lock(&mem_map_lock); memory_region_update_topology(mr); +qemu_mutex_unlock(&mem_map_lock); } } @@ -1206,6 +1214,7 @@ void memory_region_add_eventfd(MemoryRegion *mr, }; unsigned i; +qemu_mutex_lock(&mem_map_lock); for (i = 0; i < mr->ioeventfd_nb; ++i) { if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) { break; @@ -1218,6 +1227,7 @@ void memory_region_add_eventfd(MemoryRegion *mr, sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i)); mr->ioeventfds[i] = mrfd; memory_region_update_topology(mr); +qemu_mutex_unlock(&mem_map_lock); } void memory_region_del_eventfd(MemoryRegion *mr, @@ -1236,6 +1246,7 @@ void memory_region_del_eventfd(MemoryRegion *mr, }; unsigned i; +qemu_mutex_lock(&mem_map_lock); for (i = 0; i < mr->ioeventfd_nb; ++i) { if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) { break; @@ -1248,6 +1259,7 @@ void memory_region_del_eventfd(MemoryRegion *mr, mr->ioeventfds = g_realloc(mr->ioeventfds, sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1); memory_region_update_topology(mr); +qemu_mutex_unlock(&mem_map_lock); } static void memory_region_add_subregion_common(MemoryRegion *mr, @@ -1259,6 +1271,8 @@ static void memory_region_add_subregion_common(MemoryRegion *mr, assert(!subregion->parent); subregion->parent = mr; subregion->addr = offset; + +qemu_mutex_lock(&mem_map_lock); QTAILQ_FOREACH(other, &mr->subregions, subregions_link) { if (subregion->may_overlap || other->may_overlap) { continue; @@ -1289,6 +1303,7 @@ static void memory_region_add_subregion_common(MemoryRegion *mr, QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link); done: memory_region_update_topology(mr); +qemu_mutex_unlock(&mem_map_lock); } @@ -1316,8 +1331,11 @@ void memory_region_del_subregion(MemoryRegion *mr, { assert(subregion->parent == mr); subregion->parent = NULL; + +qemu_mutex_lock(&mem_map_lock); QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link); memory_region_update_topology(mr); +qemu_mutex_unlock(&mem_map_lock); } void memory_region_set_enabled(MemoryRegion *mr, bool enabled) @@ -1325,8 +1343,10 @@ void memory_region_set_enabled(MemoryRegion *mr, bool enabled) if (enabled == mr->enabled) { return; } +qemu_mutex_lock(&mem_map_lock); mr->enabled = enabled; memory_region_update_topology(NULL); +qemu_mutex_unlock(&mem_map_lock); } void memory_region_set_address(MemoryRegion *mr, target_phys_addr
[Qemu-devel] [PATCH 11/15] lock: introduce global lock for device tree
From: Liu Ping Fan Signed-off-by: Liu Ping Fan --- cpus.c | 12 main-loop.h |3 +++ 2 files changed, 15 insertions(+), 0 deletions(-) diff --git a/cpus.c b/cpus.c index b182b3d..a734b36 100644 --- a/cpus.c +++ b/cpus.c @@ -611,6 +611,7 @@ static void qemu_tcg_init_cpu_signals(void) } #endif /* _WIN32 */ +QemuMutex qemu_device_tree_mutex; QemuMutex qemu_global_mutex; static QemuCond qemu_io_proceeded_cond; static bool iothread_requesting_mutex; @@ -634,6 +635,7 @@ void qemu_init_cpu_loop(void) qemu_cond_init(&qemu_work_cond); qemu_cond_init(&qemu_io_proceeded_cond); qemu_mutex_init(&qemu_global_mutex); +qemu_mutex_init(&qemu_device_tree_mutex); qemu_thread_get_self(&io_thread); } @@ -911,6 +913,16 @@ void qemu_mutex_unlock_iothread(void) qemu_mutex_unlock(&qemu_global_mutex); } +void qemu_lock_devtree(void) +{ +qemu_mutex_lock(&qemu_device_tree_mutex); +} + +void qemu_unlock_devtree(void) +{ +qemu_mutex_unlock(&qemu_device_tree_mutex); +} + static int all_vcpus_paused(void) { CPUArchState *penv = first_cpu; diff --git a/main-loop.h b/main-loop.h index dce1cd9..17e959a 100644 --- a/main-loop.h +++ b/main-loop.h @@ -353,6 +353,9 @@ void qemu_mutex_lock_iothread(void); */ void qemu_mutex_unlock_iothread(void); +void qemu_lock_devtree(void); +void qemu_unlock_devtree(void); + /* internal interfaces */ void qemu_fd_register(int fd); -- 1.7.4.4
[Qemu-devel] [PATCH 03/15] qom: introduce reclaimer to release obj
From: Liu Ping Fan Collect unused object and release them at caller demand. Signed-off-by: Liu Ping Fan --- include/qemu/reclaimer.h | 28 ++ main-loop.c |5 qemu-tool.c |5 qom/Makefile.objs|2 +- qom/reclaimer.c | 58 ++ 5 files changed, 97 insertions(+), 1 deletions(-) create mode 100644 include/qemu/reclaimer.h create mode 100644 qom/reclaimer.c diff --git a/include/qemu/reclaimer.h b/include/qemu/reclaimer.h new file mode 100644 index 000..9307e93 --- /dev/null +++ b/include/qemu/reclaimer.h @@ -0,0 +1,28 @@ +/* + * QEMU reclaimer + * + * Copyright IBM, Corp. 2012 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef QEMU_RECLAIMER +#define QEMU_RECLAIMER + +typedef void ReleaseHandler(void *opaque); +typedef struct Chunk { +QLIST_ENTRY(Chunk) list; +void *opaque; +ReleaseHandler *release; +} Chunk; + +typedef struct ChunkHead { +struct Chunk *lh_first; +} ChunkHead; + +void reclaimer_enqueue(ChunkHead *head, void *opaque, ReleaseHandler *release); +void reclaimer_worker(ChunkHead *head); +void qemu_reclaimer_enqueue(void *opaque, ReleaseHandler *release); +void qemu_reclaimer(void); +#endif diff --git a/main-loop.c b/main-loop.c index eb3b6e6..be9d095 100644 --- a/main-loop.c +++ b/main-loop.c @@ -26,6 +26,7 @@ #include "qemu-timer.h" #include "slirp/slirp.h" #include "main-loop.h" +#include "qemu/reclaimer.h" #ifndef _WIN32 @@ -505,5 +506,9 @@ int main_loop_wait(int nonblocking) them. */ qemu_bh_poll(); +/* ref to device from iohandler/bh/timer do not obey the rules, so delay + * reclaiming until now. + */ +qemu_reclaimer(); return ret; } diff --git a/qemu-tool.c b/qemu-tool.c index 318c5fc..f5fe319 100644 --- a/qemu-tool.c +++ b/qemu-tool.c @@ -21,6 +21,7 @@ #include "main-loop.h" #include "qemu_socket.h" #include "slirp/libslirp.h" +#include "qemu/reclaimer.h" #include @@ -75,6 +76,10 @@ void qemu_mutex_unlock_iothread(void) { } +void qemu_reclaimer(void) +{ +} + int use_icount; void qemu_clock_warp(QEMUClock *clock) diff --git a/qom/Makefile.objs b/qom/Makefile.objs index 5ef060a..a579261 100644 --- a/qom/Makefile.objs +++ b/qom/Makefile.objs @@ -1,4 +1,4 @@ -qom-obj-y = object.o container.o qom-qobject.o +qom-obj-y = object.o container.o qom-qobject.o reclaimer.o qom-obj-twice-y = cpu.o common-obj-y = $(qom-obj-twice-y) user-obj-y = $(qom-obj-twice-y) diff --git a/qom/reclaimer.c b/qom/reclaimer.c new file mode 100644 index 000..6cb53e3 --- /dev/null +++ b/qom/reclaimer.c @@ -0,0 +1,58 @@ +/* + * QEMU reclaimer + * + * Copyright IBM, Corp. 2012 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu-common.h" +#include "qemu-thread.h" +#include "main-loop.h" +#include "qemu-queue.h" +#include "qemu/reclaimer.h" + +static struct QemuMutex reclaimer_lock; +static QLIST_HEAD(rcl, Chunk) reclaimer_list; + +void reclaimer_enqueue(ChunkHead *head, void *opaque, ReleaseHandler *release) +{ +Chunk *r = g_malloc0(sizeof(Chunk)); +r->opaque = opaque; +r->release = release; +QLIST_INSERT_HEAD_RCU(head, r, list); +} + +void reclaimer_worker(ChunkHead *head) +{ +Chunk *cur, *next; + +QLIST_FOREACH_SAFE(cur, head, list, next) { +QLIST_REMOVE(cur, list); +cur->release(cur->opaque); +g_free(cur); +} +} + +void qemu_reclaimer_enqueue(void *opaque, ReleaseHandler *release) +{ +Chunk *r = g_malloc0(sizeof(Chunk)); +r->opaque = opaque; +r->release = release; +qemu_mutex_lock(&reclaimer_lock); +QLIST_INSERT_HEAD_RCU(&reclaimer_list, r, list); +qemu_mutex_unlock(&reclaimer_lock); +} + + +void qemu_reclaimer(void) +{ +Chunk *cur, *next; + +QLIST_FOREACH_SAFE(cur, &reclaimer_list, list, next) { +QLIST_REMOVE(cur, list); +cur->release(cur->opaque); +g_free(cur); +} +} -- 1.7.4.4
Re: [Qemu-devel] [RFC/PATCH 1/1] USB code fenced for s390
On 07/08/12 22:22, Blue Swirl wrote: > On Tue, Aug 7, 2012 at 12:26 PM, Peter Maydell > wrote: >> On 7 August 2012 13:19, Christian Borntraeger wrote: >>> +#if defined(TARGET_HAS_USB) && (TARGET_HAS_USB == 1) >>> /* init USB devices */ >>> if (usb_enabled) { >>> if (foreach_device_config(DEV_USB, usb_parse) < 0) >>> exit(1); >>> } >>> +#endif >> >> Whether there is USB or not is a property of the machine model, >> not the target CPU architecture, so a TARGET_HAS_USB define >> is definitely the wrong approach. > > Yes. I'd add CONFIG_USB=y to files in default-configs/ except for > s390*, Sparc32 and user emulators. Unless it's enough for USB to have > a dependency on PCI? Yes, that seems to be the right place - thanks. A dependency on pci would also do for us. On the other hand, if there are really plans to add a virtio-usb then we should not disable usb support at all - especially since disabling it does cause some trouble with libvirt and the current state does not cause problems (we assumed that libvirt will detect usb capability like it does for other parameters, but it doesnt). In other words this patch was mostly cosmetics. So lets just drop this patch, go ahead with Li's patch set and later on we can see if we should do anything regarding s390. Christian
[Qemu-devel] [PATCH 15/15] e1000: using new interface--unmap to unplug
From: Liu Ping Fan Signed-off-by: Liu Ping Fan --- hw/e1000.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/hw/e1000.c b/hw/e1000.c index 4573f13..fa71455 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -1192,6 +1192,13 @@ e1000_cleanup(VLANClientState *nc) s->nic = NULL; } +static void +pci_e1000_unmap(PCIDevice *p) +{ +/* DO NOT FREE anything!until refcnt=0 */ +/* isolate from memory view */ +} + static int pci_e1000_uninit(PCIDevice *dev) { @@ -1275,6 +1282,7 @@ static void e1000_class_init(ObjectClass *klass, void *data) PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); k->init = pci_e1000_init; +k->unmap = pci_e1000_unmap; k->exit = pci_e1000_uninit; k->romfile = "pxe-e1000.rom"; k->vendor_id = PCI_VENDOR_ID_INTEL; -- 1.7.4.4
[Qemu-devel] [PATCH 0/15 v2] prepare unplug out of protection of global lock
background: refer to orignal plan posted by Marcelo Tosatti, http://lists.gnu.org/archive/html/qemu-devel/2012-06/msg04315.html prev version: https://lists.gnu.org/archive/html/qemu-devel/2012-07/msg03312.html changes v1->v2 --introduce atomic ops --introduce ref cnt for MemoryRegion --make memory's flat view and radix tree toward rcu style.
Re: [Qemu-devel] Cirrus bugs vs endian: how two bugs cancel each other out
Hi, >>> The only thing >>> its missing is to fix the endianess for server/client handshaking. >> >> What exactly do you mean here? > > Well that are negotiation messages configuring each channel, its > capabilities, encryption keys , etc. After this negotiation, the > server start to send SPICE data, which are already swapped by the > marshallers. Ah, so the initial handshake isn't covered by the generated marshallers. >>> We have tested it first running >>> spice sever tests in a PPC machine and then we run it in an experimental >>> virtio-qxl driver we are working on. >> >> Huh? How does this work? > > Well, our first though was to minimize changes on xf86-video-qxl. > [ ... ] Keep in mind that the linux world is moving to kms & drm. A virtual hardware design trying to minimize the changes to todays userland X driver may turn out to be not be the best pick long-term. We also must make sure it works for both linux and windows guests. I suggest to discuss the virtual hardware design @ qemu-devel and spice-devel. >> The QXLCommand passed on to spice-server (via get_command callback) is >> supposed to be little endian. > > Actually the command endianness doesn't matter at this point once > QXLCommand will be marshalled (and then swapped) before get to the > wire. Well, the flow of a command from the guest to the spice client looks like this: (1) guest places the command into memory (QXLCommand, little endian) and queues it up (qxl uses its own ring format, but using virtio rings doesn't make a difference). (2) qemu takes the QXLCommand and passes it as-is to the spice-server. (3) spice-server parses and sanity-checks the command, also translates QXLCommand into internal representation (struct {Red,Spice}*), see server/red_parse_qxl.c. It should also translate from little endian to native endian but doesn't yet. (4) spice-server can process the commands (in native byte order) locally in case the rendered screen is needed. Happens for example if you ask for a screenshot via qemu monitor. (5) The generated marshaller code translates the command into wire format (and swaps again from native to little endian if needed). (6) The generated demarshaller code (in the client) translates back from the wire format to the internal representation (in native endian). (7) spice client renders the result. /me wonders how this works for you with step #3 not byteswapping on bigendian hosts. Maybe the guest driver places the qxl commands in native endian instead of big endian into memory? cheers, Gerd
Re: [Qemu-devel] KVM segfaults with 3.5 while installing ubuntu 12.04
Any news? Was this applied upstream? Am 06.08.2012 14:37, schrieb Avi Kivity: On 08/06/2012 03:12 PM, Avi Kivity wrote: On 08/06/2012 11:46 AM, Stefan Priebe - Profihost AG wrote: But still i got the segfault and core dump - this is my main problem? I mean qemu-kvm master isn't declared as stable. So i don't care about the slowness here. What can we do about the core dump and crash? Okay, I reproduced it; it seems aio=native is the culprit. You can try aio=threads as a workaround. Copying some relevant people (context: aio=native on qemu-kvm-1.1.1 segfaults pretty early during guest install) The following ought to fix it: From: Avi Kivity Date: Mon, 6 Aug 2012 15:35:02 +0300 Subject: [PATCH] virtio-mlk: fix use-after-free while handling scsi commands The scsi passthrough handler falls through after completing a request into the failure path, resulting in a use after free. Reprducible by running a guest with aio=native on a block device. Reported-by: Stefan Priebe Signed-off-by: Avi Kivity diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index f21757e..552b3b6 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -254,6 +254,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req) virtio_blk_req_complete(req, status); g_free(req); +return; #else abort(); #endif
[Qemu-devel] [PATCH 08/10] pseries: Add PCI MSI/MSI-X support
This patch implements MSI and MSI-X support for the pseries PCI host bridge. To do this it adds: * A "config_space_address to msi_table" map, since the MSI RTAS calls take a PCI config space address as an identifier. * A MSIX memory region to catch msi_notify()/msix_notiry() from virtio-pci and pass them to the guest via qemu_irq_pulse(). * RTAS call "ibm,change-msi" which sets up MSI vectors for a device. Note that this call may configure and return lesser number of vectors than requested. * RTAS call "ibm,query-interrupt-source-number" which translates MSI vector to interrupt controller (XICS) IRQ number. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- hw/spapr.c |7 +- hw/spapr_pci.c | 245 +++- hw/spapr_pci.h | 15 +++- trace-events |5 ++ 4 files changed, 268 insertions(+), 4 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index 2b66f54..9efed0e 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -41,6 +41,7 @@ #include "hw/spapr_vio.h" #include "hw/spapr_pci.h" #include "hw/xics.h" +#include "hw/msi.h" #include "kvm.h" #include "kvm_ppc.h" @@ -78,6 +79,7 @@ #define SPAPR_PCI_MEM_WIN_ADDR (0x100ULL + 0xA000) #define SPAPR_PCI_MEM_WIN_SIZE 0x2000 #define SPAPR_PCI_IO_WIN_ADDR (0x100ULL + 0x8000) +#define SPAPR_PCI_MSI_WIN_ADDR (0x100ULL + 0x9000) #define PHANDLE_XICP0x @@ -596,6 +598,8 @@ static void ppc_spapr_init(ram_addr_t ram_size, long pteg_shift = 17; char *filename; +msi_supported = true; + spapr = g_malloc0(sizeof(*spapr)); QLIST_INIT(&spapr->phbs); @@ -712,7 +716,8 @@ static void ppc_spapr_init(ram_addr_t ram_size, spapr_create_phb(spapr, "pci", SPAPR_PCI_BUID, SPAPR_PCI_MEM_WIN_ADDR, SPAPR_PCI_MEM_WIN_SIZE, - SPAPR_PCI_IO_WIN_ADDR); + SPAPR_PCI_IO_WIN_ADDR, + SPAPR_PCI_MSI_WIN_ADDR); for (i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 1eb1a7e..1108eea 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -24,6 +24,8 @@ */ #include "hw.h" #include "pci.h" +#include "msi.h" +#include "msix.h" #include "pci_host.h" #include "hw/spapr.h" #include "hw/spapr_pci.h" @@ -33,6 +35,17 @@ #include "hw/pci_internals.h" +/* Copied from the kernel arch/powerpc/platforms/pseries/msi.c */ +#define RTAS_QUERY_FN 0 +#define RTAS_CHANGE_FN 1 +#define RTAS_RESET_FN 2 +#define RTAS_CHANGE_MSI_FN 3 +#define RTAS_CHANGE_MSIX_FN 4 + +/* Interrupt types to return on RTAS_CHANGE_* */ +#define RTAS_TYPE_MSI 1 +#define RTAS_TYPE_MSIX 2 + static sPAPRPHBState *find_phb(sPAPREnvironment *spapr, uint64_t buid) { sPAPRPHBState *phb; @@ -211,6 +224,191 @@ static void rtas_write_pci_config(sPAPREnvironment *spapr, finish_write_pci_config(spapr, 0, addr, size, val, rets); } +/* + * Find an entry with config_addr or returns the empty one if not found AND + * alloc_new is set. + * At the moment the msi_table entries are never released so there is + * no point to look till the end of the list if we need to find the free entry. + */ +static int spapr_msicfg_find(sPAPRPHBState *phb, uint32_t config_addr, + bool alloc_new) +{ +int i; + +for (i = 0; i < SPAPR_MSIX_MAX_DEVS; ++i) { +if (!phb->msi_table[i].nvec) { +break; +} +if (phb->msi_table[i].config_addr == config_addr) { +return i; +} +} +if ((i < SPAPR_MSIX_MAX_DEVS) && alloc_new) { +trace_spapr_pci_msi("Allocating new MSI config", i, config_addr); +return i; +} + +return -1; +} + +/* + * Set MSI/MSIX message data. + * This is required for msi_notify()/msix_notify() which + * will write at the addresses via spapr_msi_write(). + */ +static void spapr_msi_setmsg(PCIDevice *pdev, target_phys_addr_t addr, + bool msix, unsigned req_num) +{ +unsigned i; +MSIMessage msg = { .address = addr, .data = 0 }; + +if (!msix) { +msi_set_message(pdev, msg); +trace_spapr_pci_msi_setup(pdev->name, 0, msg.address); +return; +} + +for (i = 0; i < req_num; ++i) { +msg.address = addr | (i << 2); +msix_set_message(pdev, i, msg); +trace_spapr_pci_msi_setup(pdev->name, i, msg.address); +} +} + +static void rtas_ibm_change_msi(sPAPREnvironment *spapr, +uint32_t token, uint32_t nargs, +target_ulong args, uint32_t nret, +target_ulong rets) +{ +uint32_t config_addr = rtas_ld(args, 0); +uint64_t buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); +unsigned int func = rtas_ld(args, 3); +unsigned int req_num =
[Qemu-devel] [0/10] pseries updates and cleanups
Hi Alex, This series contains all my outstanding pseries updates which aren't dependent on getting a generic patch upstream first. I have a number more which are actually more urgent to get into 1.2, but we need to get some word on the generic patches before I can really push those. In the meantime, if you could pull these various updates and cleanups into ppc-next ready for the 1.2 freeze, that would be great.
[Qemu-devel] [PATCH 07/10] pseries: Add trace event for PCI irqs
From: Alexey Kardashevskiy This adds a trace event in the pseries PCI specific set_irq() function to assist in debugging. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- hw/spapr_pci.c |1 + trace-events |3 +++ 2 files changed, 4 insertions(+) diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 842068f..1eb1a7e 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -235,6 +235,7 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level) */ sPAPRPHBState *phb = opaque; +trace_spapr_pci_lsi_set(phb->busname, irq_num, phb->lsi_table[irq_num].irq); qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level); } diff --git a/trace-events b/trace-events index 6b12f83..191b39e 100644 --- a/trace-events +++ b/trace-events @@ -970,3 +970,6 @@ qxl_render_blit_guest_primary_initialized(void) "" qxl_render_blit(int32_t stride, int32_t left, int32_t right, int32_t top, int32_t bottom) "stride=%d [%d, %d, %d, %d]" qxl_render_guest_primary_resized(int32_t width, int32_t height, int32_t stride, int32_t bytes_pp, int32_t bits_pp) "%dx%d, stride %d, bpp %d, depth %d" qxl_render_update_area_done(void *cookie) "%p" + +# hw/spapr_pci.c +spapr_pci_lsi_set(const char *busname, int pin, uint32_t irq) "%s PIN%d IRQ %u" -- 1.7.10.4
[Qemu-devel] [PATCH 02/10] pseries: Remove extraneous prints
The pseries machine prints several messages to stderr whenever it starts up and another whenever the vm is reset. It's not normal for qemu machines to do this though, so this patch removes them. We can put them back conditional on a DEBUG symbol if we really need them in future. Signed-off-by: David Gibson --- hw/spapr.c | 18 -- 1 file changed, 18 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index ab5a0c2..3a303cd 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -532,8 +532,6 @@ static void spapr_reset(void *opaque) { sPAPREnvironment *spapr = (sPAPREnvironment *)opaque; -fprintf(stderr, "sPAPR reset\n"); - /* flush out the hash table */ memset(spapr->htab, 0, spapr->htab_size); @@ -716,14 +714,6 @@ static void ppc_spapr_init(ram_addr_t ram_size, exit(1); } -fprintf(stderr, "sPAPR memory map:\n"); -fprintf(stderr, "RTAS : 0x%08lx..%08lx\n", -(unsigned long)spapr->rtas_addr, -(unsigned long)(spapr->rtas_addr + spapr->rtas_size - 1)); -fprintf(stderr, "FDT : 0x%08lx..%08lx\n", -(unsigned long)spapr->fdt_addr, -(unsigned long)(spapr->fdt_addr + FDT_MAX_SIZE - 1)); - if (kernel_filename) { uint64_t lowaddr = 0; @@ -739,8 +729,6 @@ static void ppc_spapr_init(ram_addr_t ram_size, kernel_filename); exit(1); } -fprintf(stderr, "Kernel : 0x%08x..%08lx\n", -KERNEL_LOAD_ADDR, KERNEL_LOAD_ADDR + kernel_size - 1); /* load initrd */ if (initrd_filename) { @@ -755,8 +743,6 @@ static void ppc_spapr_init(ram_addr_t ram_size, initrd_filename); exit(1); } -fprintf(stderr, "Ramdisk : 0x%08lx..%08lx\n", -(long)initrd_base, (long)(initrd_base + initrd_size - 1)); } else { initrd_base = 0; initrd_size = 0; @@ -770,10 +756,6 @@ static void ppc_spapr_init(ram_addr_t ram_size, exit(1); } g_free(filename); -fprintf(stderr, "Firmware load: 0x%08x..%08lx\n", -0, fw_size); -fprintf(stderr, "Firmware runtime : 0x%08lx..%08lx\n", -load_limit, (unsigned long)spapr->fdt_addr); spapr->entry_point = 0x100; -- 1.7.10.4
[Qemu-devel] [PATCH 06/10] pseries: Export find_phb() utility function for PCI code
From: Alexey Kardashevskiy The pseries PCI code makes use of an internal find_dev() function which locates a PCIDevice * given a (platform specific) bus ID and device address. Internally this needs to first locate the host bridge on which the device resides based on the bus ID. This patch exposes that host bridge lookup as a separate function, which we will need later in the MSI and VFIO code. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- hw/spapr_pci.c | 32 ++-- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index fcc358e..842068f 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -29,27 +29,39 @@ #include "hw/spapr_pci.h" #include "exec-memory.h" #include +#include "trace.h" #include "hw/pci_internals.h" -static PCIDevice *find_dev(sPAPREnvironment *spapr, - uint64_t buid, uint32_t config_addr) +static sPAPRPHBState *find_phb(sPAPREnvironment *spapr, uint64_t buid) { -int devfn = (config_addr >> 8) & 0xFF; sPAPRPHBState *phb; QLIST_FOREACH(phb, &spapr->phbs, list) { -BusChild *kid; - if (phb->buid != buid) { continue; } +return phb; +} + +return NULL; +} + +static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid, + uint32_t config_addr) +{ +sPAPRPHBState *phb = find_phb(spapr, buid); +BusChild *kid; +int devfn = (config_addr >> 8) & 0xFF; + +if (!phb) { +return NULL; +} -QTAILQ_FOREACH(kid, &phb->host_state.bus->qbus.children, sibling) { -PCIDevice *dev = (PCIDevice *)kid->child; -if (dev->devfn == devfn) { -return dev; -} +QTAILQ_FOREACH(kid, &phb->host_state.bus->qbus.children, sibling) { +PCIDevice *dev = (PCIDevice *)kid->child; +if (dev->devfn == devfn) { +return dev; } } -- 1.7.10.4
[Qemu-devel] [PATCH 04/10] pseries: Separate PCI RTAS setup from common from emulation specific PCI setup
Currently the RTAS functions for handling PCI are registered from the class init code for the PCI host bridge. That sort of makes sense now, but will break in the future when vfio gives us multiple types of host bridge for pseries (emulated and pass-through, at least). The RTAS functions will be common across all host bridge types (and will call out to different places internally depending on the type). So, this patch moves the RTAS registration into its own function called direct from the machine setup code. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- hw/spapr.c |2 ++ hw/spapr_pci.c | 13 - hw/spapr_pci.h |2 ++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index cdc66d1..8b4af62 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -681,6 +681,8 @@ static void ppc_spapr_init(ram_addr_t ram_size, } /* Set up PCI */ +spapr_pci_rtas_init(); + spapr_create_phb(spapr, "pci", SPAPR_PCI_BUID, SPAPR_PCI_MEM_WIN_ADDR, SPAPR_PCI_MEM_WIN_SIZE, diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 65ae8c4..fcc358e 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -359,11 +359,6 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data) sdc->init = spapr_phb_init; dc->props = spapr_phb_properties; - -spapr_rtas_register("read-pci-config", rtas_read_pci_config); -spapr_rtas_register("write-pci-config", rtas_write_pci_config); -spapr_rtas_register("ibm,read-pci-config", rtas_ibm_read_pci_config); -spapr_rtas_register("ibm,write-pci-config", rtas_ibm_write_pci_config); } static TypeInfo spapr_phb_info = { @@ -488,6 +483,14 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, return 0; } +void spapr_pci_rtas_init(void) +{ +spapr_rtas_register("read-pci-config", rtas_read_pci_config); +spapr_rtas_register("write-pci-config", rtas_write_pci_config); +spapr_rtas_register("ibm,read-pci-config", rtas_ibm_read_pci_config); +spapr_rtas_register("ibm,write-pci-config", rtas_ibm_write_pci_config); +} + static void register_types(void) { type_register_static(&spapr_phb_info); diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h index 6bba885..2aee67f 100644 --- a/hw/spapr_pci.h +++ b/hw/spapr_pci.h @@ -63,4 +63,6 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt); +void spapr_pci_rtas_init(void); + #endif /* __HW_SPAPR_PCI_H__ */ -- 1.7.10.4
[Qemu-devel] [PATCH 10/10] pseries: Update SLOF firmware image
This updates SLOF to handle the necessary device tree properties for MSI and MSI-X. Signed-off-by: David Gibson --- pc-bios/README |2 +- pc-bios/slof.bin | Bin 878088 -> 878640 bytes roms/SLOF|2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pc-bios/README b/pc-bios/README index e71bcd0..f4b37d6 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -17,7 +17,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/dgibson/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20120719. + built from git tag qemu-slof-20120731. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin index 320b8f001cf9962318812a5b9109242e210fe499..84ba6b83f3c7fe523cb0b0e73ae8522872d1feef 100644 GIT binary patch delta 970 zcmb7?&rj1}7{}MHWur`EB4Q#5J^>FyEv#cd%oLfCAtXX(Fu02e-P%GE=tfsyBt|@F zSYk|ANO(yQ4szk32}Vh8WXBzdfeU&tWdDHH$iSQUc5D-a9()HPU+b3bFB=G=@<4Cs8-k&`RR8>J6<_>do|MQf3osJONJN z1wjRtg=WSJiI~jB_yjA-iU5^x0zNCsnwbt^JOMpjjQa|x8lPliaYd4c*vTMPJHfQY zCz=``!G0X5$zfU2zz=-c??^LU5(U}<92T0MKDc4}a*&+l6EJdAXnIbFF)gkpo3Kt) zVsSxaWkrKVkfWnlRdK8d|FaRyUPM)!VnTQOLrhB}^e7Yjh%7*Fe^1!~l=0E1sN&L= zX^5%J{q9iT(c?N3D7KERQYW!++~2wU7nam9E`G@={U%bvTm(~51vpp0g*!&K=IFDX ze^Mx4!M|v*sbf4UO`;c{sTTC%BW1f-zWgG0^U5oIGXmy_h%eMR{qiG5eX56edMZQO z2T}Gr{g|u{qu?H1@3>IbTq8jgEYMwKID!VZ?e%D-K-ZHG*HE@V`xqlm!wFG(YXf=jkK(pZ>@EZK0{aaQAGaMtLNCCBR= JwSK90?HATCK#BkW delta 440 zcmdmR!L;Ly=>#*TG>(ZDrp(G>1``WJSlV;HR7_ux!Yekpp4VaHy+!r{=0@h0W~Qcz zX-26@i58}&nYUZfNSOo1`uGISup(uGov5VJB{fYER1GMZx(D%U}3yBkLzs$NS;sRZNhes#fd1jNkS<@8x9)=r;&k41HQ*Bus~_V@Q#w!go}`dyTX&0_kCFRXP; z>>ATEz5;1ij_EHzbeP2SjBl)NOnwH_H+*9?V~XyW{sKsIyM&)^S0$$#er1)Ke(F1`4Aa{k(_egNwPX5}F1XurV3w*3MV`?NVyZv%kVumZ6f o*t+H`6(Abu>w@-%`RqW<0mPg@%mu{U+Z*QdtU1B*d19Rx0DW1U^8f$< diff --git a/roms/SLOF b/roms/SLOF index 7279655..f21f7a3 16 --- a/roms/SLOF +++ b/roms/SLOF @@ -1 +1 @@ -Subproject commit 7279655af2eba855bd2df61303d25abd1eeb2300 +Subproject commit f21f7a3f46b557eb5923f899ce8b4401b3cc6d91 -- 1.7.10.4
[Qemu-devel] [PATCH 09/10] pseries dma: DMA window params added to PHB and DT population changed
From: Alexey Kardashevskiy Previously the only PCI bus supported was the emulated PCI bus with fixed DMA window with start at 0 and size 1GB. As we are going to support PCI pass through which DMA window properties are set by the host kernel, we have to support DMA windows with parameters other than default. This patch adds: 1. DMA window properties to sPAPRPHBState: LIOBN (bus id), start, size of the window. 2. An additional function spapr_dma_dt() to populate DMA window properties in the device tree which simply accepts all the parameters and does not try to guess what kind of IOMMU is given to it. The original spapr_dma_dt() is renamed to spapr_tcet_dma_dt(). Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- hw/spapr.h |4 +++- hw/spapr_iommu.c | 58 ++ hw/spapr_pci.c | 11 +++ hw/spapr_pci.h |4 +++- hw/spapr_vio.c |2 +- 5 files changed, 51 insertions(+), 28 deletions(-) diff --git a/hw/spapr.h b/hw/spapr.h index 76493cb..5d76c5e 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -336,6 +336,8 @@ void spapr_iommu_init(void); DMAContext *spapr_tce_new_dma_context(uint32_t liobn, size_t window_size); void spapr_tce_free(DMAContext *dma); int spapr_dma_dt(void *fdt, int node_off, const char *propname, - DMAContext *dma); + uint32_t liobn, uint64_t window, uint32_t size); +int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, + DMAContext *dma); #endif /* !defined (__HW_SPAPR_H__) */ diff --git a/hw/spapr_iommu.c b/hw/spapr_iommu.c index 388ffa4..53b7317 100644 --- a/hw/spapr_iommu.c +++ b/hw/spapr_iommu.c @@ -216,31 +216,47 @@ void spapr_iommu_init(void) } int spapr_dma_dt(void *fdt, int node_off, const char *propname, - DMAContext *dma) + uint32_t liobn, uint64_t window, uint32_t size) { -if (dma) { -sPAPRTCETable *tcet = DO_UPCAST(sPAPRTCETable, dma, dma); -uint32_t dma_prop[] = {cpu_to_be32(tcet->liobn), - 0, 0, - 0, cpu_to_be32(tcet->window_size)}; -int ret; - -ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-address-cells", 2); -if (ret < 0) { -return ret; -} +uint32_t dma_prop[5]; +int ret; + +dma_prop[0] = cpu_to_be32(liobn); +dma_prop[1] = cpu_to_be32(window >> 32); +dma_prop[2] = cpu_to_be32(window & 0x); +dma_prop[3] = 0; /* window size is 32 bits */ +dma_prop[4] = cpu_to_be32(size); + +ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-address-cells", 2); +if (ret < 0) { +return ret; +} -ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-size-cells", 2); -if (ret < 0) { -return ret; -} +ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-size-cells", 2); +if (ret < 0) { +return ret; +} -ret = fdt_setprop(fdt, node_off, propname, dma_prop, - sizeof(dma_prop)); -if (ret < 0) { -return ret; -} +ret = fdt_setprop(fdt, node_off, propname, dma_prop, sizeof(dma_prop)); +if (ret < 0) { +return ret; } return 0; } + +int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, + DMAContext *iommu) +{ +if (!iommu) { +return 0; +} + +if (iommu->translate == spapr_tce_translate) { +sPAPRTCETable *tcet = DO_UPCAST(sPAPRTCETable, dma, iommu); +return spapr_dma_dt(fdt, node_off, propname, +tcet->liobn, 0, tcet->window_size); +} + +return -1; +} diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 1108eea..0e0ab64 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -518,7 +518,6 @@ static int spapr_phb_init(SysBusDevice *s) char *namebuf; int i; PCIBus *bus; -uint32_t liobn; phb->dtbusname = g_strdup_printf("pci@%" PRIx64, phb->buid); namebuf = alloca(strlen(phb->dtbusname) + 32); @@ -570,8 +569,10 @@ static int spapr_phb_init(SysBusDevice *s) PCI_DEVFN(0, 0), PCI_NUM_PINS); phb->host_state.bus = bus; -liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16); -phb->dma = spapr_tce_new_dma_context(liobn, 0x4000); +phb->dma_liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16); +phb->dma_window_start = 0; +phb->dma_window_size = 0x4000; +phb->dma = spapr_tce_new_dma_context(phb->dma_liobn, phb->dma_window_size); pci_setup_iommu(bus, spapr_pci_dma_context_fn, phb); QLIST_INSERT_HEAD(&spapr->phbs, phb, list); @@ -729,7 +730,9 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map, sizeof(interrupt_map))); -spapr_dma_dt(fdt, bus_off, "ibm,dma-window", phb->dma); +spapr_dma_dt(fdt, bus_off, "ib
[Qemu-devel] [PATCH v8 6/6] allower the user to disable pv event support
Signed-off-by: Wen Congyang --- hw/pc_piix.c|6 +- qemu-config.c |4 qemu-options.hx |3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 4af8403..9b877a7 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -151,6 +151,8 @@ static void pc_init1(MemoryRegion *system_memory, MemoryRegion *pci_memory; MemoryRegion *rom_memory; void *fw_cfg = NULL; +QemuOptsList *list = qemu_find_opts("machine"); +bool enable_pv_event; pc_cpus_init(cpu_model); @@ -289,8 +291,10 @@ static void pc_init1(MemoryRegion *system_memory, pc_pci_device_init(pci_bus); } +enable_pv_event = qemu_opt_get_bool(QTAILQ_FIRST(&list->head), +"enable_pv_event", false); #ifdef KVM_PV_EVENT_PORT -if (kvm_enabled()) { +if (kvm_enabled() && enable_pv_event) { kvm_pv_event_init(isa_bus); } #endif diff --git a/qemu-config.c b/qemu-config.c index 5c3296b..5ec5aa9 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -595,6 +595,10 @@ static QemuOptsList qemu_machine_opts = { .name = "dt_compatible", .type = QEMU_OPT_STRING, .help = "Overrides the \"compatible\" property of the dt root node", +}, { +.name = "enable_pv_event", +.type = QEMU_OPT_BOOL, +.help = "handle pv event" }, { /* End of list */ } }, diff --git a/qemu-options.hx b/qemu-options.hx index 5e7d0dc..94d7865 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -37,7 +37,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ "property accel=accel1[:accel2[:...]] selects accelerator\n" "supported accelerators are kvm, xen, tcg (default: tcg)\n" "kernel_irqchip=on|off controls accelerated irqchip support\n" -"kvm_shadow_mem=size of KVM shadow MMU\n", +"kvm_shadow_mem=size of KVM shadow MMU\n" +"enable_pv_event=on|off controls pv event support\n", QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] -- 1.7.1
[Qemu-devel] [PATCH v8 5/6] introduce a new qom device to deal with panicked event
If the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new qom device kvm_pv_ioport to listen this I/O port, and deal with panicked event according to panicked_action's value. The possible actions are: 1. emit QEVENT_GUEST_PANICKED only 2. emit QEVENT_GUEST_PANICKED and pause the guest 3. emit QEVENT_GUEST_PANICKED and poweroff the guest 4. emit QEVENT_GUEST_PANICKED and reset the guest I/O ports does not work for some targets(for example: s390). And you can implement another qom device, and include it's code into pv_event.c for such target. Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked. Signed-off-by: Wen Congyang --- hw/kvm/Makefile.objs |2 +- hw/kvm/pv_event.c| 109 ++ hw/kvm/pv_ioport.c | 93 ++ hw/pc_piix.c |9 kvm.h|2 + 5 files changed, 214 insertions(+), 1 deletions(-) create mode 100644 hw/kvm/pv_event.c create mode 100644 hw/kvm/pv_ioport.c diff --git a/hw/kvm/Makefile.objs b/hw/kvm/Makefile.objs index 226497a..23e3b30 100644 --- a/hw/kvm/Makefile.objs +++ b/hw/kvm/Makefile.objs @@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pv_event.o diff --git a/hw/kvm/pv_event.c b/hw/kvm/pv_event.c new file mode 100644 index 000..8897237 --- /dev/null +++ b/hw/kvm/pv_event.c @@ -0,0 +1,109 @@ +/* + * QEMU KVM support, paravirtual event device + * + * Copyright Fujitsu, Corp. 2012 + * + * Authors: + * Wen Congyang + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Possible values for action parameter. */ +#define PANICKED_REPORT 1 /* emit QEVENT_GUEST_PANICKED only */ +#define PANICKED_PAUSE 2 /* emit QEVENT_GUEST_PANICKED and pause VM */ +#define PANICKED_POWEROFF 3 /* emit QEVENT_GUEST_PANICKED and quit VM */ +#define PANICKED_RESET 4 /* emit QEVENT_GUEST_PANICKED and reset VM */ + +#define PV_EVENT_DRIVER "kvm_pv_event" + +struct pv_event_action { +char *panicked_action; +int panicked_action_value; +}; + +#define DEFINE_PV_EVENT_PROPERTIES(_state, _conf) \ +DEFINE_PROP_STRING("panicked_action", _state, _conf.panicked_action) + +static void panicked_mon_event(const char *action) +{ +QObject *data; + +data = qobject_from_jsonf("{ 'action': %s }", action); +monitor_protocol_event(QEVENT_GUEST_PANICKED, data); +qobject_decref(data); +} + +static void panicked_perform_action(uint32_t panicked_action) +{ +switch (panicked_action) { +case PANICKED_REPORT: +panicked_mon_event("report"); +break; + +case PANICKED_PAUSE: +panicked_mon_event("pause"); +vm_stop(RUN_STATE_GUEST_PANICKED); +break; + +case PANICKED_POWEROFF: +panicked_mon_event("poweroff"); +qemu_system_shutdown_request(); +break; +case PANICKED_RESET: +panicked_mon_event("reset"); +qemu_system_reset_request(); +break; +} +} + +static uint64_t supported_event(void) +{ +return 1 << KVM_PV_FEATURE_PANICKED; +} + +static void handle_event(int event, struct pv_event_action *conf) +{ +if (event == KVM_PV_EVENT_PANICKED) { +panicked_perform_action(conf->panicked_action_value); +} +} + +static int pv_event_init(struct pv_event_action *conf) +{ +if (!conf->panicked_action) { +conf->panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf->panicked_action, "none") == 0) { +conf->panicked_action_value = PANICKED_REPORT; +} else if (strcasecmp(conf->panicked_action, "pause") == 0) { +conf->panicked_action_value = PANICKED_PAUSE; +} else if (strcasecmp(conf->panicked_action, "poweroff") == 0) { +conf->panicked_action_value = PANICKED_POWEROFF; +} else if (strcasecmp(conf->panicked_action, "reset") == 0) { +conf->panicked_action_value = PANICKED_RESET; +} else { +return -1; +} + +return 0; +} + +#if defined(KVM_PV_EVENT_PORT) + +#include "pv_ioport.c" + +#else +void kvm_pv_event_init(void *opaque) +{ +} +#endif diff --git a/hw/kvm/pv_ioport.c b/hw/kvm/pv_ioport.c new file mode 100644 index 000..c2ed6b5 --- /dev/null +++ b/hw/kvm/pv_ioport.c @@ -0,0 +1,93 @@ +/* + * QEMU KVM support, paravirtual I/O port device + * + * Copyright Fujitsu, Corp. 2012 + * + * Authors: + * Wen Congyang + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#in
[Qemu-devel] [PATCH v8 4/6] add a new qevent: QEVENT_GUEST_PANICKED
This event will be emited when the guest is panicked. Signed-off-by: Wen Congyang --- monitor.c |1 + monitor.h |1 + 2 files changed, 2 insertions(+), 0 deletions(-) diff --git a/monitor.c b/monitor.c index 49dccfe..c892b7e 100644 --- a/monitor.c +++ b/monitor.c @@ -458,6 +458,7 @@ static const char *monitor_event_names[] = { [QEVENT_SUSPEND] = "SUSPEND", [QEVENT_WAKEUP] = "WAKEUP", [QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE", +[QEVENT_GUEST_PANICKED] = "GUEST_PANICKED", }; QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX) diff --git a/monitor.h b/monitor.h index 5f4de1b..cb7de8c 100644 --- a/monitor.h +++ b/monitor.h @@ -42,6 +42,7 @@ typedef enum MonitorEvent { QEVENT_SUSPEND, QEVENT_WAKEUP, QEVENT_BALLOON_CHANGE, +QEVENT_GUEST_PANICKED, /* Add to 'monitor_event_names' array in monitor.c when * defining new events here */ -- 1.7.1
[Qemu-devel] [PATCH v8 3/6] add a new runstate: RUN_STATE_GUEST_PANICKED
The guest will be in this state when it is panicked. Signed-off-by: Wen Congyang --- qapi-schema.json |6 +- qmp.c|3 ++- vl.c |7 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index cddf63a..3f699ff 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -119,11 +119,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', -'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } +'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', +'guest-panicked' ] } ## # @StatusInfo: diff --git a/qmp.c b/qmp.c index a111dff..3b0c9bc 100644 --- a/qmp.c +++ b/qmp.c @@ -148,7 +148,8 @@ void qmp_cont(Error **errp) error_set(errp, QERR_MIGRATION_EXPECTED); return; } else if (runstate_check(RUN_STATE_INTERNAL_ERROR) || - runstate_check(RUN_STATE_SHUTDOWN)) { + runstate_check(RUN_STATE_SHUTDOWN) || + runstate_check(RUN_STATE_GUEST_PANICKED)) { error_set(errp, QERR_RESET_REQUIRED); return; } else if (runstate_check(RUN_STATE_SUSPENDED)) { diff --git a/vl.c b/vl.c index 856e089..55dcdf2 100644 --- a/vl.c +++ b/vl.c @@ -363,6 +363,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM }, { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN }, { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG }, +{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, @@ -377,6 +378,9 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, +{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, }; @@ -1530,7 +1534,8 @@ static bool main_loop_should_exit(void) qemu_system_reset(VMRESET_REPORT); resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || -runstate_check(RUN_STATE_SHUTDOWN)) { +runstate_check(RUN_STATE_SHUTDOWN) || +runstate_check(RUN_STATE_GUEST_PANICKED)) { bdrv_iterate(iostatus_bdrv_it, NULL); vm_start(); } -- 1.7.1
[Qemu-devel] [PATCH v8 2/6] kvm: Update kernel headers
Corresponding kvm.git hash: 439793d4 with my patch for kvm --- linux-headers/asm-s390/kvm.h |2 +- linux-headers/asm-s390/kvm_para.h |2 +- linux-headers/asm-x86/kvm.h |1 + linux-headers/asm-x86/kvm_para.h |9 + linux-headers/linux/kvm.h |3 +++ linux-headers/linux/kvm_para.h|6 ++ 6 files changed, 21 insertions(+), 2 deletions(-) diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h index bdcbe0f..d25da59 100644 --- a/linux-headers/asm-s390/kvm.h +++ b/linux-headers/asm-s390/kvm.h @@ -1,7 +1,7 @@ #ifndef __LINUX_KVM_S390_H #define __LINUX_KVM_S390_H /* - * asm-s390/kvm.h - KVM s390 specific structures and definitions + * KVM s390 specific structures and definitions * * Copyright IBM Corp. 2008 * diff --git a/linux-headers/asm-s390/kvm_para.h b/linux-headers/asm-s390/kvm_para.h index 8e2dd67..870051f 100644 --- a/linux-headers/asm-s390/kvm_para.h +++ b/linux-headers/asm-s390/kvm_para.h @@ -1,5 +1,5 @@ /* - * asm-s390/kvm_para.h - definition for paravirtual devices on s390 + * definition for paravirtual devices on s390 * * Copyright IBM Corp. 2008 * diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h index e7d1c19..246617e 100644 --- a/linux-headers/asm-x86/kvm.h +++ b/linux-headers/asm-x86/kvm.h @@ -12,6 +12,7 @@ /* Select x86 specific features in */ #define __KVM_HAVE_PIT #define __KVM_HAVE_IOAPIC +#define __KVM_HAVE_IRQ_LINE #define __KVM_HAVE_DEVICE_ASSIGNMENT #define __KVM_HAVE_MSI #define __KVM_HAVE_USER_NMI diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h index f2ac46a..53aca59 100644 --- a/linux-headers/asm-x86/kvm_para.h +++ b/linux-headers/asm-x86/kvm_para.h @@ -22,6 +22,7 @@ #define KVM_FEATURE_CLOCKSOURCE23 #define KVM_FEATURE_ASYNC_PF 4 #define KVM_FEATURE_STEAL_TIME 5 +#define KVM_FEATURE_PV_EOI 6 /* The last 8 bits are used to indicate how to interpret the flags field * in pvclock structure. If no bits are set, all flags are ignored. @@ -37,6 +38,7 @@ #define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01 #define MSR_KVM_ASYNC_PF_EN 0x4b564d02 #define MSR_KVM_STEAL_TIME 0x4b564d03 +#define MSR_KVM_PV_EOI_EN 0x4b564d04 struct kvm_steal_time { __u64 steal; @@ -89,5 +91,12 @@ struct kvm_vcpu_pv_apf_data { __u32 enabled; }; +#define KVM_PV_EOI_BIT 0 +#define KVM_PV_EOI_MASK (0x1 << KVM_PV_EOI_BIT) +#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK +#define KVM_PV_EOI_DISABLED 0x0 + +#define KVM_PV_EVENT_PORT (0x505UL) + #endif /* _ASM_X86_KVM_PARA_H */ diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 5a9d4e3..4b9e575 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -617,6 +617,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_SIGNAL_MSI 77 #define KVM_CAP_PPC_GET_SMMU_INFO 78 #define KVM_CAP_S390_COW 79 +#define KVM_CAP_PPC_ALLOC_HTAB 80 #ifdef KVM_CAP_IRQ_ROUTING @@ -828,6 +829,8 @@ struct kvm_s390_ucas_mapping { #define KVM_SIGNAL_MSI_IOW(KVMIO, 0xa5, struct kvm_msi) /* Available with KVM_CAP_PPC_GET_SMMU_INFO */ #define KVM_PPC_GET_SMMU_INFO_IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info) +/* Available with KVM_CAP_PPC_ALLOC_HTAB */ +#define KVM_PPC_ALLOCATE_HTAB_IOWR(KVMIO, 0xa7, __u32) /* * ioctls for vcpu fds diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h index 7bdcf93..f6be0bb 100644 --- a/linux-headers/linux/kvm_para.h +++ b/linux-headers/linux/kvm_para.h @@ -20,6 +20,12 @@ #define KVM_HC_FEATURES3 #define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 + /* * hypercalls use architecture specific */ -- 1.7.1
[Qemu-devel] [PATCH v8 1/6] start vm after reseting it
The guest should run after reseting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED. We don't set runstate to RUN_STATE_PAUSED when reseting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED). Signed-off-by: Wen Congyang --- block.h |2 ++ qmp.c |2 +- vl.c|7 --- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/block.h b/block.h index 650d872..29449bd 100644 --- a/block.h +++ b/block.h @@ -338,6 +338,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); void bdrv_set_in_use(BlockDriverState *bs, int in_use); int bdrv_in_use(BlockDriverState *bs); +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs); + enum BlockAcctType { BDRV_ACCT_READ, BDRV_ACCT_WRITE, diff --git a/qmp.c b/qmp.c index fee9fb2..a111dff 100644 --- a/qmp.c +++ b/qmp.c @@ -125,7 +125,7 @@ SpiceInfo *qmp_query_spice(Error **errp) }; #endif -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs) { bdrv_iostatus_reset(bs); } diff --git a/vl.c b/vl.c index e71cb30..856e089 100644 --- a/vl.c +++ b/vl.c @@ -333,7 +333,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH }, -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING }, @@ -366,7 +366,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED }, @@ -1531,7 +1531,8 @@ static bool main_loop_should_exit(void) resume_all_vcpus(); if (runstate_check(RUN_STATE_INTERNAL_ERROR) || runstate_check(RUN_STATE_SHUTDOWN)) { -runstate_set(RUN_STATE_PAUSED); +bdrv_iterate(iostatus_bdrv_it, NULL); +vm_start(); } } if (qemu_powerdown_requested()) { -- 1.7.1
[Qemu-devel] [PATCH v8] kvm: notify host when the guest is panicked
We can know the guest is panicked when the guest runs on xen. But we do not have such feature on kvm. Another purpose of this feature is: management app(for example: libvirt) can do auto dump when the guest is panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked. We have three solutions to implement this feature: 1. use vmcall 2. use I/O port 3. use virtio-serial. We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is: 1. it is easier to implememt 2. it does not depend any virtual device 3. it can work when starting the kernel Signed-off-by: Wen Congyang --- Documentation/virtual/kvm/pv_event.txt | 32 arch/ia64/include/asm/kvm_para.h | 14 ++ arch/powerpc/include/asm/kvm_para.h| 14 ++ arch/s390/include/asm/kvm_para.h | 14 ++ arch/x86/include/asm/kvm_para.h| 27 +++ arch/x86/kernel/kvm.c | 25 + include/linux/kvm_para.h | 23 +++ 7 files changed, 149 insertions(+), 0 deletions(-) create mode 100644 Documentation/virtual/kvm/pv_event.txt diff --git a/Documentation/virtual/kvm/pv_event.txt b/Documentation/virtual/kvm/pv_event.txt new file mode 100644 index 000..0ebc890 --- /dev/null +++ b/Documentation/virtual/kvm/pv_event.txt @@ -0,0 +1,32 @@ +The KVM paravirtual event interface += + +Initializing the paravirtual event interface +== +kvm_pv_event_init() +Argiments: + None + +Return Value: + 0 : The guest kernel can't use paravirtual event interface. + -1: The guest kernel can use paravirtual event interface. + +Querying whether the event can be ejected +== +kvm_pv_has_feature() +Arguments: + feature: The bit value of this paravirtual event to query + +Return Value: + 0: The guest kernel can't eject this paravirtual event. + 1: The guest kernel can eject this paravirtual event. + + +Ejecting paravirtual event +== +kvm_pv_eject_event() +Arguments: + event: The event to be ejected. + +Return Value: + None diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h index 2019cb9..b5ec658 100644 --- a/arch/ia64/include/asm/kvm_para.h +++ b/arch/ia64/include/asm/kvm_para.h @@ -31,6 +31,20 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + #endif #endif diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h index c18916b..01b98c7 100644 --- a/arch/powerpc/include/asm/kvm_para.h +++ b/arch/powerpc/include/asm/kvm_para.h @@ -211,6 +211,20 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + #endif /* __KERNEL__ */ #endif /* __POWERPC_KVM_PARA_H__ */ diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index da44867..00ce058 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h @@ -154,6 +154,20 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init(void) +{ + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + return 0; +} + +static inline void kvm_arch_pv_eject_event(unsigned int event) +{ +} + #endif #endif /* __S390_KVM_PARA_H */ diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 2f7712e..7d297f0 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -96,8 +96,11 @@ struct kvm_vcpu_pv_apf_data { #define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK #define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) + #ifdef __KERNEL__ #include +#include extern void kvmclock_init(void); extern int kvm_register_clock(char *txt); @@ -228,6 +231,30 @@ static inline void kvm_disable_steal_time(void) } #endif +static inline int kvm_arch_pv_event_init(void) +{ + if (!request_region(KVM_PV_EVENT_PORT, 1, "KVM_PV_EVENT")) + return -1; + + return 0; +} + +static inline unsigned int kvm_arch_pv_features(void) +{ + unsigned int features = inl(KVM_PV_EVENT_PORT); + + /* Reading from an invalid I/O port will return -1 */ + if (features == ~0) + features = 0; + + return features; +} + +
[Qemu-devel] [PATCH 03/10] pseries: Rework irq assignment to avoid carrying qemu_irqs around
Currently, the interfaces in the pseries machine code for assignment and setup of interrupts pass around qemu_irq objects. That was done in an attempt not to be too closely linked to the specific XICS interrupt controller. However interactions with the device tree setup made that attempt rather futile, and XICS is part of the PAPR spec anyway, so this really just meant we had to carry both the qemu_irq pointers and the XICS irq numbers around. This mess will just get worse when we add upcoming PCI MSI support, since that will require tracking a bunch more interrupt. Therefore, this patch reworks the spapr code to just use XICS irq numbers (roughly equivalent to GSIs on x86) and only retrieve the qemu_irq pointers from the XICS code when we need them (a trivial lookup). This is a reworked and generalized version of an earlier spapr_pci specific patch from Alexey Kardashevskiy. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- hw/spapr.c | 18 +++--- hw/spapr.h | 11 +-- hw/spapr_llan.c |2 +- hw/spapr_pci.c | 14 ++ hw/spapr_pci.h |8 ++-- hw/spapr_vio.c | 12 ++-- hw/spapr_vio.h |8 ++-- hw/spapr_vty.c |2 +- hw/xics.c | 12 +--- hw/xics.h |5 +++-- 10 files changed, 50 insertions(+), 42 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index 3a303cd..cdc66d1 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -83,11 +83,9 @@ sPAPREnvironment *spapr; -qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num, -enum xics_irq_type type) +int spapr_allocate_irq(int hint, enum xics_irq_type type) { -uint32_t irq; -qemu_irq qirq; +int irq; if (hint) { irq = hint; @@ -96,16 +94,14 @@ qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num, irq = spapr->next_irq++; } -qirq = xics_assign_irq(spapr->icp, irq, type); -if (!qirq) { -return NULL; +/* Configure irq type */ +if (!xics_get_qirq(spapr->icp, irq)) { +return 0; } -if (irq_num) { -*irq_num = irq; -} +xics_set_irq_type(spapr->icp, irq, type); -return qirq; +return irq; } static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr) diff --git a/hw/spapr.h b/hw/spapr.h index 9153f29..c5de18d 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -288,17 +288,16 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); target_ulong spapr_hypercall(CPUPPCState *env, target_ulong opcode, target_ulong *args); -qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num, -enum xics_irq_type type); +int spapr_allocate_irq(int hint, enum xics_irq_type type); -static inline qemu_irq spapr_allocate_msi(uint32_t hint, uint32_t *irq_num) +static inline int spapr_allocate_msi(int hint) { -return spapr_allocate_irq(hint, irq_num, XICS_MSI); +return spapr_allocate_irq(hint, XICS_MSI); } -static inline qemu_irq spapr_allocate_lsi(uint32_t hint, uint32_t *irq_num) +static inline int spapr_allocate_lsi(int hint) { -return spapr_allocate_irq(hint, irq_num, XICS_LSI); +return spapr_allocate_irq(hint, XICS_LSI); } static inline uint32_t rtas_ld(target_ulong phys, int n) diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c index 01e54f3..bd3f131 100644 --- a/hw/spapr_llan.c +++ b/hw/spapr_llan.c @@ -169,7 +169,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf, } if (sdev->signal_state & 1) { -qemu_irq_pulse(sdev->qirq); +qemu_irq_pulse(spapr_vio_qirq(sdev)); } return size; diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 2913540..65ae8c4 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -223,7 +223,7 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level) */ sPAPRPHBState *phb = opaque; -qemu_set_irq(phb->lsi_table[irq_num].qirq, level); +qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level); } static uint64_t spapr_io_read(void *opaque, target_phys_addr_t addr, @@ -329,16 +329,14 @@ static int spapr_phb_init(SysBusDevice *s) /* Initialize the LSI table */ for (i = 0; i < PCI_NUM_PINS; i++) { -qemu_irq qirq; -uint32_t num; +uint32_t irq; -qirq = spapr_allocate_lsi(0, &num); -if (!qirq) { +irq = spapr_allocate_lsi(0); +if (!irq) { return -1; } -phb->lsi_table[i].dt_irq = num; -phb->lsi_table[i].qirq = qirq; +phb->lsi_table[i].irq = irq; } return 0; @@ -477,7 +475,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, irqmap[2] = 0; irqmap[3] = cpu_to_be32(j+1); irqmap[4] = cpu_to_be32(xics_phandle); -irqmap[5] = cpu_to_be32(phb->lsi_table[lsi_num].dt_irq); +irqmap[5] = cpu_to_be32(phb->lsi_table[lsi_n
[Qemu-devel] [PATCH 05/10] pseries: added allocator for a block of IRQs
From: Alexey Kardashevskiy The patch adds a simple helper which allocates a consecutive sequence of IRQs calling spapr_allocate_irq for each and checks that allocated IRQs go consequently. The patch is required for upcoming support of MSI/MSIX on POWER. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- hw/spapr.c | 26 ++ hw/spapr.h |1 + 2 files changed, 27 insertions(+) diff --git a/hw/spapr.c b/hw/spapr.c index 8b4af62..2b66f54 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -104,6 +104,32 @@ int spapr_allocate_irq(int hint, enum xics_irq_type type) return irq; } +/* Allocate block of consequtive IRQs, returns a number of the first */ +int spapr_allocate_irq_block(int num, enum xics_irq_type type) +{ +int first = -1; +int i; + +for (i = 0; i < num; ++i) { +int irq; + +irq = spapr_allocate_irq(0, type); +if (!irq) { +return -1; +} + +if (0 == i) { +first = irq; +} + +/* If the above doesn't create a consecutive block then that's + * an internal bug */ +assert(irq == (first + i)); +} + +return first; +} + static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr) { int ret = 0, offset; diff --git a/hw/spapr.h b/hw/spapr.h index c5de18d..76493cb 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -289,6 +289,7 @@ target_ulong spapr_hypercall(CPUPPCState *env, target_ulong opcode, target_ulong *args); int spapr_allocate_irq(int hint, enum xics_irq_type type); +int spapr_allocate_irq_block(int num, enum xics_irq_type type); static inline int spapr_allocate_msi(int hint) { -- 1.7.10.4
Re: [Qemu-devel] [PATCH 2/2] pseries: Use new hook to correct reset sequence
On Wed, Aug 08, 2012 at 12:32:39AM +0200, Andreas Färber wrote: > Am 08.08.2012 00:02, schrieb Benjamin Herrenschmidt: > > On Fri, 2012-08-03 at 17:01 +0200, Andreas Färber wrote: > >> > >> I have posted a suggestion where CPU reset is triggered by "the > >> machine > >> as an abstract concept" (needs a bit of tweaking still, but the > >> general > >> idea is there). > >> Based on that, shouldn't it be rather easy to add a Notifier similar > >> to > >> "machine init done" that lets individual machines do post-reset setup? > >> I.e. not have QEMUMachine trigger and control the reset. > >> > > > > Note that we really want pre and post reset vs the device reset. > > > > That's why the machine should be the one in charge. The top level of the > > reset sequencing is -not- the CPU, it's the machine. All machines (or > > SoCs) have some kind of reset controller and provide facilities for > > resetting individual devices, busses, processor cores the global > > "system" reset (when it exists) itself might have interesting ordering > > or sequencing requirements. > > > > Now, to fix our immediate problem on ppc for 1.2 the hook proposed by > > Anthony for which David sent a patch does the job just fine, it allows > > us to clean out all our iommu tables before the device-reset, meaning > > that in-flights DMA cannot overwrite the various "files" (SLOF image > > etc that are auto-loaded via reset handlers implicitely created by > > load_image_targphys), and we can then do some post-initializations as > > well to get things ready for a restart (rebuild the device-tree, etc...) > > That's all good, except for embedded machines without such implicit > reset handling. It does contradict the "a machine is just a config file, > setting up QOM objects" concept, but I was not the one to push that! :) > > What I was thinking about however were those mentioned individual cores > being reset using cpu_reset(). If we want to piggy-back some > machine-specific register initialization for individual CPUStates then > QEMUMachine::reset is not going to be enough because it only gets > triggered for complete system reset. My suggestion was thus to just call > cpu_reset() in your QEMUMachine::reset and have cpu_reset() take care of > its initialization wherever called from. Any of these solutions are easy > to implement for 1.2 if agreement is reached what people want. So, I more or less reaslied that myself and my new version of the reset patch (which I expect to send out later today) kind of does that. I no longer do the machine specific CPU state setup from the QEMUMachine::reset, it's done from the per-cpu reset handler. The QEMUMachine::reset just does the special setup that's only for the CPU0 entry conditions, which *is* specific to a full system reset (not that I think we can get an individual CPU reset on pseries, anyway). > What I am missing from Anthony's side is some communication to machine > maintainers on the course to adopt before applying random patches. Right > now x86 and ppc are moving into opposite directions and arm, mips, etc. > maintainers may not even be aware of ongoing changes, and there's a > pending uc32 machine that should be reviewed in this light. So.. having the CPU reset at the top of the tree definitely makes no sense - if nothing else, *which* cpu when there's more than one. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Re: [Qemu-devel] [PATCH 2/2] pseries: Use new hook to correct reset sequence
On Aug 7, 2012 5:32 PM, "Andreas Färber" wrote: > > Am 08.08.2012 00:02, schrieb Benjamin Herrenschmidt: > > On Fri, 2012-08-03 at 17:01 +0200, Andreas Färber wrote: > >> > >> I have posted a suggestion where CPU reset is triggered by "the > >> machine > >> as an abstract concept" (needs a bit of tweaking still, but the > >> general > >> idea is there). > >> Based on that, shouldn't it be rather easy to add a Notifier similar > >> to > >> "machine init done" that lets individual machines do post-reset setup? > >> I.e. not have QEMUMachine trigger and control the reset. > >> > > > > Note that we really want pre and post reset vs the device reset. > > > > That's why the machine should be the one in charge. The top level of the > > reset sequencing is -not- the CPU, it's the machine. All machines (or > > SoCs) have some kind of reset controller and provide facilities for > > resetting individual devices, busses, processor cores the global > > "system" reset (when it exists) itself might have interesting ordering > > or sequencing requirements. > > > > Now, to fix our immediate problem on ppc for 1.2 the hook proposed by > > Anthony for which David sent a patch does the job just fine, it allows > > us to clean out all our iommu tables before the device-reset, meaning > > that in-flights DMA cannot overwrite the various "files" (SLOF image > > etc that are auto-loaded via reset handlers implicitely created by > > load_image_targphys), and we can then do some post-initializations as > > well to get things ready for a restart (rebuild the device-tree, etc...) > > That's all good, except for embedded machines without such implicit > reset handling. It does contradict the "a machine is just a config file, > setting up QOM objects" concept, but I was not the one to push that! :) > I will be without a proper email client for 24 hours so I'll keep this brief for now. What Ben et al are trying to model is something that exists outside of the model of virtual hardware that QOM is designed for. Since they are trying to model something that exists outside the scope of virtual hardware, they need something that exists at a higher level. They need a per machine hook before and after devices are created. This is okay and it turns out it can be handy for other machines too that do similiar could not exist outside of a simulator features. Regards, Anthony Liguori > What I was thinking about however were those mentioned individual cores > being reset using cpu_reset(). If we want to piggy-back some > machine-specific register initialization for individual CPUStates then > QEMUMachine::reset is not going to be enough because it only gets > triggered for complete system reset. My suggestion was thus to just call > cpu_reset() in your QEMUMachine::reset and have cpu_reset() take care of > its initialization wherever called from. Any of these solutions are easy > to implement for 1.2 if agreement is reached what people want. > > What I am missing from Anthony's side is some communication to machine > maintainers on the course to adopt before applying random patches. Right > now x86 and ppc are moving into opposite directions and arm, mips, etc. > maintainers may not even be aware of ongoing changes, and there's a > pending uc32 machine that should be reviewed in this light. > > Cheers, > Andreas > > -- > SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany > GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 1/2] qom: Reimplement Interfaces
Hi All, We seem to be having difficulty getting a review/merge on this patch. I have sent two series, two pings and a PULL, with only a single reply from P. Maydell asking for other reviewers to weigh in: - on July 17 P. Maydell wrote --- I guess I should mention that I'm assuming somebody else is going to review this patchset. It looks generally OK to me but whether the stream API has the details of QOM interface use right is a bit out of my area of expertise. -- PMM What needs to happen (and what can I do) to make this series go through? Edgar has reviewed P2 this morning and I have already remade the series, but my primary concern is this patch, considering it touches the core QOM infrastructure. I have tested this patch on target i386 with no obvious breakages along with testing on the the embedded platforms we work with (Zynq and MB). Regards, Peter On Mon, 2012-08-06 at 13:07 +1000, Peter A. G. Crosthwaite wrote: > From: Anthony Liguori > > The current implementation of Interfaces is poorly designed. Each interface > that an object implements ends up being an object that's tracked by the > implementing object. There's all sorts of gymnastics to deal with casting > between these objects. > > But an interface shouldn't be associated with an Object. Interfaces are > global > to a class. This patch moves all Interface knowledge to ObjectClass > eliminating > the relationship between Object and Interfaces. > > Interfaces are now abstract (as they should be) but this is okay. Interfaces > essentially act as additional parents for the classes and are treated as such. > > With this new implementation, we should fully support derived interfaces > including reimplementing an inherited interface. > > PC: Rebased against qom-next merge Jun-2012. > > PC: Removed replication of cast logic for interfaces, i.e. there is only > one cast function - object_dynamic_cast() (and object_dynamic_cast_assert()) > > Signed-off-by: Anthony Liguori > Signed-off-by: Peter A. G. Crosthwaite > --- > include/qemu/object.h | 46 +++ > qom/object.c | 220 > +++-- > 2 files changed, 116 insertions(+), 150 deletions(-) > > diff --git a/include/qemu/object.h b/include/qemu/object.h > index 8b17776..cc75fee 100644 > --- a/include/qemu/object.h > +++ b/include/qemu/object.h > @@ -239,6 +239,7 @@ struct ObjectClass > { > /*< private >*/ > Type type; > +GSList *interfaces; > }; > > /** > @@ -260,7 +261,6 @@ struct Object > { > /*< private >*/ > ObjectClass *class; > -GSList *interfaces; > QTAILQ_HEAD(, ObjectProperty) properties; > uint32_t ref; > Object *parent; > @@ -387,6 +387,16 @@ struct TypeInfo > OBJECT_CLASS_CHECK(class, object_get_class(OBJECT(obj)), name) > > /** > + * InterfaceInfo: > + * @type: The name of the interface. > + * > + * The information associated with an interface. > + */ > +struct InterfaceInfo { > +const char *type; > +}; > + > +/** > * InterfaceClass: > * @parent_class: the base class > * > @@ -396,26 +406,30 @@ struct TypeInfo > struct InterfaceClass > { > ObjectClass parent_class; > +/*< private >*/ > +ObjectClass *concrete_class; > }; > > +#define TYPE_INTERFACE "interface" > + > /** > - * InterfaceInfo: > - * @type: The name of the interface. > - * @interface_initfn: This method is called during class initialization and > is > - * used to initialize an interface associated with a class. This function > - * should initialize any default virtual functions for a class and/or > override > - * virtual functions in a parent class. > - * > - * The information associated with an interface. > + * INTERFACE_CLASS: > + * @klass: class to cast from > + * Returns: An #InterfaceClass or raise an error if cast is invalid > */ > -struct InterfaceInfo > -{ > -const char *type; > +#define INTERFACE_CLASS(klass) \ > +OBJECT_CLASS_CHECK(InterfaceClass, klass, TYPE_INTERFACE) > > -void (*interface_initfn)(ObjectClass *class, void *data); > -}; > - > -#define TYPE_INTERFACE "interface" > +/** > + * INTERFACE_CHECK: > + * @interface: the type to return > + * @obj: the object to convert to an interface > + * @name: the interface type name > + * > + * Returns: @obj casted to @interface if cast is valid, otherwise raise > error. > + */ > +#define INTERFACE_CHECK(interface, obj, name) \ > +((interface *)object_dynamic_cast_assert(OBJECT((obj)), (name))) > > /** > * object_new: > diff --git a/qom/object.c b/qom/object.c > index 00bb3b0..a552be2 100644 > --- a/qom/object.c > +++ b/qom/object.c > @@ -31,9 +31,7 @@ typedef struct TypeImpl TypeImpl; > > struct InterfaceImpl > { > -const char *parent; > -void (*interface_initfn)(ObjectClass *class, void *data); > -TypeImpl *type; > +const char *typename; > }; > > struct TypeImpl > @@ -64,14 +62
Re: [Qemu-devel] [PATCH 2/2] xilinx_axi*: Re-implemented interconnect
On Mon, Aug 06, 2012 at 01:07:15PM +1000, Peter A. G. Crosthwaite wrote: > Re-implemented the interconnect between the Xilinx AXI ethernet and DMA > controllers. A QOM interface "stream" is created, for the two stream > interfaces. > > As per Edgars request, this is designed to be more generic than AXI-stream, > so in the future we may see more clients of this interface beyond AXI stream. > > This is based primarily on Paolos original refactoring of the interconnect. Hi Peter, Can we drop the axi_ prefix from stream.c? Also the *app arg is xilinx specific but it can maybe refactored when more users of the interface come along as those might have similar needs. A scatter-gathering data interface might do. Cheers, Edgar > > Signed-off-by: Paolo Bonzini > Signed-off-by: Peter A.G. Crosthwaite > --- > hw/Makefile.objs |1 + > hw/petalogix_ml605_mmu.c | 24 +-- > hw/stream.c | 23 ++ > hw/stream.h | 31 +++ > hw/xilinx.h | 22 + > hw/xilinx_axidma.c | 74 + > hw/xilinx_axidma.h | 39 > hw/xilinx_axienet.c | 32 --- > 8 files changed, 139 insertions(+), 107 deletions(-) > create mode 100644 hw/stream.c > create mode 100644 hw/stream.h > delete mode 100644 hw/xilinx_axidma.h > > diff --git a/hw/Makefile.objs b/hw/Makefile.objs > index 8327e55..a2d537d 100644 > --- a/hw/Makefile.objs > +++ b/hw/Makefile.objs > @@ -65,6 +65,7 @@ hw-obj-$(CONFIG_XILINX) += xilinx_timer.o > hw-obj-$(CONFIG_XILINX) += xilinx_uartlite.o > hw-obj-$(CONFIG_XILINX_AXI) += xilinx_axidma.o > hw-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o > +hw-obj-$(CONFIG_XILINX_AXI) += stream.o > > # PCI watchdog devices > hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o > diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c > index 6a7d0c0..dced648 100644 > --- a/hw/petalogix_ml605_mmu.c > +++ b/hw/petalogix_ml605_mmu.c > @@ -39,7 +39,8 @@ > > #include "microblaze_boot.h" > #include "microblaze_pic_cpu.h" > -#include "xilinx_axidma.h" > + > +#include "stream.h" > > #define LMB_BRAM_SIZE (128 * 1024) > #define FLASH_SIZE (32 * 1024 * 1024) > @@ -76,7 +77,7 @@ petalogix_ml605_init(ram_addr_t ram_size, >const char *initrd_filename, const char *cpu_model) > { > MemoryRegion *address_space_mem = get_system_memory(); > -DeviceState *dev; > +DeviceState *dev, *dma, *eth0; > MicroBlazeCPU *cpu; > CPUMBState *env; > DriveInfo *dinfo; > @@ -125,15 +126,18 @@ petalogix_ml605_init(ram_addr_t ram_size, > /* 2 timers at irq 2 @ 100 Mhz. */ > xilinx_timer_create(TIMER_BASEADDR, irq[2], 0, 100 * 100); > > -/* axi ethernet and dma initialization. TODO: Dynamically connect them. > */ > -{ > -static struct XilinxDMAConnection dmach; > +/* axi ethernet and dma initialization. */ > +dma = qdev_create(NULL, "xlnx.axi-dma"); > > -xilinx_axiethernet_create(&dmach, &nd_table[0], 0x8278, > - irq[3], 0x1000, 0x1000); > -xilinx_axiethernetdma_create(&dmach, 0x8460, > - irq[1], irq[0], 100 * 100); > -} > +/* FIXME: attach to the sysbus instead */ > +object_property_add_child(container_get(qdev_get_machine(), > "/unattached"), > + "xilinx-dma", OBJECT(dma), NULL); > + > +eth0 = xilinx_axiethernet_create(&nd_table[0], STREAM_SLAVE(dma), > + 0x8278, irq[3], 0x1000, 0x1000); > + > +xilinx_axiethernetdma_init(dma, STREAM_SLAVE(eth0), > + 0x8460, irq[1], irq[0], 100 * 100); > > microblaze_load_kernel(cpu, ddr_base, ram_size, BINARY_DEVICE_TREE_FILE, > > machine_cpu_reset); > diff --git a/hw/stream.c b/hw/stream.c > new file mode 100644 > index 000..001e2bd > --- /dev/null > +++ b/hw/stream.c > @@ -0,0 +1,23 @@ > +#include "stream.h" > + > +void > +axi_stream_push(StreamSlave *sink, uint8_t *buf, size_t len, uint32_t *app) > +{ > +StreamSlaveClass *k = STREAM_SLAVE_GET_CLASS(sink); > + > +k->push(sink, buf, len, app); > +} > + > +static TypeInfo axi_stream_slave_info = { > +.name = TYPE_STREAM_SLAVE, > +.parent= TYPE_INTERFACE, > +.class_size = sizeof(StreamSlaveClass), > +}; > + > + > +static void axi_stream_slave_register_types(void) > +{ > +type_register_static(&axi_stream_slave_info); > +} > + > +type_init(axi_stream_slave_register_types) > diff --git a/hw/stream.h b/hw/stream.h > new file mode 100644 > index 000..b7f3b3e > --- /dev/null > +++ b/hw/stream.h > @@ -0,0 +1,31 @@ > +#ifndef STREAM_H > +#define STREAM_H 1 > + > +#include "qemu-common.h" > +#include "qemu/object.h" > + > +/* AXI st
[Qemu-devel] tracing the guest physical address of tb->pc
Hi, I have a question about obtaining the guest physical address of tb->pc of a running VM. I use "-d exec" to get the log file of tb->pc of each executed TB. For example, in the log file I have Trace 0x40ef8140 [7ffe8afd] Trace 0x40e89fc0 [7ffe625c] Trace 0x40e8a420 [7ffe5e98] Trace 0x40e8b470 [7ffe627d] My question is that are the numbers in the last column the guest physical address of the executed instructions? If not, how can I convert this virtual address to guest physical address? Could anyone offer some help? Thanks. - Steven
Re: [Qemu-devel] [PATCH 2/2] pseries: Use new hook to correct reset sequence
Am 08.08.2012 00:02, schrieb Benjamin Herrenschmidt: > On Fri, 2012-08-03 at 17:01 +0200, Andreas Färber wrote: >> >> I have posted a suggestion where CPU reset is triggered by "the >> machine >> as an abstract concept" (needs a bit of tweaking still, but the >> general >> idea is there). >> Based on that, shouldn't it be rather easy to add a Notifier similar >> to >> "machine init done" that lets individual machines do post-reset setup? >> I.e. not have QEMUMachine trigger and control the reset. >> > > Note that we really want pre and post reset vs the device reset. > > That's why the machine should be the one in charge. The top level of the > reset sequencing is -not- the CPU, it's the machine. All machines (or > SoCs) have some kind of reset controller and provide facilities for > resetting individual devices, busses, processor cores the global > "system" reset (when it exists) itself might have interesting ordering > or sequencing requirements. > > Now, to fix our immediate problem on ppc for 1.2 the hook proposed by > Anthony for which David sent a patch does the job just fine, it allows > us to clean out all our iommu tables before the device-reset, meaning > that in-flights DMA cannot overwrite the various "files" (SLOF image > etc that are auto-loaded via reset handlers implicitely created by > load_image_targphys), and we can then do some post-initializations as > well to get things ready for a restart (rebuild the device-tree, etc...) That's all good, except for embedded machines without such implicit reset handling. It does contradict the "a machine is just a config file, setting up QOM objects" concept, but I was not the one to push that! :) What I was thinking about however were those mentioned individual cores being reset using cpu_reset(). If we want to piggy-back some machine-specific register initialization for individual CPUStates then QEMUMachine::reset is not going to be enough because it only gets triggered for complete system reset. My suggestion was thus to just call cpu_reset() in your QEMUMachine::reset and have cpu_reset() take care of its initialization wherever called from. Any of these solutions are easy to implement for 1.2 if agreement is reached what people want. What I am missing from Anthony's side is some communication to machine maintainers on the course to adopt before applying random patches. Right now x86 and ppc are moving into opposite directions and arm, mips, etc. maintainers may not even be aware of ongoing changes, and there's a pending uc32 machine that should be reviewed in this light. Cheers, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v7 2/6] qapi: Introduce add-fd, remove-fd, query-fdsets
On 08/07/2012 11:07 AM, Corey Bryant wrote: >>> +# >>> +# Since: 1.2.0 >> >> We're not very consistent on '1.2' vs. '1.2.0' in since listings, but >> that's probably worth a global cleanup closer to hard freeze. >> > > I'll make a note of it. Or does Luiz usually do a cleanup? No idea. >>> +## >>> +{ 'type': 'FdsetFdInfo', 'data': {'fd': 'int', 'removed': 'bool'} } >> >> Is it worth providing any additional information? For example, knowing >> whether the fd is O_RDONLY, O_WRONLY, or O_RDWR might be beneficial to >> management apps trying to discover what fds are already present after a >> reconnection, in order to decide whether to close them without having to >> resort to /proc/$qemupid/fdinfo/nnn lookups. It might even be worth >> marking such information optional, present only when 'removed':false. >> > > It makes sense but I'd like to limit the new functionality at this point > so that I can get this support into QEMU 1.2. Can this be added as a > follow up patch? I'm personally okay with the idea of adding additional output fields in later releases, but I know that has been questioned in the past, so you may want to get buy-in from Luiz or Anthony. I guess the other thing is to see what libvirt would actually find useful, once I complete some counterpart libvirt patches. If libvirt can get by without any extra information and without needing to hack things from procfs, then it's not worth you spending the effort coding something that will be ignored; conversely, if a piece of info is so important that I end up hacking procfs anyways, that says we have a hole in QMP. I'm okay waiting for now. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH 2/2] pseries: Use new hook to correct reset sequence
On Fri, 2012-08-03 at 17:01 +0200, Andreas Färber wrote: > > I have posted a suggestion where CPU reset is triggered by "the > machine > as an abstract concept" (needs a bit of tweaking still, but the > general > idea is there). > Based on that, shouldn't it be rather easy to add a Notifier similar > to > "machine init done" that lets individual machines do post-reset setup? > I.e. not have QEMUMachine trigger and control the reset. > Note that we really want pre and post reset vs the device reset. That's why the machine should be the one in charge. The top level of the reset sequencing is -not- the CPU, it's the machine. All machines (or SoCs) have some kind of reset controller and provide facilities for resetting individual devices, busses, processor cores the global "system" reset (when it exists) itself might have interesting ordering or sequencing requirements. Now, to fix our immediate problem on ppc for 1.2 the hook proposed by Anthony for which David sent a patch does the job just fine, it allows us to clean out all our iommu tables before the device-reset, meaning that in-flights DMA cannot overwrite the various "files" (SLOF image etc that are auto-loaded via reset handlers implicitely created by load_image_targphys), and we can then do some post-initializations as well to get things ready for a restart (rebuild the device-tree, etc...) Cheers, Ben.
Re: [Qemu-devel] [PATCH] Allow QEMUMachine to override reset sequencing
On Tue, 2012-08-07 at 16:41 +1000, David Gibson wrote: > qemu_system_reset() function always performs the same basic actions on > all machines. This includes running all the reset handler hooks, > however the order in which these will run is not always easily predictable. > > This patch splits the core of qemu_system_reset() - the invocation of > the reset handlers - out into a new qemu_devices_reset() function. > qemu_system_reset() will usually call qemu_devices_reset(), but that > can be now overriden by a new reset method in the QEMUMachine > structure. .../... Hi Anthony ! What's your take on this one ? It's a pre-req for a subsequent patch that finally fixes reset/reboot for us, and we'd like to have that latter patch in before the hard freeze :-) But Alex can't really take it until the hook is in. Will you take this hook directly ? Cheers, Ben.
Re: [Qemu-devel] [Qemu-ppc] [PATCH] ppc: Fix bug in handling of PAPR hypercall exits
On 07.08.2012, at 23:03, Benjamin Herrenschmidt wrote: > On Tue, 2012-08-07 at 11:05 +0200, Alexander Graf wrote: > >>> This patch therefore changes to ret = 0, which is both a bugfix and a small >>> optimization. >>> >>> Signed-off-by: David Gibson >> >> Thanks, applied to ppc-next. > > When do you plan to send your queue to Anthony ? Some of that stuff > should be going in ASAP. Before the hard freeze. Alex
[Qemu-devel] [Bug 918791] Re: qemu-kvm dies when using vmvga driver and unity in the guest
the oneiric-proposed fix was deleted by a security update. As noone has verified it since march, I will wait until someone asks for it before re-uploading. (simple debdiff from the cached .dsc's for 6.2 and 6.3) -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/918791 Title: qemu-kvm dies when using vmvga driver and unity in the guest Status in QEMU: New Status in “qemu-kvm” package in Ubuntu: Fix Released Status in “xserver-xorg-video-vmware” package in Ubuntu: Invalid Status in “qemu-kvm” source package in Oneiric: Fix Committed Status in “xserver-xorg-video-vmware” source package in Oneiric: Invalid Status in “qemu-kvm” source package in Precise: Fix Released Status in “xserver-xorg-video-vmware” source package in Precise: Invalid Bug description: = SRU Justification: 1. impact: kvm crashes 2. Development fix: don't allow attempts to set_bit to negative offsets 3. Stable fix: same as development fix 4. Test case (see below) 5. Regression potential: if the patch is wrong, graphics for vmware vga over vnc could get messed up = 12.04's qemu-kvm has been unstable for me and Marc Deslauriers and I figured out it has something to do with the interaction of qemu-kvm, unity and the vmvga driver. This is a regression over qemu-kvm in 11.10. TEST CASE: 1. start a VM that uses unity (eg, 11.04, 11.10 or 12.04). My tests use unity-2d on an amd64 host and amd64 guests 2. on 11.04 and 11.10, open empathy via the messaging indicator and click 'Chat'. On 12.04, open empathy via the messaging indicator and click 'Chat', close the empathy wizard, move the empathy window over the unity luancher (so it autohides), then do 'ctrl+alt+t' to open a terminal When the launcher tries to auto(un)hide, qemu-kvm dies with this: [10574.958149] do_general_protection: 132 callbacks suppressed [10574.958154] kvm[13192] general protection ip:7fab9680ea0f sp:74440148 error:0 in qemu-system-x86_64[7fab966c4000+2c9000] Relevant libvirt xml: If I change to using 'cirrus', then qemu-kvm no longer crashes. Eg: The workaround is therefore to use the cirrus driver instead of vmvga, however being able to kill qemu-kvm in this manner is not ideal. Also, unfortunately unity-2d does not run with with cirrus driver under 11.04, so the security and SRU teams are unable to properly test updates in GUI applications under unity when using the current 12.04 qemu-kvm. I tried to report this via apport, but apport complained about a CRC error, so I could not. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/918791/+subscriptions
Re: [Qemu-devel] For all targets and machine types: "start to monitor" smoke test
On Tue, Aug 7, 2012 at 7:26 PM, Markus Armbruster wrote: > Very basic smoke test: start QEMU with -monitor stdio, quit immediately. > Wouldn't it be nice if that worked for all targets and machine types? > > Many targets have mandatory options (fun oxymoron), such as -kernel or > -pflash. Can't stop me, I just try a bunch until something works. > Funny, I tried pretty similar stuff earlier but with qtest: http://lists.nongnu.org/archive/html/qemu-devel/2012-04/msg01880.html > Many targets expect various files to be present, and some of them need > to have the right size. Can't stop me, I hack up the file loaders until > it works (silly patch appended). To do this right, we'd need the > required files or suitable mock-ups in-tree. > > Test script: > > #!/bin/sh > for i in ../qemu/bld/*-softmmu/qemu-system-* > do > echo "= $i =" > for m in `$i -M help | sed -n '2,$s/ .*//gp'` > do > echo "== $m ==" > for k in "" "-kernel /dev/null" "-pflash /dev/null" "-pflash > /dev/null -pflash /dev/null -kernel /dev/null" > do > echo "=== ${k:-(default)} ===" > if echo q | QEMU_AUDIO_DRV=none $i -S -vnc :0 -M $m $k -monitor > stdio | fgrep -q '(qemu)' > then break > else false > fi > done > if [ $? -eq 0 ] > then echo "*** Success $k ***" > else echo '*** Fail' > fi > done > done > > Summary of results: > > * Bad unexplained > > qemu-system-arm lm3s811evb > qemu-system-arm lm3s6965evb > qemu-system-arm: /work/armbru/qemu/hw/qdev.c:310: qdev_get_gpio_in: > Assertion `n >= 0 && n < dev->num_gpio_in' failed. > > qemu-system-ppc64 prep > qemu: hardware error: Unknown device 'i82378' for bus 'PCI' > > qemu-system-ppcemb ref405ep > qemu-system-ppcemb taihu > Unable to find PowerPC 405ep CPU definition > > qemu-system-ppcemb mac99 > qemu-system-ppcemb g3beige > qemu-system-ppcemb prep > Unable to find PowerPC CPU definition > > qemu-system-xtensaeb lx60 > qemu-system-xtensaeb lx200 > qemu-system-xtensaeb sim > Unable to find CPU definition > > I'm not saying these are all busted. If you know how to "start to > monitor" one of these, let us know. > > * Not easily testable for me > > qemu-system-i386 xenfv > qemu-system-i386 xenpv > qemu-system-x86_64 xenfv > qemu-system-x86_64 xenpv > failed to initialize Xen: Operation not permitted > No accelerator found! > > * Good > > qemu-system-alpha clipper > qemu-system-arm collie nuri smdkc210 connex verdex highbank > integratorcp kzm mainstone musicpal n800 n810 sx1 sx1-v1 cheetah > realview-eb realview-eb-mpcore realview-pb-a8 realview-pbx-a9 > akita spitz borzoi terrier tosa versatilepb versatileab > vexpress-a9 vexpress-a15 xilinx-zynq-a9 z2 > qemu-system-cris axis-dev88 > qemu-system-i386 pc pc-1.2 pc-1.1 pc-1.0 pc-0.15 pc-0.14 pc-0.13 > pc-0.12 pc-0.11 pc-0.10 isapc > qemu-system-lm32 lm32-uclinux lm32-evr milkymist > qemu-system-m68k an5206 dummy mcf5208evb > qemu-system-microblaze petalogix-ml605 petalogix-s3adsp1800 > qemu-system-microblazeel petalogix-ml605 petalogix-s3adsp1800 > qemu-system-mips magnum pica61 malta mipssim mips > qemu-system-mips64 magnum pica61 malta mipssim mips > qemu-system-mips64el fulong2e magnum pica61 malta mipssim mips > qemu-system-mipsel magnum pica61 malta mipssim mips > qemu-system-or32 or32-sim > qemu-system-ppc ref405ep taihu bamboo mac99 g3beige prep virtex-ml507 > qemu-system-ppc64 ref405ep taihu bamboo mac99 g3beige virtex-ml507 > qemu-system-ppcemb bamboo virtex-ml507 > qemu-system-s390x s390 s390-virtio > qemu-system-sh4 r2d shix > qemu-system-sh4eb r2d shix > qemu-system-sparc leon3_generic SS-5 SS-10 SS-600MP SS-20 Voyager LX > SS-4 SPARCClassic SPARCbook SS-1000 SS-2000 SS-2 > qemu-system-sparc64 sun4u sun4v Niagara > qemu-system-x86_64 pc pc-1.2 pc-1.1 pc-1.0 pc-0.15 pc-0.14 pc-0.13 > pc-0.12 pc-0.11 pc-0.10 isapc > qemu-system-xtensa lx60 lx200 sim > > > diff --git a/hw/loader.c b/hw/loader.c > index 33acc2f..e23af6c 100644 > --- a/hw/loader.c > +++ b/hw/loader.c > @@ -62,7 +62,7 @@ int get_image_size(const char *filename) > int fd, size; > fd = open(filename, O_RDONLY | O_BINARY); > if (fd < 0) > -return -1; > +return 0;//-1; > size = lseek(fd, 0, SEEK_END); > close(fd); > return size; > @@ -75,7 +75,7 @@ int load_image(const char *filename, uint8_t *addr) > int fd, size; > fd = open(filename, O_RDONLY | O_BINARY); > if (fd < 0) > -return -1; > +return 0;//-1; > size = lseek(fd, 0, SEEK_END); > lseek(fd, 0, SEEK_SET); > if (read(fd, addr, size) != size) { > @@ -108,6 +108,7 @@ int load_image_targphys(const char *filename, > int size; > > size = get_image_size(filename); > +if (size < 0) size = 0; > if (size > max_sz)
Re: [Qemu-devel] [Qemu-ppc] [PATCH] ppc: Fix bug in handling of PAPR hypercall exits
On Tue, 2012-08-07 at 11:05 +0200, Alexander Graf wrote: > > This patch therefore changes to ret = 0, which is both a bugfix and a small > > optimization. > > > > Signed-off-by: David Gibson > > Thanks, applied to ppc-next. When do you plan to send your queue to Anthony ? Some of that stuff should be going in ASAP. Cheers, Ben.
Re: [Qemu-devel] [PATCH 2/5] s390: Virtual channel subsystem support.
On Tue, Aug 7, 2012 at 2:52 PM, Cornelia Huck wrote: > Provide a mechanism for qemu to provide fully virtual subchannels to > the guest. In the KVM case, this relies on the kernel's css support. > The !KVM case is not yet supported. > > Signed-off-by: Cornelia Huck > --- > hw/s390x/Makefile.objs | 1 + > hw/s390x/css.c | 440 > + > hw/s390x/css.h | 62 +++ > target-s390x/Makefile.objs | 2 +- > target-s390x/cpu.h | 108 +++ > target-s390x/ioinst.c | 38 > target-s390x/ioinst.h | 173 ++ > target-s390x/kvm.c | 101 +++ > 8 files changed, 924 insertions(+), 1 deletion(-) > create mode 100644 hw/s390x/css.c > create mode 100644 hw/s390x/css.h > create mode 100644 target-s390x/ioinst.c > create mode 100644 target-s390x/ioinst.h > > diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs > index dcdcac8..93b41fb 100644 > --- a/hw/s390x/Makefile.objs > +++ b/hw/s390x/Makefile.objs > @@ -1,3 +1,4 @@ > obj-y = s390-virtio-bus.o s390-virtio.o > > obj-y := $(addprefix ../,$(obj-y)) > +obj-y += css.o > diff --git a/hw/s390x/css.c b/hw/s390x/css.c > new file mode 100644 > index 000..7941c44 > --- /dev/null > +++ b/hw/s390x/css.c > @@ -0,0 +1,440 @@ > +/* > + * Channel subsystem base support. > + * > + * Copyright 2012 IBM Corp. > + * Author(s): Cornelia Huck > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or (at > + * your option) any later version. See the COPYING file in the top-level > + * directory. > + */ > + > +#include "qemu-thread.h" > +#include "qemu-queue.h" > +#include > +#include "kvm.h" > +#include "cpu.h" > +#include "ioinst.h" > +#include "css.h" > + > +struct chp_info { CamelCase, please. > +uint8_t in_use; > +uint8_t type; > +}; > + > +static struct chp_info chpids[MAX_CSSID + 1][MAX_CHPID + 1]; > + > +static css_subch_cb_func css_subch_cb; Probably these can be put to a container structure which can be passed around. > + > +int css_set_subch_cb(css_subch_cb_func func) > +{ > +if (func && css_subch_cb) { > +return -EBUSY; > +} > +css_subch_cb = func; > +return 0; > +} > + > +static void css_inject_io_interrupt(SubchDev *sch, uint8_t func) > +{ > +s390_io_interrupt(sch->cssid, sch->ssid, sch->schid, > &sch->curr_status.scsw, > + &sch->curr_status.pmcw, &sch->sense_data, 0, > + sch->curr_status.pmcw.isc, > sch->curr_status.pmcw.intparm, > + func); > +} > + > +void css_conditional_io_interrupt(SubchDev *sch) > +{ > +s390_io_interrupt(sch->cssid, sch->ssid, sch->schid, > &sch->curr_status.scsw, > + &sch->curr_status.pmcw, &sch->sense_data, 1, > + sch->curr_status.pmcw.isc, > sch->curr_status.pmcw.intparm, 0); > +} > + > +static void sch_handle_clear_func(SubchDev *sch) > +{ > +struct pmcw *p = &sch->curr_status.pmcw; > +struct scsw *s = &sch->curr_status.scsw; > +int path; > + > +/* Path management: In our simple css, we always choose the only path. */ > +path = 0x80; > + > +/* Reset values prior to 'issueing the clear signal'. */ > +p->lpum = 0; > +p->pom = 0xff; > +s->pno = 0; > + > +/* We always 'attempt to issue the clear signal', and we always succeed. > */ > +sch->orb = NULL; > +sch->channel_prog = NULL; > +sch->last_cmd = NULL; > +s->actl &= ~SCSW_ACTL_CLEAR_PEND; > +s->stctl |= SCSW_STCTL_STATUS_PEND; > + > +s->dstat = 0; > +s->cstat = 0; > +p->lpum = path; > + > +} > + > +static void sch_handle_halt_func(SubchDev *sch) > +{ > + > +struct pmcw *p = &sch->curr_status.pmcw; > +struct scsw *s = &sch->curr_status.scsw; > +int path; > + > +/* Path management: In our simple css, we always choose the only path. */ > +path = 0x80; > + > +/* We always 'attempt to issue the halt signal', and we always succeed. > */ > +sch->orb = NULL; > +sch->channel_prog = NULL; > +sch->last_cmd = NULL; > +s->actl &= ~SCSW_ACTL_HALT_PEND; > +s->stctl |= SCSW_STCTL_STATUS_PEND; > + > +if ((s->actl & (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) || > +!((s->actl & SCSW_ACTL_START_PEND) || > + (s->actl & SCSW_ACTL_SUSP))) { > +s->dstat = SCSW_DSTAT_DEVICE_END; > +} > +s->cstat = 0; > +p->lpum = path; > + > +} > + > +static int css_interpret_ccw(SubchDev *sch, struct ccw1 *ccw) > +{ > +int ret; > +bool check_len; > +int len; > +int i; > + > +if (!ccw) { > +return -EIO; > +} > + > +/* Check for invalid command codes. */ > +if ((ccw->cmd_code & 0x0f) == 0) { > +return -EINVAL; > +} > +if (((ccw->cmd_code & 0x0f) == CCW_CMD_TIC) && > +((ccw->cmd_code & 0xf0) != 0)) { > +return -EINVAL; > +} > + > +if (ccw->flags & CCW_FLAG_SUSPEND) { > +retu
[Qemu-devel] [RFC 11/15] rename qdev_prop_register_global_list to qemu_globals_register_list
The function is not qdev-specific, it just keeps a global driver/property/value list. Signed-off-by: Eduardo Habkost --- global-properties.c | 2 +- hw/qdev.h | 8 +--- vl.c| 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/global-properties.c b/global-properties.c index d827955..20a838c 100644 --- a/global-properties.c +++ b/global-properties.c @@ -8,7 +8,7 @@ static void qdev_prop_register_global(GlobalProperty *prop) QTAILQ_INSERT_TAIL(&global_props, prop, next); } -void qdev_prop_register_global_list(GlobalProperty *props) +void qemu_globals_register_list(GlobalProperty *props) { int i; diff --git a/hw/qdev.h b/hw/qdev.h index b522f11..5941cae 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -329,12 +329,14 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value); /* FIXME: Remove opaque pointer properties. */ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); -void qdev_prop_register_global_list(GlobalProperty *props); -void qdev_prop_set_globals(DeviceState *dev); -void object_prop_set_globals(Object *obj); void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, Property *prop, const char *value); +/* Handling of global properties: */ +void qemu_globals_register_list(GlobalProperty *props); +void qdev_prop_set_globals(DeviceState *dev); +void object_prop_set_globals(Object *obj); + char *qdev_get_fw_dev_path(DeviceState *dev); /** diff --git a/vl.c b/vl.c index e71cb30..d8e409c 100644 --- a/vl.c +++ b/vl.c @@ -559,7 +559,7 @@ static void configure_rtc(QemuOpts *opts) { /* end of list */ } }; -qdev_prop_register_global_list(slew_lost_ticks); +qemu_globals_register_list(slew_lost_ticks); } else if (!strcmp(value, "none")) { /* discard is default */ } else { @@ -2951,7 +2951,7 @@ int main(int argc, char **argv, char **envp) { /* end of list */ } }; -qdev_prop_register_global_list(slew_lost_ticks); +qemu_globals_register_list(slew_lost_ticks); break; } case QEMU_OPTION_acpitable: @@ -3510,7 +3510,7 @@ int main(int argc, char **argv, char **envp) } if (machine->compat_props) { -qdev_prop_register_global_list(machine->compat_props); +qemu_globals_register_list(machine->compat_props); } qemu_add_globals(); -- 1.7.11.2
[Qemu-devel] [RFC 03/15] kvm: set vcpu_id to APIC ID instead of CPU index
The CPU ID in KVM is supposed to be the APIC ID, so change the KVM_CREATE_VCPU call to match it. It didn't break anything yet because today the APIC ID is assumed to be == the CPU index, but this won't be true in the future. Signed-off-by: Eduardo Habkost --- kvm-all.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvm-all.c b/kvm-all.c index 2148b20..38de992 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -213,7 +213,7 @@ int kvm_init_vcpu(CPUArchState *env) DPRINTF("kvm_init_vcpu\n"); -ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpu_index); +ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpuid_apic_id); if (ret < 0) { DPRINTF("kvm_create_vcpu failed\n"); goto err; -- 1.7.11.2
[Qemu-devel] [RFC 06/15] pc: set FW_CFG data based on APIC ID calculation
This changes FW_CFG_MAX_CPUS and FW_CFG_NUMA to use apic_id_for_cpu(), so the NUMA table can be based on the APIC IDs, instead of CPU index (SeaBIOS knows nothing about CPU indexes, just APIC IDs). Signed-off-by: Eduardo Habkost --- hw/pc.c | 23 --- target-i386/cpu.h | 7 +++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 10449bd..9afb838 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -581,6 +581,11 @@ int e820_add_entry(uint64_t address, uint64_t length, uint32_t type) return index; } +unsigned int apic_id_limit(void) +{ +return apic_id_for_cpu(max_cpus - 1) + 1; +} + static void *bochs_bios_init(void) { void *fw_cfg; @@ -588,6 +593,7 @@ static void *bochs_bios_init(void) size_t smbios_len; uint64_t *numa_fw_cfg; int i, j; +unsigned int max_apic_id = apic_id_limit(); register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL); register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL); @@ -602,7 +608,7 @@ static void *bochs_bios_init(void) register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL); fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0); -fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_apic_id); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES, (uint8_t *)acpi_tables, @@ -622,21 +628,24 @@ static void *bochs_bios_init(void) * of nodes, one word for each VCPU->node and one word for each node to * hold the amount of memory. */ -numa_fw_cfg = g_malloc0((1 + max_cpus + nb_numa_nodes) * 8); +numa_fw_cfg = g_malloc0((1 + max_apic_id + nb_numa_nodes) * 8); numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes); -for (i = 0; i < max_cpus; i++) { +unsigned int cpu_idx; +for (cpu_idx = 0; cpu_idx < max_cpus; cpu_idx++) { +unsigned int apic_id = apic_id_for_cpu(cpu_idx); +assert(apic_id < max_apic_id); for (j = 0; j < nb_numa_nodes; j++) { -if (test_bit(i, node_cpumask[j])) { -numa_fw_cfg[i + 1] = cpu_to_le64(j); +if (test_bit(cpu_idx, node_cpumask[j])) { +numa_fw_cfg[apic_id + 1] = cpu_to_le64(j); break; } } } for (i = 0; i < nb_numa_nodes; i++) { -numa_fw_cfg[max_cpus + 1 + i] = cpu_to_le64(node_mem[i]); +numa_fw_cfg[max_apic_id + 1 + i] = cpu_to_le64(node_mem[i]); } fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, (uint8_t *)numa_fw_cfg, - (1 + max_cpus + nb_numa_nodes) * 8); + (1 + max_apic_id + nb_numa_nodes) * 8); return fw_cfg; } diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 39ea005..257d6c7 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -919,6 +919,13 @@ void host_cpuid(uint32_t function, uint32_t count, */ unsigned int apic_id_for_cpu(int cpu_index); +/* Calculate limit for the APIC ID value, based on max_cpus + * + * On PC, FW_CFG_MAX_CPUS is not max_cpus, but the limit for the APIC IDs + * of all CPUs (so that of all CPUs APIC ID < MAX_CPUS). + */ +unsigned int apic_id_limit(void); + /* helper.c */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, -- 1.7.11.2
Re: [Qemu-devel] [PATCH 3/5] s390: Add new channel I/O based virtio transport.
On Tue, Aug 7, 2012 at 2:52 PM, Cornelia Huck wrote: > Add a new virtio transport that uses channel commands to perform > virtio operations. > > Add a new machine type s390-ccw that uses this virtio-ccw transport > and make it the default machine for s390. > > Signed-off-by: Cornelia Huck > --- > hw/qdev-monitor.c | 5 + > hw/s390-virtio.c | 268 ++ > hw/s390x/Makefile.objs | 1 + > hw/s390x/virtio-ccw.c | 962 > + > hw/s390x/virtio-ccw.h | 77 > vl.c | 1 + > 6 files changed, 1243 insertions(+), 71 deletions(-) > create mode 100644 hw/s390x/virtio-ccw.c > create mode 100644 hw/s390x/virtio-ccw.h > > diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c > index b22a37a..79f7e6b 100644 > --- a/hw/qdev-monitor.c > +++ b/hw/qdev-monitor.c > @@ -42,6 +42,11 @@ static const QDevAlias qdev_alias_table[] = { > { "virtio-blk-s390", "virtio-blk", QEMU_ARCH_S390X }, > { "virtio-net-s390", "virtio-net", QEMU_ARCH_S390X }, > { "virtio-serial-s390", "virtio-serial", QEMU_ARCH_S390X }, > +{ "virtio-blk-ccw", "virtio-blk", QEMU_ARCH_S390X }, > +{ "virtio-net-ccw", "virtio-net", QEMU_ARCH_S390X }, > +{ "virtio-serial-ccw", "virtio-serial", QEMU_ARCH_S390X }, > +{ "virtio-balloon-ccw", "virtio-balloon", QEMU_ARCH_S390X }, > +{ "virtio-scsi-ccw", "virtio-scsi", QEMU_ARCH_S390X }, > { "lsi53c895a", "lsi" }, > { "ich9-ahci", "ahci" }, > { } > diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c > index 47eed35..b8bdf80 100644 > --- a/hw/s390-virtio.c > +++ b/hw/s390-virtio.c > @@ -30,8 +30,11 @@ > #include "hw/sysbus.h" > #include "kvm.h" > #include "exec-memory.h" > +#include "qemu-thread.h" > > #include "hw/s390-virtio-bus.h" > +#include "hw/s390x/css.h" > +#include "hw/s390x/virtio-ccw.h" > > //#define DEBUG_S390 > > @@ -46,6 +49,7 @@ > #define KVM_S390_VIRTIO_NOTIFY 0 > #define KVM_S390_VIRTIO_RESET 1 > #define KVM_S390_VIRTIO_SET_STATUS 2 > +#define KVM_S390_VIRTIO_CCW_NOTIFY 3 > > #define KERN_IMAGE_START0x01UL > #define KERN_PARM_AREA 0x010480UL > @@ -62,6 +66,7 @@ > > static VirtIOS390Bus *s390_bus; > static S390CPU **ipi_states; > +VirtioCcwBus *ccw_bus; > > S390CPU *s390_cpu_addr2state(uint16_t cpu_addr) > { > @@ -75,15 +80,21 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr) > int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t > hypercall) > { > int r = 0, i; > +int cssid, ssid, schid, m; > +SubchDev *sch; > > dprintf("KVM hypercall: %ld\n", hypercall); > switch (hypercall) { > case KVM_S390_VIRTIO_NOTIFY: > if (mem > ram_size) { > -VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, > - mem, &i); > -if (dev) { > -virtio_queue_notify(dev->vdev, i); > +if (s390_bus) { > +VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, > + mem, &i); > +if (dev) { > +virtio_queue_notify(dev->vdev, i); > +} else { > +r = -EINVAL; > +} > } else { > r = -EINVAL; > } > @@ -92,28 +103,49 @@ int s390_virtio_hypercall(CPUS390XState *env, uint64_t > mem, uint64_t hypercall) > } > break; > case KVM_S390_VIRTIO_RESET: > -{ > -VirtIOS390Device *dev; > - > -dev = s390_virtio_bus_find_mem(s390_bus, mem); > -virtio_reset(dev->vdev); > -stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0); > -s390_virtio_device_sync(dev); > -s390_virtio_reset_idx(dev); > +if (s390_bus) { > +VirtIOS390Device *dev; > + > +dev = s390_virtio_bus_find_mem(s390_bus, mem); > +virtio_reset(dev->vdev); > +stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0); > +s390_virtio_device_sync(dev); > +s390_virtio_reset_idx(dev); > +} else { > +r = -EINVAL; > +} > break; > -} > case KVM_S390_VIRTIO_SET_STATUS: > -{ > -VirtIOS390Device *dev; > +if (s390_bus) { > +VirtIOS390Device *dev; > > -dev = s390_virtio_bus_find_mem(s390_bus, mem); > -if (dev) { > -s390_virtio_device_update_status(dev); > +dev = s390_virtio_bus_find_mem(s390_bus, mem); > +if (dev) { > +s390_virtio_device_update_status(dev); > +} else { > +r = -EINVAL; > +} > } else { > r = -EINVAL; > } > break; > -} > +case KVM_S390_VIRTIO_CCW_NOTIFY: > +if (ccw_bus) { > +if (ioinst_disassemble_sch_ide
[Qemu-devel] [RFC 01/15] cpus.h: include cpu-common.h
Needed for the definition of fprint_function. This is not necessary right now, but it will be necessary if code that doesn't include cpu-common.h includes cpus.h. Signed-off-by: Eduardo Habkost --- cpus.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpus.h b/cpus.h index 81bd817..061ff7f 100644 --- a/cpus.h +++ b/cpus.h @@ -1,6 +1,8 @@ #ifndef QEMU_CPUS_H #define QEMU_CPUS_H +#include "qemu-common.h" + /* cpus.c */ void qemu_init_cpu_loop(void); void resume_all_vcpus(void); -- 1.7.11.2
[Qemu-devel] [RFC 12/15] create qemu_global_get() function
Useful for cases where code is not converted to QOM and/or QDEV yet, but needs to check the value of a global property. Signed-off-by: Eduardo Habkost --- global-properties.c | 11 +++ hw/qdev.h | 8 2 files changed, 19 insertions(+) diff --git a/global-properties.c b/global-properties.c index 20a838c..0c3d1b6 100644 --- a/global-properties.c +++ b/global-properties.c @@ -49,6 +49,17 @@ static void object_set_globals(Object *obj, } while (class); } +const char *qemu_global_get(const char *driver, const char *property) +{ +GlobalProperty *prop; +QTAILQ_FOREACH(prop, &global_props, next) { +if (!strcmp(prop->driver, driver) && !strcmp(prop->property, property)) { +return prop->value; +} +} +return NULL; +} + void qdev_prop_set_globals(DeviceState *dev) { return object_set_globals(OBJECT(dev), qdev_global_parse); diff --git a/hw/qdev.h b/hw/qdev.h index 5941cae..d3210d8 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -337,6 +337,14 @@ void qemu_globals_register_list(GlobalProperty *props); void qdev_prop_set_globals(DeviceState *dev); void object_prop_set_globals(Object *obj); +/* Get the string value of a global property directly + * + * Using this function is discouraged. Code should be converted to use + * QOM and/or qdev instead of using it. It is provided only as a convenience + * for code that is not converted yet. + */ +const char *qemu_global_get(const char *driver, const char *property); + char *qdev_get_fw_dev_path(DeviceState *dev); /** -- 1.7.11.2
[Qemu-devel] [PATCH v2 6/9] x86: use wrappers for memory access helpers
Switch to wrapped versions of memory access functions. Signed-off-by: Blue Swirl --- target-i386/cpu.h| 10 ++ target-i386/mem_helper.c | 10 ++ target-i386/seg_helper.c | 209 +++--- 3 files changed, 126 insertions(+), 103 deletions(-) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 9b2ead8..2d4ca0d 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1148,4 +1148,14 @@ void cpu_stw_data(CPUX86State *env, target_ulong ptr, uint32_t data); void cpu_stl_data(CPUX86State *env, target_ulong ptr, uint32_t data); void cpu_stq_data(CPUX86State *env, target_ulong ptr, uint64_t data); +uint32_t cpu_ldub_kernel(CPUX86State *env, target_ulong ptr); +uint32_t cpu_lduw_kernel(CPUX86State *env, target_ulong ptr); +uint32_t cpu_ldl_kernel(CPUX86State *env, target_ulong ptr); +uint64_t cpu_ldq_kernel(CPUX86State *env, target_ulong ptr); + +void cpu_stb_kernel(CPUX86State *env, target_ulong ptr, uint32_t data); +void cpu_stw_kernel(CPUX86State *env, target_ulong ptr, uint32_t data); +void cpu_stl_kernel(CPUX86State *env, target_ulong ptr, uint32_t data); +void cpu_stq_kernel(CPUX86State *env, target_ulong ptr, uint64_t data); + #endif /* CPU_I386_H */ diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c index 30c3bd0..3dd4406 100644 --- a/target-i386/mem_helper.c +++ b/target-i386/mem_helper.c @@ -190,6 +190,11 @@ WRAP_LD(uint32_t, ldub_data) WRAP_LD(uint32_t, lduw_data) WRAP_LD(uint32_t, ldl_data) WRAP_LD(uint64_t, ldq_data) + +WRAP_LD(uint32_t, ldub_kernel) +WRAP_LD(uint32_t, lduw_kernel) +WRAP_LD(uint32_t, ldl_kernel) +WRAP_LD(uint64_t, ldq_kernel) #undef WRAP_LD #define WRAP_ST(datatype, fn) \ @@ -207,4 +212,9 @@ WRAP_ST(uint32_t, stb_data) WRAP_ST(uint32_t, stw_data) WRAP_ST(uint32_t, stl_data) WRAP_ST(uint64_t, stq_data) + +WRAP_ST(uint32_t, stb_kernel) +WRAP_ST(uint32_t, stw_kernel) +WRAP_ST(uint32_t, stl_kernel) +WRAP_ST(uint64_t, stq_kernel) #undef WRAP_ST diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index 41d146c..f5dcf01 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -23,10 +23,6 @@ #include "qemu-log.h" #include "helper.h" -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif /* !defined(CONFIG_USER_ONLY) */ - //#define DEBUG_PCALL #ifdef DEBUG_PCALL @@ -56,8 +52,8 @@ static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr, return -1; } ptr = dt->base + index; -*e1_ptr = ldl_kernel(ptr); -*e2_ptr = ldl_kernel(ptr + 4); +*e1_ptr = cpu_ldl_kernel(env, ptr); +*e2_ptr = cpu_ldl_kernel(env, ptr + 4); return 0; } @@ -125,11 +121,11 @@ static inline void get_ss_esp_from_tss(uint32_t *ss_ptr, raise_exception_err(env, EXCP0A_TSS, env->tr.selector & 0xfffc); } if (shift == 0) { -*esp_ptr = lduw_kernel(env->tr.base + index); -*ss_ptr = lduw_kernel(env->tr.base + index + 2); +*esp_ptr = cpu_lduw_kernel(env, env->tr.base + index); +*ss_ptr = cpu_lduw_kernel(env, env->tr.base + index + 2); } else { -*esp_ptr = ldl_kernel(env->tr.base + index); -*ss_ptr = lduw_kernel(env->tr.base + index + 4); +*esp_ptr = cpu_ldl_kernel(env, env->tr.base + index); +*ss_ptr = cpu_lduw_kernel(env, env->tr.base + index + 4); } } @@ -262,29 +258,30 @@ static void switch_tss(int tss_selector, /* read all the registers from the new TSS */ if (type & 8) { /* 32 bit */ -new_cr3 = ldl_kernel(tss_base + 0x1c); -new_eip = ldl_kernel(tss_base + 0x20); -new_eflags = ldl_kernel(tss_base + 0x24); +new_cr3 = cpu_ldl_kernel(env, tss_base + 0x1c); +new_eip = cpu_ldl_kernel(env, tss_base + 0x20); +new_eflags = cpu_ldl_kernel(env, tss_base + 0x24); for (i = 0; i < 8; i++) { -new_regs[i] = ldl_kernel(tss_base + (0x28 + i * 4)); +new_regs[i] = cpu_ldl_kernel(env, tss_base + (0x28 + i * 4)); } for (i = 0; i < 6; i++) { -new_segs[i] = lduw_kernel(tss_base + (0x48 + i * 4)); +new_segs[i] = cpu_lduw_kernel(env, tss_base + (0x48 + i * 4)); } -new_ldt = lduw_kernel(tss_base + 0x60); -new_trap = ldl_kernel(tss_base + 0x64); +new_ldt = cpu_lduw_kernel(env, tss_base + 0x60); +new_trap = cpu_ldl_kernel(env, tss_base + 0x64); } else { /* 16 bit */ new_cr3 = 0; -new_eip = lduw_kernel(tss_base + 0x0e); -new_eflags = lduw_kernel(tss_base + 0x10); +new_eip = cpu_lduw_kernel(env, tss_base + 0x0e); +new_eflags = cpu_lduw_kernel(env, tss_base + 0x10); for (i = 0; i < 8; i++) { -new_regs[i] = lduw_kernel(tss_base + (0x12 + i * 2)) | 0x; +new_regs[i] = cpu_lduw_kernel(env, tss_base + (0x12 + i * 2)) | +0x; } for (i
[Qemu-devel] [RFC 15/15] generate APIC IDs according to CPU topology (v2)
This keeps compatibility on machine-types pc-1.1 and lower, and prints a warning in case the requested configuration won't get the correct topology. Changes v1 -> v2: - Move code to cpu.c - keep using cpu_index on *-user - Use SMP.contiguous_apic_ids global property - Prints warning in case the compatibility mode will expose incorrect topology Signed-off-by: Eduardo Habkost --- hw/pc_piix.c | 4 target-i386/cpu.c | 34 ++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 0c0096f..f073916 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -375,6 +375,10 @@ static QEMUMachine pc_machine_v1_2 = { .driver = "qxl",\ .property = "vgamem_mb",\ .value= stringify(8),\ +},{\ +.driver = "SMP",\ +.property = "contiguous_apic_ids",\ +.value= "true",\ } static QEMUMachine pc_machine_v1_1 = { diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 1703373..ea6c7a7 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -23,9 +23,11 @@ #include "cpu.h" #include "kvm.h" +#include "topology.h" #ifndef CONFIG_USER_ONLY -#include "sysemu.h" +#include "hw/qdev.h" +#include "cpus.h" #endif #include "qemu-option.h" @@ -492,13 +494,37 @@ static x86_def_t builtin_x86_defs[] = { }, }; +#ifdef CONFIG_USER_ONLY unsigned int apic_id_for_cpu(int cpu_index) { -/* right now APIC ID == CPU index. this will eventually change to use - * the CPU topology configuration properly - */ +/* *-user doesn't have any CPU topology settings, just use the CPU index */ return cpu_index; } +#else +unsigned int apic_id_for_cpu(int cpu_index) +{ +const char *contig; +bool is_contiguous; +unsigned int correct_id; +static bool warned = false; + +/* Global property SMP.contiguous_apic_ids=true will keep compatibility + * with the old (broken) behavior when calculating APIC IDs + */ +contig = qemu_global_get("SMP", "contiguous_apic_ids"); +is_contiguous = contig && !strcmp(contig, "true"); +correct_id = topo_apicid_for_cpu(smp_cores, smp_threads, cpu_index); +if (is_contiguous) { +if (cpu_index != correct_id && !warned) { +fprintf(stderr, "warning: CPU topology in compatibility mode, it will not match the requested topology\n"); +warned = true; +} +return cpu_index; +} else { +return correct_id; +} +} +#endif static int cpu_x86_fill_model_id(char *str) { -- 1.7.11.2
[Qemu-devel] [RFC 09/15] isolate qdev-independent parts of qdev_prop_set_globals()
Create a qdev-independent function, and use a callback that calls qdev_prop_parse(). Signed-off-by: Eduardo Habkost --- global-properties.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/global-properties.c b/global-properties.c index a1c3581..d99bcee 100644 --- a/global-properties.c +++ b/global-properties.c @@ -17,9 +17,20 @@ void qdev_prop_register_global_list(GlobalProperty *props) } } -void qdev_prop_set_globals(DeviceState *dev) +static void qdev_global_parse(Object *obj, const char *property, + const char *value, Error **errp) +{ +DeviceState *dev = DEVICE(obj); +qdev_prop_parse(dev, property, value, errp); +} + +static void object_set_globals(Object *obj, + void (*parse_fn)(Object *obj, +const char *property, +const char *value, +Error **errp)) { -ObjectClass *class = object_get_class(OBJECT(dev)); +ObjectClass *class = object_get_class(obj); do { GlobalProperty *prop; @@ -28,7 +39,7 @@ void qdev_prop_set_globals(DeviceState *dev) if (strcmp(object_class_get_name(class), prop->driver) != 0) { continue; } -qdev_prop_parse(dev, prop->property, prop->value, &err); +parse_fn(obj, prop->property, prop->value, &err); if (err) { qerror_report_err(err); exit(1); @@ -38,6 +49,11 @@ void qdev_prop_set_globals(DeviceState *dev) } while (class); } +void qdev_prop_set_globals(DeviceState *dev) +{ +return object_set_globals(OBJECT(dev), qdev_global_parse); +} + static int qdev_add_one_global(QemuOpts *opts, void *opaque) { GlobalProperty *g; -- 1.7.11.2
Re: [Qemu-devel] [RFC V2 03/10] quorum: Add quorum_open().
On 08/07/2012 02:30 PM, Blue Swirl wrote: > On Tue, Aug 7, 2012 at 1:44 PM, Benoît Canet wrote: >> Signed-off-by: Benoit Canet >> --- >> block/quorum.c | 62 >> >> 1 file changed, 62 insertions(+) >> >> diff --git a/block/quorum.c b/block/quorum.c >> index e0405b6..de58ab8 100644 >> --- a/block/quorum.c >> +++ b/block/quorum.c >> @@ -47,11 +47,73 @@ struct QuorumAIOCB { >> int vote_ret; >> }; >> >> +/* Valid quorum filenames look like >> + * quorum:path/to/a_image:path/to/b_image:path/to/c_image > > This syntax would mean that stacking for example curl or other network > paths would not be possible. How about comma as separator? Also, what escaping mechanism is in place for allowing a file containing the same character as the separator (whether you end up with : or , as the separator)? If you support a larger quorum (whether always n/(2n-1) or whether fully configurable n/m), rather than hard-coded 2/3, then you also need a way to specify how many quorum members will follow. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] For all targets and machine types: "start to monitor" smoke test
On 08/07/2012 02:30 PM, Markus Armbruster wrote: > Peter Maydell writes: > >> On 7 August 2012 20:55, Markus Armbruster wrote: >>> Anthony Liguori writes: Perhaps we could add a QEMUMachine parameter that indicates that the machine doesn't start without special options. >>> >>> Recommend to make it a string that lists the mandatory options. >> >> How are you going to say "need either option foo or option bar" ? I'm >> pretty sure we have some of those (eg "either you need to pass a flash >> image or a kernel"). > > Yes, we do. > > The string should be suitable for inserting into -help. Convention in other programs' -help output is to express a mandatory selection from mutually exclusive options using {}, as in: { -foo | -bar } If both options can be used together, but cannot both be omitted, then this style works: { -foo [ -bar ] | -bar } Mutually exclusive options, but where omission is okay, would then be: [ { -foo | -bar } ] or even this variant, to express the default when both are omitted: { -foo | [ -bar ] } Using strings with metasyntax like that should be usable in qemu -help. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] For all targets and machine types: "start to monitor" smoke test
Am 07.08.2012 21:26, schrieb Markus Armbruster: > Very basic smoke test: start QEMU with -monitor stdio, quit immediately. [...] > Summary of results: > > * Bad unexplained [...] > qemu-system-ppc64 prep > qemu: hardware error: Unknown device 'i82378' for bus 'PCI' This is an untested configuration, none of the PReP machines I know are 64-bit. Alex wants all ppc machines in ppc64 for convenience though. It sounds like CONFIG_I82378=y in default-configs/ppc64-softmmu.mak would fix this. > qemu-system-ppcemb ref405ep > qemu-system-ppcemb taihu > Unable to find PowerPC 405ep CPU definition Alex? > qemu-system-ppcemb mac99 > qemu-system-ppcemb g3beige > qemu-system-ppcemb prep > Unable to find PowerPC CPU definition These three are not embedded CPUs so the error seems correct. Alex, should we suppress the desktop machines for ppcemb? Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [RFC 04/15] i386: create apic_id_for_cpu() function (v2)
Currently we need a way to calculate the Initial APIC ID using only the CPU index (without needing a CPU object), as the NUMA fw_cfg data is APIC-ID-based, and may include data for hotplug CPUs (that don't exist yet), up to max_cpus. Changes v1 -> v2: - make function return value 'unsigned int' (it's not specific for the 8-bit xAPIC ID) - move implementation to cpu.c Signed-off-by: Eduardo Habkost --- target-i386/cpu.c | 14 +- target-i386/cpu.h | 10 ++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 857b94e..1703373 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -24,6 +24,10 @@ #include "cpu.h" #include "kvm.h" +#ifndef CONFIG_USER_ONLY +#include "sysemu.h" +#endif + #include "qemu-option.h" #include "qemu-config.h" @@ -488,6 +492,14 @@ static x86_def_t builtin_x86_defs[] = { }, }; +unsigned int apic_id_for_cpu(int cpu_index) +{ +/* right now APIC ID == CPU index. this will eventually change to use + * the CPU topology configuration properly + */ +return cpu_index; +} + static int cpu_x86_fill_model_id(char *str) { uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0; @@ -1774,7 +1786,7 @@ static void x86_cpu_initfn(Object *obj) x86_cpuid_get_tsc_freq, x86_cpuid_set_tsc_freq, NULL, NULL, NULL); -env->cpuid_apic_id = env->cpu_index; +env->cpuid_apic_id = apic_id_for_cpu(env->cpu_index); } static void x86_cpu_common_class_init(ObjectClass *oc, void *data) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 2a61c81..39ea005 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -910,6 +910,16 @@ void cpu_clear_apic_feature(CPUX86State *env); void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); + +/* Calculates initial APIC ID for a specific CPU index + * + * Currently we need to be able to calculate the APIC ID from the CPU index + * alone, as the QEMU<->Seabios interfaces have no concept of "CPU index", + * and the NUMA tables need the APIC ID of all CPUs up to max_cpus. + */ +unsigned int apic_id_for_cpu(int cpu_index); + + /* helper.c */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx); -- 1.7.11.2
Re: [Qemu-devel] [RFC V2 04/10] quorum: Add quorum_close().
On Tue, Aug 7, 2012 at 1:44 PM, Benoît Canet wrote: > Signed-off-by: Benoit Canet > --- > block/quorum.c | 12 > 1 file changed, 12 insertions(+) > > diff --git a/block/quorum.c b/block/quorum.c > index de58ab8..9da0432 100644 > --- a/block/quorum.c > +++ b/block/quorum.c > @@ -107,6 +107,17 @@ clean_exit: > return ret; > } > > +static void quorum_close(BlockDriverState *bs) > +{ > +BDRVQuorumState *s = bs->opaque; > +int i; > + > +/* Ensure writes reach stable storage */ > +for (i = 0; i <= 2; i++) { > +bdrv_flush(s->bs[i]); bdrv_close() > +} > +} > + > static BlockDriver bdrv_quorum = { > .format_name= "quorum", > .protocol_name = "quorum", > @@ -114,6 +125,7 @@ static BlockDriver bdrv_quorum = { > .instance_size = sizeof(BDRVQuorumState), > > .bdrv_file_open = quorum_open, > +.bdrv_close = quorum_close, > }; > > static void bdrv_quorum_init(void) > -- > 1.7.9.5 >
[Qemu-devel] [PATCH v2 5/9] x86: avoid AREG0 for SMM helpers
Add an explicit CPUX86State parameter instead of relying on AREG0. Signed-off-by: Blue Swirl --- target-i386/Makefile.objs |1 - target-i386/helper.h |2 +- target-i386/smm_helper.c | 14 -- target-i386/translate.c |2 +- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index 370fde7..f843fe9 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -6,7 +6,6 @@ obj-$(CONFIG_KVM) += kvm.o hyperv.o obj-$(CONFIG_LINUX_USER) += ioport-user.o obj-$(CONFIG_BSD_USER) += ioport-user.o -$(obj)/smm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/seg_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/helper.h b/target-i386/helper.h index 601b8dd..ec7edca 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -71,7 +71,7 @@ DEF_HELPER_1(set_inhibit_irq, void, env) DEF_HELPER_1(reset_inhibit_irq, void, env) DEF_HELPER_2(boundw, void, tl, int) DEF_HELPER_2(boundl, void, tl, int) -DEF_HELPER_0(rsm, void) +DEF_HELPER_1(rsm, void, env) DEF_HELPER_1(into, void, int) DEF_HELPER_1(cmpxchg8b, void, tl) #ifdef TARGET_X86_64 diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c index bc1bfa2..8b04eb2 100644 --- a/target-i386/smm_helper.c +++ b/target-i386/smm_helper.c @@ -18,18 +18,17 @@ */ #include "cpu.h" -#include "dyngen-exec.h" #include "helper.h" /* SMM support */ #if defined(CONFIG_USER_ONLY) -void do_smm_enter(CPUX86State *env1) +void do_smm_enter(CPUX86State *env) { } -void helper_rsm(void) +void helper_rsm(CPUX86State *env) { } @@ -41,15 +40,11 @@ void helper_rsm(void) #define SMM_REVISION_ID 0x0002 #endif -void do_smm_enter(CPUX86State *env1) +void do_smm_enter(CPUX86State *env) { target_ulong sm_state; SegmentCache *dt; int i, offset; -CPUX86State *saved_env; - -saved_env = env; -env = env1; qemu_log_mask(CPU_LOG_INT, "SMM: enter\n"); log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP); @@ -180,10 +175,9 @@ void do_smm_enter(CPUX86State *env1) cpu_x86_update_cr4(env, 0); env->dr[7] = 0x0400; CC_OP = CC_OP_EFLAGS; -env = saved_env; } -void helper_rsm(void) +void helper_rsm(CPUX86State *env) { target_ulong sm_state; int i, offset; diff --git a/target-i386/translate.c b/target-i386/translate.c index 9f4c712..840d281 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7721,7 +7721,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) goto illegal_op; gen_update_cc_op(s); gen_jmp_im(s->pc - s->cs_base); -gen_helper_rsm(); +gen_helper_rsm(cpu_env); gen_eob(s); break; case 0x1b8: /* SSE4.2 popcnt */ -- 1.7.2.5
Re: [Qemu-devel] [RFC V2 03/10] quorum: Add quorum_open().
On Tue, Aug 7, 2012 at 1:44 PM, Benoît Canet wrote: > Signed-off-by: Benoit Canet > --- > block/quorum.c | 62 > > 1 file changed, 62 insertions(+) > > diff --git a/block/quorum.c b/block/quorum.c > index e0405b6..de58ab8 100644 > --- a/block/quorum.c > +++ b/block/quorum.c > @@ -47,11 +47,73 @@ struct QuorumAIOCB { > int vote_ret; > }; > > +/* Valid quorum filenames look like > + * quorum:path/to/a_image:path/to/b_image:path/to/c_image This syntax would mean that stacking for example curl or other network paths would not be possible. How about comma as separator? > + */ > +static int quorum_open(BlockDriverState *bs, const char *filename, int flags) > +{ > +BDRVQuorumState *s = bs->opaque; > +int ret, i; > +char *a, *b, *c, *filenames[3]; > + > +/* Parse the quorum: prefix */ > +if (strncmp(filename, "quorum:", strlen("quorum:"))) { > +return -EINVAL; > +} > +a = g_strdup(filename + strlen("quorum:")); > + > +/* Find separators */ > +b = strchr(a, ':'); > +if (b == NULL) { > +return -EINVAL; > +} > + > +c = strrchr(a, ':'); > +if (c == NULL) { > +return -EINVAL; > +} > + > +/* Check that filename contains two separate ':' */ > +if (b == c) { > +return -EINVAL; > +} > + > +/* Split string */ > +*b = '\0'; > +*c = '\0'; > + > +filenames[0] = a; > +filenames[1] = b + 1; > +filenames[2] = c + 1; > + > +/* Open files */ > +for (i = 0; i <= 2; i++) { > +s->bs[i] = bdrv_new(""); > +ret = bdrv_open(s->bs[i], filenames[i], flags, NULL); > +if (ret < 0) { > +goto error_exit; Successfully opening two out of three should be enough, but maybe it does not make much sense. > +} > +} > + > +goto clean_exit; > + > +error_exit: > +for (; i >= 0; i--) { > +bdrv_delete(s->bs[i]); bdrv_close() instead? > +s->bs[i] = NULL; > +} > +clean_exit: > +g_free(a); > +return ret; > +} > + > static BlockDriver bdrv_quorum = { > .format_name= "quorum", > .protocol_name = "quorum", > > .instance_size = sizeof(BDRVQuorumState), > + > +.bdrv_file_open = quorum_open, > }; > > static void bdrv_quorum_init(void) > -- > 1.7.9.5 >
Re: [Qemu-devel] For all targets and machine types: "start to monitor" smoke test
Peter Maydell writes: > On 7 August 2012 20:55, Markus Armbruster wrote: >> Anthony Liguori writes: >>> Perhaps we could add a QEMUMachine parameter that indicates that the >>> machine doesn't start without special options. >> >> Recommend to make it a string that lists the mandatory options. > > How are you going to say "need either option foo or option bar" ? I'm > pretty sure we have some of those (eg "either you need to pass a flash > image or a kernel"). Yes, we do. The string should be suitable for inserting into -help.
[Qemu-devel] [PATCH v2 9/9] x86: switch to AREG0 free mode
Add an explicit CPUX86State parameter instead of relying on AREG0. Remove temporary wrappers and switch to AREG0 free mode. Signed-off-by: Blue Swirl --- configure |2 +- cpu-all.h | 22 ++ target-i386/Makefile.objs |2 - target-i386/cpu.h | 21 - target-i386/fpu_helper.c |4 + target-i386/helper.h |8 +- target-i386/mem_helper.c | 101 +- target-i386/misc_helper.c |4 + target-i386/seg_helper.c |4 + target-i386/svm_helper.c |4 + target-i386/translate.c | 179 +++-- 11 files changed, 151 insertions(+), 200 deletions(-) diff --git a/configure b/configure index 280726c..f4711bc 100755 --- a/configure +++ b/configure @@ -3755,7 +3755,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile" case "$target_arch2" in - alpha | or32 | sparc* | xtensa* | ppc*) + alpha | i386 | or32 | sparc* | x86_64 | xtensa* | ppc*) echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak ;; esac diff --git a/cpu-all.h b/cpu-all.h index 82ba1d7..5e07d28 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -274,6 +274,28 @@ extern unsigned long reserved_va; #define cpu_ldsw_code(env1, p) ldsw_raw(p) #define cpu_ldl_code(env1, p) ldl_raw(p) #define cpu_ldq_code(env1, p) ldq_raw(p) + +#define cpu_ldub_data(env, addr) ldub_raw(addr) +#define cpu_lduw_data(env, addr) lduw_raw(addr) +#define cpu_ldsw_data(env, addr) ldsw_raw(addr) +#define cpu_ldl_data(env, addr) ldl_raw(addr) +#define cpu_ldq_data(env, addr) ldq_raw(addr) + +#define cpu_stb_data(env, addr, data) stb_raw(addr, data) +#define cpu_stw_data(env, addr, data) stw_raw(addr, data) +#define cpu_stl_data(env, addr, data) stl_raw(addr, data) +#define cpu_stq_data(env, addr, data) stq_raw(addr, data) + +#define cpu_ldub_kernel(env, addr) ldub_raw(addr) +#define cpu_lduw_kernel(env, addr) lduw_raw(addr) +#define cpu_ldsw_kernel(env, addr) ldsw_raw(addr) +#define cpu_ldl_kernel(env, addr) ldl_raw(addr) +#define cpu_ldq_kernel(env, addr) ldq_raw(addr) + +#define cpu_stb_kernel(env, addr, data) stb_raw(addr, data) +#define cpu_stw_kernel(env, addr, data) stw_raw(addr, data) +#define cpu_stl_kernel(env, addr, data) stl_raw(addr, data) +#define cpu_stq_kernel(env, addr, data) stq_raw(addr, data) #endif #define ldub_kernel(p) ldub_raw(p) diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index 3ea19ca..963698a 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -5,5 +5,3 @@ obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o obj-$(CONFIG_KVM) += kvm.o hyperv.o obj-$(CONFIG_LINUX_USER) += ioport-user.o obj-$(CONFIG_BSD_USER) += ioport-user.o - -$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 2d4ca0d..2a61c81 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1137,25 +1137,4 @@ void do_smm_enter(CPUX86State *env1); void cpu_report_tpr_access(CPUX86State *env, TPRAccess access); -/* temporary wrappers */ -uint32_t cpu_ldub_data(CPUX86State *env, target_ulong ptr); -uint32_t cpu_lduw_data(CPUX86State *env, target_ulong ptr); -uint32_t cpu_ldl_data(CPUX86State *env, target_ulong ptr); -uint64_t cpu_ldq_data(CPUX86State *env, target_ulong ptr); - -void cpu_stb_data(CPUX86State *env, target_ulong ptr, uint32_t data); -void cpu_stw_data(CPUX86State *env, target_ulong ptr, uint32_t data); -void cpu_stl_data(CPUX86State *env, target_ulong ptr, uint32_t data); -void cpu_stq_data(CPUX86State *env, target_ulong ptr, uint64_t data); - -uint32_t cpu_ldub_kernel(CPUX86State *env, target_ulong ptr); -uint32_t cpu_lduw_kernel(CPUX86State *env, target_ulong ptr); -uint32_t cpu_ldl_kernel(CPUX86State *env, target_ulong ptr); -uint64_t cpu_ldq_kernel(CPUX86State *env, target_ulong ptr); - -void cpu_stb_kernel(CPUX86State *env, target_ulong ptr, uint32_t data); -void cpu_stw_kernel(CPUX86State *env, target_ulong ptr, uint32_t data); -void cpu_stl_kernel(CPUX86State *env, target_ulong ptr, uint32_t data); -void cpu_stq_kernel(CPUX86State *env, target_ulong ptr, uint64_t data); - #endif /* CPU_I386_H */ diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c index a1d7ef7..dfc34a6 100644 --- a/target-i386/fpu_helper.c +++ b/target-i386/fpu_helper.c @@ -21,6 +21,10 @@ #include "cpu.h" #include "helper.h" +#if !defined(CONFIG_USER_ONLY) +#include "softmmu_exec.h" +#endif /* !defined(CONFIG_USER_ONLY) */ + #define FPU_RC_MASK 0xc00 #define FPU_RC_NEAR 0x000 #define FPU_RC_DOWN 0x400 diff --git a/target-i386/helper.h b/target-i386/helper.h index 0f02103..ab6af63 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -69,13 +69,13 @@ DEF_HELPER_1(cli, void, env) DEF_HELPER_1(sti, void, env) DEF_HELPER_1(set_inhibit_irq, void, env) DEF_HELPER_1(reset_inhibit_irq, void, env) -DEF_HELPER_2(boundw, void, tl, int) -DEF_HELPER_2(boundl, void, tl, int) +DEF_HE
[Qemu-devel] [RFC 10/15] create object_prop_set_globals()
It's like qdev_prop_set_globals(), but calls object_property_parse(). Signed-off-by: Eduardo Habkost --- global-properties.c | 5 + hw/qdev.h | 1 + 2 files changed, 6 insertions(+) diff --git a/global-properties.c b/global-properties.c index d99bcee..d827955 100644 --- a/global-properties.c +++ b/global-properties.c @@ -54,6 +54,11 @@ void qdev_prop_set_globals(DeviceState *dev) return object_set_globals(OBJECT(dev), qdev_global_parse); } +void object_prop_set_globals(Object *obj) +{ +return object_set_globals(obj, object_property_parse); +} + static int qdev_add_one_global(QemuOpts *opts, void *opaque) { GlobalProperty *g; diff --git a/hw/qdev.h b/hw/qdev.h index 41db6c0..b522f11 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -331,6 +331,7 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); void qdev_prop_register_global_list(GlobalProperty *props); void qdev_prop_set_globals(DeviceState *dev); +void object_prop_set_globals(Object *obj); void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, Property *prop, const char *value); -- 1.7.11.2
[Qemu-devel] [RFC 05/15] remove FW_CFG_MAX_CPUS from fw_cfg_init()
PC will not use max_cpus for that field, so move it outside the common code so it can use a different value on PC. Signed-off-by: Eduardo Habkost --- hw/fw_cfg.c | 1 - hw/pc.c | 2 +- hw/ppc_newworld.c | 1 + hw/ppc_oldworld.c | 1 + hw/sun4m.c| 3 +++ hw/sun4u.c| 1 + 6 files changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c index 7b3b576..ce3da2e 100644 --- a/hw/fw_cfg.c +++ b/hw/fw_cfg.c @@ -494,7 +494,6 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port, fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16); fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC)); fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); -fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu); fw_cfg_bootsplash(s); diff --git a/hw/pc.c b/hw/pc.c index 81c391c..10449bd 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -602,7 +602,7 @@ static void *bochs_bios_init(void) register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL); fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0); - +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES, (uint8_t *)acpi_tables, diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index 4e2a6e6..13c597c 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -381,6 +381,7 @@ static void ppc_core99_init (ram_addr_t ram_size, /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch); diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index f2c6908..7b6af68 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -296,6 +296,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size, /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW); diff --git a/hw/sun4m.c b/hw/sun4m.c index a959261..edaaeaa 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -1000,6 +1000,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size, hwdef->ecc_version); fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); @@ -1611,6 +1612,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, "Sun4d"); fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); @@ -1803,6 +1805,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size, "Sun4c"); fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); diff --git a/hw/sun4u.c b/hw/sun4u.c index 137a7c6..2291270 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -873,6 +873,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, (uint8_t *)&nd_table[0].macaddr); fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0); +fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id); -- 1.7.11.2
[Qemu-devel] [RFC 13/15] tests: support target-specific unit tests
To make unit tests that depend on target-specific files, use check-unit--y and test-obj--y. Signed-off-by: Eduardo Habkost --- tests/Makefile | 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index f3f4159..79796aa 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -40,8 +40,6 @@ test-qapi-obj-y = $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o test-qapi-obj-y += module.o -$(test-obj-y): QEMU_INCLUDES += -Itests - tests/check-qint$(EXESUF): tests/check-qint.o qint.o $(tools-obj-y) tests/check-qstring$(EXESUF): tests/check-qstring.o qstring.o $(tools-obj-y) tests/check-qdict$(EXESUF): tests/check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qlist.o $(tools-obj-y) @@ -75,9 +73,21 @@ tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y) tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y) tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o $(trace-obj-y) -# QTest rules +# unit test rules: TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGET_DIRS))) + +# target-specific tests/objs: +test-obj-y += $(foreach TARGET,$(TARGETS), $(test-obj-$(TARGET)-y)) +check-unit-y += $(foreach TARGET,$(TARGETS), $(check-unit-$(TARGET)-y)) + +$(foreach TARGET,$(TARGETS),$(eval $(test-obj-$(TARGET)-y): QEMU_INCLUDES += -Itarget-$(TARGET))) + + +$(test-obj-y): QEMU_INCLUDES += -Itests + +# QTest rules + QTEST_TARGETS=$(foreach TARGET,$(TARGETS), $(if $(check-qtest-$(TARGET)-y), $(TARGET),)) check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y)) -- 1.7.11.2
[Qemu-devel] [RFC 00/15] attempt to fix CPU topology info on CPU APIC IDs
First, the bug description: The CPU APIC IDs generated by QEMU are broken if the number of cores-per-socket or threads-per-core are not powers of 2, as the bits on the APIC ID do not correspond to what's expected to reflect the CPU sockets/cores/threads topology[1]. [1] http://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/ This is an attempt to fix it, but there were some obstacles on the way: 1) The NUMA fw_cfg interface requires the full topology information to be available even for hotplug CPUs that don't exist yet, so we need to be able to calculate the APIC ID solely from the CPU index. 2) CPU objects are not qdev objects (yet). 3) We don't have a "list CPUs" object (yet), so we don't have an object where a compatibility global property could be set, and that would be responsible for calculating the APIC IDs. That said, the patches are organized as follows: - Patches 1 to 3 are just code movements or smaller fixes to prepare for the actual fix. They should be safe to be applied right now. - Patches 4 to 6 addresses issue #1 above. - Patches 7 to 12 change the global property handling code to make it at least possible to use a global property without requiring QOM or qdev (due to issues #2 and #3 above). I expect it to be controversial and I would like to get some feedback. - Patches 13 and 14 are the actual fix, that changes the APIC ID calculation to match the requested CPU topology, and use a "SMP.contiguous_apic_ids" global property to keep compatibility on pc-1.1 and older machine-types. The fix depends on commit 008c1fc5bd4f1c545c38e07242ad676830ea7785 of SeaBIOS, that allows CPU APIC IDs to be non-contiguous. However, older SeaBIOS verions should still work, as long as cores/threads are powers of 2 or you use the "pc-1.1" machine-type (or older). I am aware of the coding style warnings from checkpatch.pl (mainly "line over 80 characters" warnings), and I plan to fix them in the final version of the fix. Eduardo Habkost (15): cpus.h: include cpu-common.h hw/apic.c: rename bit functions to not conflict with bitops.h (v2) kvm: set vcpu_id to APIC ID instead of CPU index i386: create apic_id_for_cpu() function (v2) remove FW_CFG_MAX_CPUS from fw_cfg_init() pc: set FW_CFG data based on APIC ID calculation qdev: allow qdev_prop_parse() to report errors move global properties code to global-properties.c isolate qdev-independent parts of qdev_prop_set_globals() create object_prop_set_globals() rename qdev_prop_register_global_list to qemu_globals_register_list create qemu_global_get() function tests: support target-specific unit tests i386: topology & APIC ID utility functions (v2) generate APIC IDs according to CPU topology (v2) Makefile.objs | 1 + cpus.h | 2 + global-properties.c| 88 ++ hw/apic.c | 35 ++-- hw/fw_cfg.c| 1 - hw/pc.c| 23 +--- hw/pc_piix.c | 4 ++ hw/ppc_newworld.c | 1 + hw/ppc_oldworld.c | 1 + hw/qdev-monitor.c | 6 ++- hw/qdev-properties.c | 67 ++- hw/qdev.h | 18 +-- hw/sun4m.c | 3 ++ hw/sun4u.c | 1 + kvm-all.c | 2 +- target-i386/cpu.c | 40 +- target-i386/cpu.h | 17 ++ target-i386/topology.h | 144 + tests/.gitignore | 1 + tests/Makefile | 19 +-- tests/test-x86-cpuid.c | 108 + vl.c | 6 +-- 22 files changed, 488 insertions(+), 100 deletions(-) create mode 100644 global-properties.c create mode 100644 target-i386/topology.h create mode 100644 tests/test-x86-cpuid.c -- 1.7.11.2
Re: [Qemu-devel] [RFC V2 01/10] quorum: Create quorum.c, add QuorumSingleAIOCB and QuorumAIOCB.
On Tue, Aug 7, 2012 at 1:44 PM, Benoît Canet wrote: > Signed-off-by: Benoit Canet > --- > block/Makefile.objs |1 + > block/quorum.c | 44 > 2 files changed, 45 insertions(+) > create mode 100644 block/quorum.c > > diff --git a/block/Makefile.objs b/block/Makefile.objs > index b5754d3..66af6dc 100644 > --- a/block/Makefile.objs > +++ b/block/Makefile.objs > @@ -4,6 +4,7 @@ block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o > qed-cluster.o > block-obj-y += qed-check.o > block-obj-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o > block-obj-y += stream.o > +block-obj-y += quorum.o > block-obj-$(CONFIG_WIN32) += raw-win32.o > block-obj-$(CONFIG_POSIX) += raw-posix.o > block-obj-$(CONFIG_LIBISCSI) += iscsi.o > diff --git a/block/quorum.c b/block/quorum.c > new file mode 100644 > index 000..046b183 > --- /dev/null > +++ b/block/quorum.c > @@ -0,0 +1,44 @@ > +/* > + * Quorum Block filter > + * > + * Copyright (C) Nodalink, SARL. 2012 > + * > + * Author: > + * Benoît Canet > + * > + * Based on the design and code of blkverify.c (Copyright (C) 2010 IBM, Corp) > + * and blkmirror.c (Copyright (C) 2011 Red Hat, Inc). > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + */ > + > +#include "block_int.h" > + > +typedef struct QuorumAIOCB QuorumAIOCB; > + > +typedef struct QuorumSingleAIOCB { > +BlockDriverAIOCB *aiocb; > +char *buf; uint8_t *buf? > +int ret; > +QuorumAIOCB *parent; > +} QuorumSingleAIOCB; > + > +struct QuorumAIOCB { > +BlockDriverAIOCB common; > +QEMUBH *bh; > + > +/* Request metadata */ > +int64_t sector_num; > +int nb_sectors; > + > +QEMUIOVector *qiov; /* calling readv IOV */ > + > +QuorumSingleAIOCB aios[3]; /* individual AIOs */ > +QEMUIOVector qiovs[3]; /* individual IOVs */ > +int count; /* number of completed AIOCB */ > +bool *finished; /* completion signal for cancel */ > + > +void (*vote)(QuorumAIOCB *acb); > +int vote_ret; > +}; > -- > 1.7.9.5 >
Re: [Qemu-devel] [RFC/PATCH 1/1] USB code fenced for s390
On Tue, Aug 7, 2012 at 12:26 PM, Peter Maydell wrote: > On 7 August 2012 13:19, Christian Borntraeger wrote: >> +#if defined(TARGET_HAS_USB) && (TARGET_HAS_USB == 1) >> /* init USB devices */ >> if (usb_enabled) { >> if (foreach_device_config(DEV_USB, usb_parse) < 0) >> exit(1); >> } >> +#endif > > Whether there is USB or not is a property of the machine model, > not the target CPU architecture, so a TARGET_HAS_USB define > is definitely the wrong approach. Yes. I'd add CONFIG_USB=y to files in default-configs/ except for s390*, Sparc32 and user emulators. Unless it's enough for USB to have a dependency on PCI? > > -- PMM >
[Qemu-devel] [RFC 02/15] hw/apic.c: rename bit functions to not conflict with bitops.h (v2)
Changes v1 -> v2: - Coding style change: break too-long line Signed-off-by: Eduardo Habkost --- hw/apic.c | 35 ++- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/hw/apic.c b/hw/apic.c index 38e..e1f633a 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -51,7 +51,7 @@ static int ffs_bit(uint32_t value) return ctz32(value); } -static inline void set_bit(uint32_t *tab, int index) +static inline void apic_set_bit(uint32_t *tab, int index) { int i, mask; i = index >> 5; @@ -59,7 +59,7 @@ static inline void set_bit(uint32_t *tab, int index) tab[i] |= mask; } -static inline void reset_bit(uint32_t *tab, int index) +static inline void apic_reset_bit(uint32_t *tab, int index) { int i, mask; i = index >> 5; @@ -67,7 +67,7 @@ static inline void reset_bit(uint32_t *tab, int index) tab[i] &= ~mask; } -static inline int get_bit(uint32_t *tab, int index) +static inline int apic_get_bit(uint32_t *tab, int index) { int i, mask; i = index >> 5; @@ -184,7 +184,7 @@ void apic_deliver_pic_intr(DeviceState *d, int level) case APIC_DM_FIXED: if (!(lvt & APIC_LVT_LEVEL_TRIGGER)) break; -reset_bit(s->irr, lvt & 0xff); +apic_reset_bit(s->irr, lvt & 0xff); /* fall through */ case APIC_DM_EXTINT: cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); @@ -379,13 +379,13 @@ void apic_poll_irq(DeviceState *d) static void apic_set_irq(APICCommonState *s, int vector_num, int trigger_mode) { -apic_report_irq_delivered(!get_bit(s->irr, vector_num)); +apic_report_irq_delivered(!apic_get_bit(s->irr, vector_num)); -set_bit(s->irr, vector_num); +apic_set_bit(s->irr, vector_num); if (trigger_mode) -set_bit(s->tmr, vector_num); +apic_set_bit(s->tmr, vector_num); else -reset_bit(s->tmr, vector_num); +apic_reset_bit(s->tmr, vector_num); if (s->vapic_paddr) { apic_sync_vapic(s, SYNC_ISR_IRR_TO_VAPIC); /* @@ -405,8 +405,9 @@ static void apic_eoi(APICCommonState *s) isrv = get_highest_priority_int(s->isr); if (isrv < 0) return; -reset_bit(s->isr, isrv); -if (!(s->spurious_vec & APIC_SV_DIRECTED_IO) && get_bit(s->tmr, isrv)) { +apic_reset_bit(s->isr, isrv); +if (!(s->spurious_vec & APIC_SV_DIRECTED_IO) && +apic_get_bit(s->tmr, isrv)) { ioapic_eoi_broadcast(isrv); } apic_sync_vapic(s, SYNC_FROM_VAPIC | SYNC_TO_VAPIC); @@ -445,7 +446,7 @@ static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask, int idx = apic_find_dest(dest); memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t)); if (idx >= 0) -set_bit(deliver_bitmask, idx); +apic_set_bit(deliver_bitmask, idx); } } else { /* XXX: cluster mode */ @@ -455,11 +456,11 @@ static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask, if (apic_iter) { if (apic_iter->dest_mode == 0xf) { if (dest & apic_iter->log_dest) -set_bit(deliver_bitmask, i); +apic_set_bit(deliver_bitmask, i); } else if (apic_iter->dest_mode == 0x0) { if ((dest & 0xf0) == (apic_iter->log_dest & 0xf0) && (dest & apic_iter->log_dest & 0x0f)) { -set_bit(deliver_bitmask, i); +apic_set_bit(deliver_bitmask, i); } } } else { @@ -502,14 +503,14 @@ static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode, break; case 1: memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask)); -set_bit(deliver_bitmask, s->idx); +apic_set_bit(deliver_bitmask, s->idx); break; case 2: memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask)); break; case 3: memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask)); -reset_bit(deliver_bitmask, s->idx); +apic_reset_bit(deliver_bitmask, s->idx); break; } @@ -566,8 +567,8 @@ int apic_get_interrupt(DeviceState *d) apic_sync_vapic(s, SYNC_TO_VAPIC); return s->spurious_vec & 0xff; } -reset_bit(s->irr, intno); -set_bit(s->isr, intno); +apic_reset_bit(s->irr, intno); +apic_set_bit(s->isr, intno); apic_sync_vapic(s, SYNC_TO_VAPIC); /* re-inject if there is still a pending PIC interrupt */ -- 1.7.11.2
Re: [Qemu-devel] [PATCH v5 1/2] qemu: Add a config option for GlusterFS as block backend
On Tue, Aug 7, 2012 at 8:00 AM, Bharata B Rao wrote: > qemu: Add a config option for GlusterFS as block backend > > From: Bharata B Rao > > GlusterFS support in QEMU depends on libgfapi, libgfrpc and > libgfxdr provided by GlusterFS. > > Signed-off-by: Bharata B Rao > --- > > configure | 34 ++ > 1 files changed, 34 insertions(+), 0 deletions(-) > > > diff --git a/configure b/configure > index 027a718..5bcf6d5 100755 > --- a/configure > +++ b/configure > @@ -824,6 +824,10 @@ for opt do >;; >--disable-guest-agent) guest_agent="no" >;; > + --disable-glusterfs) glusterfs="no" This is the first use of $glusterfs. Please define the default value, the rationale is given at the start of configure: # Default value for a variable defining feature "foo". # * foo="no" feature will only be used if --enable-foo arg is given # * foo=""feature will be searched for, and if found, will be used # unless --disable-foo is given # * foo="yes" this value will only be set by --enable-foo flag. # feature will searched for, # if not found, configure exits with error I think "" would match other features. > + ;; > + --enable-glusterfs) glusterfs="yes" > + ;; >*) echo "ERROR: unknown option $opt"; show_help="yes" >;; >esac > @@ -1112,6 +1116,8 @@ echo " --disable-guest-agentdisable building of > the QEMU Guest Agent" > echo " --enable-guest-agent enable building of the QEMU Guest Agent" > echo " --with-coroutine=BACKEND coroutine backend. Supported options:" > echo " gthread, ucontext, sigaltstack, windows" > +echo " --enable-glusterfs enable GlusterFS backend" > +echo " --disable-glusterfs disable GlusterFS backend" > echo "" > echo "NOTE: The object files are built at the place where configure is > launched" > exit 1 > @@ -2279,6 +2285,29 @@ EOF >fi > fi > > +## > +# glusterfs probe > +if test "$glusterfs" != "no" ; then > + cat > $TMPC < +#include > +int main(void) { > +(void) glfs_new("volume"); > +return 0; > +} > +EOF > + glusterfs_libs="-lgfapi -lgfrpc -lgfxdr" > + if compile_prog "" "$glusterfs_libs" ; then > +glusterfs=yes > +libs_tools="$glusterfs_libs $libs_tools" > +libs_softmmu="$glusterfs_libs $libs_softmmu" > + else > +if test "$glusterfs" = "yes" ; then > + feature_not_found "GlusterFS backend support" > +fi > +glusterfs=no > + fi > +fi > + > # > # Check for xxxat() functions when we are building linux-user > # emulator. This is done because older glibc versions don't > @@ -3104,6 +3133,7 @@ echo "OpenGL support$opengl" > echo "libiscsi support $libiscsi" > echo "build guest agent $guest_agent" > echo "coroutine backend $coroutine_backend" > +echo "GlusterFS support $glusterfs" > > if test "$sdl_too_old" = "yes"; then > echo "-> Your SDL version is too old - please upgrade to have SDL support" > @@ -3441,6 +3471,10 @@ if test "$has_environ" = "yes" ; then >echo "CONFIG_HAS_ENVIRON=y" >> $config_host_mak > fi > > +if test "$glusterfs" = "yes" ; then > + echo "CONFIG_GLUSTERFS=y" >> $config_host_mak > +fi > + > # USB host support > case "$usb" in > linux) >
[Qemu-devel] [RFC 08/15] move global properties code to global-properties.c
Signed-off-by: Eduardo Habkost --- Makefile.objs| 1 + global-properties.c | 56 hw/qdev-properties.c | 54 -- 3 files changed, 57 insertions(+), 54 deletions(-) create mode 100644 global-properties.c diff --git a/Makefile.objs b/Makefile.objs index 5ebbcfa..5cd4082 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -77,6 +77,7 @@ common-obj-y += qemu-char.o #aio.o common-obj-y += block-migration.o iohandler.o common-obj-y += pflib.o common-obj-y += bitmap.o bitops.o +common-obj-y += global-properties.o common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o common-obj-$(CONFIG_WIN32) += version.o diff --git a/global-properties.c b/global-properties.c new file mode 100644 index 000..a1c3581 --- /dev/null +++ b/global-properties.c @@ -0,0 +1,56 @@ +#include "hw/qdev.h" +#include "qerror.h" + +static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props); + +static void qdev_prop_register_global(GlobalProperty *prop) +{ +QTAILQ_INSERT_TAIL(&global_props, prop, next); +} + +void qdev_prop_register_global_list(GlobalProperty *props) +{ +int i; + +for (i = 0; props[i].driver != NULL; i++) { +qdev_prop_register_global(props+i); +} +} + +void qdev_prop_set_globals(DeviceState *dev) +{ +ObjectClass *class = object_get_class(OBJECT(dev)); + +do { +GlobalProperty *prop; +Error *err = NULL; +QTAILQ_FOREACH(prop, &global_props, next) { +if (strcmp(object_class_get_name(class), prop->driver) != 0) { +continue; +} +qdev_prop_parse(dev, prop->property, prop->value, &err); +if (err) { +qerror_report_err(err); +exit(1); +} +} +class = object_class_get_parent(class); +} while (class); +} + +static int qdev_add_one_global(QemuOpts *opts, void *opaque) +{ +GlobalProperty *g; + +g = g_malloc0(sizeof(*g)); +g->driver = qemu_opt_get(opts, "driver"); +g->property = qemu_opt_get(opts, "property"); +g->value= qemu_opt_get(opts, "value"); +qdev_prop_register_global(g); +return 0; +} + +void qemu_add_globals(void) +{ +qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0); +} diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index a52884f..3217490 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -1219,57 +1219,3 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) ptr = qdev_get_prop_ptr(dev, prop); *ptr = value; } - -static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props); - -static void qdev_prop_register_global(GlobalProperty *prop) -{ -QTAILQ_INSERT_TAIL(&global_props, prop, next); -} - -void qdev_prop_register_global_list(GlobalProperty *props) -{ -int i; - -for (i = 0; props[i].driver != NULL; i++) { -qdev_prop_register_global(props+i); -} -} - -void qdev_prop_set_globals(DeviceState *dev) -{ -ObjectClass *class = object_get_class(OBJECT(dev)); - -do { -GlobalProperty *prop; -Error *err = NULL; -QTAILQ_FOREACH(prop, &global_props, next) { -if (strcmp(object_class_get_name(class), prop->driver) != 0) { -continue; -} -qdev_prop_parse(dev, prop->property, prop->value, &err); -if (err) { -qerror_report_err(err); -exit(1); -} -} -class = object_class_get_parent(class); -} while (class); -} - -static int qdev_add_one_global(QemuOpts *opts, void *opaque) -{ -GlobalProperty *g; - -g = g_malloc0(sizeof(*g)); -g->driver = qemu_opt_get(opts, "driver"); -g->property = qemu_opt_get(opts, "property"); -g->value= qemu_opt_get(opts, "value"); -qdev_prop_register_global(g); -return 0; -} - -void qemu_add_globals(void) -{ -qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0); -} -- 1.7.11.2
Re: [Qemu-devel] For all targets and machine types: "start to monitor" smoke test
On 7 August 2012 20:55, Markus Armbruster wrote: > Anthony Liguori writes: >> Perhaps we could add a QEMUMachine parameter that indicates that the >> machine doesn't start without special options. > > Recommend to make it a string that lists the mandatory options. How are you going to say "need either option foo or option bar" ? I'm pretty sure we have some of those (eg "either you need to pass a flash image or a kernel"). -- PMM
Re: [Qemu-devel] [PATCH v6 2/6] qapi: Introduce add-fd, remove-fd, query-fdsets
On 08/07/2012 02:16 PM, Stefan Hajnoczi wrote: On Fri, Aug 3, 2012 at 6:28 PM, Corey Bryant wrote: diff --git a/monitor.c b/monitor.c index 49dccfe..9aa9f7e 100644 --- a/monitor.c +++ b/monitor.c @@ -140,6 +140,24 @@ struct mon_fd_t { QLIST_ENTRY(mon_fd_t) next; }; +/* file descriptor associated with a file descriptor set */ +typedef struct mon_fdset_fd_t mon_fdset_fd_t; +struct mon_fdset_fd_t { QEMU coding style is: typedef struct MonFdsetFd MonFdsetFd; struct MonFdsetFd { See ./CODING_STYLE for more info. Thanks, I'll fix that. +int fd; +bool removed; +QLIST_ENTRY(mon_fdset_fd_t) next; +}; + +/* file descriptor set containing fds passed via SCM_RIGHTS */ +typedef struct mon_fdset_t mon_fdset_t; +struct mon_fdset_t { +int64_t id; +int refcount; +bool in_use; +QLIST_HEAD(, mon_fdset_fd_t) fds; +QLIST_ENTRY(mon_fdset_t) next; +}; At this point in the patch series it's not clear to me whether the removed and refcount/in_use fields are a clean and correct solution. Exposing these fields via QMP is also something I'm going to carefully review because they seem like internals. Yes, please review the v7 patches and let me know what you think. I explained the purpose of these fields in the previous email I just sent you, so I won't go into their details again here. But I will point out that refcount/in-use came about after concern of fd leakage if libvirt's monitor connection disconnects. query-fdsets allows the client to determine the state of the fd sets after reconnecting. + typedef struct MonitorControl { QObject *id; JSONMessageParser parser; @@ -176,7 +194,8 @@ struct Monitor { int print_calls_nr; #endif QError *error; -QLIST_HEAD(,mon_fd_t) fds; +QLIST_HEAD(, mon_fd_t) fds; +QLIST_HEAD(, mon_fdset_t) fdsets; QLIST_ENTRY(Monitor) entry; }; @@ -2389,6 +2408,157 @@ int monitor_get_fd(Monitor *mon, const char *fdname) return -1; } +static void monitor_fdset_cleanup(mon_fdset_t *mon_fdset) +{ +mon_fdset_fd_t *mon_fdset_fd; +mon_fdset_fd_t *mon_fdset_fd_next; + +if (mon_fdset->refcount != 0) { +return; +} + +QLIST_FOREACH_SAFE(mon_fdset_fd, &mon_fdset->fds, next, mon_fdset_fd_next) { +if (!mon_fdset->in_use || mon_fdset_fd->removed) { +close(mon_fdset_fd->fd); +QLIST_REMOVE(mon_fdset_fd, next); +g_free(mon_fdset_fd); +} +} + +if (QLIST_EMPTY(&mon_fdset->fds)) { +QLIST_REMOVE(mon_fdset, next); +g_free(mon_fdset); +} +} + +AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, Error **errp) +{ +int fd; +Monitor *mon = cur_mon; +mon_fdset_t *mon_fdset; +mon_fdset_fd_t *mon_fdset_fd; +AddfdInfo *fdinfo; + +fd = qemu_chr_fe_get_msgfd(mon->chr); +if (fd == -1) { +qerror_report(QERR_FD_NOT_SUPPLIED); +return NULL; +} + +if (has_fdset_id) { +QLIST_FOREACH(mon_fdset, &mon->fdsets, next) { +if (mon_fdset->id == fdset_id) { +break; +} +} +if (mon_fdset == NULL) { +qerror_report(QERR_FDSET_NOT_FOUND, fdset_id); +return NULL; fd is leaked? Yes, it looks like it is. I'll fix that. +} +} else { +int64_t fdset_id_prev = -1; +mon_fdset_t *mon_fdset_cur = QLIST_FIRST(&mon->fdsets); + +/* Use first available fdset ID */ +QLIST_FOREACH(mon_fdset, &mon->fdsets, next) { +mon_fdset_cur = mon_fdset; +if (fdset_id_prev == mon_fdset_cur->id - 1) { +fdset_id_prev = mon_fdset_cur->id; +continue; +} +break; +} + +mon_fdset = g_malloc0(sizeof(*mon_fdset)); +mon_fdset->id = fdset_id_prev + 1; +mon_fdset->refcount = 0; +mon_fdset->in_use = true; + +/* The fdset list is ordered by fdset ID */ +if (mon_fdset->id == 0) { +QLIST_INSERT_HEAD(&mon->fdsets, mon_fdset, next); +} else if (mon_fdset->id < mon_fdset_cur->id) { +QLIST_INSERT_BEFORE(mon_fdset_cur, mon_fdset, next); +} else { +QLIST_INSERT_AFTER(mon_fdset_cur, mon_fdset, next); +} +} + +mon_fdset_fd = g_malloc0(sizeof(*mon_fdset_fd)); +mon_fdset_fd->fd = fd; +mon_fdset_fd->removed = false; +QLIST_INSERT_HEAD(&mon_fdset->fds, mon_fdset_fd, next); + +fdinfo = g_malloc0(sizeof(*fdinfo)); +fdinfo->fdset_id = mon_fdset->id; +fdinfo->fd = mon_fdset_fd->fd; + +return fdinfo; +} + +void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp) +{ +Monitor *mon = cur_mon; +mon_fdset_t *mon_fdset; +mon_fdset_fd_t *mon_fdset_fd; +char fd_str[20]; + +QLIST_FOREACH(mon_fdset, &mon->fdsets, next) { +if (mon_fdset->id != fdset_id) { +continue; +} +QLIST_FOREACH(mon_fdset_fd, &mon_fds
[Qemu-devel] [RFC 14/15] i386: topology & APIC ID utility functions (v2)
Changes v1 -> v2: - Support 32-bit APIC IDs (in case x2APIC is going to be used) - Coding style changes - Use TARGET_I386_TOPOLOGY_H instead of __QEMU_X86_TOPOLOGY_H__ - Rename topo_make_apic_id() to topo_apicid_for_cpu() - Rename __make_apicid() to topo_make_apicid() - Spaces around operators on test-x86-cpuid.c, as requested by Blue Swirl - Make test-x86-cpuid a target-specific test Cc: Blue Swirl Signed-off-by: Eduardo Habkost --- target-i386/topology.h | 144 + tests/.gitignore | 1 + tests/Makefile | 3 ++ tests/test-x86-cpuid.c | 108 + 4 files changed, 256 insertions(+) create mode 100644 target-i386/topology.h create mode 100644 tests/test-x86-cpuid.c diff --git a/target-i386/topology.h b/target-i386/topology.h new file mode 100644 index 000..35d9817 --- /dev/null +++ b/target-i386/topology.h @@ -0,0 +1,144 @@ +/* + * x86 CPU topology data structures and functions + * + * Copyright (c) 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef TARGET_I386_TOPOLOGY_H +#define TARGET_I386_TOPOLOGY_H + +#include +#include + +#include "bitops.h" + +/* APIC IDs can be 32-bit, but beware: APIC IDs > 255 require x2APIC support + */ +typedef uint32_t apic_id_t; + +/* Return the bit width needed for 'count' IDs + */ +static unsigned bits_for_count(unsigned count) +{ +g_assert(count >= 1); +if (count == 1) { +return 0; +} +return bitops_flsl(count - 1) + 1; +} + +/* Bit width of the SMT_ID (thread ID) field on the APIC ID + */ +static inline unsigned apicid_smt_width(unsigned nr_cores, unsigned nr_threads) +{ +return bits_for_count(nr_threads); +} + +/* Bit width of the Core_ID field + */ +static inline unsigned apicid_core_width(unsigned nr_cores, unsigned nr_threads) +{ +return bits_for_count(nr_cores); +} + +/* Bit offset of the Core_ID field + */ +static inline unsigned apicid_core_offset(unsigned nr_cores, + unsigned nr_threads) +{ +return apicid_smt_width(nr_cores, nr_threads); +} + +/* Bit offset of the Pkg_ID (socket ID) field + */ +static inline unsigned apicid_pkg_offset(unsigned nr_cores, unsigned nr_threads) +{ +return apicid_core_offset(nr_cores, nr_threads) + \ + apicid_core_width(nr_cores, nr_threads); +} + +/* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID + * + * The caller must make sure core_id < nr_cores and smt_id < nr_threads. + */ +static inline apic_id_t topo_make_apicid(unsigned nr_cores, + unsigned nr_threads, + unsigned pkg_id, unsigned core_id, + unsigned smt_id) +{ +return (pkg_id << apicid_pkg_offset(nr_cores, nr_threads)) | \ + (core_id << apicid_core_offset(nr_cores, nr_threads)) | \ + smt_id; +} + +/* Calculate thread/core/package IDs for a specific topology, + * based on (continguous) CPU index + */ +static inline void topo_ids_from_idx(unsigned nr_cores, unsigned nr_threads, + unsigned cpu_index, + unsigned *pkg_id, unsigned *core_id, + unsigned *smt_id) +{ +unsigned core_index = cpu_index / nr_threads; +*smt_id = cpu_index % nr_threads; +*core_id = core_index % nr_cores; +*pkg_id = core_index / nr_cores; +} + +/* Get package ID from an APIC ID + */ +static inline unsigned apicid_pkg_id(unsigned nr_cores, unsigned nr_threads, + apic_id_t apic_id) +{ +return apic_id >> apicid_pkg_offset(nr_cores, nr_threads); +} + +/* Get core ID from an APIC ID + */ +static inline unsigned apicid_core_id(unsigned nr_cores, unsigned nr_threads, + apic_id_t apic_id) +{ +retur
[Qemu-devel] [RFC 07/15] qdev: allow qdev_prop_parse() to report errors
Signed-off-by: Eduardo Habkost --- hw/qdev-monitor.c| 6 +- hw/qdev-properties.c | 21 - hw/qdev.h| 3 ++- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index b22a37a..99784c1 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -101,13 +101,17 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque) static int set_property(const char *name, const char *value, void *opaque) { DeviceState *dev = opaque; +Error *err = NULL; if (strcmp(name, "driver") == 0) return 0; if (strcmp(name, "bus") == 0) return 0; -if (qdev_prop_parse(dev, name, value) == -1) { +qdev_prop_parse(dev, name, value, &err); +if (err) { +qerror_report_err(err); +error_free(err); return -1; } return 0; diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 8aca0d4..a52884f 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -1087,25 +1087,17 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, } } -int qdev_prop_parse(DeviceState *dev, const char *name, const char *value) +void qdev_prop_parse(DeviceState *dev, const char *name, const char *value, + Error **errp) { char *legacy_name; -Error *err = NULL; - legacy_name = g_strdup_printf("legacy-%s", name); if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) { -object_property_parse(OBJECT(dev), value, legacy_name, &err); +object_property_parse(OBJECT(dev), value, legacy_name, errp); } else { -object_property_parse(OBJECT(dev), value, name, &err); +object_property_parse(OBJECT(dev), value, name, errp); } g_free(legacy_name); - -if (err) { -qerror_report_err(err); -error_free(err); -return -1; -} -return 0; } void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value) @@ -1250,11 +1242,14 @@ void qdev_prop_set_globals(DeviceState *dev) do { GlobalProperty *prop; +Error *err = NULL; QTAILQ_FOREACH(prop, &global_props, next) { if (strcmp(object_class_get_name(class), prop->driver) != 0) { continue; } -if (qdev_prop_parse(dev, prop->property, prop->value) != 0) { +qdev_prop_parse(dev, prop->property, prop->value, &err); +if (err) { +qerror_report_err(err); exit(1); } } diff --git a/hw/qdev.h b/hw/qdev.h index d699194..41db6c0 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -311,7 +311,8 @@ extern PropertyInfo qdev_prop_pci_host_devaddr; /* Set properties between creation and init. */ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop); -int qdev_prop_parse(DeviceState *dev, const char *name, const char *value); +void qdev_prop_parse(DeviceState *dev, const char *name, const char *value, + Error **errp); void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value); void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value); void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value); -- 1.7.11.2
Re: [Qemu-devel] For all targets and machine types: "start to monitor" smoke test
Anthony Liguori writes: > Markus Armbruster writes: > >> Very basic smoke test: start QEMU with -monitor stdio, quit immediately. >> Wouldn't it be nice if that worked for all targets and machine types? >> >> Many targets have mandatory options (fun oxymoron), such as -kernel or >> -pflash. Can't stop me, I just try a bunch until something works. >> >> Many targets expect various files to be present, and some of them need >> to have the right size. Can't stop me, I hack up the file loaders until >> it works (silly patch appended). To do this right, we'd need the >> required files or suitable mock-ups in-tree. > > I attempted something similar in the past and ran into similar results. > >> >> Test script: >> >> #!/bin/sh >> for i in ../qemu/bld/*-softmmu/qemu-system-* >> do >> echo "= $i =" >> for m in `$i -M help | sed -n '2,$s/ .*//gp'` >> do >> echo "== $m ==" >> for k in "" "-kernel /dev/null" "-pflash /dev/null" "-pflash /dev/null >> -pflash /dev/null -kernel /dev/null" >> do >> echo "=== ${k:-(default)} ===" >> if echo q | QEMU_AUDIO_DRV=none $i -S -vnc :0 -M $m $k -monitor >> stdio | fgrep -q '(qemu)' >> then break >> else false >> fi >> done >> if [ $? -eq 0 ] >> then echo "*** Success $k ***" >> else echo '*** Fail' >> fi >> done >> done >> >> Summary of results: >> >> * Bad unexplained >> >> qemu-system-arm lm3s811evb >> qemu-system-arm lm3s6965evb >> qemu-system-arm: /work/armbru/qemu/hw/qdev.c:310: qdev_get_gpio_in: >> Assertion `n >= 0 && n < dev->num_gpio_in' failed. >> >> qemu-system-ppc64 prep >> qemu: hardware error: Unknown device 'i82378' for bus 'PCI' >> >> qemu-system-ppcemb ref405ep >> qemu-system-ppcemb taihu >> Unable to find PowerPC 405ep CPU definition >> >> qemu-system-ppcemb mac99 >> qemu-system-ppcemb g3beige >> qemu-system-ppcemb prep >> Unable to find PowerPC CPU definition >> >> qemu-system-xtensaeb lx60 >> qemu-system-xtensaeb lx200 >> qemu-system-xtensaeb sim >> Unable to find CPU definition >> >> I'm not saying these are all busted. If you know how to "start to >> monitor" one of these, let us know. > > Perhaps we could add a QEMUMachine parameter that indicates that the > machine doesn't start without special options. Recommend to make it a string that lists the mandatory options. > At least a handful of these machines cannot be run without the use of > non-free binaries firmware :-( Yes, and that's bad. However, my test isn't trying to execute any guest code. It *should* be possible to pull off with mocked-up firmware. The mock-ups could then serve as documentation on what firmware binaries are required.
[Qemu-devel] [PATCH v2 8/9] x86: avoid AREG0 in segmentation helpers
Add an explicit CPUX86State parameter instead of relying on AREG0. Rename remains of op_helper.c to seg_helper.c. Signed-off-by: Blue Swirl --- target-i386/Makefile.objs |1 - target-i386/helper.h | 38 target-i386/seg_helper.c | 217 + target-i386/translate.c | 54 ++-- 4 files changed, 150 insertions(+), 160 deletions(-) diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index 04e34f8..3ea19ca 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -7,4 +7,3 @@ obj-$(CONFIG_LINUX_USER) += ioport-user.o obj-$(CONFIG_BSD_USER) += ioport-user.o $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) -$(obj)/seg_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/helper.h b/target-i386/helper.h index 9a9c064..0f02103 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -28,19 +28,19 @@ DEF_HELPER_1(aas, void, env) DEF_HELPER_1(daa, void, env) DEF_HELPER_1(das, void, env) -DEF_HELPER_1(lsl, tl, tl) -DEF_HELPER_1(lar, tl, tl) -DEF_HELPER_1(verr, void, tl) -DEF_HELPER_1(verw, void, tl) -DEF_HELPER_1(lldt, void, int) -DEF_HELPER_1(ltr, void, int) -DEF_HELPER_2(load_seg, void, int, int) -DEF_HELPER_3(ljmp_protected, void, int, tl, int) -DEF_HELPER_4(lcall_real, void, int, tl, int, int) -DEF_HELPER_4(lcall_protected, void, int, tl, int, int) -DEF_HELPER_1(iret_real, void, int) -DEF_HELPER_2(iret_protected, void, int, int) -DEF_HELPER_2(lret_protected, void, int, int) +DEF_HELPER_2(lsl, tl, env, tl) +DEF_HELPER_2(lar, tl, env, tl) +DEF_HELPER_2(verr, void, env, tl) +DEF_HELPER_2(verw, void, env, tl) +DEF_HELPER_2(lldt, void, env, int) +DEF_HELPER_2(ltr, void, env, int) +DEF_HELPER_3(load_seg, void, env, int, int) +DEF_HELPER_4(ljmp_protected, void, env, int, tl, int) +DEF_HELPER_5(lcall_real, void, env, int, tl, int, int) +DEF_HELPER_5(lcall_protected, void, env, int, tl, int, int) +DEF_HELPER_2(iret_real, void, env, int) +DEF_HELPER_3(iret_protected, void, env, int, int) +DEF_HELPER_3(lret_protected, void, env, int, int) DEF_HELPER_2(read_crN, tl, env, int) DEF_HELPER_3(write_crN, void, env, int, tl) DEF_HELPER_2(lmsw, void, env, tl) @@ -48,15 +48,15 @@ DEF_HELPER_1(clts, void, env) DEF_HELPER_3(movl_drN_T0, void, env, int, tl) DEF_HELPER_2(invlpg, void, env, tl) -DEF_HELPER_3(enter_level, void, int, int, tl) +DEF_HELPER_4(enter_level, void, env, int, int, tl) #ifdef TARGET_X86_64 -DEF_HELPER_3(enter64_level, void, int, int, tl) +DEF_HELPER_4(enter64_level, void, env, int, int, tl) #endif -DEF_HELPER_0(sysenter, void) -DEF_HELPER_1(sysexit, void, int) +DEF_HELPER_1(sysenter, void, env) +DEF_HELPER_2(sysexit, void, env, int) #ifdef TARGET_X86_64 -DEF_HELPER_1(syscall, void, int) -DEF_HELPER_1(sysret, void, int) +DEF_HELPER_2(syscall, void, env, int) +DEF_HELPER_2(sysret, void, env, int) #endif DEF_HELPER_2(hlt, void, env, int) DEF_HELPER_2(monitor, void, env, tl) diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index f5dcf01..f136128 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -19,7 +19,6 @@ */ #include "cpu.h" -#include "dyngen-exec.h" #include "qemu-log.h" #include "helper.h" @@ -35,8 +34,8 @@ #endif /* return non zero if error */ -static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr, - int selector) +static inline int load_segment(CPUX86State *env, uint32_t *e1_ptr, + uint32_t *e2_ptr, int selector) { SegmentCache *dt; int index; @@ -82,14 +81,14 @@ static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, } /* init the segment cache in vm86 mode. */ -static inline void load_seg_vm(int seg, int selector) +static inline void load_seg_vm(CPUX86State *env, int seg, int selector) { selector &= 0x; cpu_x86_load_seg_cache(env, seg, selector, (selector << 4), 0x, 0); } -static inline void get_ss_esp_from_tss(uint32_t *ss_ptr, +static inline void get_ss_esp_from_tss(CPUX86State *env, uint32_t *ss_ptr, uint32_t *esp_ptr, int dpl) { int type, index, shift; @@ -130,13 +129,13 @@ static inline void get_ss_esp_from_tss(uint32_t *ss_ptr, } /* XXX: merge with load_seg() */ -static void tss_load_seg(int seg_reg, int selector) +static void tss_load_seg(CPUX86State *env, int seg_reg, int selector) { uint32_t e1, e2; int rpl, dpl, cpl; if ((selector & 0xfffc) != 0) { -if (load_segment(&e1, &e2, selector) != 0) { +if (load_segment(env, &e1, &e2, selector) != 0) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); } if (!(e2 & DESC_S_MASK)) { @@ -195,7 +194,7 @@ static void tss_load_seg(int seg_reg, int selector) #define SWITCH_TSS_CALL 2 /* XXX: restore CPU state in registers (PowerPC case) */ -static void switch_tss(int tss_selector, +static vo
[Qemu-devel] [PATCH v2 7/9] x86: avoid AREG0 for misc helpers
Add an explicit CPUX86State parameter instead of relying on AREG0. Signed-off-by: Blue Swirl --- target-i386/Makefile.objs |1 - target-i386/helper.h | 40 target-i386/misc_helper.c | 77 + target-i386/translate.c | 49 4 files changed, 84 insertions(+), 83 deletions(-) diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index f843fe9..04e34f8 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -6,6 +6,5 @@ obj-$(CONFIG_KVM) += kvm.o hyperv.o obj-$(CONFIG_LINUX_USER) += ioport-user.o obj-$(CONFIG_BSD_USER) += ioport-user.o -$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/seg_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/helper.h b/target-i386/helper.h index ec7edca..9a9c064 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -41,12 +41,12 @@ DEF_HELPER_4(lcall_protected, void, int, tl, int, int) DEF_HELPER_1(iret_real, void, int) DEF_HELPER_2(iret_protected, void, int, int) DEF_HELPER_2(lret_protected, void, int, int) -DEF_HELPER_1(read_crN, tl, int) -DEF_HELPER_2(write_crN, void, int, tl) -DEF_HELPER_1(lmsw, void, tl) +DEF_HELPER_2(read_crN, tl, env, int) +DEF_HELPER_3(write_crN, void, env, int, tl) +DEF_HELPER_2(lmsw, void, env, tl) DEF_HELPER_1(clts, void, env) -DEF_HELPER_2(movl_drN_T0, void, int, tl) -DEF_HELPER_1(invlpg, void, tl) +DEF_HELPER_3(movl_drN_T0, void, env, int, tl) +DEF_HELPER_2(invlpg, void, env, tl) DEF_HELPER_3(enter_level, void, int, int, tl) #ifdef TARGET_X86_64 @@ -58,10 +58,10 @@ DEF_HELPER_1(sysexit, void, int) DEF_HELPER_1(syscall, void, int) DEF_HELPER_1(sysret, void, int) #endif -DEF_HELPER_1(hlt, void, int) -DEF_HELPER_1(monitor, void, tl) -DEF_HELPER_1(mwait, void, int) -DEF_HELPER_0(debug, void) +DEF_HELPER_2(hlt, void, env, int) +DEF_HELPER_2(monitor, void, env, tl) +DEF_HELPER_2(mwait, void, env, int) +DEF_HELPER_1(debug, void, env) DEF_HELPER_1(reset_rf, void, env) DEF_HELPER_3(raise_interrupt, void, env, int, int) DEF_HELPER_2(raise_exception, void, env, int) @@ -72,22 +72,22 @@ DEF_HELPER_1(reset_inhibit_irq, void, env) DEF_HELPER_2(boundw, void, tl, int) DEF_HELPER_2(boundl, void, tl, int) DEF_HELPER_1(rsm, void, env) -DEF_HELPER_1(into, void, int) +DEF_HELPER_2(into, void, env, int) DEF_HELPER_1(cmpxchg8b, void, tl) #ifdef TARGET_X86_64 DEF_HELPER_1(cmpxchg16b, void, tl) #endif -DEF_HELPER_0(single_step, void) -DEF_HELPER_0(cpuid, void) -DEF_HELPER_0(rdtsc, void) -DEF_HELPER_0(rdtscp, void) -DEF_HELPER_0(rdpmc, void) -DEF_HELPER_0(rdmsr, void) -DEF_HELPER_0(wrmsr, void) +DEF_HELPER_1(single_step, void, env) +DEF_HELPER_1(cpuid, void, env) +DEF_HELPER_1(rdtsc, void, env) +DEF_HELPER_1(rdtscp, void, env) +DEF_HELPER_1(rdpmc, void, env) +DEF_HELPER_1(rdmsr, void, env) +DEF_HELPER_1(wrmsr, void, env) -DEF_HELPER_1(check_iob, void, i32) -DEF_HELPER_1(check_iow, void, i32) -DEF_HELPER_1(check_iol, void, i32) +DEF_HELPER_2(check_iob, void, env, i32) +DEF_HELPER_2(check_iow, void, env, i32) +DEF_HELPER_2(check_iol, void, env, i32) DEF_HELPER_2(outb, void, i32, i32) DEF_HELPER_1(inb, tl, i32) DEF_HELPER_2(outw, void, i32, i32) diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c index 272a636..154601b 100644 --- a/target-i386/misc_helper.c +++ b/target-i386/misc_helper.c @@ -18,16 +18,11 @@ */ #include "cpu.h" -#include "dyngen-exec.h" #include "ioport.h" #include "helper.h" -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -#endif /* !defined(CONFIG_USER_ONLY) */ - /* check if Port I/O is allowed in TSS */ -static inline void check_io(int addr, int size) +static inline void check_io(CPUX86State *env, int addr, int size) { int io_offset, val, mask; @@ -37,13 +32,13 @@ static inline void check_io(int addr, int size) env->tr.limit < 103) { goto fail; } -io_offset = lduw_kernel(env->tr.base + 0x66); +io_offset = cpu_lduw_kernel(env, env->tr.base + 0x66); io_offset += (addr >> 3); /* Note: the check needs two bytes */ if ((io_offset + 1) > env->tr.limit) { goto fail; } -val = lduw_kernel(env->tr.base + io_offset); +val = cpu_lduw_kernel(env, env->tr.base + io_offset); val >>= (addr & 7); mask = (1 << size) - 1; /* all bits must be zero to allow the I/O */ @@ -53,19 +48,19 @@ static inline void check_io(int addr, int size) } } -void helper_check_iob(uint32_t t0) +void helper_check_iob(CPUX86State *env, uint32_t t0) { -check_io(t0, 1); +check_io(env, t0, 1); } -void helper_check_iow(uint32_t t0) +void helper_check_iow(CPUX86State *env, uint32_t t0) { -check_io(t0, 2); +check_io(env, t0, 2); } -void helper_check_iol(uint32_t t0) +void helper_check_iol(CPUX86State *env, uint32_t t0) { -check_io(t0, 4); +check_io(env, t0, 4); } void helpe
[Qemu-devel] [PATCH v2 4/9] x86: avoid AREG0 for SVM helpers
Add an explicit CPUX86State parameter instead of relying on AREG0. Signed-off-by: Blue Swirl --- target-i386/Makefile.objs |1 - target-i386/helper.h | 22 +++--- target-i386/svm_helper.c | 181 ++--- target-i386/translate.c | 21 +++--- 4 files changed, 110 insertions(+), 115 deletions(-) diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index 71b7c7b..370fde7 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -6,7 +6,6 @@ obj-$(CONFIG_KVM) += kvm.o hyperv.o obj-$(CONFIG_LINUX_USER) += ioport-user.o obj-$(CONFIG_BSD_USER) += ioport-user.o -$(obj)/svm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/smm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/helper.h b/target-i386/helper.h index 67c81bf..601b8dd 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -95,17 +95,17 @@ DEF_HELPER_1(inw, tl, i32) DEF_HELPER_2(outl, void, i32, i32) DEF_HELPER_1(inl, tl, i32) -DEF_HELPER_2(svm_check_intercept_param, void, i32, i64) -DEF_HELPER_2(vmexit, void, i32, i64) -DEF_HELPER_3(svm_check_io, void, i32, i32, i32) -DEF_HELPER_2(vmrun, void, int, int) -DEF_HELPER_0(vmmcall, void) -DEF_HELPER_1(vmload, void, int) -DEF_HELPER_1(vmsave, void, int) -DEF_HELPER_0(stgi, void) -DEF_HELPER_0(clgi, void) -DEF_HELPER_0(skinit, void) -DEF_HELPER_1(invlpga, void, int) +DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64) +DEF_HELPER_3(vmexit, void, env, i32, i64) +DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32) +DEF_HELPER_3(vmrun, void, env, int, int) +DEF_HELPER_1(vmmcall, void, env) +DEF_HELPER_2(vmload, void, env, int) +DEF_HELPER_2(vmsave, void, env, int) +DEF_HELPER_1(stgi, void, env) +DEF_HELPER_1(clgi, void, env) +DEF_HELPER_1(skinit, void, env) +DEF_HELPER_2(invlpga, void, env, int) /* x86 FPU */ diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c index 64d842c..f370ac5 100644 --- a/target-i386/svm_helper.c +++ b/target-i386/svm_helper.c @@ -18,46 +18,46 @@ */ #include "cpu.h" -#include "dyngen-exec.h" +#include "cpu-all.h" #include "helper.h" /* Secure Virtual Machine helpers */ #if defined(CONFIG_USER_ONLY) -void helper_vmrun(int aflag, int next_eip_addend) +void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend) { } -void helper_vmmcall(void) +void helper_vmmcall(CPUX86State *env) { } -void helper_vmload(int aflag) +void helper_vmload(CPUX86State *env, int aflag) { } -void helper_vmsave(int aflag) +void helper_vmsave(CPUX86State *env, int aflag) { } -void helper_stgi(void) +void helper_stgi(CPUX86State *env) { } -void helper_clgi(void) +void helper_clgi(CPUX86State *env) { } -void helper_skinit(void) +void helper_skinit(CPUX86State *env) { } -void helper_invlpga(int aflag) +void helper_invlpga(CPUX86State *env, int aflag) { } -void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) +void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1) { } @@ -65,7 +65,8 @@ void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1) { } -void helper_svm_check_intercept_param(uint32_t type, uint64_t param) +void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type, + uint64_t param) { } @@ -74,13 +75,13 @@ void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type, { } -void helper_svm_check_io(uint32_t port, uint32_t param, +void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param, uint32_t next_eip_addend) { } #else -static inline void svm_save_seg(target_phys_addr_t addr, +static inline void svm_save_seg(CPUX86State *env, target_phys_addr_t addr, const SegmentCache *sc) { stw_phys(addr + offsetof(struct vmcb_seg, selector), @@ -93,7 +94,8 @@ static inline void svm_save_seg(target_phys_addr_t addr, ((sc->flags >> 8) & 0xff) | ((sc->flags >> 12) & 0x0f00)); } -static inline void svm_load_seg(target_phys_addr_t addr, SegmentCache *sc) +static inline void svm_load_seg(CPUX86State *env, target_phys_addr_t addr, +SegmentCache *sc) { unsigned int flags; @@ -104,23 +106,23 @@ static inline void svm_load_seg(target_phys_addr_t addr, SegmentCache *sc) sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12); } -static inline void svm_load_seg_cache(target_phys_addr_t addr, - CPUX86State *env, int seg_reg) +static inline void svm_load_seg_cache(CPUX86State *env, target_phys_addr_t addr, + int seg_reg) { SegmentCache sc1, *sc = &sc1; -svm_load_seg(addr, sc); +svm_load_seg(env, addr, sc); cpu_x86_load_seg_cache(env, seg_reg, sc->selector,
[Qemu-devel] [PATCH v2 3/9] x86: avoid AREG0 for integer helpers
Add an explicit CPUX86State parameter instead of relying on AREG0. Signed-off-by: Blue Swirl --- target-i386/Makefile.objs |1 - target-i386/helper.h| 50 +- target-i386/int_helper.c| 36 +- target-i386/shift_helper_template.h |6 ++- target-i386/translate.c | 66 +- 5 files changed, 88 insertions(+), 71 deletions(-) diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index fab2385..71b7c7b 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -6,7 +6,6 @@ obj-$(CONFIG_KVM) += kvm.o hyperv.o obj-$(CONFIG_LINUX_USER) += ioport-user.o obj-$(CONFIG_BSD_USER) += ioport-user.o -$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/svm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/smm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/helper.h b/target-i386/helper.h index d647e54..67c81bf 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -7,26 +7,26 @@ DEF_HELPER_0(lock, void) DEF_HELPER_0(unlock, void) DEF_HELPER_3(write_eflags, void, env, tl, i32) DEF_HELPER_1(read_eflags, tl, env) -DEF_HELPER_1(divb_AL, void, tl) -DEF_HELPER_1(idivb_AL, void, tl) -DEF_HELPER_1(divw_AX, void, tl) -DEF_HELPER_1(idivw_AX, void, tl) -DEF_HELPER_1(divl_EAX, void, tl) -DEF_HELPER_1(idivl_EAX, void, tl) +DEF_HELPER_2(divb_AL, void, env, tl) +DEF_HELPER_2(idivb_AL, void, env, tl) +DEF_HELPER_2(divw_AX, void, env, tl) +DEF_HELPER_2(idivw_AX, void, env, tl) +DEF_HELPER_2(divl_EAX, void, env, tl) +DEF_HELPER_2(idivl_EAX, void, env, tl) #ifdef TARGET_X86_64 -DEF_HELPER_1(mulq_EAX_T0, void, tl) -DEF_HELPER_1(imulq_EAX_T0, void, tl) -DEF_HELPER_2(imulq_T0_T1, tl, tl, tl) -DEF_HELPER_1(divq_EAX, void, tl) -DEF_HELPER_1(idivq_EAX, void, tl) +DEF_HELPER_2(mulq_EAX_T0, void, env, tl) +DEF_HELPER_2(imulq_EAX_T0, void, env, tl) +DEF_HELPER_3(imulq_T0_T1, tl, env, tl, tl) +DEF_HELPER_2(divq_EAX, void, env, tl) +DEF_HELPER_2(idivq_EAX, void, env, tl) #endif -DEF_HELPER_1(aam, void, int) -DEF_HELPER_1(aad, void, int) -DEF_HELPER_0(aaa, void) -DEF_HELPER_0(aas, void) -DEF_HELPER_0(daa, void) -DEF_HELPER_0(das, void) +DEF_HELPER_2(aam, void, env, int) +DEF_HELPER_2(aad, void, env, int) +DEF_HELPER_1(aaa, void, env) +DEF_HELPER_1(aas, void, env) +DEF_HELPER_1(daa, void, env) +DEF_HELPER_1(das, void, env) DEF_HELPER_1(lsl, tl, tl) DEF_HELPER_1(lar, tl, tl) @@ -207,15 +207,15 @@ DEF_HELPER_3(movq, void, env, ptr, ptr) #define SHIFT 1 #include "ops_sse_header.h" -DEF_HELPER_2(rclb, tl, tl, tl) -DEF_HELPER_2(rclw, tl, tl, tl) -DEF_HELPER_2(rcll, tl, tl, tl) -DEF_HELPER_2(rcrb, tl, tl, tl) -DEF_HELPER_2(rcrw, tl, tl, tl) -DEF_HELPER_2(rcrl, tl, tl, tl) +DEF_HELPER_3(rclb, tl, env, tl, tl) +DEF_HELPER_3(rclw, tl, env, tl, tl) +DEF_HELPER_3(rcll, tl, env, tl, tl) +DEF_HELPER_3(rcrb, tl, env, tl, tl) +DEF_HELPER_3(rcrw, tl, env, tl, tl) +DEF_HELPER_3(rcrl, tl, env, tl, tl) #ifdef TARGET_X86_64 -DEF_HELPER_2(rclq, tl, tl, tl) -DEF_HELPER_2(rcrq, tl, tl, tl) +DEF_HELPER_3(rclq, tl, env, tl, tl) +DEF_HELPER_3(rcrq, tl, env, tl, tl) #endif #include "def-helper.h" diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c index 1a13e4e..f39747e 100644 --- a/target-i386/int_helper.c +++ b/target-i386/int_helper.c @@ -18,7 +18,6 @@ */ #include "cpu.h" -#include "dyngen-exec.h" #include "host-utils.h" #include "helper.h" @@ -42,7 +41,7 @@ static const uint8_t rclw_table[32] = { /* division, flags are undefined */ -void helper_divb_AL(target_ulong t0) +void helper_divb_AL(CPUX86State *env, target_ulong t0) { unsigned int num, den, q, r; @@ -60,7 +59,7 @@ void helper_divb_AL(target_ulong t0) EAX = (EAX & ~0x) | (r << 8) | q; } -void helper_idivb_AL(target_ulong t0) +void helper_idivb_AL(CPUX86State *env, target_ulong t0) { int num, den, q, r; @@ -78,7 +77,7 @@ void helper_idivb_AL(target_ulong t0) EAX = (EAX & ~0x) | (r << 8) | q; } -void helper_divw_AX(target_ulong t0) +void helper_divw_AX(CPUX86State *env, target_ulong t0) { unsigned int num, den, q, r; @@ -97,7 +96,7 @@ void helper_divw_AX(target_ulong t0) EDX = (EDX & ~0x) | r; } -void helper_idivw_AX(target_ulong t0) +void helper_idivw_AX(CPUX86State *env, target_ulong t0) { int num, den, q, r; @@ -116,7 +115,7 @@ void helper_idivw_AX(target_ulong t0) EDX = (EDX & ~0x) | r; } -void helper_divl_EAX(target_ulong t0) +void helper_divl_EAX(CPUX86State *env, target_ulong t0) { unsigned int den, r; uint64_t num, q; @@ -135,7 +134,7 @@ void helper_divl_EAX(target_ulong t0) EDX = (uint32_t)r; } -void helper_idivl_EAX(target_ulong t0) +void helper_idivl_EAX(CPUX86State *env, target_ulong t0) { int den, r; int64_t num, q; @@ -157,7 +156,7 @@ void helper_idivl_EAX(target_ulong t0) /* bcd */ /* XXX: excep
[Qemu-devel] [PATCH v2 2/9] x86: avoid AREG0 for condition code helpers
Add an explicit CPUX86State parameter instead of relying on AREG0. Signed-off-by: Blue Swirl --- target-i386/Makefile.objs |1 - target-i386/cc_helper.c | 199 +-- target-i386/cc_helper_template.h| 36 +++--- target-i386/helper.h| 20 ++-- target-i386/int_helper.c|8 +- target-i386/mem_helper.c|4 +- target-i386/misc_helper.c |2 +- target-i386/seg_helper.c|8 +- target-i386/shift_helper_template.h |4 +- target-i386/translate.c | 66 10 files changed, 179 insertions(+), 169 deletions(-) diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index af99b81..fab2385 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -6,7 +6,6 @@ obj-$(CONFIG_KVM) += kvm.o hyperv.o obj-$(CONFIG_LINUX_USER) += ioport-user.o obj-$(CONFIG_BSD_USER) += ioport-user.o -$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/svm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) $(obj)/smm_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c index ff654bc..07892f9 100644 --- a/target-i386/cc_helper.c +++ b/target-i386/cc_helper.c @@ -18,7 +18,6 @@ */ #include "cpu.h" -#include "dyngen-exec.h" #include "helper.h" const uint8_t parity_table[256] = { @@ -76,184 +75,177 @@ const uint8_t parity_table[256] = { #endif -static int compute_all_eflags(void) +static int compute_all_eflags(CPUX86State *env) { return CC_SRC; } -static int compute_c_eflags(void) +static int compute_c_eflags(CPUX86State *env) { return CC_SRC & CC_C; } -uint32_t helper_cc_compute_all(int op) +uint32_t helper_cc_compute_all(CPUX86State *env, int op) { switch (op) { default: /* should never happen */ return 0; case CC_OP_EFLAGS: -return compute_all_eflags(); +return compute_all_eflags(env); case CC_OP_MULB: -return compute_all_mulb(); +return compute_all_mulb(env); case CC_OP_MULW: -return compute_all_mulw(); +return compute_all_mulw(env); case CC_OP_MULL: -return compute_all_mull(); +return compute_all_mull(env); case CC_OP_ADDB: -return compute_all_addb(); +return compute_all_addb(env); case CC_OP_ADDW: -return compute_all_addw(); +return compute_all_addw(env); case CC_OP_ADDL: -return compute_all_addl(); +return compute_all_addl(env); case CC_OP_ADCB: -return compute_all_adcb(); +return compute_all_adcb(env); case CC_OP_ADCW: -return compute_all_adcw(); +return compute_all_adcw(env); case CC_OP_ADCL: -return compute_all_adcl(); +return compute_all_adcl(env); case CC_OP_SUBB: -return compute_all_subb(); +return compute_all_subb(env); case CC_OP_SUBW: -return compute_all_subw(); +return compute_all_subw(env); case CC_OP_SUBL: -return compute_all_subl(); +return compute_all_subl(env); case CC_OP_SBBB: -return compute_all_sbbb(); +return compute_all_sbbb(env); case CC_OP_SBBW: -return compute_all_sbbw(); +return compute_all_sbbw(env); case CC_OP_SBBL: -return compute_all_sbbl(); +return compute_all_sbbl(env); case CC_OP_LOGICB: -return compute_all_logicb(); +return compute_all_logicb(env); case CC_OP_LOGICW: -return compute_all_logicw(); +return compute_all_logicw(env); case CC_OP_LOGICL: -return compute_all_logicl(); +return compute_all_logicl(env); case CC_OP_INCB: -return compute_all_incb(); +return compute_all_incb(env); case CC_OP_INCW: -return compute_all_incw(); +return compute_all_incw(env); case CC_OP_INCL: -return compute_all_incl(); +return compute_all_incl(env); case CC_OP_DECB: -return compute_all_decb(); +return compute_all_decb(env); case CC_OP_DECW: -return compute_all_decw(); +return compute_all_decw(env); case CC_OP_DECL: -return compute_all_decl(); +return compute_all_decl(env); case CC_OP_SHLB: -return compute_all_shlb(); +return compute_all_shlb(env); case CC_OP_SHLW: -return compute_all_shlw(); +return compute_all_shlw(env); case CC_OP_SHLL: -return compute_all_shll(); +return compute_all_shll(env); case CC_OP_SARB: -return compute_all_sarb(); +return compute_all_sarb(env); case CC_OP_SARW: -return compute_all_sarw(); +return compute_all_sarw(env); case CC_OP_SARL: -return compute_all_sarl(); +return compute_all_sarl(env
[Qemu-devel] [PATCH v2 0/9] x86 AREG0 conversion
Finally, I found the bug in SSE helpers (passed cpu_env to pshufx, not caught because of the ugly casts). Now this also passes the test with OpenSUSE-12.1-GNOME-LiveCD-x86_64. It's also possible to use Clang to compile x86 targets with my earlier Clang patch set applied. I think this is 1.2 material. Blue Swirl (9): x86: avoid AREG0 for FPU helpers x86: avoid AREG0 for condition code helpers x86: avoid AREG0 for integer helpers x86: avoid AREG0 for SVM helpers x86: avoid AREG0 for SMM helpers x86: use wrappers for memory access helpers x86: avoid AREG0 for misc helpers x86: avoid AREG0 in segmentation helpers x86: switch to AREG0 free mode configure |2 +- cpu-all.h | 22 + target-i386/Makefile.objs |9 - target-i386/cc_helper.c | 199 target-i386/cc_helper_template.h| 36 +- target-i386/fpu_helper.c| 429 - target-i386/helper.h| 352 +++--- target-i386/int_helper.c| 44 +- target-i386/mem_helper.c| 46 +- target-i386/misc_helper.c | 75 ++-- target-i386/ops_sse.h | 378 --- target-i386/ops_sse_header.h| 334 +++--- target-i386/seg_helper.c| 434 +- target-i386/shift_helper_template.h | 10 +- target-i386/smm_helper.c| 14 +- target-i386/svm_helper.c| 185 target-i386/translate.c | 903 +++ 17 files changed, 1772 insertions(+), 1700 deletions(-) -- 1.7.2.5
Re: [Qemu-devel] [PATCH v6 3/6] monitor: Clean up fd sets on monitor disconnect
On 08/07/2012 01:32 PM, Stefan Hajnoczi wrote: On Fri, Aug 03, 2012 at 01:28:06PM -0400, Corey Bryant wrote: Each fd set has a boolean that keeps track of whether or not the fd set is in use by a monitor connection. When a monitor disconnects, all fds that are members of an fd set with refcount of zero are closed. This prevents any fd leakage associated with a client disconnect prior to using a passed fd. v5: -This patch is new in v5. -This support addresses concerns from v4 regarding fd leakage if the client disconnects unexpectedly. (ebl...@redhat.com, kw...@redhat.com, dberra...@redhat.com) v6: -No changes Signed-off-by: Corey Bryant --- monitor.c | 15 +++ 1 file changed, 15 insertions(+) The lifecycle of fdsets and fds isn't clear to me. It seems like just a refcount in fdset should handle this without extra fields like in_use. The lifecycle of fdsets and fds starts with add-fd. I'll explain the lifecycle end of fdsets and fds below. To follow along with the code, this cleanup occurs in monitor_fdset_cleanup(). Fds are closed and removed from an fdset when there are no more open dup() fds (refcount == 0) for the fd set, and there are either no monitor connections (!in-use) or the fd has been removed with remove-fd. In other words fds get cleaned up when: (refcount == 0 && (!in-use || removed)) Let me explain each variable: (1) refcount is incremented when qemu_open() dup()s an fd from an fd set and is decremented when qemu_close() closes a dup()d fd. We don't want to close any fds in an fd set if refcount > 0, because this file could be reopened with different access mode flags, which would require dup() of another fd from the fdset. (2) in-use is used to prevent fd leakage if a monitor disconnects and abandons fds. If libvirt adds fds and then disconnects without issuing a command that references the fds, then refcount will be zero, and in-use will be false, and the fds will be closed and removed from the fd set. When the monitor connection is restored, the query-fdsets command can be used to see what fd sets and fds are available. (3) If the remove-fd command is issued, the fd is marked for removal. It won't be closed until there are no more outstanding dup() references on the fd set, for similar reasons to why we don't close the fd in (1). fdsets simply get cleaned up once all fds from the set have been closed and removed. Hopefully this clears things up a bit more. Please also take a look at the v7 series that I sent out today. Fd sets are now stored globally, rather than one per Monitor object. This simplifies things a bit. -- Regards, Corey
Re: [Qemu-devel] Cirrus bugs vs endian: how two bugs cancel each other out
>On Tue, Aug 7, 2012 at 11:07 AM, Gerd Hoffmann wrote: > > On 08/07/12 15:05, Erlon Cruz wrote: > > Em 07/08/2012 05:01, "Gerd Hoffmann" escreveu: > >> > >> Hi, > >> > >>> Why not make libspice mandatory? > >> > >> spice needs to build and run on alot of platforms where it doesn't run > >> today. So it isn't an option right now. Which doesn't imply it will > >> never happen, but spice certainly needs some work before we can > >> seriously discuss that. > >> > >> Make spice work on bigendian is probably the biggest part of it. > > > > Spice has a good support for endianess issues. The protocol handles > > endianess for commands sent from spice server to the client. > > The spice wire protocol is little endian. Functions for > generating/parsing the wire protocol are generated, maybe the generator > already supports byteswapping as needed, not sure. Yes, it does. There are marshellers that are generated based on SPICE command definitions. > > The only thing > > its missing is to fix the endianess for server/client handshaking. > > What exactly do you mean here? Well that are negotiation messages configuring each channel, its capabilities, encryption keys , etc. After this negotiation, the server start to send SPICE data, which are already swapped by the marshallers. > > We a > > patch for that. We can send that later on. > > Patches welcome. Please make sure spice-devel is included (additionally > to qemu-devel). I've sent then on spice-devel mailing list. > > We have tested it first running > > spice sever tests in a PPC machine and then we run it in an experimental > > virtio-qxl driver we are working on. > > Huh? How does this work? Well, our first though was to minimize changes on xf86-video-qxl. The device allocates the video memory on QEMU and memory on guest (the same amount). A virtio kernel drivers makes the connection/mapping between xf86-video-driver and the device. Guest memory then works mirroring all commands to the device (the X driver tell the kernel which areas changed and the kernel pushes the pages to the device. we only need one VQ to to that) and the xf86-driver can work like if does in the QXL PCI. ' > The QXLCommand passed on to spice-server (via get_command callback) is > supposed to be little endian. Actually the command endianness doesn't matter at this point once QXLCommand will be marshalled (and then swapped) before get to the wire. > The qxl parser (server/red_parse_qxl.c in > spice repo) doesn't support bigendian hosts yet. Not that a big deal, > basically just a bunch of le{16,32]_to_cpu() calls when copying > (+checking) fields from struct QXL* (little endian) to struct Spice* > (native endian). But not done yet and likewise not tested yet ... > > So I'm wondering how this works for you on ppc ... Well, I think that once QEMU and libspice are both BE or LE this code will run. And we only server/reds.c, server/red_channel.c, and server/inputs_channel.c check the patches I send in spice-devel. > > The device only have support for QXL (nor VGA) and works well in x86 and > > i > > PPC guest with a few issues we still working on. Another limitation is > > that > > in the design we used virtio transport, the device wont work with mixed > > guest/host configurations (e.g. Guest ppc host x86) > > Which should be fixable. > > cheers, > Gerd Cheers, Erlon
Re: [Qemu-devel] For all targets and machine types: "start to monitor" smoke test
On 7 August 2012 20:26, Markus Armbruster wrote: > qemu-system-arm lm3s811evb > qemu-system-arm lm3s6965evb > qemu-system-arm: /work/armbru/qemu/hw/qdev.c:310: qdev_get_gpio_in: > Assertion `n >= 0 && n < dev->num_gpio_in' failed. This is fixed by http://patchwork.ozlabs.org/patch/172820/ (which should be in my arm-devs.next queue, I just haven't got round to flushing it yet.) -- PMM
Re: [Qemu-devel] For all targets and machine types: "start to monitor" smoke test
Markus Armbruster writes: > Very basic smoke test: start QEMU with -monitor stdio, quit immediately. > Wouldn't it be nice if that worked for all targets and machine types? > > Many targets have mandatory options (fun oxymoron), such as -kernel or > -pflash. Can't stop me, I just try a bunch until something works. > > Many targets expect various files to be present, and some of them need > to have the right size. Can't stop me, I hack up the file loaders until > it works (silly patch appended). To do this right, we'd need the > required files or suitable mock-ups in-tree. I attempted something similar in the past and ran into similar results. > > Test script: > > #!/bin/sh > for i in ../qemu/bld/*-softmmu/qemu-system-* > do > echo "= $i =" > for m in `$i -M help | sed -n '2,$s/ .*//gp'` > do > echo "== $m ==" > for k in "" "-kernel /dev/null" "-pflash /dev/null" "-pflash /dev/null > -pflash /dev/null -kernel /dev/null" > do > echo "=== ${k:-(default)} ===" > if echo q | QEMU_AUDIO_DRV=none $i -S -vnc :0 -M $m $k -monitor > stdio | fgrep -q '(qemu)' > then break > else false > fi > done > if [ $? -eq 0 ] > then echo "*** Success $k ***" > else echo '*** Fail' > fi > done > done > > Summary of results: > > * Bad unexplained > > qemu-system-arm lm3s811evb > qemu-system-arm lm3s6965evb > qemu-system-arm: /work/armbru/qemu/hw/qdev.c:310: qdev_get_gpio_in: > Assertion `n >= 0 && n < dev->num_gpio_in' failed. > > qemu-system-ppc64 prep > qemu: hardware error: Unknown device 'i82378' for bus 'PCI' > > qemu-system-ppcemb ref405ep > qemu-system-ppcemb taihu > Unable to find PowerPC 405ep CPU definition > > qemu-system-ppcemb mac99 > qemu-system-ppcemb g3beige > qemu-system-ppcemb prep > Unable to find PowerPC CPU definition > > qemu-system-xtensaeb lx60 > qemu-system-xtensaeb lx200 > qemu-system-xtensaeb sim > Unable to find CPU definition > > I'm not saying these are all busted. If you know how to "start to > monitor" one of these, let us know. Perhaps we could add a QEMUMachine parameter that indicates that the machine doesn't start without special options. At least a handful of these machines cannot be run without the use of non-free binaries firmware :-( Regards, Anthony Liguori > > * Not easily testable for me > > qemu-system-i386 xenfv > qemu-system-i386 xenpv > qemu-system-x86_64 xenfv > qemu-system-x86_64 xenpv > failed to initialize Xen: Operation not permitted > No accelerator found! > > * Good > > qemu-system-alpha clipper > qemu-system-arm collie nuri smdkc210 connex verdex highbank > integratorcp kzm mainstone musicpal n800 n810 sx1 sx1-v1 cheetah > realview-eb realview-eb-mpcore realview-pb-a8 realview-pbx-a9 > akita spitz borzoi terrier tosa versatilepb versatileab > vexpress-a9 vexpress-a15 xilinx-zynq-a9 z2 > qemu-system-cris axis-dev88 > qemu-system-i386 pc pc-1.2 pc-1.1 pc-1.0 pc-0.15 pc-0.14 pc-0.13 > pc-0.12 pc-0.11 pc-0.10 isapc > qemu-system-lm32 lm32-uclinux lm32-evr milkymist > qemu-system-m68k an5206 dummy mcf5208evb > qemu-system-microblaze petalogix-ml605 petalogix-s3adsp1800 > qemu-system-microblazeel petalogix-ml605 petalogix-s3adsp1800 > qemu-system-mips magnum pica61 malta mipssim mips > qemu-system-mips64 magnum pica61 malta mipssim mips > qemu-system-mips64el fulong2e magnum pica61 malta mipssim mips > qemu-system-mipsel magnum pica61 malta mipssim mips > qemu-system-or32 or32-sim > qemu-system-ppc ref405ep taihu bamboo mac99 g3beige prep virtex-ml507 > qemu-system-ppc64 ref405ep taihu bamboo mac99 g3beige virtex-ml507 > qemu-system-ppcemb bamboo virtex-ml507 > qemu-system-s390x s390 s390-virtio > qemu-system-sh4 r2d shix > qemu-system-sh4eb r2d shix > qemu-system-sparc leon3_generic SS-5 SS-10 SS-600MP SS-20 Voyager LX > SS-4 SPARCClassic SPARCbook SS-1000 SS-2000 SS-2 > qemu-system-sparc64 sun4u sun4v Niagara > qemu-system-x86_64 pc pc-1.2 pc-1.1 pc-1.0 pc-0.15 pc-0.14 pc-0.13 > pc-0.12 pc-0.11 pc-0.10 isapc > qemu-system-xtensa lx60 lx200 sim > > > diff --git a/hw/loader.c b/hw/loader.c > index 33acc2f..e23af6c 100644 > --- a/hw/loader.c > +++ b/hw/loader.c > @@ -62,7 +62,7 @@ int get_image_size(const char *filename) > int fd, size; > fd = open(filename, O_RDONLY | O_BINARY); > if (fd < 0) > -return -1; > +return 0;//-1; > size = lseek(fd, 0, SEEK_END); > close(fd); > return size; > @@ -75,7 +75,7 @@ int load_image(const char *filename, uint8_t *addr) > int fd, size; > fd = open(filename, O_RDONLY | O_BINARY); > if (fd < 0) > -return -1; > +return 0;//-1; > size = lseek(fd, 0, SEEK_END); > lseek(fd, 0, SEEK_SET); > if (read(fd, addr, size) != size) { > @@ -108,6 +108,7 @@ int load_image_targphys(cons
[Qemu-devel] For all targets and machine types: "start to monitor" smoke test
Very basic smoke test: start QEMU with -monitor stdio, quit immediately. Wouldn't it be nice if that worked for all targets and machine types? Many targets have mandatory options (fun oxymoron), such as -kernel or -pflash. Can't stop me, I just try a bunch until something works. Many targets expect various files to be present, and some of them need to have the right size. Can't stop me, I hack up the file loaders until it works (silly patch appended). To do this right, we'd need the required files or suitable mock-ups in-tree. Test script: #!/bin/sh for i in ../qemu/bld/*-softmmu/qemu-system-* do echo "= $i =" for m in `$i -M help | sed -n '2,$s/ .*//gp'` do echo "== $m ==" for k in "" "-kernel /dev/null" "-pflash /dev/null" "-pflash /dev/null -pflash /dev/null -kernel /dev/null" do echo "=== ${k:-(default)} ===" if echo q | QEMU_AUDIO_DRV=none $i -S -vnc :0 -M $m $k -monitor stdio | fgrep -q '(qemu)' then break else false fi done if [ $? -eq 0 ] then echo "*** Success $k ***" else echo '*** Fail' fi done done Summary of results: * Bad unexplained qemu-system-arm lm3s811evb qemu-system-arm lm3s6965evb qemu-system-arm: /work/armbru/qemu/hw/qdev.c:310: qdev_get_gpio_in: Assertion `n >= 0 && n < dev->num_gpio_in' failed. qemu-system-ppc64 prep qemu: hardware error: Unknown device 'i82378' for bus 'PCI' qemu-system-ppcemb ref405ep qemu-system-ppcemb taihu Unable to find PowerPC 405ep CPU definition qemu-system-ppcemb mac99 qemu-system-ppcemb g3beige qemu-system-ppcemb prep Unable to find PowerPC CPU definition qemu-system-xtensaeb lx60 qemu-system-xtensaeb lx200 qemu-system-xtensaeb sim Unable to find CPU definition I'm not saying these are all busted. If you know how to "start to monitor" one of these, let us know. * Not easily testable for me qemu-system-i386 xenfv qemu-system-i386 xenpv qemu-system-x86_64 xenfv qemu-system-x86_64 xenpv failed to initialize Xen: Operation not permitted No accelerator found! * Good qemu-system-alpha clipper qemu-system-arm collie nuri smdkc210 connex verdex highbank integratorcp kzm mainstone musicpal n800 n810 sx1 sx1-v1 cheetah realview-eb realview-eb-mpcore realview-pb-a8 realview-pbx-a9 akita spitz borzoi terrier tosa versatilepb versatileab vexpress-a9 vexpress-a15 xilinx-zynq-a9 z2 qemu-system-cris axis-dev88 qemu-system-i386 pc pc-1.2 pc-1.1 pc-1.0 pc-0.15 pc-0.14 pc-0.13 pc-0.12 pc-0.11 pc-0.10 isapc qemu-system-lm32 lm32-uclinux lm32-evr milkymist qemu-system-m68k an5206 dummy mcf5208evb qemu-system-microblaze petalogix-ml605 petalogix-s3adsp1800 qemu-system-microblazeel petalogix-ml605 petalogix-s3adsp1800 qemu-system-mips magnum pica61 malta mipssim mips qemu-system-mips64 magnum pica61 malta mipssim mips qemu-system-mips64el fulong2e magnum pica61 malta mipssim mips qemu-system-mipsel magnum pica61 malta mipssim mips qemu-system-or32 or32-sim qemu-system-ppc ref405ep taihu bamboo mac99 g3beige prep virtex-ml507 qemu-system-ppc64 ref405ep taihu bamboo mac99 g3beige virtex-ml507 qemu-system-ppcemb bamboo virtex-ml507 qemu-system-s390x s390 s390-virtio qemu-system-sh4 r2d shix qemu-system-sh4eb r2d shix qemu-system-sparc leon3_generic SS-5 SS-10 SS-600MP SS-20 Voyager LX SS-4 SPARCClassic SPARCbook SS-1000 SS-2000 SS-2 qemu-system-sparc64 sun4u sun4v Niagara qemu-system-x86_64 pc pc-1.2 pc-1.1 pc-1.0 pc-0.15 pc-0.14 pc-0.13 pc-0.12 pc-0.11 pc-0.10 isapc qemu-system-xtensa lx60 lx200 sim diff --git a/hw/loader.c b/hw/loader.c index 33acc2f..e23af6c 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -62,7 +62,7 @@ int get_image_size(const char *filename) int fd, size; fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) -return -1; +return 0;//-1; size = lseek(fd, 0, SEEK_END); close(fd); return size; @@ -75,7 +75,7 @@ int load_image(const char *filename, uint8_t *addr) int fd, size; fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) -return -1; +return 0;//-1; size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); if (read(fd, addr, size) != size) { @@ -108,6 +108,7 @@ int load_image_targphys(const char *filename, int size; size = get_image_size(filename); +if (size < 0) size = 0; if (size > max_sz) { return -1; } @@ -293,7 +294,7 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) { perror(filename); -return -1; +return 0;//-1; } if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident)) goto fail; @@ -332,7 +333,7 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *
Re: [Qemu-devel] [PATCH 00/12] Migration next v12
On Mon, 6 Aug 2012 21:42:46 +0300 Orit Wasserman wrote: > Changes from v11: > Fix example for query-migrate-cache-size commands > Move patch 10 (Change total_time to total-time) to patch 9 and fix > comment. Looks good now: Reviewed-by: Luiz Capitulino
Re: [Qemu-devel] [PATCH 4/6] migration: remove iohandlers before closing the file
Paolo Bonzini writes: > This will be needed as soon as process_incoming_migration will set > handlers on the file. The patch may be removed if ...? Regards, Anthony Liguori > > Signed-off-by: Paolo Bonzini > --- > savevm.c | 3 +++ > 1 file modificato, 3 inserzioni(+) > > diff --git a/savevm.c b/savevm.c > index 57cae52..8f075e5 100644 > --- a/savevm.c > +++ b/savevm.c > @@ -210,6 +210,7 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, > int64_t pos, int size) > static int socket_close(void *opaque) > { > QEMUFileSocket *s = opaque; > +qemu_set_fd_handler(s->fd, NULL, NULL, NULL); > close(s->fd); > g_free(s); > return 0; > @@ -238,6 +239,7 @@ static int stdio_pclose(void *opaque) > { > QEMUFileStdio *s = opaque; > int ret; > +qemu_set_fd_handler(fileno(s->stdio_file), NULL, NULL, NULL); > ret = pclose(s->stdio_file); > if (ret == -1) { > ret = -errno; > @@ -250,6 +252,7 @@ static int stdio_fclose(void *opaque) > { > QEMUFileStdio *s = opaque; > int ret = 0; > +qemu_set_fd_handler(fileno(s->stdio_file), NULL, NULL, NULL); > if (fclose(s->stdio_file) == EOF) { > ret = -errno; > } > -- > 1.7.11.2
Re: [Qemu-devel] [PATCH v6 3/6] monitor: Clean up fd sets on monitor disconnect
On Fri, Aug 03, 2012 at 01:28:06PM -0400, Corey Bryant wrote: > Each fd set has a boolean that keeps track of whether or not the > fd set is in use by a monitor connection. When a monitor > disconnects, all fds that are members of an fd set with refcount > of zero are closed. This prevents any fd leakage associated with > a client disconnect prior to using a passed fd. > > v5: > -This patch is new in v5. > -This support addresses concerns from v4 regarding fd leakage > if the client disconnects unexpectedly. (ebl...@redhat.com, > kw...@redhat.com, dberra...@redhat.com) > > v6: > -No changes > > Signed-off-by: Corey Bryant > --- > monitor.c | 15 +++ > 1 file changed, 15 insertions(+) The lifecycle of fdsets and fds isn't clear to me. It seems like just a refcount in fdset should handle this without extra fields like in_use. Stefan
Re: [Qemu-devel] [PATCH v6 2/6] qapi: Introduce add-fd, remove-fd, query-fdsets
On Fri, Aug 3, 2012 at 6:28 PM, Corey Bryant wrote: > diff --git a/monitor.c b/monitor.c > index 49dccfe..9aa9f7e 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -140,6 +140,24 @@ struct mon_fd_t { > QLIST_ENTRY(mon_fd_t) next; > }; > > +/* file descriptor associated with a file descriptor set */ > +typedef struct mon_fdset_fd_t mon_fdset_fd_t; > +struct mon_fdset_fd_t { QEMU coding style is: typedef struct MonFdsetFd MonFdsetFd; struct MonFdsetFd { See ./CODING_STYLE for more info. > +int fd; > +bool removed; > +QLIST_ENTRY(mon_fdset_fd_t) next; > +}; > + > +/* file descriptor set containing fds passed via SCM_RIGHTS */ > +typedef struct mon_fdset_t mon_fdset_t; > +struct mon_fdset_t { > +int64_t id; > +int refcount; > +bool in_use; > +QLIST_HEAD(, mon_fdset_fd_t) fds; > +QLIST_ENTRY(mon_fdset_t) next; > +}; At this point in the patch series it's not clear to me whether the removed and refcount/in_use fields are a clean and correct solution. Exposing these fields via QMP is also something I'm going to carefully review because they seem like internals. > + > typedef struct MonitorControl { > QObject *id; > JSONMessageParser parser; > @@ -176,7 +194,8 @@ struct Monitor { > int print_calls_nr; > #endif > QError *error; > -QLIST_HEAD(,mon_fd_t) fds; > +QLIST_HEAD(, mon_fd_t) fds; > +QLIST_HEAD(, mon_fdset_t) fdsets; > QLIST_ENTRY(Monitor) entry; > }; > > @@ -2389,6 +2408,157 @@ int monitor_get_fd(Monitor *mon, const char *fdname) > return -1; > } > > +static void monitor_fdset_cleanup(mon_fdset_t *mon_fdset) > +{ > +mon_fdset_fd_t *mon_fdset_fd; > +mon_fdset_fd_t *mon_fdset_fd_next; > + > +if (mon_fdset->refcount != 0) { > +return; > +} > + > +QLIST_FOREACH_SAFE(mon_fdset_fd, &mon_fdset->fds, next, > mon_fdset_fd_next) { > +if (!mon_fdset->in_use || mon_fdset_fd->removed) { > +close(mon_fdset_fd->fd); > +QLIST_REMOVE(mon_fdset_fd, next); > +g_free(mon_fdset_fd); > +} > +} > + > +if (QLIST_EMPTY(&mon_fdset->fds)) { > +QLIST_REMOVE(mon_fdset, next); > +g_free(mon_fdset); > +} > +} > + > +AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, Error **errp) > +{ > +int fd; > +Monitor *mon = cur_mon; > +mon_fdset_t *mon_fdset; > +mon_fdset_fd_t *mon_fdset_fd; > +AddfdInfo *fdinfo; > + > +fd = qemu_chr_fe_get_msgfd(mon->chr); > +if (fd == -1) { > +qerror_report(QERR_FD_NOT_SUPPLIED); > +return NULL; > +} > + > +if (has_fdset_id) { > +QLIST_FOREACH(mon_fdset, &mon->fdsets, next) { > +if (mon_fdset->id == fdset_id) { > +break; > +} > +} > +if (mon_fdset == NULL) { > +qerror_report(QERR_FDSET_NOT_FOUND, fdset_id); > +return NULL; fd is leaked? > +} > +} else { > +int64_t fdset_id_prev = -1; > +mon_fdset_t *mon_fdset_cur = QLIST_FIRST(&mon->fdsets); > + > +/* Use first available fdset ID */ > +QLIST_FOREACH(mon_fdset, &mon->fdsets, next) { > +mon_fdset_cur = mon_fdset; > +if (fdset_id_prev == mon_fdset_cur->id - 1) { > +fdset_id_prev = mon_fdset_cur->id; > +continue; > +} > +break; > +} > + > +mon_fdset = g_malloc0(sizeof(*mon_fdset)); > +mon_fdset->id = fdset_id_prev + 1; > +mon_fdset->refcount = 0; > +mon_fdset->in_use = true; > + > +/* The fdset list is ordered by fdset ID */ > +if (mon_fdset->id == 0) { > +QLIST_INSERT_HEAD(&mon->fdsets, mon_fdset, next); > +} else if (mon_fdset->id < mon_fdset_cur->id) { > +QLIST_INSERT_BEFORE(mon_fdset_cur, mon_fdset, next); > +} else { > +QLIST_INSERT_AFTER(mon_fdset_cur, mon_fdset, next); > +} > +} > + > +mon_fdset_fd = g_malloc0(sizeof(*mon_fdset_fd)); > +mon_fdset_fd->fd = fd; > +mon_fdset_fd->removed = false; > +QLIST_INSERT_HEAD(&mon_fdset->fds, mon_fdset_fd, next); > + > +fdinfo = g_malloc0(sizeof(*fdinfo)); > +fdinfo->fdset_id = mon_fdset->id; > +fdinfo->fd = mon_fdset_fd->fd; > + > +return fdinfo; > +} > + > +void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp) > +{ > +Monitor *mon = cur_mon; > +mon_fdset_t *mon_fdset; > +mon_fdset_fd_t *mon_fdset_fd; > +char fd_str[20]; > + > +QLIST_FOREACH(mon_fdset, &mon->fdsets, next) { > +if (mon_fdset->id != fdset_id) { > +continue; > +} > +QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) { > +if (has_fd && mon_fdset_fd->fd != fd) { > +continue; > +} > +mon_fdset_fd->removed = true; > +if (has_fd) { > +break; > +} > +} > +monitor_fdset_
Re: [Qemu-devel] [PATCH v7 2/6] qapi: Introduce add-fd, remove-fd, query-fdsets
On 08/07/2012 12:49 PM, Eric Blake wrote: On 08/07/2012 09:58 AM, Corey Bryant wrote: This patch adds support that enables passing of file descriptors to the QEMU monitor where they will be stored in specified file descriptor sets. A file descriptor set can be used by a client like libvirt to store file descriptors for the same file. This allows the client to open a file with different access modes (O_RDWR, O_WRONLY, O_RDONLY) and add/remove the passed fds to/from an fd set as needed. This will allow QEMU to (in a later patch in this series) "open" and "reopen" the same file by dup()ing the fd in the fd set that corresponds to the file, where the fd has the matching access mode flag that QEMU requests. The new QMP commands are: add-fd: Add a file descriptor to an fd set remove-fd: Remove a file descriptor from an fd set query-fdsets: Return information describing all fd sets + +# @AddfdInfo: +# +# Information about a file descriptor that was added to an fd set. +# +# @fdset_id: The ID of the fd set that @fd was added to. +# +# @fd: The file descriptor that was received via SCM rights and +# added to the fd set. +# +# Since: 1.2.0 We're not very consistent on '1.2' vs. '1.2.0' in since listings, but that's probably worth a global cleanup closer to hard freeze. I'll make a note of it. Or does Luiz usually do a cleanup? +## +{ 'type': 'AddfdInfo', 'data': {'fdset_id': 'int', 'fd': 'int'} } This is a new command, so s/fdset_id/fdset-id/ Ok + +## +# @add-fd: +# +# Add a file descriptor, that was passed via SCM rights, to an fd set. +# +# @fdset_id: #optional The ID of the fd set to add the file descriptor to. +# +# Returns: @AddfdInfo on success +# If file descriptor was not received, FdNotSupplied +# If @fdset_id does not exist, FdSetNotFound +# +# Notes: The list of fd sets is shared by all monitor connections. +# +#If @fdset_id is not specified, a new fd set will be created. +# +# Since: 1.2.0 +## +{ 'command': 'add-fd', 'data': {'*fdset_id': 'int'}, Again, s/fdset_id/fdset-id/ Ok + 'returns': 'AddfdInfo' } + +## +# @remove-fd: +# +# Remove a file descriptor from an fd set. +# +# @fdset_id: The ID of the fd set that the file descriptor belongs to. +# +# @fd: #optional The file descriptor that is to be removed. +# +# Returns: Nothing on success +# If @fdset_id or @fd is not found, FdNotFound +# +# Since: 1.2.0 +# +# Notes: The list of fd sets is shared by all monitor connections. +# +#File descriptors that are removed: +#o will not be closed until the reference count corresponding +# to @fdset_id reaches zero. +#o will not be available for use after successful completion +# of the remove-fd command. +# +#If @fd is not specified, all file descriptors in @fdset_id +#will be removed. +## +{ 'command': 'remove-fd', 'data': {'fdset_id': 'int', '*fd': 'int'} } And again. Ok + +## +# @FdsetFdInfo: +# +# Information about a file descriptor that belongs to an fd set. +# +# @fd: The file descriptor value. +# +# @removed: If true, the remove-fd command has been issued for this fd. +# +# Since: 1.2.0 +## +{ 'type': 'FdsetFdInfo', 'data': {'fd': 'int', 'removed': 'bool'} } Is it worth providing any additional information? For example, knowing whether the fd is O_RDONLY, O_WRONLY, or O_RDWR might be beneficial to management apps trying to discover what fds are already present after a reconnection, in order to decide whether to close them without having to resort to /proc/$qemupid/fdinfo/nnn lookups. It might even be worth marking such information optional, present only when 'removed':false. It makes sense but I'd like to limit the new functionality at this point so that I can get this support into QEMU 1.2. Can this be added as a follow up patch? + +## +# @FdsetInfo: +# +# Information about an fd set. +# +# @fdset_id: The ID of the fd set. +# +# @refcount: A count of the number of outstanding dup() references to +#this fd set. +# +# @in_use: If true, a monitor is connected and has access to this fd set. +# +# @fds: A list of file descriptors that belong to this fd set. +# +# Since: 1.2.0 +## +{ 'type': 'FdsetInfo', + 'data': {'fdset_id': 'int', 'refcount': 'int', 'in_use': 'bool', + 'fds': ['FdsetFdInfo']} } s/fdset_id/fdset-id/; s/in_use/in-use/ Ok + +## +# @query-fdsets: +# +# Return information describing all fd sets. +# +# Returns: A list of @FdsetInfo +# +# Since: 1.2.0 +# +# Notes: The list of fd sets is shared by all monitor connections. +# +#File descriptors are not closed until @refcount is zero, +#and either @in_use is false or @removed is true. +# +## +{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] } diff --git a/qerror.c b/qerror.c index 92c4eff..63a0aa1 100644 --- a/qerror.c +++ b/qerror.c @@ -148,6 +148,10 @@ static const QErrorStringTable qerror_table[] = { .desc = "No file descrip
Re: [Qemu-devel] [PATCH v7 2/6] qapi: Introduce add-fd, remove-fd, query-fdsets
On 08/07/2012 09:58 AM, Corey Bryant wrote: > This patch adds support that enables passing of file descriptors > to the QEMU monitor where they will be stored in specified file > descriptor sets. > > A file descriptor set can be used by a client like libvirt to > store file descriptors for the same file. This allows the > client to open a file with different access modes (O_RDWR, > O_WRONLY, O_RDONLY) and add/remove the passed fds to/from an fd > set as needed. This will allow QEMU to (in a later patch in this > series) "open" and "reopen" the same file by dup()ing the fd in > the fd set that corresponds to the file, where the fd has the > matching access mode flag that QEMU requests. > > The new QMP commands are: > add-fd: Add a file descriptor to an fd set > remove-fd: Remove a file descriptor from an fd set > query-fdsets: Return information describing all fd sets > > + > +# @AddfdInfo: > +# > +# Information about a file descriptor that was added to an fd set. > +# > +# @fdset_id: The ID of the fd set that @fd was added to. > +# > +# @fd: The file descriptor that was received via SCM rights and > +# added to the fd set. > +# > +# Since: 1.2.0 We're not very consistent on '1.2' vs. '1.2.0' in since listings, but that's probably worth a global cleanup closer to hard freeze. > +## > +{ 'type': 'AddfdInfo', 'data': {'fdset_id': 'int', 'fd': 'int'} } This is a new command, so s/fdset_id/fdset-id/ > + > +## > +# @add-fd: > +# > +# Add a file descriptor, that was passed via SCM rights, to an fd set. > +# > +# @fdset_id: #optional The ID of the fd set to add the file descriptor to. > +# > +# Returns: @AddfdInfo on success > +# If file descriptor was not received, FdNotSupplied > +# If @fdset_id does not exist, FdSetNotFound > +# > +# Notes: The list of fd sets is shared by all monitor connections. > +# > +#If @fdset_id is not specified, a new fd set will be created. > +# > +# Since: 1.2.0 > +## > +{ 'command': 'add-fd', 'data': {'*fdset_id': 'int'}, Again, s/fdset_id/fdset-id/ > + 'returns': 'AddfdInfo' } > + > +## > +# @remove-fd: > +# > +# Remove a file descriptor from an fd set. > +# > +# @fdset_id: The ID of the fd set that the file descriptor belongs to. > +# > +# @fd: #optional The file descriptor that is to be removed. > +# > +# Returns: Nothing on success > +# If @fdset_id or @fd is not found, FdNotFound > +# > +# Since: 1.2.0 > +# > +# Notes: The list of fd sets is shared by all monitor connections. > +# > +#File descriptors that are removed: > +#o will not be closed until the reference count corresponding > +# to @fdset_id reaches zero. > +#o will not be available for use after successful completion > +# of the remove-fd command. > +# > +#If @fd is not specified, all file descriptors in @fdset_id > +#will be removed. > +## > +{ 'command': 'remove-fd', 'data': {'fdset_id': 'int', '*fd': 'int'} } And again. > + > +## > +# @FdsetFdInfo: > +# > +# Information about a file descriptor that belongs to an fd set. > +# > +# @fd: The file descriptor value. > +# > +# @removed: If true, the remove-fd command has been issued for this fd. > +# > +# Since: 1.2.0 > +## > +{ 'type': 'FdsetFdInfo', 'data': {'fd': 'int', 'removed': 'bool'} } Is it worth providing any additional information? For example, knowing whether the fd is O_RDONLY, O_WRONLY, or O_RDWR might be beneficial to management apps trying to discover what fds are already present after a reconnection, in order to decide whether to close them without having to resort to /proc/$qemupid/fdinfo/nnn lookups. It might even be worth marking such information optional, present only when 'removed':false. > + > +## > +# @FdsetInfo: > +# > +# Information about an fd set. > +# > +# @fdset_id: The ID of the fd set. > +# > +# @refcount: A count of the number of outstanding dup() references to > +#this fd set. > +# > +# @in_use: If true, a monitor is connected and has access to this fd set. > +# > +# @fds: A list of file descriptors that belong to this fd set. > +# > +# Since: 1.2.0 > +## > +{ 'type': 'FdsetInfo', > + 'data': {'fdset_id': 'int', 'refcount': 'int', 'in_use': 'bool', > + 'fds': ['FdsetFdInfo']} } s/fdset_id/fdset-id/; s/in_use/in-use/ > + > +## > +# @query-fdsets: > +# > +# Return information describing all fd sets. > +# > +# Returns: A list of @FdsetInfo > +# > +# Since: 1.2.0 > +# > +# Notes: The list of fd sets is shared by all monitor connections. > +# > +#File descriptors are not closed until @refcount is zero, > +#and either @in_use is false or @removed is true. > +# > +## > +{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] } > diff --git a/qerror.c b/qerror.c > index 92c4eff..63a0aa1 100644 > --- a/qerror.c > +++ b/qerror.c > @@ -148,6 +148,10 @@ static const QErrorStringTable qerror_table[] = { > .desc = "No file descriptor supplied via SCM_RIGHTS", > }, > { >
Re: [Qemu-devel] [PATCH v5 6/6] block: Enable qemu_open/close to work with fd sets
On 08/06/2012 10:15 AM, Corey Bryant wrote: On 08/06/2012 09:51 AM, Kevin Wolf wrote: Am 06.08.2012 15:32, schrieb Corey Bryant: On 08/06/2012 05:15 AM, Kevin Wolf wrote: Am 03.08.2012 00:21, schrieb Corey Bryant: @@ -84,6 +158,36 @@ int qemu_open(const char *name, int flags, ...) int ret; int mode = 0; +#ifndef _WIN32 +const char *fdset_id_str; + +/* Attempt dup of fd from fd set */ +if (strstart(name, "/dev/fdset/", &fdset_id_str)) { +int64_t fdset_id; +int fd, dupfd; + +fdset_id = qemu_parse_fdset(fdset_id_str); +if (fdset_id == -1) { +errno = EINVAL; +return -1; +} + +fd = monitor_fdset_get_fd(default_mon, fdset_id, flags); I know that use of default_mon in this patch is not correct, but I wanted to get these patches out for review. I used default_mon for testing because cur_mon wasn't pointing to the monitor I'd added fd sets to. I need to figure out why. Does it make sense to use default_mon here? After digging into this some more, I'm thinking it makes sense, and I'll explain why. It looks like cur_mon can't be used. cur_mon will point to the monitor object for the duration of a command, and be reset to old_mon (NULL in my case) after the command completes. qemu_open() and qemu_close() are frequently called long after a monitor command has come and gone, so cur_mon won't work. For example, drive_add will cause qemu_open() to be called, but after the command has completed, the file will keep getting opened/closed during normal QEMU operation. I'm not sure why, I've just noticed this behavior. Does anyone have any thoughts on this? It would require fd sets to be added to the default monitor only. I think we have two design options that would make sense: 1. Make the file descriptors global instead of per-monitor. Is there a reason why each monitor has its own set of fds? (Also I'm wondering if they survive a monitor disconnect this way?) I'd prefer to have them associated with a monitor object so that we can more easily keep track of whether or not they're in use by a monitor connection. Hm, I see. 2. Save a monitor reference with the fdset information. Are you saying that each monitor would have the same copy of fdset information? This one doesn't really make sense indeed... Allowing to send file descriptors on every monitor, but making only those of the default monitor actually usable, sounds like a bad choice to me. What if we also allow them to be added only to the default monitor? Would get you some kind of consistency at least, even though I don't like that secondary monitors can't use the functionality. Can't we make the fdset information global, so that a qemu_open/close() searches all of them, but let it have a Monitor* owner for keeping track whether it's in use? I think global fdsets might work (sorry I didn't think it through enough on my first reply). I think I'll need to drop the "in_use" flag and tie monitor references into the refcount. (I know I know, you suggested that a while back.. :). I'll give it a shot and see how it goes. I just submitted the v7 patch series which makes fd sets global, rather than each Monitor object having an fd set. This allows the list of fd sets to be shared among all monitor connections. -- Regards, Corey
[Qemu-devel] [PATCH 08/35] qerror: qerror_format(): return an allocated string
Simplifies current and future users. Signed-off-by: Luiz Capitulino --- error.c | 5 + qerror.c | 10 -- qerror.h | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/error.c b/error.c index 58f55a0..3a62592 100644 --- a/error.c +++ b/error.c @@ -65,10 +65,7 @@ bool error_is_set(Error **errp) const char *error_get_pretty(Error *err) { if (err->msg == NULL) { -QString *str; -str = qerror_format(err->fmt, err->obj); -err->msg = g_strdup(qstring_get_str(str)); -QDECREF(str); +err->msg = qerror_format(err->fmt, err->obj); } return err->msg; diff --git a/qerror.c b/qerror.c index 6f9f49c..d073ed7 100644 --- a/qerror.c +++ b/qerror.c @@ -493,9 +493,11 @@ static QString *qerror_format_desc(QDict *error, return qstring; } -QString *qerror_format(const char *fmt, QDict *error) +char *qerror_format(const char *fmt, QDict *error) { const QErrorStringTable *entry = NULL; +QString *qstr; +char *ret; int i; for (i = 0; qerror_table[i].error_fmt; i++) { @@ -505,7 +507,11 @@ QString *qerror_format(const char *fmt, QDict *error) } } -return qerror_format_desc(error, entry); +qstr = qerror_format_desc(error, entry); +ret = g_strdup(qstring_get_str(qstr)); +QDECREF(qstr); + +return ret; } /** diff --git a/qerror.h b/qerror.h index 3c0b14c..aec76b2 100644 --- a/qerror.h +++ b/qerror.h @@ -34,7 +34,7 @@ QString *qerror_human(const QError *qerror); void qerror_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); void qerror_report_err(Error *err); void assert_no_error(Error *err); -QString *qerror_format(const char *fmt, QDict *error); +char *qerror_format(const char *fmt, QDict *error); /* * QError class list -- 1.7.11.2.249.g31c7954.dirty
[Qemu-devel] [PATCH 11/35] qmp: query-block: add 'valid_encryption_key' field
Signed-off-by: Luiz Capitulino --- block.c | 1 + qapi-schema.json | 8 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 24323c1..59f6dd8 100644 --- a/block.c +++ b/block.c @@ -2445,6 +2445,7 @@ BlockInfoList *qmp_query_block(Error **errp) info->value->inserted->ro = bs->read_only; info->value->inserted->drv = g_strdup(bs->drv->format_name); info->value->inserted->encrypted = bs->encrypted; +info->value->inserted->valid_encryption_key = bs->valid_key; if (bs->backing_file[0]) { info->value->inserted->has_backing_file = true; info->value->inserted->backing_file = g_strdup(bs->backing_file); diff --git a/qapi-schema.json b/qapi-schema.json index cddf63a..5805f74 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -402,6 +402,8 @@ # # @encrypted: true if the backing device is encrypted # +# @valid_encryption_key: true if a valid encryption key has been set +# # @bps: total throughput limit in bytes per second is specified # # @bps_rd: read throughput limit in bytes per second is specified @@ -421,9 +423,9 @@ { 'type': 'BlockDeviceInfo', 'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str', '*backing_file': 'str', 'backing_file_depth': 'int', -'encrypted': 'bool', 'bps': 'int', 'bps_rd': 'int', -'bps_wr': 'int', 'iops': 'int', 'iops_rd': 'int', -'iops_wr': 'int'} } +'encrypted': 'bool', 'valid_encryption_key': 'bool', +'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int', +'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int'} } ## # @BlockDeviceIoStatus: -- 1.7.11.2.249.g31c7954.dirty
[Qemu-devel] [PATCH 09/35] qerror: don't delay error message construction
Today, the error message is only constructed when it's used. This commit changes qerror to construct the error message when the error object is built (ie. when the error is reported). This eliminates the need of storing a pointer to qerror_table[], which will be dropped soon, and also simplifies the code. Signed-off-by: Luiz Capitulino --- qerror.c | 29 - qerror.h | 2 +- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/qerror.c b/qerror.c index d073ed7..a254f88 100644 --- a/qerror.c +++ b/qerror.c @@ -385,22 +385,6 @@ static QDict *error_obj_from_fmt_no_fail(const char *fmt, va_list *va) return ret; } -static const QErrorStringTable *get_desc_no_fail(const char *fmt) -{ -int i; - -// FIXME: inefficient loop - -for (i = 0; qerror_table[i].error_fmt; i++) { -if (strcmp(qerror_table[i].error_fmt, fmt) == 0) { -return &qerror_table[i]; -} -} - -fprintf(stderr, "error format '%s' not found\n", fmt); -abort(); -} - /** * qerror_from_info(): Create a new QError from error information * @@ -414,7 +398,7 @@ static QError *qerror_from_info(const char *fmt, va_list *va) loc_save(&qerr->loc); qerr->error = error_obj_from_fmt_no_fail(fmt, va); -qerr->entry = get_desc_no_fail(fmt); +qerr->err_msg = qerror_format(fmt, qerr->error); return qerr; } @@ -519,7 +503,7 @@ char *qerror_format(const char *fmt, QDict *error) */ QString *qerror_human(const QError *qerror) { -return qerror_format_desc(qerror->error, qerror->entry); +return qstring_from_str(qerror->err_msg); } /** @@ -566,19 +550,13 @@ struct Error void qerror_report_err(Error *err) { QError *qerr; -int i; qerr = qerror_new(); loc_save(&qerr->loc); QINCREF(err->obj); qerr->error = err->obj; -for (i = 0; qerror_table[i].error_fmt; i++) { -if (strcmp(qerror_table[i].error_fmt, err->fmt) == 0) { -qerr->entry = &qerror_table[i]; -break; -} -} +qerr->err_msg = qerror_format(err->fmt, qerr->error); if (monitor_cur_is_qmp()) { monitor_set_error(cur_mon, qerr); @@ -619,5 +597,6 @@ static void qerror_destroy_obj(QObject *obj) qerr = qobject_to_qerror(obj); QDECREF(qerr->error); +g_free(qerr->err_msg); g_free(qerr); } diff --git a/qerror.h b/qerror.h index aec76b2..de8497d 100644 --- a/qerror.h +++ b/qerror.h @@ -27,7 +27,7 @@ typedef struct QError { QObject_HEAD; QDict *error; Location loc; -const QErrorStringTable *entry; +char *err_msg; } QError; QString *qerror_human(const QError *qerror); -- 1.7.11.2.249.g31c7954.dirty
[Qemu-devel] [PATCH v7 4/6] block: Convert open calls to qemu_open
This patch converts all block layer open calls to qemu_open. Note that this adds the O_CLOEXEC flag to the changed open paths when the O_CLOEXEC macro is defined. Signed-off-by: Corey Bryant --- v2: -Convert calls to qemu_open instead of file_open (kw...@redhat.com) -Mention introduction of O_CLOEXEC (kw...@redhat.com) v3-v7: -No changes block/raw-posix.c | 18 +- block/raw-win32.c |4 ++-- block/vdi.c |5 +++-- block/vmdk.c | 21 + block/vpc.c |2 +- block/vvfat.c |4 ++-- 6 files changed, 26 insertions(+), 28 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index 0dce089..7408a42 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -572,8 +572,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, - 0644); +fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, + 0644); if (fd < 0) { result = -errno; } else { @@ -846,7 +846,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) if ( bsdPath[ 0 ] != '\0' ) { strcat(bsdPath,"s0"); /* some CDs don't have a partition 0 */ -fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); +fd = qemu_open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); if (fd < 0) { bsdPath[strlen(bsdPath)-1] = '1'; } else { @@ -903,7 +903,7 @@ static int fd_open(BlockDriverState *bs) #endif return -EIO; } -s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK); +s->fd = qemu_open(bs->filename, s->open_flags & ~O_NONBLOCK); if (s->fd < 0) { s->fd_error_time = get_clock(); s->fd_got_error = 1; @@ -977,7 +977,7 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_BINARY); +fd = qemu_open(filename, O_WRONLY | O_BINARY); if (fd < 0) return -errno; @@ -1055,7 +1055,7 @@ static int floppy_probe_device(const char *filename) if (strstart(filename, "/dev/fd", NULL)) prio = 50; -fd = open(filename, O_RDONLY | O_NONBLOCK); +fd = qemu_open(filename, O_RDONLY | O_NONBLOCK); if (fd < 0) { goto out; } @@ -1108,7 +1108,7 @@ static void floppy_eject(BlockDriverState *bs, bool eject_flag) close(s->fd); s->fd = -1; } -fd = open(bs->filename, s->open_flags | O_NONBLOCK); +fd = qemu_open(bs->filename, s->open_flags | O_NONBLOCK); if (fd >= 0) { if (ioctl(fd, FDEJECT, 0) < 0) perror("FDEJECT"); @@ -1158,7 +1158,7 @@ static int cdrom_probe_device(const char *filename) int prio = 0; struct stat st; -fd = open(filename, O_RDONLY | O_NONBLOCK); +fd = qemu_open(filename, O_RDONLY | O_NONBLOCK); if (fd < 0) { goto out; } @@ -1282,7 +1282,7 @@ static int cdrom_reopen(BlockDriverState *bs) */ if (s->fd >= 0) close(s->fd); -fd = open(bs->filename, s->open_flags, 0644); +fd = qemu_open(bs->filename, s->open_flags, 0644); if (fd < 0) { s->fd = -1; return -EIO; diff --git a/block/raw-win32.c b/block/raw-win32.c index e4b0b75..8d7838d 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -255,8 +255,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, - 0644); +fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, + 0644); if (fd < 0) return -EIO; set_sparse(fd); diff --git a/block/vdi.c b/block/vdi.c index 57325d6..c4f1529 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -653,8 +653,9 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, - 0644); +fd = qemu_open(filename, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, + 0644); if (fd < 0) { return -errno; } diff --git a/block/vmdk.c b/block/vmdk.c index 18e9b4c..557dc1b 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1161,10 +1161,9 @@ static int vmdk_create_extent(const char *filename, int64_t filesize, VMDK4Header header; uint32_t tmp, magic, grains, gd_size, gt_size, gt_count; -fd = open( -filename, -O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, -0644); +fd = qemu_open(filename, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, + 0644); if (fd < 0) { return -errno; } @@ -148
[Qemu-devel] [PATCH 4/6] migration: remove iohandlers before closing the file
This will be needed as soon as process_incoming_migration will set handlers on the file. The patch may be removed if Signed-off-by: Paolo Bonzini --- savevm.c | 3 +++ 1 file modificato, 3 inserzioni(+) diff --git a/savevm.c b/savevm.c index 57cae52..8f075e5 100644 --- a/savevm.c +++ b/savevm.c @@ -210,6 +210,7 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size) static int socket_close(void *opaque) { QEMUFileSocket *s = opaque; +qemu_set_fd_handler(s->fd, NULL, NULL, NULL); close(s->fd); g_free(s); return 0; @@ -238,6 +239,7 @@ static int stdio_pclose(void *opaque) { QEMUFileStdio *s = opaque; int ret; +qemu_set_fd_handler(fileno(s->stdio_file), NULL, NULL, NULL); ret = pclose(s->stdio_file); if (ret == -1) { ret = -errno; @@ -250,6 +252,7 @@ static int stdio_fclose(void *opaque) { QEMUFileStdio *s = opaque; int ret = 0; +qemu_set_fd_handler(fileno(s->stdio_file), NULL, NULL, NULL); if (fclose(s->stdio_file) == EOF) { ret = -errno; } -- 1.7.11.2
[Qemu-devel] [PATCH 1/6] migration: clean up server sockets and handlers before invoking process_incoming_migration
We will not accept any other migration from the server socket, so we can close it. Signed-off-by: Paolo Bonzini --- migration-exec.c | 2 +- migration-fd.c | 2 +- migration-tcp.c | 7 +++ migration-unix.c | 7 +++ 4 file modificati, 8 inserzioni(+), 10 rimozioni(-) diff --git a/migration-exec.c b/migration-exec.c index 6c97db9..061131a 100644 --- a/migration-exec.c +++ b/migration-exec.c @@ -97,8 +97,8 @@ static void exec_accept_incoming_migration(void *opaque) { QEMUFile *f = opaque; -process_incoming_migration(f); qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL); +process_incoming_migration(f); qemu_fclose(f); } diff --git a/migration-fd.c b/migration-fd.c index 50138ed..87705c0 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -103,8 +103,8 @@ static void fd_accept_incoming_migration(void *opaque) { QEMUFile *f = opaque; -process_incoming_migration(f); qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL); +process_incoming_migration(f); qemu_fclose(f); } diff --git a/migration-tcp.c b/migration-tcp.c index 440804d..587413e 100644 --- a/migration-tcp.c +++ b/migration-tcp.c @@ -119,12 +119,14 @@ static void tcp_accept_incoming_migration(void *opaque) do { c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen); } while (c == -1 && socket_error() == EINTR); +qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); +close(s); DPRINTF("accepted migration\n"); if (c == -1) { fprintf(stderr, "could not accept migration connection\n"); -goto out2; +goto out; } f = qemu_fopen_socket(c); @@ -137,9 +139,6 @@ static void tcp_accept_incoming_migration(void *opaque) qemu_fclose(f); out: close(c); -out2: -qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); -close(s); } int tcp_start_incoming_migration(const char *host_port, Error **errp) diff --git a/migration-unix.c b/migration-unix.c index 169de88..a407af2 100644 --- a/migration-unix.c +++ b/migration-unix.c @@ -129,12 +129,14 @@ static void unix_accept_incoming_migration(void *opaque) do { c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen); } while (c == -1 && errno == EINTR); +qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); +close(s); DPRINTF("accepted migration\n"); if (c == -1) { fprintf(stderr, "could not accept migration connection\n"); -goto out2; +goto out; } f = qemu_fopen_socket(c); @@ -147,9 +149,6 @@ static void unix_accept_incoming_migration(void *opaque) qemu_fclose(f); out: close(c); -out2: -qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); -close(s); } int unix_start_incoming_migration(const char *path) -- 1.7.11.2
[Qemu-devel] [PATCH 27/35] hmp: hmp_change(): use error_get_class()
The error_is_type() function is going to be dropped. Signed-off-by: Luiz Capitulino --- hmp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hmp.c b/hmp.c index 3a9688d..5900251 100644 --- a/hmp.c +++ b/hmp.c @@ -799,7 +799,8 @@ void hmp_change(Monitor *mon, const QDict *qdict) } qmp_change(device, target, !!arg, arg, &err); -if (error_is_type(err, QERR_DEVICE_ENCRYPTED)) { +if (error_is_set(&err) && +error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) { error_free(err); monitor_read_block_device_key(mon, device, NULL, NULL); return; -- 1.7.11.2.249.g31c7954.dirty
[Qemu-devel] [PATCH v7 1/6] qemu-char: Add MSG_CMSG_CLOEXEC flag to recvmsg
Set the close-on-exec flag for the file descriptor received via SCM_RIGHTS. Signed-off-by: Corey Bryant --- v4 -This patch is new in v4 (ebl...@redhat.com) v5 -Fallback to FD_CLOEXEC if MSG_CMSG_CLOEXEC is not available (ebl...@redhat.com, stefa...@linux.vnet.ibm.com) v6 -Set cloexec on correct fd (ebl...@redhat.com) v7 -No changes qemu-char.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index c2aaaee..ab4a928 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2238,6 +2238,9 @@ static void unix_process_msgfd(CharDriverState *chr, struct msghdr *msg) if (fd < 0) continue; +#ifndef MSG_CMSG_CLOEXEC +qemu_set_cloexec(fd); +#endif if (s->msgfd != -1) close(s->msgfd); s->msgfd = fd; @@ -2253,6 +2256,7 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) struct cmsghdr cmsg; char control[CMSG_SPACE(sizeof(int))]; } msg_control; +int flags = 0; ssize_t ret; iov[0].iov_base = buf; @@ -2263,9 +2267,13 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len) msg.msg_control = &msg_control; msg.msg_controllen = sizeof(msg_control); -ret = recvmsg(s->fd, &msg, 0); -if (ret > 0 && s->is_unix) +#ifdef MSG_CMSG_CLOEXEC +flags |= MSG_CMSG_CLOEXEC; +#endif +ret = recvmsg(s->fd, &msg, flags); +if (ret > 0 && s->is_unix) { unix_process_msgfd(chr, &msg); +} return ret; } -- 1.7.10.4