[Qemu-devel] [PATCH v5 10/11] spapr-vfio: add spapr-pci-vfio-host-bridge to support vfio
The patch adds a spapr-pci-vfio-host-bridge device type which is a PCI Host Bridge with VFIO support. The new device inherits from the spapr-pci-host-bridge device and adds the following properties: iommu - IOMMU group ID which represents a Partitionable Endpoint, QEMU/ppc64 uses a separate PHB for an IOMMU group so the guest kernel has to have PCI Domain support enabled. forceaddr (optional, 0 by default) - forces QEMU to copy device:function from the host address as certain guest drivers expect devices to appear in particular locations; mf (optional, 0 by default) - forces multifunction bit for the function #0 of a found device, only makes sense for multifunction devices and only with the forceaddr property set. It would not be required if there was a way to know in advance whether a device is multifunctional or not. scan (optional, 1 by default) - if non-zero, the new PHB walks through all non-bridge devices in the group and tries adding them to the PHB; if zero, all devices in the group have to be configured manually via the QEMU command line. Examples of use: 1) Scan and add all devices from IOMMU group with ID=1 to QEMU's PHB #6: -device spapr-pci-vfio-host-bridge,id=DEVICENAME,iommu=1,index=6 2) Configure and Add 3 functions of a multifunctional device to QEMU: (the NEC PCI USB card is used as an example here): -device spapr-pci-vfio-host-bridge,id=USB,iommu=4,scan=0,index=7 \ -device vfio-pci,host=4:0:1.0,addr=1.0,bus=USB,multifunction=true -device vfio-pci,host=4:0:1.1,addr=1.1,bus=USB -device vfio-pci,host=4:0:1.2,addr=1.2,bus=USB Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Changes: v5: * added handling of possible failure of spapr_vfio_new_table() v4: * moved IOMMU changes to separate patches * moved spapr-pci-vfio-host-bridge to new file --- hw/ppc/Makefile.objs| 2 +- hw/ppc/spapr_pci_vfio.c | 206 include/hw/pci-host/spapr.h | 13 +++ 3 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 hw/ppc/spapr_pci_vfio.c diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index ea747f0..2239192 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -3,7 +3,7 @@ obj-y += ppc.o ppc_booke.o # IBM pSeries (sPAPR) obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o -obj-$(CONFIG_PSERIES) += spapr_pci.o +obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_pci_vfio.o # PowerPC 4xx boards obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o obj-y += ppc4xx_pci.o diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c new file mode 100644 index 000..40f6673 --- /dev/null +++ b/hw/ppc/spapr_pci_vfio.c @@ -0,0 +1,206 @@ +/* + * QEMU sPAPR PCI host for VFIO + * + * Copyright (c) 2011 Alexey Kardashevskiy, IBM Corporation. + * + * 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. + */ +#include sys/types.h +#include dirent.h + +#include hw/hw.h +#include hw/ppc/spapr.h +#include hw/pci-host/spapr.h +#include hw/misc/vfio.h +#include hw/pci/pci_bus.h +#include trace.h +#include qemu/error-report.h + +/* sPAPR VFIO */ +static Property spapr_phb_vfio_properties[] = { +DEFINE_PROP_INT32(iommu, sPAPRPHBVFIOState, iommugroupid, -1), +DEFINE_PROP_UINT8(scan, sPAPRPHBVFIOState, scan, 1), +DEFINE_PROP_UINT8(mf, sPAPRPHBVFIOState, enable_multifunction, 0), +DEFINE_PROP_UINT8(forceaddr, sPAPRPHBVFIOState, force_addr, 0), +DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_pci_vfio_scan(sPAPRPHBVFIOState *svphb, Error **errp) +{ +PCIHostState *phb = PCI_HOST_BRIDGE(svphb); +char *iommupath; +
Re: [Qemu-devel] [RFC v3 2/3] i386: use CpuTopoInfo instead apic_id as argument for pc_new_cpu()
On Tue, 2014-03-11 at 15:00 -0300, Eduardo Habkost wrote: On Tue, Mar 11, 2014 at 06:58:53PM +0800, chen.fan.fnst wrote: From: chen.fan.fnst chen.fan.f...@cn.fujitsu.com Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com --- hw/i386/pc.c | 12 target-i386/cpu.c | 2 -- target-i386/cpu.h | 3 +++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e715a33..c754042 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -927,11 +927,12 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } } -static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, +static X86CPU *pc_new_cpu(const char *cpu_model, CpuTopoInfo *topo, DeviceState *icc_bridge, Error **errp) { X86CPU *cpu; Error *local_err = NULL; +uint32_t apic_id = apicid_from_topo_ids(smp_cores, smp_threads, topo); cpu = cpu_x86_create(cpu_model, icc_bridge, local_err); if (local_err != NULL) { @@ -956,6 +957,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) { DeviceState *icc_bridge; int64_t apic_id = x86_cpu_apic_id_from_index(id); With this patch, pc_new_cpu() is CPUTopoInfo-based, but cpu_exists() is apic_id-based. This requires apic_id to be calculated here, but pc_new_cpu() doesn't require it anymore. We could make this more consistent, and avoid calculating the APIC ID in two different places. We are eveng using two different methods: here we use x86_cpu_apic_id_from_index() and pc_new_cpu() is using apicid_from_topo_ids(). Maybe we could simply move the cpu_exists() check inside pc_new_cpu()? +CpuTopoInfo topo; if (id 0) { error_setg(errp, Invalid CPU id: % PRIi64, id); @@ -976,7 +978,8 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) icc_bridge = DEVICE(object_resolve_path_type(icc-bridge, TYPE_ICC_BRIDGE, NULL)); -pc_new_cpu(current_cpu_model, apic_id, icc_bridge, errp); +x86_topo_ids_from_idx(smp_cores, smp_threads, id, topo); +pc_new_cpu(current_cpu_model, topo, icc_bridge, errp); } void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) @@ -996,8 +999,9 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) current_cpu_model = cpu_model; for (i = 0; i smp_cpus; i++) { -cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), - icc_bridge, error); x86_cpu_apic_id_from_index() has compat code to keep compatibility on older machine-types, and you are removing the compat behavior. To keep the compat code isolated on pc_cpus_init() and keep pc_new_cpu() interface saner, we could do something like this, on pc_cpus_init() only: CPUTopoInfo topo; x86_topo_ids_from_idx(cpu_index, topo); if (apic_id_compat) { correct_apic_id = apicid_from_topo_ids(topo); apic_id = cpu_index; if (apic_id != correct_apic_id) { error_report(APIC IDs set in compatibility mode, CPU topology won't match the configuration); } // get_topo_from_apic_id() needs to be written: get_topo_from_apic_id(apic_id, topo); // just in case: assert(apicid_from_topo_ids(topo) == apic_id); } I think we can write new x86_cpu_topo_ids_from_index() to do this compat work. I think I can make it soon. And on pc_hot_add_cpu(): if (apic_id_compat) { error_setg(errp, CPU hotplug is not supported on this machine); return; } cpu hotplug supported since pc 1.5, and apic_id_compat is below pc 1.3, so I think this must be unnecessary. Thanks, Chen +CpuTopoInfo topo; +x86_topo_ids_from_idx(smp_cores, smp_threads, i, topo); +cpu = pc_new_cpu(cpu_model, topo, icc_bridge, error); if (error) { error_report(%s, error_get_pretty(error)); error_free(error); diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 0e8812a..3a5df33 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -23,8 +23,6 @@ #include cpu.h #include sysemu/kvm.h -#include sysemu/cpus.h -#include topology.h #include qemu/option.h #include qemu/config-file.h diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 0014acc..8bc7b45 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -22,6 +22,9 @@ #include config.h #include qemu-common.h +#include sysemu/cpus.h +#include topology.h + #ifdef TARGET_X86_64 #define TARGET_LONG_BITS 64 #else -- 1.8.1.4
Re: [Qemu-devel] [PATCH v22 07/25] change block layer to support both QemuOpts and QEMUOptionParamter
2014-03-12 0:54 GMT+08:00 Eric Blake ebl...@redhat.com: On 03/10/2014 01:31 AM, Chunyan Liu wrote: Change block layer to support both QemuOpts and QEMUOptionParameter. After this patch, it will change backend drivers one by one. At the end, QEMUOptionParameter will be removed and only QemuOpts is kept. Signed-off-by: Dong Xu Wang wdon...@linux.vnet.ibm.com Signed-off-by: Chunyan Liu cy...@suse.com --- int bdrv_create(BlockDriver *drv, const char* filename, -QEMUOptionParameter *options, Error **errp) +QEMUOptionParameter *options, QemuOpts *opts, Error **errp) { int ret; In addition to my remarks last night: I wonder if you should add: assert(!(options opts)) to prove that all callers are passing at most one of the two supported option lists, while doing the conversion. @@ -5248,28 +5266,31 @@ void bdrv_img_create(const char *filename, const char *fmt, return; } -create_options = append_option_parameters(create_options, - drv-create_options); -create_options = append_option_parameters(create_options, - proto_drv-create_options); +if (drv-bdrv_create2) { +create_opts = qemu_opts_append(create_opts, drv-create_opts); +create_opts = qemu_opts_append(create_opts, proto_drv-create_opts); In addition to the memory leak I pointed out earlier, Should use g_realloc in qemu_opts_append, realloc create_opts to the desired space and append 2nd list to it. Saving the effort to free memory while append many times. I see another potential problem: What if drv has been converted to QemuOpts, but proto_drv is still on QEMUOptionParameter? +} else { +create_options = append_option_parameters(create_options, + drv-create_options); +create_options = append_option_parameters(create_options, + proto_drv-create_options); Or the converse, if drv is still on QEMUOptionParameter, but proto_drv has been converted to QEMUOpts? Either way, you will be appending NULL for the proto_drv case, when what you really wanted to be doing was merging both the QemuOpts and QEMUOptionParameters into a single list. +create_opts = params_to_opts(create_options); +} I think a better path to conversion would be doing everything possible in QemuOpts, and only switching to QEMUOptionParameters at the last possible moment, rather than having two separate append code paths. My suggestion: until the conversion is complete, add a new function, something like: void qemu_opts_append_pair(QemuOpts *dst, QemuOpts *opts, QEMUOptionParameter *options) { assert(!(opts options)); ... modify dst in-place to have it cover the entries from opts or options } then in this code, you do: create_options = /* generate empty QemuOpts */; qemu_opts_append_pair(options, drv-create_opts, drv-create_options); qemu_opts_append_pair(options, proto_drv-create_options, proto_drv-create_options); Good. Together with always using QemuOpts and only converting to QEMUOptionParameter until it calls .bdrv_create in specific driver, the drv/proto_drv inconsistent problem could be solved. Will update. Thanks very much for all your suggestions! Chunyan /* Create parameter list with default values */ -param = parse_option_parameters(, create_options, param); - -set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size); +opts = qemu_opts_create(create_opts, NULL, 0, error_abort); +qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size); This part worked nicely - once you convert both incoming styles to QemuOpts, it really is easier to have this part of the code just use QemuOpts functions for setting the size ... @@ -5343,16 +5364,23 @@ void bdrv_img_create(const char *filename, const char *fmt, if (!quiet) { printf(Formatting '%s', fmt=%s , filename, fmt); -print_option_parameters(param); +qemu_opts_print(opts); puts(); } -ret = bdrv_create(drv, filename, param, local_err); + +if (drv-bdrv_create2) { +ret = bdrv_create(drv, filename, NULL, opts, local_err); +} else { +param = opts_to_params(opts); +ret = bdrv_create(drv, filename, param, NULL, local_err); +} ...and finally convert back to QEMUOptionParameters at the last moment. But wait a minute - why are you checking for drv-bdrv_create2 here? Isn't the last possible moment really inside bdrv_create() (that is, the actual function that decides whether to call drv-bdrv_create vs. drv-bdrv_create2)? For the code to be as clean as possible, you want to use QemuOpts everywhere until the actual point where you are calling the unconverted callback. -int
[Qemu-devel] [PATCH v2 0/9] QMP: Introduce incremental drive-backup with in-memory dirty bitmap
Introduction This implements incremental backup. A convenient option bitmap-use-mode for drive-backup is introduced since v1. Commands A new sync mode for drive-backup is introduced: drive-backup device=.. mode=.. sync=dirty-bitmap bitmap=bitmap0 bitmap-use-mode=reset This mode will scan dirty bitmap bitmap0 and only copy all dirty sectors to target. bitmap-use-mode controls what operation is done on the given bitmap: - reset: Clear all the bits (block job save a copy) - consume: Block job takes the bitmap and make it invisible to user, and release it after use. A few low level commands related to dirty bitmap are also added: dirty-bitmap-add dirty-bitmap-remove dirty-bitmap-enable dirty-bitmap-disable Example --- (QMP) dirty-bitmap-add device=? name=bitmap0 [guest writes to device] (QMP) drive-backup device=? target=backup1.qcow2 format=qcow2 \ sync=dirty-bitmap bitmap=bitmap0 bitmap-use-mode=reset [guest writes more to device] (QMP) drive-backup device=? target=backup2.qcow2 format=qcow2 \ sync=dirty-bitmap bitmap=bitmap0 bitmap-use-mode=reset ... Fam Fam Zheng (9): qapi: Add optional field name to block dirty bitmap qmp: Add dirty-bitmap-add and dirty-bitmap-remove block: Handle error of bdrv_getlength in bdrv_create_dirty_bitmap block: Introduce bdrv_dirty_bitmap_granularity() hbitmap: Add hbitmap_copy block: Add bdrv_copy_dirty_bitmap and bdrv_reset_dirty_bitmap qmp: Add dirty-bitmap-enable and dirty-bitmap-disable qmp: Add support of dirty-bitmap sync mode for drive-backup qapi: Add transaction support to dirty-bitmap-{add,disable} block-migration.c | 3 +- block.c | 90 ++- block/backup.c| 51 - block/mirror.c| 6 +- blockdev.c| 181 +- hmp.c | 4 +- include/block/block.h | 16 +++- include/block/block_int.h | 3 + include/qemu/hbitmap.h| 8 ++ qapi-schema.json | 115 +++-- qmp-commands.hx | 66 - util/hbitmap.c| 13 12 files changed, 538 insertions(+), 18 deletions(-) -- 1.9.0
[Qemu-devel] [PATCH v2 3/9] block: Handle error of bdrv_getlength in bdrv_create_dirty_bitmap
bdrv_getlength could fail, check the return value before using it. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block.c b/block.c index ce48fff..9de1385 100644 --- a/block.c +++ b/block.c @@ -5083,7 +5083,12 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, } granularity = BDRV_SECTOR_BITS; assert(granularity); -bitmap_size = (bdrv_getlength(bs) BDRV_SECTOR_BITS); +bitmap_size = bdrv_getlength(bs); +if (bitmap_size 0) { +error_setg(errp, could not get length of device); +return NULL; +} +bitmap_size = BDRV_SECTOR_BITS; bitmap = g_malloc0(sizeof(BdrvDirtyBitmap)); bitmap-bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1); if (name) { -- 1.9.0
[Qemu-devel] [PATCH v2 2/9] qmp: Add dirty-bitmap-add and dirty-bitmap-remove
The new command pair is added to manage user created dirty bitmap. The dirty bitmap's name is mandatory and must be unique for the same device, but different devices can have bitmaps with the same names. Signed-off-by: Fam Zheng f...@redhat.com --- blockdev.c | 60 qapi-schema.json | 45 ++ qmp-commands.hx | 49 + 3 files changed, 154 insertions(+) diff --git a/blockdev.c b/blockdev.c index c3422a1..662c950 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1713,6 +1713,66 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd, } } +void qmp_dirty_bitmap_add(const char *device, const char *name, + bool has_granularity, int64_t granularity, + Error **errp) +{ +BlockDriverState *bs; +BdrvDirtyBitmap *bitmap; + +bs = bdrv_find(device); +if (!bs) { +error_set(errp, QERR_DEVICE_NOT_FOUND, device); +return; +} + +if (!name || name[0] == '\0') { +error_setg(errp, Bitmap name cannot be empty); +return; +} +if (has_granularity) { +if (granularity (granularity - 1)) { +error_setg(errp, Granularity must be power of 2); +return; +} +} else { +granularity = 65536; +} + +bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp); +if (!bitmap) { +return; +} +} + +void qmp_dirty_bitmap_remove(const char *device, const char *name, + Error **errp) +{ +BlockDriverState *bs; +BdrvDirtyBitmap *bitmap; + +bs = bdrv_find(device); +if (!bs) { +error_set(errp, QERR_DEVICE_NOT_FOUND, device); +return; +} + +if (!name || name[0] == '\0') { +error_setg(errp, Bitmap name cannot be empty); +return; +} +bitmap = bdrv_find_dirty_bitmap(bs, name); +if (!bitmap) { +error_setg(errp, Dirty bitmap not found: %s, name); +return; +} + +/* Make it invisible to user in case the following + * bdrv_release_dirty_bitmap doens't free it because of refcnt */ +bdrv_dirty_bitmap_make_anon(bs, bitmap); +bdrv_release_dirty_bitmap(bs, bitmap); +} + int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *id = qdict_get_str(qdict, id); diff --git a/qapi-schema.json b/qapi-schema.json index 4d5bc13..632bb10 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2180,6 +2180,51 @@ '*on-target-error': 'BlockdevOnError' } } ## +# @DirtyBitmap +# +# @device: name of device which the bitmap is tracking +# +# @name: name of the dirty bitmap +# +# @granularity: #optional the bitmap granularity, default is 64k for +# dirty-bitmap-add +# +# Since 2.1 +## +{ 'type': 'DirtyBitmap', + 'data': { 'device': 'str', 'name': 'str', '*granularity': 'int' } } + +## +# @dirty-bitmap-add +# +# Create a dirty bitmap with a name on the device +# +# Returns: nothing on success +# If @device is not a valid block device, DeviceNotFound +# If @name is already taken, GenericError with an explaining message +# +# Since 2.1 +## +{'command': 'dirty-bitmap-add', + 'data': 'DirtyBitmap' } + +## +# @dirty-bitmap-remove +# +# Remove a dirty bitmap on the device +# +# Setting granularity has no effect here. +# +# Returns: nothing on success +# If @device is not a valid block device, DeviceNotFound +# If @name is not found, GenericError with an explaining message +# +# Since 2.1 +## +{'command': 'dirty-bitmap-remove', + 'data': { 'device': 'str', 'name': 'str' } } + +## # @migrate_cancel # # Cancel the current executing migration process. diff --git a/qmp-commands.hx b/qmp-commands.hx index d982cd6..c42516d 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1185,6 +1185,55 @@ Example: EQMP { +.name = dirty-bitmap-add, +.args_type = device:B,name:s,granularity:i?, +.mhandler.cmd_new = qmp_marshal_input_dirty_bitmap_add, +}, +{ +.name = dirty-bitmap-remove, +.args_type = device:B,name:s, +.mhandler.cmd_new = qmp_marshal_input_dirty_bitmap_remove, +}, + +SQMP + +dirty-bitmap-add + + +Create a dirty bitmap with a name on the device, and start tracking the writes. + +Arguments: + +- device: device name to create dirty bitmap (json-string) +- name: name of the new dirty bitmap (json-string) +- granularity: granularity to track writes with. (int) + +Example: + +- { execute: dirty-bitmap-add, arguments: { device: drive0, + name: bitmap0 } } +- { return: {} } + +dirty-bitmap-remove + + +Stop write tracking and remove the dirty bitmap that was created with +dirty-bitmap-add. + +Arguments: + +- device: device name to remove dirty
[Qemu-devel] [PATCH v2 9/9] qapi: Add transaction support to dirty-bitmap-{add, disable}
This adds dirty-bitmap-add and dirty-bitmap-disable to transactions. With this, user can stop a dirty bitmap, start backup of it, and start another dirty bitmap atomically, so that the dirty bitmap is tracked incrementally and we don't miss any write. Signed-off-by: Fam Zheng f...@redhat.com --- blockdev.c | 68 qapi-schema.json | 4 +++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/blockdev.c b/blockdev.c index 4120dee..38dabe6 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1411,6 +1411,64 @@ static void drive_backup_abort(BlkTransactionState *common) } } +static void dirty_bitmap_add_prepare(BlkTransactionState *common, Error **errp) +{ +DirtyBitmap *action; +Error *local_err = NULL; + +action = common-action-dirty_bitmap_add; +qmp_dirty_bitmap_add(action-device, action-name, false, 0, local_err); +if (error_is_set(local_err)) { +error_propagate(errp, local_err); +} +} + +static void dirty_bitmap_add_abort(BlkTransactionState *common) +{ +DirtyBitmap *action; +BdrvDirtyBitmap *bm; +BlockDriverState *bs; + +action = common-action-dirty_bitmap_add; +bs = bdrv_find(action-device); +if (bs) { +bm = bdrv_find_dirty_bitmap(bs, action-name); +if (bm) { +bdrv_release_dirty_bitmap(bs, bm); +} +} +} + +static void dirty_bitmap_disable_prepare(BlkTransactionState *common, + Error **errp) +{ +DirtyBitmap *action; +Error *local_err = NULL; + +action = common-action-dirty_bitmap_disable; +qmp_dirty_bitmap_disable(action-device, action-name, + false, 0, local_err); +if (error_is_set(local_err)) { +error_propagate(errp, local_err); +} +} + +static void dirty_bitmap_disable_abort(BlkTransactionState *common) +{ +DirtyBitmap *action; +BdrvDirtyBitmap *bitmap; +BlockDriverState *bs; + +action = common-action-dirty_bitmap_disable; +bs = bdrv_find(action-device); +if (bs) { +bitmap = bdrv_find_dirty_bitmap(bs, action-name); +if (bitmap) { +bdrv_enable_dirty_bitmap(bs, bitmap); +} +} +} + static void abort_prepare(BlkTransactionState *common, Error **errp) { error_setg(errp, Transaction aborted using Abort action); @@ -1443,6 +1501,16 @@ static const BdrvActionOps actions[] = { .prepare = internal_snapshot_prepare, .abort = internal_snapshot_abort, }, +[TRANSACTION_ACTION_KIND_DIRTY_BITMAP_ADD] = { +.instance_size = sizeof(BlkTransactionState), +.prepare = dirty_bitmap_add_prepare, +.abort = dirty_bitmap_add_abort, +}, +[TRANSACTION_ACTION_KIND_DIRTY_BITMAP_DISABLE] = { +.instance_size = sizeof(BlkTransactionState), +.prepare = dirty_bitmap_disable_prepare, +.abort = dirty_bitmap_disable_abort, +}, }; /* diff --git a/qapi-schema.json b/qapi-schema.json index e4e66cb..5c6c3fb 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1963,7 +1963,9 @@ 'blockdev-snapshot-sync': 'BlockdevSnapshot', 'drive-backup': 'DriveBackup', 'abort': 'Abort', - 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal' + 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal', + 'dirty-bitmap-add': 'DirtyBitmap', + 'dirty-bitmap-disable': 'DirtyBitmap' } } ## -- 1.9.0
[Qemu-devel] [PATCH v2 5/9] hbitmap: Add hbitmap_copy
This makes a deep copy of an HBitmap. Signed-off-by: Fam Zheng f...@redhat.com --- include/qemu/hbitmap.h | 8 util/hbitmap.c | 13 + 2 files changed, 21 insertions(+) diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h index 550d7ce..b645cfc 100644 --- a/include/qemu/hbitmap.h +++ b/include/qemu/hbitmap.h @@ -65,6 +65,14 @@ struct HBitmapIter { HBitmap *hbitmap_alloc(uint64_t size, int granularity); /** + * hbitmap_copy: + * @bitmap: The original bitmap to copy. + * + * Copy a HBitmap. + */ +HBitmap *hbitmap_copy(const HBitmap *bitmap); + +/** * hbitmap_empty: * @hb: HBitmap to operate on. * diff --git a/util/hbitmap.c b/util/hbitmap.c index d936831..cf670c7 100644 --- a/util/hbitmap.c +++ b/util/hbitmap.c @@ -400,3 +400,16 @@ HBitmap *hbitmap_alloc(uint64_t size, int granularity) hb-levels[0][0] |= 1UL (BITS_PER_LONG - 1); return hb; } + +HBitmap *hbitmap_copy(const HBitmap *bitmap) +{ +int i; +HBitmap *hb = g_memdup(bitmap, sizeof(struct HBitmap)); + +for (i = HBITMAP_LEVELS; i-- 0; ) { +hb-levels[i] = g_memdup(bitmap-levels[i], + bitmap-size * sizeof(unsigned long)); +} + +return hb; +} -- 1.9.0
[Qemu-devel] [PATCH v2 1/9] qapi: Add optional field name to block dirty bitmap
This field will be set for user created dirty bitmap. Also pass in an error pointer to bdrv_create_dirty_bitmap, so when a name is already taken on this BDS, it can report an error message. This is not global check, two BDSes can have dirty bitmap with a common name. Implemented bdrv_find_dirty_bitmap to find a dirty bitmap by name, will be used later when other QMP commands want to reference dirty bitmap by name. Add bdrv_dirty_bitmap_make_anon. This unsets the name of dirty bitmap. Signed-off-by: Fam Zheng f...@redhat.com --- block-migration.c | 3 ++- block.c | 34 +- block/mirror.c| 2 +- include/block/block.h | 8 +++- qapi-schema.json | 4 +++- 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/block-migration.c b/block-migration.c index 897fdba..e6e016a 100644 --- a/block-migration.c +++ b/block-migration.c @@ -315,7 +315,8 @@ static void set_dirty_tracking(void) BlkMigDevState *bmds; QSIMPLEQ_FOREACH(bmds, block_mig_state.bmds_list, entry) { -bmds-dirty_bitmap = bdrv_create_dirty_bitmap(bmds-bs, BLOCK_SIZE); +bmds-dirty_bitmap = bdrv_create_dirty_bitmap(bmds-bs, BLOCK_SIZE, + NULL, NULL); } } diff --git a/block.c b/block.c index f1ef4b0..ce48fff 100644 --- a/block.c +++ b/block.c @@ -52,6 +52,7 @@ struct BdrvDirtyBitmap { HBitmap *bitmap; +char *name; QLIST_ENTRY(BdrvDirtyBitmap) list; }; @@ -5048,18 +5049,46 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) return true; } -BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity) +BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, +const char *name) +{ +BdrvDirtyBitmap *bm; +QLIST_FOREACH(bm, bs-dirty_bitmaps, list) { +if (!strcmp(name, bm-name)) { +return bm; +} +} +return NULL; +} + +void bdrv_dirty_bitmap_make_anon(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) +{ +g_free(bitmap-name); +bitmap-name = NULL; +} + +BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, + int granularity, + const char *name, + Error **errp) { int64_t bitmap_size; BdrvDirtyBitmap *bitmap; assert((granularity (granularity - 1)) == 0); +if (name bdrv_find_dirty_bitmap(bs, name)) { +error_setg(errp, Bitmap already exists: %s, name); +return NULL; +} granularity = BDRV_SECTOR_BITS; assert(granularity); bitmap_size = (bdrv_getlength(bs) BDRV_SECTOR_BITS); bitmap = g_malloc0(sizeof(BdrvDirtyBitmap)); bitmap-bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1); +if (name) { +bitmap-name = g_strdup(name); +} QLIST_INSERT_HEAD(bs-dirty_bitmaps, bitmap, list); return bitmap; } @@ -5071,6 +5100,7 @@ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) if (bm == bitmap) { QLIST_REMOVE(bitmap, list); hbitmap_free(bitmap-bitmap); +g_free(bitmap-name); g_free(bitmap); return; } @@ -5089,6 +5119,8 @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) info-count = bdrv_get_dirty_count(bs, bm); info-granularity = ((int64_t) BDRV_SECTOR_SIZE hbitmap_granularity(bm-bitmap)); +info-has_name = bm-name[0] != '\0'; +info-name = g_strdup(bm-name); entry-value = info; *plist = entry; plist = entry-next; diff --git a/block/mirror.c b/block/mirror.c index dd5ee05..be8b2a1 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -596,7 +596,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, s-granularity = granularity; s-buf_size = MAX(buf_size, granularity); -s-dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity); +s-dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp); bdrv_set_enable_write_cache(s-target, true); bdrv_set_on_error(s-target, on_target_error, on_target_error); bdrv_iostatus_enable(s-target); diff --git a/include/block/block.h b/include/block/block.h index 780f48b..aa0c5e4 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -437,7 +437,13 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov); struct HBitmapIter; typedef struct BdrvDirtyBitmap BdrvDirtyBitmap; -BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity); +BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, + int granularity, + const char *name, + Error **errp);
[Qemu-devel] [PATCH v2 7/9] qmp: Add dirty-bitmap-enable and dirty-bitmap-disable
This allows to put the dirty bitmap into a disabled state where no more writes will be tracked. It will be used before backup or writing to persistent file. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 15 +++ blockdev.c| 44 include/block/block.h | 2 ++ qapi-schema.json | 32 qmp-commands.hx | 10 ++ 5 files changed, 103 insertions(+) diff --git a/block.c b/block.c index 199a465..1530fd1 100644 --- a/block.c +++ b/block.c @@ -55,6 +55,7 @@ struct BdrvDirtyBitmap { int64_t size; int64_t granularity; char *name; +bool enabled; QLIST_ENTRY(BdrvDirtyBitmap) list; }; @@ -5120,6 +5121,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, if (name) { bitmap-name = g_strdup(name); } +bitmap-enabled = true; QLIST_INSERT_HEAD(bs-dirty_bitmaps, bitmap, list); return bitmap; } @@ -5138,6 +5140,16 @@ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) } } +void bdrv_disable_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) +{ +bitmap-enabled = false; +} + +void bdrv_enable_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) +{ +bitmap-enabled = true; +} + BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) { BdrvDirtyBitmap *bm; @@ -5186,6 +5198,9 @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, { BdrvDirtyBitmap *bitmap; QLIST_FOREACH(bitmap, bs-dirty_bitmaps, list) { +if (!bitmap-enabled) { +continue; +} hbitmap_set(bitmap-bitmap, cur_sector, nr_sectors); } } diff --git a/blockdev.c b/blockdev.c index 662c950..aa3ee55 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1773,6 +1773,50 @@ void qmp_dirty_bitmap_remove(const char *device, const char *name, bdrv_release_dirty_bitmap(bs, bitmap); } +void qmp_dirty_bitmap_enable(const char *device, const char *name, + bool has_granularity, int64_t granularity, + Error **errp) +{ +BlockDriverState *bs; +BdrvDirtyBitmap *bitmap; + +bs = bdrv_find(device); +if (!bs) { +error_set(errp, QERR_DEVICE_NOT_FOUND, device); +return; +} + +bitmap = bdrv_find_dirty_bitmap(bs, name); +if (!bitmap) { +error_setg(errp, Dirty bitmap not found: %s, name); +return; +} + +bdrv_enable_dirty_bitmap(bs, bitmap); +} + +void qmp_dirty_bitmap_disable(const char *device, const char *name, + bool has_granularity, int64_t granularity, + Error **errp) +{ +BlockDriverState *bs; +BdrvDirtyBitmap *bitmap; + +bs = bdrv_find(device); +if (!bs) { +error_set(errp, QERR_DEVICE_NOT_FOUND, device); +return; +} + +bitmap = bdrv_find_dirty_bitmap(bs, name); +if (!bitmap) { +error_setg(errp, Dirty bitmap not found: %s, name); +return; +} + +bdrv_disable_dirty_bitmap(bs, bitmap); +} + int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *id = qdict_get_str(qdict, id); diff --git a/include/block/block.h b/include/block/block.h index 66aae57..2875d7d 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -449,6 +449,8 @@ BdrvDirtyBitmap *bdrv_copy_dirty_bitmap(BlockDriverState *bs, const BdrvDirtyBitmap *bitmap, const char *name); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +void bdrv_disable_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +void bdrv_enable_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); int bdrv_dirty_bitmap_granularity(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); diff --git a/qapi-schema.json b/qapi-schema.json index 632bb10..f8cd6b8 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2225,6 +2225,38 @@ 'data': { 'device': 'str', 'name': 'str' } } ## +# @dirty-bitmap-enable +# +# Enable a dirty bitmap on the device +# +# Setting granularity has no effect here. +# +# Returns: nothing on success +# If @device is not a valid block device, DeviceNotFound +# If @name is not found, GenericError with an explaining message +# +# Since 2.1 +## +{'command': 'dirty-bitmap-enable', + 'data': 'DirtyBitmap' } + +## +# @dirty-bitmap-disable +# +# Disable a dirty bitmap on the device +# +# Setting granularity has no effect here. +# +# Returns: nothing on success +# If @device is not a valid block device, DeviceNotFound +# If @name is not found, GenericError with an explaining message +# +# Since 2.1 +## +{'command': 'dirty-bitmap-disable', +
[Qemu-devel] [PATCH v2 4/9] block: Introduce bdrv_dirty_bitmap_granularity()
This returns the granularity (in sectors) of dirty bitmap. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 6 ++ include/block/block.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/block.c b/block.c index 9de1385..26a43eb 100644 --- a/block.c +++ b/block.c @@ -5143,6 +5143,12 @@ int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector } } +int bdrv_dirty_bitmap_granularity(BlockDriverState *bs, + BdrvDirtyBitmap *bitmap) +{ +return hbitmap_granularity(bitmap-bitmap); +} + void bdrv_dirty_iter_init(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, HBitmapIter *hbi) { diff --git a/include/block/block.h b/include/block/block.h index aa0c5e4..b87c071 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -446,6 +446,8 @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, void bdrv_dirty_bitmap_make_anon(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); +int bdrv_dirty_bitmap_granularity(BlockDriverState *bs, + BdrvDirtyBitmap *bitmap); int bdrv_get_dirty(BlockDriverState *bs, BdrvDirtyBitmap *bitmap, int64_t sector); void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors); void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, int nr_sectors); -- 1.9.0
Re: [Qemu-devel] [PATCH v22 04/25] improve assertion in qemu_opt_get functions
2014-03-11 5:44 GMT+08:00 Eric Blake ebl...@redhat.com: On 03/10/2014 01:31 AM, Chunyan Liu wrote: In qemu_opt_set functions, if desc doen't exist but opts_accepts_any is true, it s/doen't/doesn't/ I mentioned the same problem against v20. It is very depressing when review comments are not addressed. won't report error, but can still alloc an opt for the option and save it. However, after that, when doing qemu_opt_get, this option could be found in opts but opt-desc is NULL. This is correct, should not be treated as error. This patch would fix vvfat issue after changing to QemuOpts. Signed-off-by: Chunyan Liu cy...@suse.com --- util/qemu-option.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/util/qemu-option.c b/util/qemu-option.c index c7639e8..df79235 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -603,7 +603,9 @@ bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval) } return defval; } -assert(opt-desc opt-desc-type == QEMU_OPT_BOOL); +if (opt-desc) { +assert(opt-desc-type == QEMU_OPT_BOOL); +} return opt-value.boolean; I'm not sure I like this. opt-value is a union, but opt_set() does NOT populate the union when opts_accepts_any() fails. Previously, we were using opt-desc-type as the discriminator for which branch of the union is valid. But with your patch, if an option was set as a string, but then queried as a boolean, we may be reading bogus contents from the union. Or even worse, if someone sets the uint member of the union to 0x1 via qemu_opt_set_number(), then later calls qemu_opt_get_bool, the boolean member _might_ read as true on some platforms and false on others, depending on things such as host endianness. How is vvfat broken without this patch? That is, what specific option are you setting without specifying its type, that later triggers the assertion when you try to get the option via a specific type? Well, now I think it caused by drv (vvfat.c) and proto_drv (raw-posix.c) not consistent, one is using QemuOpts, the other is using QEMUOptionParameter. That will cause create_opts became NULL, then when passing a size option, qemu_opt_set_size is OK, but later qemu_opt_get_size will segment fault. After solving the drv/proto_drv consistent issue, this problem won't happen. So, in this patch series, this place could not be changed. ( But with opts_accept_any, I still think this place may bring problem some time in future.) I'm wondering if the fix should look more like: if (opt-desc) { assert(opt-desc-type == QEMU_OPT_BOOL); return opt-value.boolean; } else { code to parse opt-str } so that you are not dereferencing an undefined state of the union. @@ -625,7 +627,9 @@ uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval) } return defval; } -assert(opt-desc opt-desc-type == QEMU_OPT_NUMBER); +if (opt-desc) { +assert(opt-desc-type == QEMU_OPT_NUMBER); +} return opt-value.uint; } @@ -645,7 +649,9 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval) } return defval; } -assert(opt-desc opt-desc-type == QEMU_OPT_SIZE); +if (opt-desc) { +assert(opt-desc-type == QEMU_OPT_SIZE); +} return opt-value.uint; Same problem in these two spots. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org
[Qemu-devel] [PATCH v2 8/9] qmp: Add support of dirty-bitmap sync mode for drive-backup
For dirty-bitmap sync mode, the block job will iterate through the given dirty bitmap to decide if a sector needs backup (backup all the dirty clusters and skip clean ones), just as allocation conditions of top sync mode. There are two bitmap use modes for sync=dirty-bitmap: - reset: backup job makes a copy of bitmap and resets the original one. - consume: back job makes the original anonymous (invisible to user) and releases it after use. Signed-off-by: Fam Zheng f...@redhat.com --- block/backup.c| 51 ++- block/mirror.c| 4 blockdev.c| 9 - hmp.c | 4 +++- include/block/block_int.h | 3 +++ qapi-schema.json | 30 qmp-commands.hx | 7 --- 7 files changed, 98 insertions(+), 10 deletions(-) diff --git a/block/backup.c b/block/backup.c index 15a2e55..6b05429 100644 --- a/block/backup.c +++ b/block/backup.c @@ -37,6 +37,8 @@ typedef struct CowRequest { typedef struct BackupBlockJob { BlockJob common; BlockDriverState *target; +BdrvDirtyBitmap *sync_bitmap; +int sync_bitmap_gran; MirrorSyncMode sync_mode; RateLimit limit; BlockdevOnError on_source_error; @@ -263,7 +265,7 @@ static void coroutine_fn backup_run(void *opaque) job-common.busy = true; } } else { -/* Both FULL and TOP SYNC_MODE's require copying.. */ +/* FULL, TOP and DIRTY_BITMAP SYNC_MODE's require copying.. */ for (; start end; start++) { bool error_is_read; @@ -317,7 +319,21 @@ static void coroutine_fn backup_run(void *opaque) if (alloced == 0) { continue; } +} else if (job-sync_mode == MIRROR_SYNC_MODE_DIRTY_BITMAP) { +int i, dirty = 0; +for (i = 0; i BACKUP_SECTORS_PER_CLUSTER; + i += job-sync_bitmap_gran) { +if (bdrv_get_dirty(bs, job-sync_bitmap, +start * BACKUP_SECTORS_PER_CLUSTER + i)) { +dirty = 1; +break; +} +} +if (!dirty) { +continue; +} } + /* FULL sync mode we copy the whole drive. */ ret = backup_do_cow(bs, start * BACKUP_SECTORS_PER_CLUSTER, BACKUP_SECTORS_PER_CLUSTER, error_is_read); @@ -341,6 +357,9 @@ static void coroutine_fn backup_run(void *opaque) qemu_co_rwlock_wrlock(job-flush_rwlock); qemu_co_rwlock_unlock(job-flush_rwlock); +if (job-sync_bitmap) { +bdrv_release_dirty_bitmap(bs, job-sync_bitmap); +} hbitmap_free(job-bitmap); bdrv_iostatus_disable(target); @@ -351,12 +370,15 @@ static void coroutine_fn backup_run(void *opaque) void backup_start(BlockDriverState *bs, BlockDriverState *target, int64_t speed, MirrorSyncMode sync_mode, + BdrvDirtyBitmap *sync_bitmap, + BitmapUseMode bitmap_mode, BlockdevOnError on_source_error, BlockdevOnError on_target_error, BlockDriverCompletionFunc *cb, void *opaque, Error **errp) { int64_t len; +BdrvDirtyBitmap *original; assert(bs); assert(target); @@ -369,6 +391,28 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target, return; } +if (sync_mode == MIRROR_SYNC_MODE_DIRTY_BITMAP !sync_bitmap) { +error_setg(errp, must provide a valid bitmap name for \dirty-bitmap\ + sync mode); +return; +} + +if (sync_bitmap) { +switch (bitmap_mode) { +case BITMAP_USE_MODE_RESET: +original = sync_bitmap; +sync_bitmap = bdrv_copy_dirty_bitmap(bs, sync_bitmap, NULL); +bdrv_reset_dirty_bitmap(bs, original); +break; +case BITMAP_USE_MODE_CONSUME: +bdrv_dirty_bitmap_make_anon(bs, sync_bitmap); +break; +default: +assert(0); +} +bdrv_disable_dirty_bitmap(bs, sync_bitmap); +} + len = bdrv_getlength(bs); if (len 0) { error_setg_errno(errp, -len, unable to get length for '%s', @@ -386,6 +430,11 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target, job-on_target_error = on_target_error; job-target = target; job-sync_mode = sync_mode; +job-sync_bitmap = sync_bitmap; +if (sync_bitmap) { +job-sync_bitmap_gran = +bdrv_dirty_bitmap_granularity(bs, job-sync_bitmap); +} job-common.len = len; job-common.co = qemu_coroutine_create(backup_run); qemu_coroutine_enter(job-common.co, job); diff --git a/block/mirror.c b/block/mirror.c index be8b2a1..6e4f3f3 100644 --- a/block/mirror.c +++
[Qemu-devel] [PATCH v2 6/9] block: Add bdrv_copy_dirty_bitmap and bdrv_reset_dirty_bitmap
Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 30 -- include/block/block.h | 4 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 26a43eb..199a465 100644 --- a/block.c +++ b/block.c @@ -52,6 +52,8 @@ struct BdrvDirtyBitmap { HBitmap *bitmap; +int64_t size; +int64_t granularity; char *name; QLIST_ENTRY(BdrvDirtyBitmap) list; }; @@ -5067,6 +5069,29 @@ void bdrv_dirty_bitmap_make_anon(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) bitmap-name = NULL; } +BdrvDirtyBitmap *bdrv_copy_dirty_bitmap(BlockDriverState *bs, +const BdrvDirtyBitmap *bitmap, +const char *name) +{ +BdrvDirtyBitmap *new_bitmap; + +new_bitmap = g_memdup(bitmap, sizeof(BdrvDirtyBitmap)); +new_bitmap-bitmap = hbitmap_copy(bitmap-bitmap); +if (name) { +new_bitmap-name = g_strdup(name); +} +QLIST_INSERT_HEAD(bs-dirty_bitmaps, new_bitmap, list); +return new_bitmap; +} + +void bdrv_reset_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) +{ +HBitmap *original = bitmap-bitmap; + +bitmap-bitmap = hbitmap_alloc(bitmap-size, bitmap-granularity); +hbitmap_free(original); +} + BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity, const char *name, @@ -5088,9 +5113,10 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, error_setg(errp, could not get length of device); return NULL; } -bitmap_size = BDRV_SECTOR_BITS; bitmap = g_malloc0(sizeof(BdrvDirtyBitmap)); -bitmap-bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1); +bitmap-size = bitmap_size BDRV_SECTOR_BITS; +bitmap-granularity = ffs(granularity) - 1; +bitmap-bitmap = hbitmap_alloc(bitmap-size, bitmap-granularity); if (name) { bitmap-name = g_strdup(name); } diff --git a/include/block/block.h b/include/block/block.h index b87c071..66aae57 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -444,6 +444,10 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name); void bdrv_dirty_bitmap_make_anon(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +void bdrv_reset_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); +BdrvDirtyBitmap *bdrv_copy_dirty_bitmap(BlockDriverState *bs, +const BdrvDirtyBitmap *bitmap, +const char *name); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs); int bdrv_dirty_bitmap_granularity(BlockDriverState *bs, -- 1.9.0
Re: [Qemu-devel] [PATCH v22 03/25] improve some functions in qemu-option.c
2014-03-11 5:21 GMT+08:00 Eric Blake ebl...@redhat.com: On 03/10/2014 02:29 PM, Eric Blake wrote: +opt = qemu_opt_find(opts, name); +if (opt) { +g_free((char *)opt-str); ...which means the cast is pointless here. Hmm. This means that you are giving opt_set() the behavior of 'last version wins', by silently overwriting earlier versions. If I'm understanding the existing code correctly, the previous behavior was that calling opt_set twice in a row on the same name would inject BOTH names into 'opts', but then subsequent lookups on opts would find the FIRST hit. Doesn't that mean this is a semantic change: qemu -opt key=value1,key=value2 would previously set key to value1, but now sets key to value2. I've played with this a bit more, and now am more confused. QemuOpts is a LOT to comprehend. Pre-patch, 'qemu-system-x86_64 -nodefaults -machine type=none,type-noone' displayed a help message about unknown machine type noone, while swapping type=noone,type=none proceeded with the 'none' type. So the last version silently won, which was not the behavior I had predicted. In qemu_opt_find(), it uses: QTAILQ_FOREACH_REVERSE(), so that means find the last setting, the same result with replacement. Post-patch, I get a compilation error (so how did you test your patch?): qapi/opts-visitor.c: In function ‘opts_start_struct’: qapi/opts-visitor.c:146:31: error: assignment discards ‘const’ qualifier from pointer target type [-Werror] ov-fake_id_opt-name = id; ^ If I press on in spite of that warning, then I get the same behavior where the last type= still wins on behavior. So I'm not sure how it all worked, but at least behavior wise, my one test didn't uncover a regression. Still, I'd feel a LOT better with a testsuite of what QemuOpts is supposed to be able to do. tests/test-opts-visitor.c was the only file in tests/ that even mentions QemuOpts. @@ -744,16 +777,24 @@ void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value, int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val) +opt = qemu_opt_find(opts, name); +if (opt) { +g_free((char *)opt-str); Another pointless cast. Maybe not pointless, if you end up not removing the const in the struct declaration due to the compile error; but that brings me back to my earlier question - since the compiler error proves that we have places that are assigning compile-time string constants into the name field, we must NOT call g_free on those copies - how does your code distinguish between a QemuOpt that is built up by mallocs, vs. one that is described by compile-time constants? -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org
Re: [Qemu-devel] [PATCH] gtk: Add mouse wheel support
On Di, 2014-03-11 at 17:26 +0100, Jan Kiszka wrote: Hook into scroll-event to properly forward mouse wheel movements to the guest, just like we already do in SDL. Added to input queue. thanks, Gerd
Re: [Qemu-devel] [PATCH 1/6] slirp: Remove default_mon usage
On 2014-03-12 00:15, Cole Robinson wrote: These errors don't seem user initiated, so forcibly printing to the monitor doesn't seem right. Just print to stderr. Drop lprint since it's now unused. Cc: Jan Kiszka jan.kis...@siemens.com Signed-off-by: Cole Robinson crobi...@redhat.com --- checkpatch flags some pre-existing tab issues, but I didn't retab. Should I? slirp/misc.c | 13 ++--- slirp/slirp.c | 8 slirp/slirp.h | 2 -- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/slirp/misc.c b/slirp/misc.c index 6c1636f..662fb1d 100644 --- a/slirp/misc.c +++ b/slirp/misc.c @@ -136,7 +136,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) 0 || bind(s, (struct sockaddr *)addr, addrlen) 0 || listen(s, 1) 0) { - lprint(Error: inet socket: %s\n, strerror(errno)); + fprintf(stderr, Error: inet socket: %s\n, strerror(errno)); closesocket(s); return 0; @@ -146,7 +146,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) pid = fork(); switch(pid) { case -1: - lprint(Error: fork failed: %s\n, strerror(errno)); + fprintf(stderr, Error: fork failed: %s\n, strerror(errno)); close(s); return 0; @@ -242,15 +242,6 @@ strdup(str) } #endif -void lprint(const char *format, ...) -{ -va_list args; - -va_start(args, format); -monitor_vprintf(default_mon, format, args); -va_end(args); -} - void slirp_connection_info(Slirp *slirp, Monitor *mon) { const char * const tcpstates[] = { diff --git a/slirp/slirp.c b/slirp/slirp.c index bad8dad..3fb48a4 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -139,7 +139,7 @@ int get_dns_addr(struct in_addr *pdns_addr) return -1; #ifdef DEBUG -lprint(IP address of your DNS(s): ); +fprintf(stderr, IP address of your DNS(s): ); #endif while (fgets(buff, 512, f) != NULL) { if (sscanf(buff, nameserver%*[ \t]%256s, buff2) == 1) { @@ -153,17 +153,17 @@ int get_dns_addr(struct in_addr *pdns_addr) } #ifdef DEBUG else -lprint(, ); +fprintf(stderr, , ); #endif if (++found 3) { #ifdef DEBUG -lprint((more)); +fprintf(stderr, (more)); #endif break; } #ifdef DEBUG else -lprint(%s, inet_ntoa(tmp_addr)); +fprintf(stderr, %s, inet_ntoa(tmp_addr)); #endif } } diff --git a/slirp/slirp.h b/slirp/slirp.h index e4a1bd4..6589d7e 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -287,8 +287,6 @@ void if_start(struct ttys *); long gethostid(void); #endif -void lprint(const char *, ...) GCC_FMT_ATTR(1, 2); - #ifndef _WIN32 #include netdb.h #endif Reviewed-by: Jan Kiszka jan.kis...@siemens.com I suppose this goes through Luiz' queue? Jan -- Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux
Re: [Qemu-devel] slirp smb with modern win guests when samba is also running on host
On 2013-11-28 20:32, Michael Tokarev wrote: After numerous reports that -smb (or -netdev user,smb=foo) not working with modern windows (win7 and vista are reported as non-working), I started digging myself. And found that indeed it doesn't work, and why. The thing is that modern win tries to connect to port 445 (microsoft-ds) first, and if that fails, it falls back to old port 139 (netbios-ssn). slirp code in qemu only redirects port 139, it does not touch port 445. So the prob is that if samba is also running on the host, guest will try to communicate using port 445, and that will succed, but ofcourse guest will not talk with our samba but with samba running on the host. If samba is not running on the host, guest will fall back to port 139, and will reach the redirecting rule and qemu will spawn smbd correctly. The solution is to redirect both ports (139 and 445), and the fix is a one-liner, adding second call to slirp_add_exec() at the end of net/slirp.c:slirp_smb() function (provided below). But it looks like that is not a proper fix really, since in theory we should redirect both ports to the SAME, single samba instance, but I'm not sure this is possible with slirp. Well, even if two smbd processes will be run on the same config dir, it should not be a problem. I don't see either that this is expressible with the current exec feature of slirp. The one-liner (not exactly 1 since it touches previous line too) is like this: Signed-off-By: Michael Tokarev m...@tls.msk.ru diff --git a/net/slirp.c b/net/slirp.c index 124e953..a22e976 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -549,7 +549,8 @@ static int slirp_smb(SlirpState* s, const char *exported_dir snprintf(smb_cmdline, sizeof(smb_cmdline), %s -s %s, CONFIG_SMBD_COMMAND, smb_conf); -if (slirp_add_exec(s-slirp, 0, smb_cmdline, vserver_addr, 139) 0) { +if (slirp_add_exec(s-slirp, 0, smb_cmdline, vserver_addr, 139) 0 || +slirp_add_exec(s-slirp, 0, smb_cmdline, vserver_addr, 445) 0) { slirp_smb_cleanup(s); error_report(conflicting/invalid smbserver address); return -1; Thanks, merged to my slirp queue. Will send this out ASAP, sorry for the excessive delay. JAn -- Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCHv3 00/16] slirp: Adding IPv6 support to Qemu -net user mode
On 2014-02-11 14:08, Samuel Thibault wrote: Hello, This is a respin of IPv6 in Qemu -net user mode. These patches add ICMPv6, NDP, and make UDP and TCP compatible with IPv6. We have made some refactoring to make current code compatible with IPv6. Some patches, like 2 and 13, can be reviewed using interdiff -w /dev/null patchfile to get rid of the indentation. The alternative is to split reindention from refactoring patches. Difference with version 2 is: - The default IP range has been made fec0::/64 instead of fc00::/64 This is very valuable work. Unfortunately, I'm lacking time to review or even test this ATM. If someone else could, that would be great. Thanks, Jan -- Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux
[Qemu-devel] [PULL] target-sparc: Add and use CPU_FEATURE_CASA
Hi Peter, This request contains just a single patch to add CPU_FEATURE_CASA for target-sparc. Please pull for 2.0. Many thanks, Mark. The following changes since commit 239618707637ec87eba8c452d2b2f75dc5ca20c7: Merge remote-tracking branch 'remotes/kvm/uq/master' into staging (2014-03-11 19:39:17 +) are available in the git repository at: https://github.com/mcayland/qemu.git qemu-sparc for you to fetch changes up to 16c358e96e0597b7d60754547166ad05ecc6d93d: target-sparc: Add and use CPU_FEATURE_CASA (2014-03-12 00:22:01 +) Sebastian Huber (1): target-sparc: Add and use CPU_FEATURE_CASA target-sparc/cpu.c |3 ++- target-sparc/cpu.h |4 +++- target-sparc/helper.h |4 +++- target-sparc/ldst_helper.c | 28 ++--- target-sparc/translate.c | 49 +--- 5 files changed, 56 insertions(+), 32 deletions(-)
[Qemu-devel] [pull] slirp queue
The following changes since commit 239618707637ec87eba8c452d2b2f75dc5ca20c7: Merge remote-tracking branch 'remotes/kvm/uq/master' into staging (2014-03-11 19:39:17 +) are available in the git repository at: git://git.kiszka.org/qemu.git queues/slirp for you to fetch changes up to 5c1e1890bfa1f6b4bc3f51e368bfd47af1b60db0: slirp smb with modern win guests when samba is also running on host (2014-03-12 08:13:24 +0100) Michael Buesch (1): qemu/slirp: Fix SMB security configuration on newer samba versions Michael Tokarev (1): slirp smb with modern win guests when samba is also running on host net/slirp.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-)
[Qemu-devel] [PATCH][RESEND] gtk: Allow to activate grab-on-hover from the command line
As long as we have no persistent GTK configuration, this allows to enable the useful grab-on-hover feature already when starting the VM. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- include/ui/console.h | 2 +- qemu-options.hx | 5 + ui/gtk.c | 5 - vl.c | 22 +- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 08a38ea..8a86617 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -345,6 +345,6 @@ int index_from_key(const char *key); /* gtk.c */ void early_gtk_display_init(void); -void gtk_display_init(DisplayState *ds, bool full_screen); +void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover); #endif diff --git a/qemu-options.hx b/qemu-options.hx index 068da2d..ee5437b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -810,6 +810,7 @@ ETEXI DEF(display, HAS_ARG, QEMU_OPTION_display, -display sdl[,frame=on|off][,alt_grab=on|off][,ctrl_grab=on|off]\n [,window_close=on|off]|curses|none|\n +gtk[,grab_on_hover=on|off]|\n vnc=display[,optargs]\n select display type\n, QEMU_ARCH_ALL) STEXI @@ -833,6 +834,10 @@ graphics card, but its output will not be displayed to the QEMU user. This option differs from the -nographic option in that it only affects what is done with video output; -nographic also changes the destination of the serial and parallel port data. +@item gtk +Display video output in a GTK window. This interface provides drop-down +menus and other UI elements to configure and control the VM during +runtime. @item vnc Start a VNC server on display arg @end table diff --git a/ui/gtk.c b/ui/gtk.c index 1851495..992f7d7 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -1415,7 +1415,7 @@ static const DisplayChangeListenerOps dcl_ops = { .dpy_cursor_define = gd_cursor_define, }; -void gtk_display_init(DisplayState *ds, bool full_screen) +void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover) { GtkDisplayState *s = g_malloc0(sizeof(*s)); char *filename; @@ -1494,6 +1494,9 @@ void gtk_display_init(DisplayState *ds, bool full_screen) if (full_screen) { gtk_menu_item_activate(GTK_MENU_ITEM(s-full_screen_item)); } +if (grab_on_hover) { +gtk_menu_item_activate(GTK_MENU_ITEM(s-grab_on_hover_item)); +} register_displaychangelistener(s-dcl); diff --git a/vl.c b/vl.c index bca5c95..b73744d 100644 --- a/vl.c +++ b/vl.c @@ -143,6 +143,7 @@ int vga_interface_type = VGA_NONE; static int full_screen = 0; static int no_frame = 0; int no_quit = 0; +static bool grab_on_hover; CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; @@ -2241,6 +2242,25 @@ static DisplayType select_display(const char *p) } else if (strstart(p, gtk, opts)) { #ifdef CONFIG_GTK display = DT_GTK; +while (*opts) { +const char *nextopt; + +if (strstart(opts, ,grab_on_hover=, nextopt)) { +opts = nextopt; +if (strstart(opts, on, nextopt)) { +grab_on_hover = true; +} else if (strstart(opts, off, nextopt)) { +grab_on_hover = false; +} else { +goto invalid_gtk_args; +} +} else { +invalid_gtk_args: +fprintf(stderr, Invalid GTK option string: %s\n, p); +exit(1); +} +opts = nextopt; +} #else fprintf(stderr, GTK support is disabled\n); exit(1); @@ -4351,7 +4371,7 @@ int main(int argc, char **argv, char **envp) #endif #if defined(CONFIG_GTK) case DT_GTK: -gtk_display_init(ds, full_screen); +gtk_display_init(ds, full_screen, grab_on_hover); break; #endif default: -- 1.8.1.1.298.ge7eed54
Re: [Qemu-devel] [PATCH 1/2][RESENT] Add GDB qAttached support
On 2013-07-17 10:10, Jan Kiszka wrote: With this patch QEMU handles qAttached request from gdb. When QEMU replies 1, GDB sends a detach command at the end of a debugging session otherwise GDB sends kill. The default value for qAttached is 1 on system emulation and 0 on user emulation. Based on original version by Fabien Chouteau. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- gdbstub.c | 10 ++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 0ee82a9..bc626f5 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -42,6 +42,12 @@ #include sysemu/kvm.h #include qemu/bitops.h +#ifdef CONFIG_USER_ONLY +#define GDB_ATTACHED 0 +#else +#define GDB_ATTACHED 1 +#endif + #ifndef TARGET_CPU_MEMORY_RW_DEBUG static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, uint8_t *buf, int len, int is_write) @@ -2504,6 +2510,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; } #endif +if (strncmp(p, Attached, 8) == 0) { +put_packet(s, GDB_ATTACHED); +break; +} /* Unrecognised 'q' command. */ goto unknown_command; Peter, could you pick up these two almost trivial long-pending patches? They still apply and are still useful. If you prefer that I repost them, just let me know. Thanks, Jan -- Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux
[Qemu-devel] [Bug 1290558] Re: color issue (ppc as guest)
Hi Joe, Thanks for the bug report. A few things to try: - Can you confirm that you see the same color issue when booting a Darwin ISO such as darwinppc-602.iso? - Do you still see the same the issue with QEMU git master as 1.6 is fairly old now? Using the Darwin image above, I do not see the color issue in the above posts on my Linux x86-64 machine. If it is still present for you, you'll need to give more information about the libraries used to build your QEMU and your host (perhaps it is something specific to OS X and/or your build environment?). ATB, Mark. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1290558 Title: color issue (ppc as guest) Status in QEMU: New Bug description: Hi, on my qemu 1.6.1 -- installed via fink on host Mac OS X 10.8 -- guest PowerPc with Mac OS X 10.4 from original install disk, boots fine but I observe a color issue exactly as described here: http://virtuallyfun.superglobalmegacorp.com/?p=3197 http://virtuallyfun.superglobalmegacorp.com/?p=3189 Has the problem been reported and/or fixed already? Is any workaround known or has one been suggested? I apologize for a fuzzy problem description, but I am not an expert user. You may get in touch with me directly at m@gmx.net Thanks, Joe. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1290558/+subscriptions
[Qemu-devel] [RFC v4 1/3] cpu: introduce CpuTopoInfo structure for argument simplification
Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com --- target-i386/topology.h | 33 + 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/target-i386/topology.h b/target-i386/topology.h index 07a6c5f..9b811c1 100644 --- a/target-i386/topology.h +++ b/target-i386/topology.h @@ -47,6 +47,12 @@ */ typedef uint32_t apic_id_t; +typedef struct X86CPUTopoInfo { +unsigned pkg_id; +unsigned core_id; +unsigned smt_id; +} X86CPUTopoInfo; + /* Return the bit width needed for 'count' IDs */ static unsigned apicid_bitwidth_for_count(unsigned count) @@ -92,13 +98,11 @@ static inline unsigned apicid_pkg_offset(unsigned nr_cores, unsigned nr_threads) */ static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores, unsigned nr_threads, - unsigned pkg_id, - unsigned core_id, - unsigned smt_id) + X86CPUTopoInfo *topo) { -return (pkg_id apicid_pkg_offset(nr_cores, nr_threads)) | - (core_id apicid_core_offset(nr_cores, nr_threads)) | - smt_id; +return (topo-pkg_id apicid_pkg_offset(nr_cores, nr_threads)) | + (topo-core_id apicid_core_offset(nr_cores, nr_threads)) | + topo-smt_id; } /* Calculate thread/core/package IDs for a specific topology, @@ -107,14 +111,12 @@ static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores, static inline void x86_topo_ids_from_idx(unsigned nr_cores, unsigned nr_threads, unsigned cpu_index, - unsigned *pkg_id, - unsigned *core_id, - unsigned *smt_id) + X86CPUTopoInfo *topo) { 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; +topo-smt_id = cpu_index % nr_threads; +topo-core_id = core_index % nr_cores; +topo-pkg_id = core_index / nr_cores; } /* Make APIC ID for the CPU 'cpu_index' @@ -125,10 +127,9 @@ static inline apic_id_t x86_apicid_from_cpu_idx(unsigned nr_cores, unsigned nr_threads, unsigned cpu_index) { -unsigned pkg_id, core_id, smt_id; -x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index, - pkg_id, core_id, smt_id); -return apicid_from_topo_ids(nr_cores, nr_threads, pkg_id, core_id, smt_id); +X86CPUTopoInfo topo; +x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index, topo); +return apicid_from_topo_ids(nr_cores, nr_threads, topo); } #endif /* TARGET_I386_TOPOLOGY_H */ -- 1.8.1.4
[Qemu-devel] [RFC v4 0/3] prebuild cpu QOM tree /machine/node/socket/core -link-cpu
at present, after hotplug a discontinuous cpu id on source, then done migration, on target, it will fail to add the unoccupied cpu id which was skipped at source, this cause is on target Qemu prebuild CPU with continuous cpu_index. so after migration, the cpu infrastructure bewteen source and target are different. I suppose we could use apic_id as instance_id which was used at registering vmstate when create cpu. on target, we prebuild the specified cpu topology using comand line: -device /machine/node[]/socket[]/core[]/cpu[], then migration, we could keep the same cpu infrastructure on both side. V4: rename CpuTopoInfo to X86CPUTopoInfo. and move cpu_exsit() to pc_new_cpu(). V3: get rid of thread object and tie linkcpu to core directly. and prebuild full core[] and thread[] as init socket[] according to smp_cores and smp_threads. TODO: 1. add cpu path property which used for specifying the QOM path. 2. add -device cpu-foo.path supported. 3. then we could introduce hot-remove cpu probably. I don't know wether this way is right or not. pls tell me. :) Chen Fan (3): i386: introduce cpu QOM hierarchy tree cpu: introduce X86CPUTopoInfo structure for argument simplification i386: use CpuTopoInfo instead apic_id as argument for pc_new_cpu() hw/i386/pc.c | 28 --- target-i386/Makefile.objs | 2 +- target-i386/cpu-topology.c | 199 + target-i386/cpu-topology.h | 71 target-i386/cpu.c | 41 -- target-i386/cpu.h | 8 ++ target-i386/topology.h | 51 7 files changed, 367 insertions(+), 33 deletions(-) create mode 100644 target-i386/cpu-topology.c create mode 100644 target-i386/cpu-topology.h -- 1.8.1.4
[Qemu-devel] [RFC v4 2/3] i386: use CpuTopoInfo instead apic_id as argument for pc_new_cpu()
Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com --- hw/i386/pc.c | 25 ++--- target-i386/cpu.c | 28 +++- target-i386/cpu.h | 5 + target-i386/topology.h | 18 ++ 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e715a33..765b634 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -927,11 +927,18 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } } -static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, +static X86CPU *pc_new_cpu(const char *cpu_model, X86CPUTopoInfo *topo, DeviceState *icc_bridge, Error **errp) { X86CPU *cpu; Error *local_err = NULL; +int64_t apic_id = apicid_from_topo_ids(smp_cores, smp_threads, topo); + +if (cpu_exists(apic_id)) { +error_setg(errp, Unable to add CPU with APIC ID: % PRIi64 + , it already exists, apic_id); +return NULL; +} cpu = cpu_x86_create(cpu_model, icc_bridge, local_err); if (local_err != NULL) { @@ -955,19 +962,13 @@ static const char *current_cpu_model; void pc_hot_add_cpu(const int64_t id, Error **errp) { DeviceState *icc_bridge; -int64_t apic_id = x86_cpu_apic_id_from_index(id); +X86CPUTopoInfo topo; if (id 0) { error_setg(errp, Invalid CPU id: % PRIi64, id); return; } -if (cpu_exists(apic_id)) { -error_setg(errp, Unable to add CPU: % PRIi64 - , it already exists, id); -return; -} - if (id = max_cpus) { error_setg(errp, Unable to add CPU: % PRIi64 , max allowed: %d, id, max_cpus - 1); @@ -976,7 +977,8 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) icc_bridge = DEVICE(object_resolve_path_type(icc-bridge, TYPE_ICC_BRIDGE, NULL)); -pc_new_cpu(current_cpu_model, apic_id, icc_bridge, errp); +x86_cpu_topo_ids_from_index(id, topo); +pc_new_cpu(current_cpu_model, topo, icc_bridge, errp); } void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) @@ -996,8 +998,9 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) current_cpu_model = cpu_model; for (i = 0; i smp_cpus; i++) { -cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i), - icc_bridge, error); +X86CPUTopoInfo topo; +x86_cpu_topo_ids_from_index(i, topo); +cpu = pc_new_cpu(cpu_model, topo, icc_bridge, error); if (error) { error_report(%s, error_get_pretty(error)); error_free(error); diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 0e8812a..d8ad484 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -23,8 +23,6 @@ #include cpu.h #include sysemu/kvm.h -#include sysemu/cpus.h -#include topology.h #include qemu/option.h #include qemu/config-file.h @@ -2584,6 +2582,8 @@ void enable_compat_apic_id_mode(void) compat_apic_id_mode = true; } +static bool compat_apic_id_warned; + /* Calculates initial APIC ID for a specific CPU index * * Currently we need to be able to calculate the APIC ID from the CPU index @@ -2594,14 +2594,13 @@ void enable_compat_apic_id_mode(void) uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index) { uint32_t correct_id; -static bool warned; correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index); if (compat_apic_id_mode) { -if (cpu_index != correct_id !warned) { +if (cpu_index != correct_id !compat_apic_id_warned) { error_report(APIC IDs set in compatibility mode, CPU topology won't match the configuration); -warned = true; +compat_apic_id_warned = true; } return cpu_index; } else { @@ -2609,6 +2608,25 @@ uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index) } } +void x86_cpu_topo_ids_from_index(unsigned int cpu_index, X86CPUTopoInfo *topo) +{ +int64_t correct_apic_id; + +x86_topo_ids_from_idx(smp_cores, smp_threads, cpu_index, topo); +if (compat_apic_id_mode) { +correct_apic_id = apicid_from_topo_ids(smp_cores, + smp_threads, + topo); +if (cpu_index != correct_apic_id !compat_apic_id_warned) { +error_report(APIC IDs set in compatibility mode, + CPU topology won't match the configuration); +compat_apic_id_warned = true; +} +x86_topo_ids_from_apic_id(smp_cores, smp_threads, cpu_index, topo); +assert(apicid_from_topo_ids(smp_cores, smp_threads, topo) == cpu_index); +} +} + static void x86_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); diff --git a/target-i386/cpu.h b/target-i386/cpu.h index
[Qemu-devel] [RFC v4 3/3] i386: introduce cpu QOM hierarchy tree
add cpu-topology.h cpu-topology.c files for prebuilding cpu qom tree /machine/node[X]/socket[Y]/core[Z]-link cpu Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com --- hw/i386/pc.c | 3 + target-i386/Makefile.objs | 2 +- target-i386/cpu-topology.c | 199 + target-i386/cpu-topology.h | 71 target-i386/cpu.c | 13 +++ target-i386/cpu.h | 3 + 6 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 target-i386/cpu-topology.c create mode 100644 target-i386/cpu-topology.h diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 765b634..22e81be 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -948,6 +948,7 @@ static X86CPU *pc_new_cpu(const char *cpu_model, X86CPUTopoInfo *topo, object_property_set_int(OBJECT(cpu), apic_id, apic-id, local_err); object_property_set_bool(OBJECT(cpu), true, realized, local_err); +x86_topo_cpu_set_link(OBJECT(cpu), topo); if (local_err) { error_propagate(errp, local_err); @@ -997,6 +998,8 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge) } current_cpu_model = cpu_model; +cpu_topo_init(); + for (i = 0; i smp_cpus; i++) { X86CPUTopoInfo topo; x86_cpu_topo_ids_from_index(i, topo); diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs index 027b94e..239474d 100644 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -1,4 +1,4 @@ -obj-y += translate.o helper.o cpu.o +obj-y += translate.o helper.o cpu.o cpu-topology.o obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o obj-y += gdbstub.o diff --git a/target-i386/cpu-topology.c b/target-i386/cpu-topology.c new file mode 100644 index 000..707f080 --- /dev/null +++ b/target-i386/cpu-topology.c @@ -0,0 +1,199 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2014 Fujitsu Ltd. + * Author: Chen Fan chen.fan.f...@cn.fujitsu.com + * + * 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. + */ + +#include qom/object.h +#include qemu/module.h +#include hw/hw.h +#include sysemu/cpus.h +#include sysemu/sysemu.h +#include cpu-topology.h + +static QTAILQ_HEAD(, SocketState) sockets = QTAILQ_HEAD_INITIALIZER(sockets); +static QTAILQ_HEAD(, NodeState) nodes = QTAILQ_HEAD_INITIALIZER(nodes); + +static NodeState *node_get(int node_id) +{ +NodeState *node; + +QTAILQ_FOREACH(node, nodes, next) { +if (node-node_id == node_id) { +return node; +} +} +return NULL; +} + +static SocketState *cpu_socket_find(int pkg_id) +{ +SocketState *ss; + +QTAILQ_FOREACH(ss, sockets, next) { +if (ss-socket_id == pkg_id) { +return ss; +} +} +return NULL; +} + +void cpu_topo_init(void) +{ +unsigned long *node_mask; +int i; + +node_mask = bitmap_new(MAX_NODES); + +for (i = 0; i max_cpus; i++) { +NodeState *node; +SocketState *ss; +gchar *name; +int node_id = 0, socket_id; +int j; + +for (j = 0; j nb_numa_nodes; j++) { +if (test_bit(i, node_cpumask[j])) { +node_id = j; +break; +} +} + +if (test_bit(node_id, node_mask)) { +node = node_get(node_id); +} else { +node = NODE(object_new(TYPE_NODE)); +node-node_id = node_id; +name = g_strdup_printf(node[% PRIu32 ], node_id); +object_property_add_child(qdev_get_machine(), name, + OBJECT(node), NULL); +set_bit(node_id, node_mask); +g_free(name); +QTAILQ_INSERT_TAIL(nodes, node, next); +} + +socket_id = i / (smp_cores * smp_threads); +ss = cpu_socket_find(socket_id); +if (!ss) { +ss =
Re: [Qemu-devel] [PATCH 2/6] vnc: Remove default_mon usage
On Di, 2014-03-11 at 19:15 -0400, Cole Robinson wrote: These errors don't seem user initiated, so forcibly printing to the monitor doesn't seem right. Just print to stderr. Cc: Anthony Liguori aligu...@amazon.com Cc: Gerd Hoffmann kra...@redhat.com Signed-off-by: Cole Robinson crobi...@redhat.com Reviewed-by: Gerd Hoffmann kra...@gmail.com
Re: [Qemu-devel] [PATCH 1/6] slirp: Remove default_mon usage
Cole Robinson crobi...@redhat.com writes: These errors don't seem user initiated, so forcibly printing to the monitor doesn't seem right. Just print to stderr. Drop lprint since it's now unused. Cc: Jan Kiszka jan.kis...@siemens.com Signed-off-by: Cole Robinson crobi...@redhat.com --- checkpatch flags some pre-existing tab issues, but I didn't retab. Should I? slirp/misc.c | 13 ++--- slirp/slirp.c | 8 slirp/slirp.h | 2 -- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/slirp/misc.c b/slirp/misc.c index 6c1636f..662fb1d 100644 --- a/slirp/misc.c +++ b/slirp/misc.c @@ -136,7 +136,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty) if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) 0 || bind(s, (struct sockaddr *)addr, addrlen) 0 || listen(s, 1) 0) { - lprint(Error: inet socket: %s\n, strerror(errno)); + fprintf(stderr, Error: inet socket: %s\n, strerror(errno)); closesocket(s); return 0; Why not error_report()? [...]
Re: [Qemu-devel] [v2 PATCH 00/13] SMBIOS: build full tables in QEMU
On Di, 2014-03-11 at 12:58 -0400, Gabriel L. Somlo wrote: On Tue, Mar 11, 2014 at 11:46:17AM -0400, Kevin O'Connor wrote: I would suggest being bug for bug compatible in the first set of patches, and then add patches on top to add the additional functionality. Just my 2 cents. Makes sense indeed. With the patch enclosed at the end of this email, I can get it down to this: Just move patch #1 to the end of the series. So we first switch over table by table, generating output identical to current seabios, then go fix/improve things on top of that. That way it'll be easier to bisect problems in case any show up. cheers, Gerd
Re: [Qemu-devel] [PATCH v22 01/25] add def_value_str to QemuOptDesc
On Wed, Mar 12, 2014 at 10:45:57AM +0800, Chunyan Liu wrote: 2014-03-11 21:29 GMT+08:00 Stefan Hajnoczi stefa...@gmail.com: On Mon, Mar 10, 2014 at 03:31:37PM +0800, Chunyan Liu wrote: Add def_value_str (default value) to QemuOptDesc, to replace function of the default value in QEMUOptionParameter. And improved related functions. Signed-off-by: Dong Xu Wang address@hidden The address should be wdon...@linux.vnet.ibm.com. Seems this address is not valid now, so when sending patches with git send-email, it's changed to be address@hidden automatically. That sounds weird. Are you sure it's not because you grabbed the patches from a web mailing list archive that hides email address to avoid spammers? See git-send-email(1) --suppress-cc to avoid sending the patch to his old address. Since we don't have a new address, please keep wdon...@linux.vnet.ibm.com. Stefan
Re: [Qemu-devel] [PATCH V4] tests/libqtest: Fix possible deadlock in qtest initialization
On Tue, Mar 11, 2014 at 09:20:55PM +0200, Marcel Apfelbaum wrote: On Tue, 2014-03-11 at 19:51 +0100, Stefan Hajnoczi wrote: On Tue, Mar 11, 2014 at 03:00:34PM +0200, Marcel Apfelbaum wrote: 'socket_accept' waits for Qemu to init its unix socket. If Qemu encounters an error during command line parsing, it can exit before initializing the communication channel. Using a timeout for sockets fixes the issue. Reviewed-by: Eric Blake ebl...@redhat.com Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- tests/libqtest.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Thanks for the help, Stefan! Please be aware that until you take care of the abort during qtest_init issue, qtest will crash on such occasions. Last thing, which maintainer should take this? Andreas Färber is the most likely victim^H^H^H^H^H^Hmaintainer: I don't feel like the official qtest maintainer, but I care and am actively working on it. I would consider it best to have individual tests maintained by subsystem maintainers and only define a maintainer for the core libqtest.c/qtest.c code. Although I'm interested in libqtest myself I don't have the bandwidth to review/merge all future patches in that area. Stefan
Re: [Qemu-devel] [PATCH 5/6] error: Remove redundant error_printf_unless_qmp
Cole Robinson crobi...@redhat.com writes: error_printf is just a wrapper around monitor_printf, which already drops the requested output if cur_mon is qmp. Since commit 74ee59a: monitor: drop unused monitor debug code In the old QMP days, this code was used to find out QMP commands that might be calling monitor_printf() down its call chain. This is almost impossible to happen today, because the qapi converted commands don't even have a monitor object. Besides, it's been more than a year since I used this last time. Let's just drop it. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com Reviewed-by: Markus Armbruster arm...@redhat.com I gave my R-by then, but I'm no longer sure it was a sensible move. Attempting to print in QMP context is as much a sign of trouble as it ever was. I hate sweeping signs of trouble under the carpet. If misuse is really almost impossible, then we should assert() it is, and fix the bugs caught by it. I can see error_printf() / error_printf_unless_qmp() used in a couple of ways: 1. Print hints after qerror_report(), with error_printf_unless_qmp() qerror_report() is a transitional interface to help with converting existing HMP commands to QMP. It should not be used elsewhere. We suppress the hints in QMP, because the QMP wire format doesn't provide for hints. We can't add hints to an error when using error_set(), because that API lacks support for hints. Pity. Examples: see your patch below. 2. Print hints after error_report(), with error_printf() Use of error_report() in QMP context is a sign of trouble just like any other non-JSON output to the monitor. error_printf() rather than error_printf_unless_qmp(), because the latter explicitly signals intent skip this in QMP, while the former signals QMP should not happen. The difference in intent is what makes me wary of this patch. Example: vfio_pci_load_rom(). 3. Ordinary output in code shared between command line and HMP, with error_printf() error_printf() was pressed into use as convenient print to monitor in HMP context, else to tty function. Inappropriate, because it prints to stderr rather than stdout. Examples: many help texts under is_help_option(). 4. Warnings, with error_printf() I figure these should use error_report() instead. Examples: block/ssh.c, hw/misc/vfio.c, ... Cc: Luiz Capitulino lcapitul...@redhat.com Cc: Markus Armbruster arm...@redhat.com Signed-off-by: Cole Robinson crobi...@redhat.com --- hw/usb/bus.c| 2 +- hw/usb/hcd-ehci.c | 4 ++-- include/qemu/error-report.h | 1 - util/qemu-error.c | 11 --- util/qemu-option.c | 7 --- 5 files changed, 3 insertions(+), 22 deletions(-) diff --git a/hw/usb/bus.c b/hw/usb/bus.c index fe70429..f860631 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -348,7 +348,7 @@ int usb_register_companion(const char *masterbus, USBPort *ports[], qerror_report(QERR_INVALID_PARAMETER_VALUE, masterbus, an USB masterbus); if (bus) { -error_printf_unless_qmp( +error_printf( USB bus '%s' does not allow companion controllers\n, masterbus); } diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 355bbd6..81ef01d 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -855,7 +855,7 @@ static int ehci_register_companion(USBBus *bus, USBPort *ports[], if (firstport + portcount NB_PORTS) { qerror_report(QERR_INVALID_PARAMETER_VALUE, firstport, firstport on masterbus); -error_printf_unless_qmp( +error_printf( firstport value of %u makes companion take ports %u - %u, which is outside of the valid range of 0 - %u\n, firstport, firstport, firstport + portcount - 1, NB_PORTS - 1); @@ -866,7 +866,7 @@ static int ehci_register_companion(USBBus *bus, USBPort *ports[], if (s-companion_ports[firstport + i]) { qerror_report(QERR_INVALID_PARAMETER_VALUE, masterbus, an USB masterbus); -error_printf_unless_qmp( +error_printf( port %u on masterbus %s already has a companion assigned\n, firstport + i, bus-qbus.name); return -1; diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h index 000eae3..a08ee95 100644 --- a/include/qemu/error-report.h +++ b/include/qemu/error-report.h @@ -36,7 +36,6 @@ void loc_set_file(const char *fname, int lno); void error_vprintf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2); -void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2); void error_set_progname(const char *argv0); void
Re: [Qemu-devel] [PATCH qom-next v2] qom-test: Test QOM properties
Andreas Färber afaer...@suse.de writes: Recursively walk all properties under /machine and try to retrieve their value. This is a regression test for link properties and the DeviceState::hotpluggable property. Cf. be2f78b6b062eec5170e2612299fb8953046993f and 1a37eca107cece3ed454bae29eef0bd1fac4a244 I'm afraid the last sentence is too terse for me to understand. Signed-off-by: Andreas Färber afaer...@suse.de --- v2: Added g_test_message()s. Applying to qom-next. tests/qom-test.c | 43 +++ 1 file changed, 43 insertions(+) diff --git a/tests/qom-test.c b/tests/qom-test.c index b6671fb..4909258 100644 --- a/tests/qom-test.c +++ b/tests/qom-test.c @@ -10,6 +10,7 @@ #include glib.h #include string.h +#include qemu-common.h #include libqtest.h #include qemu/osdep.h #include qapi/qmp/types.h @@ -43,6 +44,44 @@ static bool is_blacklisted(const char *arch, const char *mach) return false; } +static void test_properties(const char *path) +{ +char *cmd, *child_path; +QDict *response, *tuple; +QList *list; +QListEntry *entry; + +g_test_message(Obtaining properties of %s, path); +cmd = g_strdup_printf({ 'execute': 'qom-list', +'arguments': { 'path': '%s' } }, path); +response = qmp(cmd); +g_free(cmd); +g_assert(response); + +g_assert(qdict_haskey(response, return)); +list = qobject_to_qlist(qdict_get(response, return)); +QLIST_FOREACH_ENTRY(list, entry) { +tuple = qobject_to_qdict(qlist_entry_obj(entry)); +if (strstart(qdict_get_str(tuple, type), child, NULL)) { +child_path = g_strdup_printf(%s/%s, + path, qdict_get_str(tuple, name)); +test_properties(child_path); +g_free(child_path); +} else { +const char *prop = qdict_get_str(tuple, name); +g_test_message(Testing property %s.%s, path, prop); +cmd = g_strdup_printf({ 'execute': 'qom-get', +'arguments': { 'path': '%s', + 'property': '%s' } }, + path, prop); +response = qmp(cmd); +g_free(cmd); +/* This may fail but should not, e.g., segfault. */ +g_assert(response); I'm not sure I get your comment. +} +} +} + static void test_machine(gconstpointer data) { const char *machine = data; @@ -51,8 +90,12 @@ static void test_machine(gconstpointer data) args = g_strdup_printf(-machine %s, machine); qtest_start(args); + +test_properties(/machine); + response = qmp({ 'execute': 'quit' }); g_assert(qdict_haskey(response, return)); + qtest_end(); g_free(args); } Looks like an excellent addition to the test suite. Thanks!
Re: [Qemu-devel] [PATCH] block: Unlink temporary file
On Sat, Feb 15, 2014 at 06:03:21PM +0100, Max Reitz wrote: If the image file cannot be opened and was created as a temporary file, it should be deleted; thus, in this case, we should jump to the unlink_and_fail label and not just to fail. Reported-by: Benoît Canet ben...@irqsave.net Signed-off-by: Max Reitz mre...@redhat.com --- This patch's context depends on my bdrv_open()/bdrv_file_open() series ([PATCH v3 0/8] block: Integrate bdrv_file_open() into bdrv_open()). --- block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan
Re: [Qemu-devel] [PATCH v2 0/3] nbd: fix issues when connection breaks
On Wed, Feb 26, 2014 at 03:30:17PM +0100, Stefan Hajnoczi wrote: v2: * Use qemu-iotests 083 test number to avoid conflicts [kwolf] * Test class negotiation without export name [lupine] * Test short replies from the server [lupine] The first patch ensures the nbd_receive_reply() fd handler is unregistered when the connection to the server breaks. This avoids high CPU consumption and flooding error messages. The second patch introduces an NBD server fault injection script. Using this fake NBD server it is possible to exercise error handling code paths in the NBD client. The third patch adds qemu-iotests test case 083 to verify qemu-io exits with an error at each point where the connection can break. Stefan Hajnoczi (3): nbd: close socket if connection breaks tests: add nbd-fault-injector.py utility qemu-iotests: add 083 NBD client disconnect tests block/nbd-client.c | 33 ++-- tests/qemu-iotests/083 | 129 +++ tests/qemu-iotests/083.out | 163 +++ tests/qemu-iotests/group | 1 + tests/qemu-iotests/nbd-fault-injector.py | 264 +++ 5 files changed, 575 insertions(+), 15 deletions(-) create mode 100755 tests/qemu-iotests/083 create mode 100644 tests/qemu-iotests/083.out create mode 100755 tests/qemu-iotests/nbd-fault-injector.py Ping? I'd like to get this fix into 2.0.
Re: [Qemu-devel] [PATCH] qemu-io: Fix warnings from static code analysis
On Wed, Mar 05, 2014 at 10:23:00PM +0100, Stefan Weil wrote: Smatch complains about several global symbols which should be local. Add the missing 'static' attributes and move the 'extern' declaration of variable qemuio_misalign to qemu-io.h. This variable also changes the type from 'int' to 'bool' which better fits documents its use. Signed-off-by: Stefan Weil s...@weilnetz.de --- include/qemu-io.h |2 ++ qemu-io-cmds.c|2 +- qemu-io.c |7 +++ 3 files changed, 6 insertions(+), 5 deletions(-) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan
Re: [Qemu-devel] SMBIOS (Set of 10 patches)
Hi, I think we should not generate a type0 table unless -smbios type0=... is explicitly specified on the qemu command line. It is about the firmware, and we should leave it to the firmware to fill it by default. If you are running OVMF (EFI) instead of SeaBIOS you should see it in the dmidecode output. Everything that SeaBIOS puts into table 0 is hard coded. I'd prefer it if QEMU created the table (with the same hardcoded fields) because having split ownership of the smbios is painful. The information seabios puts in there isn't correct for OVMF though. type0 on ovmf looks like this: Handle 0x, DMI type 0, 24 bytes BIOS Information Vendor: EFI Development Kit II / OVMF Version: 0.1 Release Date: 06/03/2013 Address: 0xE8000 Runtime Size: 96 kB ROM Size: 64 kB Characteristics: BIOS characteristics not supported UEFI is supported System is a virtual machine BIOS Revision: 0.1 At very least the UEFI support bit would have to be different depending on whenever seabios or ovmf is used as firmware ... cheers, Gerd
Re: [Qemu-devel] [v2 PATCH 11/13] SMBIOS: Build full type 19 tables
On Di, 2014-03-11 at 11:16 -0400, Gabriel L. Somlo wrote: From: Gabriel L. Somlo so...@cmu.edu Build full smbios type 19 (memory array mapped address) tables, and make them available via fw_cfg +smbios_build_type_19_table(0, 0, smbios_below_4g_ram 10); +if (smbios_above_4g_ram) { +smbios_build_type_19_table(1, 4 20, smbios_above_4g_ram 10); +} I think we should just use e820_table (see pc.c) here. Loop over it and add a type 19 table for each ram region in there. cheers, Gerd
[Qemu-devel] pci passthrough in Aarch64
Hi, Some one Please let me know, What is the way to assign a pass through PCI device with qemu on Aarch64 without VFIO. i tried ? -device pci-assign,host=01.00.0? got the following error qemu-system-aarch64: -device pci-assign,host=01.00.0: 'kvm-pci-assign' is not a valid device model name Regards, Tirumalesh Chalamarla
[Qemu-devel] [PULL 0/1] Docs: Introduce multiport serial support in qemupciserial.inf.
Hi, Single patch I've just found still lingering in my misc branch ... please pull, Gerd The following changes since commit 239618707637ec87eba8c452d2b2f75dc5ca20c7: Merge remote-tracking branch 'remotes/kvm/uq/master' into staging (2014-03-11 19:39:17 +) are available in the git repository at: git://git.kraxel.org/qemu tags/pull-misc-1 for you to fetch changes up to dc9528fdf9f61dfa6355b4052dc42b8cbadf9167: Docs: Introduce multiport serial support in qemupciserial.inf. (2014-03-12 10:33:23 +0100) Docs: Introduce multiport serial support in qemupciserial.inf. Miki Mishael (1): Docs: Introduce multiport serial support in qemupciserial.inf. docs/qemupciserial.inf | 167 +++-- 1 file changed, 80 insertions(+), 87 deletions(-)
[Qemu-devel] [PULL 1/1] Docs: Introduce multiport serial support in qemupciserial.inf.
From: Miki Mishael mmish...@redhat.com Support for pci-serial-2x and pci-serial-4x was added to the inf file. Standard Windows driver mf.sys used to split single function device into per-port nodes. Signed-off-by: Miki Mishael mmish...@redhat.com Signed-off-by: Dmitry Fleytman dfley...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- docs/qemupciserial.inf | 167 +++-- 1 file changed, 80 insertions(+), 87 deletions(-) diff --git a/docs/qemupciserial.inf b/docs/qemupciserial.inf index 3474310..6f7eef4 100644 --- a/docs/qemupciserial.inf +++ b/docs/qemupciserial.inf @@ -11,99 +11,92 @@ ; (Com+Lpt) from the list. Click Have a disk. Select this file. ; Procedure may vary a bit depending on the windows version. -; FIXME: This file covers the single port version only. +; This file covers all options: pci-serial, pci-serial-2x, pci-serial-4x +; for both 32 and 64 bit platforms. [Version] -Signature=$CHICAGO$ -Class=Ports -ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Signature=$Windows NT$ +Class=MultiFunction +ClassGUID={4d36e971-e325-11ce-bfc1-08002be10318} Provider=%QEMU% -DriverVer=09/24/2012,1.3.0 - -[SourceDisksNames] -3426=windows cd - -[SourceDisksFiles] -serial.sys = 3426 -serenum.sys= 3426 - -[DestinationDirs] -DefaultDestDir = 11;LDID_SYS -ComPort.NT.Copy = 12;DIRID_DRIVERS -SerialEnumerator.NT.Copy=12 ;DIRID_DRIVERS - -; Drivers -;-- +DriverVer=12/29/2013,1.3.0 +[ControlFlags] +ExcludeFromSelect=* [Manufacturer] -%QEMU%=QEMU,NTx86 +%QEMU%=QEMU,NTx86,NTAMD64 [QEMU.NTx86] -%QEMU-PCI_SERIAL.DeviceDesc% = ComPort, PCI\VEN_1b36DEV_0002CC_0700 - -; COM sections -;-- -[ComPort.AddReg] -HKR,,PortSubClass,1,01 - -[ComPort.NT] -AddReg=ComPort.AddReg, ComPort.NT.AddReg -LogConfig=caa -SyssetupPnPFlags = 1 - -[ComPort.NT.HW] -AddReg=ComPort.NT.HW.AddReg - -[ComPort.NT.AddReg] -HKR,,EnumPropPages32,,MsPorts.dll,SerialPortPropPageProvider - -[ComPort.NT.HW.AddReg] -HKR,,UpperFilters,0x0001,serenum - -;-- Service installation -; Port Driver (function driver for this device) -[ComPort.NT.Services] -AddService = Serial, 0x0002, Serial_Service_Inst, Serial_EventLog_Inst -AddService = Serenum,,Serenum_Service_Inst - -; -- Serial Port Driver install sections -[Serial_Service_Inst] -DisplayName= %Serial.SVCDESC% -ServiceType= 1 ; SERVICE_KERNEL_DRIVER -StartType = 1 ; SERVICE_SYSTEM_START (this driver may do detection) -ErrorControl = 0 ; SERVICE_ERROR_IGNORE -ServiceBinary = %12%\serial.sys -LoadOrderGroup = Extended base - -; -- Serenum Driver install section -[Serenum_Service_Inst] -DisplayName= %Serenum.SVCDESC% -ServiceType= 1 ; SERVICE_KERNEL_DRIVER -StartType = 3 ; SERVICE_DEMAND_START -ErrorControl = 1 ; SERVICE_ERROR_NORMAL -ServiceBinary = %12%\serenum.sys -LoadOrderGroup = PNP Filter - -[Serial_EventLog_Inst] -AddReg = Serial_EventLog_AddReg - -[Serial_EventLog_AddReg] -HKR,,EventMessageFile,0x0002,%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\serial.sys -HKR,,TypesSupported,0x00010001,7 - -; The following sections are COM port resource configs. -; Section name format means: -; Char 1 = c (COM port) -; Char 2 = I/O config: 1 (3f8), 2 (2f8), 3 (3e8), 4 (2e8), a (any) -; Char 3 = IRQ config: #, a (any) - -[caa] ; Any base, any IRQ -ConfigPriority=HARDRECONFIG -IOConfig=8@100-%fff8(3ff::) -IRQConfig=S:3,4,5,7,9,10,11,12,14,15 +%QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36DEV_0002 +%QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36DEV_0003 +%QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36DEV_0004 + +[QEMU.NTAMD64] +%QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36DEV_0002 +%QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36DEV_0003 +%QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36DEV_0004 + +[ComPort_inst1] +Include=mf.inf +Needs=MFINSTALL.mf + +[ComPort_inst2] +Include=mf.inf +Needs=MFINSTALL.mf + +[ComPort_inst4] +Include=mf.inf +Needs=MFINSTALL.mf + +[ComPort_inst1.HW] +AddReg=ComPort_inst1.RegHW + +[ComPort_inst2.HW] +AddReg=ComPort_inst2.RegHW + +[ComPort_inst4.HW] +AddReg=ComPort_inst4.RegHW + +[ComPort_inst1.Services] +Include=mf.inf +Needs=MFINSTALL.mf.Services + +[ComPort_inst2.Services] +Include=mf.inf +Needs=MFINSTALL.mf.Services + +[ComPort_inst4.Services] +Include=mf.inf +Needs=MFINSTALL.mf.Services + +[ComPort_inst1.RegHW] +HKR,Child,HardwareID,,*PNP0501 +HKR,Child,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00 +HKR,Child,ResourceMap,1,02 + +[ComPort_inst2.RegHW] +HKR,Child,HardwareID,,*PNP0501 +HKR,Child,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00 +HKR,Child,ResourceMap,1,02
Re: [Qemu-devel] [PATCH] block: Update image size in bdrv_invalidate_cache()
Am 11.03.2014 um 17:41 hat Benoît Canet geschrieben: I have the impression that you are silently fixing other nits; Am I? Not intentionally at least. I think I can justify every single line of the patch with respect to the bug described in the commit message. We need to recursive into the protocol layer, and we need to refresh bs-total_sectors. For drivers implementing the callback, we need to recurse to bs-file between the internal open/close pair. I can't see what could be left out in this patch. Kevin
Re: [Qemu-devel] [PATCH 1/2] tests/libqtest: Fix possible deadlock in qtest initialization
Marcel Apfelbaum marce...@redhat.com writes: 'socket_accept' waits for Qemu to init its unix socket. If Qemu encounters an error during command line parsing, it can exit before initializing the communication channel. It gets worse as the make check-qtest-* gets stuck without notifying which test exactly has problems, so debugging can be a challenge. The solution has two parts: - Use a timeout for the socket. - Expose a qtest_state_valid that checks that the connections with Qemu are OK. Asserting qtest_state_valid in each test after qtest_init is a must, as we need to trace which test failed. Is that assert in the next patch? Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- tests/libqtest.c | 26 +- tests/libqtest.h | 8 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/tests/libqtest.c b/tests/libqtest.c index f587d36..93dfa81 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -34,6 +34,7 @@ #include qapi/qmp/json-parser.h #define MAX_IRQ 256 +#define SOCKET_TIMEOUT 5 QTestState *global_qtest; @@ -83,7 +84,6 @@ static int socket_accept(int sock) do { ret = accept(sock, (struct sockaddr *)addr, addrlen); } while (ret == -1 errno == EINTR); -g_assert_no_errno(ret); close(sock); return ret; @@ -111,6 +111,8 @@ QTestState *qtest_init(const char *extra_args) gchar *command; const char *qemu_binary; struct sigaction sigact; +struct timeval socket_timeout = { .tv_sec = SOCKET_TIMEOUT, + .tv_usec = 0 }; qemu_binary = getenv(QTEST_QEMU_BINARY); g_assert(qemu_binary != NULL); @@ -123,6 +125,11 @@ QTestState *qtest_init(const char *extra_args) sock = init_socket(socket_path); qmpsock = init_socket(qmp_socket_path); +setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)socket_timeout, + sizeof(socket_timeout)); +setsockopt(qmpsock, SOL_SOCKET, SO_RCVTIMEO, (void *)socket_timeout, + sizeof(socket_timeout)); + /* Catch SIGABRT to clean up on g_assert() failure */ sigact = (struct sigaction){ .sa_handler = sigabrt_handler, @@ -147,7 +154,9 @@ QTestState *qtest_init(const char *extra_args) } s-fd = socket_accept(sock); -s-qmp_fd = socket_accept(qmpsock); +if (s-fd = 0) { +s-qmp_fd = socket_accept(qmpsock); +} unlink(socket_path); unlink(qmp_socket_path); g_free(socket_path); The conditional looks odd. But without it, we could wait for timeout two times. If s-fd 0, then s-qmp_fd remains 0, and should not be used. Are you sure that's the case? qtest_quit() and qtest_qmpv() use it. Reachable? Perhaps s-qmp_fd = -1 would be safer. Could you explain to me again why we want to continue after socket_accept() fails, regardless of whether it fails due to timeout or something else? @@ -158,9 +167,11 @@ QTestState *qtest_init(const char *extra_args) s-irq_level[i] = false; } -/* Read the QMP greeting and then do the handshake */ -qtest_qmp_discard_response(s, ); -qtest_qmp_discard_response(s, { 'execute': 'qmp_capabilities' }); +if (qtest_state_valid(s)) { +/* Read the QMP greeting and then do the handshake */ +qtest_qmp_discard_response(s, ); +qtest_qmp_discard_response(s, { 'execute': 'qmp_capabilities' }); +} if (getenv(QTEST_STOP)) { kill(s-qemu_pid, SIGSTOP); @@ -169,6 +180,11 @@ QTestState *qtest_init(const char *extra_args) return s; } +bool qtest_state_valid(QTestState *s) +{ +return (s-fd = 0) (s-qmp_fd = 0); +} + void qtest_quit(QTestState *s) { sigaction(SIGABRT, s-sigact_old, NULL); diff --git a/tests/libqtest.h b/tests/libqtest.h index 9deebdc..39a37b1 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -45,6 +45,14 @@ QTestState *qtest_init(const char *extra_args); void qtest_quit(QTestState *s); /** + * qtest_state_valid: + * @state: #QTestState instance to check + * + * Returns: True if qtest was initialized successfully If you mean the macro defined by stdbool.h, that one's spelled with a lower case 't'. + */ +bool qtest_state_valid(QTestState *s); + +/** * qtest_qmp_discard_response: * @s: #QTestState instance to operate on. * @fmt...: QMP message to send to qemu
Re: [Qemu-devel] [PATCH] block: Update image size in bdrv_invalidate_cache()
The Wednesday 12 Mar 2014 à 10:40:00 (+0100), Kevin Wolf wrote : Am 11.03.2014 um 17:41 hat Benoît Canet geschrieben: I have the impression that you are silently fixing other nits; Am I? Not intentionally at least. I think I can justify every single line of the patch with respect to the bug described in the commit message. We need to recursive into the protocol layer, and we need to refresh bs-total_sectors. For drivers implementing the callback, we need to recurse to bs-file between the internal open/close pair. I can't see what could be left out in this patch. I didn't understood the implication on recursion at first sight. Best regards Benoît Kevin
Re: [Qemu-devel] [Qemu-trivial] [PATCH v2] hw/timer/grlib_gptimer: Avoid integer overflows
Hello, On 2014-03-02 16:56, Sebastian Huber wrote: On 03/02/2014 02:17 PM, Michael Tokarev wrote: 26.02.2014 11:53, Sebastian Huber wrote: Ping. There was another comment on this, about the first hunk, see https://lists.gnu.org/archive/html/qemu-trivial/2014-02/msg00067.html Note that the comment below this line mentions the +1 which is being removed. I think I addressed this issue with the following sentence in the commit message of v2: Use the GPTIMER counter value for tracing to avoid an overflow of the 32-bit value passed to trace_grlib_gptimer_enable(). should I better split the patch into two parts? -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
Re: [Qemu-devel] [PATCH 1/2] tests/libqtest: Fix possible deadlock in qtest initialization
On Wed, 2014-03-12 at 10:42 +0100, Markus Armbruster wrote: Marcel Apfelbaum marce...@redhat.com writes: 'socket_accept' waits for Qemu to init its unix socket. If Qemu encounters an error during command line parsing, it can exit before initializing the communication channel. It gets worse as the make check-qtest-* gets stuck without notifying which test exactly has problems, so debugging can be a challenge. The solution has two parts: - Use a timeout for the socket. - Expose a qtest_state_valid that checks that the connections with Qemu are OK. Asserting qtest_state_valid in each test after qtest_init is a must, as we need to trace which test failed. Is that assert in the next patch? Yes, for every qtest test, but Stefan NACKED it :(. The reason would be that he didn't want to have a manual assertion on each test just to see the test name. The alternative is to output each test using gtest options. I have my doubts because even that we see the test name, we still receive the assert in qtestlib, but it is not the qtestlib's fault, it is the test's supplied command line fault, this why I think the test should assert. But this is too philosophical for me :), the other pacth that prevents the gtest getting stuck was accepted, I am now looking for a maintainer to put it into his tree. Thanks, Marcel Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- tests/libqtest.c | 26 +- tests/libqtest.h | 8 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/tests/libqtest.c b/tests/libqtest.c index f587d36..93dfa81 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -34,6 +34,7 @@ #include qapi/qmp/json-parser.h #define MAX_IRQ 256 +#define SOCKET_TIMEOUT 5 QTestState *global_qtest; @@ -83,7 +84,6 @@ static int socket_accept(int sock) do { ret = accept(sock, (struct sockaddr *)addr, addrlen); } while (ret == -1 errno == EINTR); -g_assert_no_errno(ret); close(sock); return ret; @@ -111,6 +111,8 @@ QTestState *qtest_init(const char *extra_args) gchar *command; const char *qemu_binary; struct sigaction sigact; +struct timeval socket_timeout = { .tv_sec = SOCKET_TIMEOUT, + .tv_usec = 0 }; qemu_binary = getenv(QTEST_QEMU_BINARY); g_assert(qemu_binary != NULL); @@ -123,6 +125,11 @@ QTestState *qtest_init(const char *extra_args) sock = init_socket(socket_path); qmpsock = init_socket(qmp_socket_path); +setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)socket_timeout, + sizeof(socket_timeout)); +setsockopt(qmpsock, SOL_SOCKET, SO_RCVTIMEO, (void *)socket_timeout, + sizeof(socket_timeout)); + /* Catch SIGABRT to clean up on g_assert() failure */ sigact = (struct sigaction){ .sa_handler = sigabrt_handler, @@ -147,7 +154,9 @@ QTestState *qtest_init(const char *extra_args) } s-fd = socket_accept(sock); -s-qmp_fd = socket_accept(qmpsock); +if (s-fd = 0) { +s-qmp_fd = socket_accept(qmpsock); +} unlink(socket_path); unlink(qmp_socket_path); g_free(socket_path); The conditional looks odd. But without it, we could wait for timeout two times. If s-fd 0, then s-qmp_fd remains 0, and should not be used. Are you sure that's the case? qtest_quit() and qtest_qmpv() use it. Reachable? Perhaps s-qmp_fd = -1 would be safer. Could you explain to me again why we want to continue after socket_accept() fails, regardless of whether it fails due to timeout or something else? @@ -158,9 +167,11 @@ QTestState *qtest_init(const char *extra_args) s-irq_level[i] = false; } -/* Read the QMP greeting and then do the handshake */ -qtest_qmp_discard_response(s, ); -qtest_qmp_discard_response(s, { 'execute': 'qmp_capabilities' }); +if (qtest_state_valid(s)) { +/* Read the QMP greeting and then do the handshake */ +qtest_qmp_discard_response(s, ); +qtest_qmp_discard_response(s, { 'execute': 'qmp_capabilities' }); +} if (getenv(QTEST_STOP)) { kill(s-qemu_pid, SIGSTOP); @@ -169,6 +180,11 @@ QTestState *qtest_init(const char *extra_args) return s; } +bool qtest_state_valid(QTestState *s) +{ +return (s-fd = 0) (s-qmp_fd = 0); +} + void qtest_quit(QTestState *s) { sigaction(SIGABRT, s-sigact_old, NULL); diff --git a/tests/libqtest.h b/tests/libqtest.h index 9deebdc..39a37b1 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -45,6 +45,14 @@ QTestState *qtest_init(const char *extra_args); void qtest_quit(QTestState *s); /** + * qtest_state_valid: + * @state: #QTestState instance to check + * + * Returns: True if qtest was
Re: [Qemu-devel] pci passthrough in Aarch64
On 12 March 2014 09:30, Chalamarla, Tirumalesh tirumalesh.chalama...@caviumnetworks.com wrote: Some one Please let me know, What is the way to assign a pass through PCI device with qemu on Aarch64 without VFIO. This isn't currently possible because the only AArch64 board model we support is virt and that does not have a PCI controller. thanks -- PMM
Re: [Qemu-devel] [PATCH v2 0/5] block: Strip protocol prefixes from filenames
On Sat, Mar 08, 2014 at 12:39:40AM +0100, Max Reitz wrote: As some kind of follow-up to the block: Strip 'file:' prefix from filenames series, this series does the same thing for other protocol drivers. All protocol drivers which implement bdrv_probe() may rely on them being selected based on that function returning success alone. However, they may have been chosen through a protocol prefix as well. Thus, if they currently do not implement bdrv_parse_filename(), they may be unaware of that possible prefix and therefore fail to interpret such filenames (and, in fact, all of those are unaware). This series makes these drivers strip their respective prefix through bdrv_parse_filename() and in bdrv_create(), if implemented. The following protocol drivers are not touched by this series since they already implement bdrv_parse_filename() and are thus very likely aware of the prefix: - vvfat, nbd, blkdebug, blkverify, ssh, curl The following protocol drivers are not touched by this series since they do not implement bdrv_probe() and therefore always receive a prefixed filename (unless they are selected through QMP options) which makes them pretty much guaranteed to handle these prefixes correctly: - nfs, sheepdog, rbd, quorum, gluster, iscsi Thus, only drivers implementing bdrv_probe() and not implementing bdrv_parse_filename() have been touched. Please note that this series does not strip the prefix in bdrv_probe(). This is due to the driver being selected anyway later on through the protocol prefix, even though bdrv_probe() returned 0. More importantly, according to a comment in bdrv_find_protocol() in block.c about why bdrv_probe() occurs before the protocol prefix is interpreted, it seems actually more desirable not to strip the prefix in bdrv_probe() (since it may in fact not be a prefix but rather some obscure device naming schema). v2: - Patch 3: Use a common cdrom_parse_filename() for both Linux and FreeBSD [Benoît] - Patch 4: Fixed commit message [Eric] Key: [] : patches are identical [] : number of functional differences between upstream/downstream patch [down] : patch is downstream-only The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively 001/5:[] [--] 'block/raw-posix: bdrv_parse_filename() for hdev' 002/5:[] [--] 'block/raw-posix: bdrv_parse_filename() for floppy' 003/5:[0013] [FC] 'block/raw-posix: bdrv_parse_filename() for cdrom' 004/5:[] [--] 'block/raw-posix: Strip protocol prefix on creation' 005/5:[] [--] 'block/raw-win32: bdrv_parse_filename() for hdev' Max Reitz (5): block/raw-posix: bdrv_parse_filename() for hdev block/raw-posix: bdrv_parse_filename() for floppy block/raw-posix: bdrv_parse_filename() for cdrom block/raw-posix: Strip protocol prefix on creation block/raw-win32: bdrv_parse_filename() for hdev block/raw-posix.c | 47 +++ block/raw-win32.c | 10 ++ 2 files changed, 57 insertions(+) -- 1.9.0 Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan
Re: [Qemu-devel] [PATCH v6] target-sparc: Add and use CPU_FEATURE_CASA
Thanks Sebastian, I will try my first pull request ;)
Re: [Qemu-devel] [PATCH v6] target-sparc: Add and use CPU_FEATURE_CASA
Thanks Sebastian, I will try my first pull request :)
Re: [Qemu-devel] [PATCH v6] target-sparc: Add and use CPU_FEATURE_CASA
Hello Fabien, On 2014-03-12 11:17, Fabien Chouteau wrote: Thanks Sebastian, I will try my first pull request :) I think Mark already did this http://lists.gnu.org/archive/html/qemu-devel/2014-03/msg02325.html ? -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
Re: [Qemu-devel] [PATCH v6] target-sparc: Add and use CPU_FEATURE_CASA
On 03/12/2014 11:22 AM, Sebastian Huber wrote: Hello Fabien, On 2014-03-12 11:17, Fabien Chouteau wrote: Thanks Sebastian, I will try my first pull request :) I think Mark already did this http://lists.gnu.org/archive/html/qemu-devel/2014-03/msg02325.html ? Very well then :) Thanks for the udpate.
[Qemu-devel] [PULL 00/24] Block patches for QEMU 2.0
The following changes since commit b304bf0021a2dfb24fa91f704a1d976b74f56f20: s390/kvm: Add Maintainers for s390/kvm (2014-03-10 16:43:11 +) are available in the git repository at: git://github.com/stefanha/qemu.git tags/block-pull-request for you to fetch changes up to 11dfe5671f5d75873d9cf89e9c989655f09ccb0a: block/raw-win32: bdrv_parse_filename() for hdev (2014-03-12 11:03:29 +0100) Block pull request Benoît Canet (1): block: Rewrite the snapshot authorization mechanism for block filters. Igor Mammedov (1): qdev: make get_pointer() handle temporary strings Kevin Wolf (3): block: Update image size in bdrv_invalidate_cache() qcow2: Keep option in qcow2_invalidate_cache() qcow2: Don't write with BDRV_O_INCOMING Max Reitz (10): qcow2-refcount: Sanitize refcount table entry qcow2: Check bs-drv in copy_sectors() block: bs-drv may be NULL in bdrv_debug_resume() iotests: Test corruption during COW request block: Unlink temporary file block/raw-posix: bdrv_parse_filename() for hdev block/raw-posix: bdrv_parse_filename() for floppy block/raw-posix: bdrv_parse_filename() for cdrom block/raw-posix: Strip protocol prefix on creation block/raw-win32: bdrv_parse_filename() for hdev Stefan Hajnoczi (8): object: add object_get_canonical_path_component() rfifolock: add recursive FIFO lock aio: add aio_context_acquire() and aio_context_release() iothread: add I/O thread object iothread: add iothread qdev property type dataplane: replace internal thread with IOThread iothread: stash thread ID away qmp: add query-iothreads command Stefan Weil (1): qemu-io: Fix warnings from static code analysis Makefile.objs| 1 + async.c | 18 block.c | 61 +++--- block/blkverify.c| 17 +++- block/qcow2-cluster.c| 4 + block/qcow2-refcount.c | 3 +- block/qcow2.c| 17 ++-- block/qed.c | 3 + block/quorum.c | 3 +- block/raw-posix.c| 47 +++ block/raw-win32.c| 10 +++ hw/block/dataplane/virtio-blk.c | 96 - hw/core/qdev-properties-system.c | 70 +-- include/block/aio.h | 18 include/block/block.h| 9 -- include/block/block_int.h| 8 +- include/hw/qdev-properties.h | 3 + include/hw/virtio/virtio-blk.h | 8 +- include/qemu-io.h| 2 + include/qemu/rfifolock.h | 54 include/qom/object.h | 8 ++ include/sysemu/iothread.h| 30 +++ iothread.c | 178 +++ qapi-schema.json | 29 +++ qemu-io-cmds.c | 2 +- qemu-io.c| 7 +- qmp-commands.hx | 39 + qom/object.c | 54 +++- tests/Makefile | 2 + tests/qemu-iotests/060 | 26 ++ tests/qemu-iotests/060.out | 15 tests/test-aio.c | 58 + tests/test-rfifolock.c | 90 util/Makefile.objs | 1 + util/rfifolock.c | 78 + 35 files changed, 936 insertions(+), 133 deletions(-) create mode 100644 include/qemu/rfifolock.h create mode 100644 include/sysemu/iothread.h create mode 100644 iothread.c create mode 100644 tests/test-rfifolock.c create mode 100644 util/rfifolock.c -- 1.8.5.3
[Qemu-devel] [PULL 04/24] block: bs-drv may be NULL in bdrv_debug_resume()
From: Max Reitz mre...@redhat.com Currently, bdrv_debug_resume() requires every bs-drv in the BDS stack to be NULL until a bs-drv with an implementation of bdrv_debug_resume() is found. For a normal function, this would be fine, but this is a function for debugging purposes and should therefore allow intermediate BDS not to have a driver (i.e., be ejected). Otherwise, it is hard to debug such situations. Signed-off-by: Max Reitz mre...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block.c b/block.c index 7b306fb..09c9258 100644 --- a/block.c +++ b/block.c @@ -4055,7 +4055,7 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag) int bdrv_debug_resume(BlockDriverState *bs, const char *tag) { -while (bs bs-drv !bs-drv-bdrv_debug_resume) { +while (bs (!bs-drv || !bs-drv-bdrv_debug_resume)) { bs = bs-file; } -- 1.8.5.3
[Qemu-devel] [PULL 01/24] qcow2-refcount: Sanitize refcount table entry
From: Max Reitz mre...@redhat.com When reading the refcount table entry in get_refcount(), only bits which are actually significant for the refcount block offset should be taken into account. Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Laszlo Ersek ler...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block/qcow2-refcount.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 8712d8b..6151148 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -96,7 +96,8 @@ static int get_refcount(BlockDriverState *bs, int64_t cluster_index) refcount_table_index = cluster_index (s-cluster_bits - REFCOUNT_SHIFT); if (refcount_table_index = s-refcount_table_size) return 0; -refcount_block_offset = s-refcount_table[refcount_table_index]; +refcount_block_offset = +s-refcount_table[refcount_table_index] REFT_OFFSET_MASK; if (!refcount_block_offset) return 0; -- 1.8.5.3
[Qemu-devel] [PULL 06/24] block: Rewrite the snapshot authorization mechanism for block filters.
From: Benoît Canet benoit.ca...@irqsave.net This patch keep the recursive way of doing things but simplify it by giving two responsabilities to all block filters implementors. They will need to do two things: -Set the is_filter field of their block driver to true. -Implement the bdrv_recurse_is_first_non_filter method of their block driver like it is done on the Quorum block driver. (block/quorum.c) [Paolo Bonzini pbonz...@redhat.com pointed out that this patch changes the semantics of blkverify, which now recurses down both bs-file and s-test_file. -- Stefan] Reported-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Benoit Canet ben...@irqsave.net Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block.c | 47 +-- block/blkverify.c | 17 - block/quorum.c| 3 +-- include/block/block.h | 9 - include/block/block_int.h | 8 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/block.c b/block.c index 09c9258..cf5645a 100644 --- a/block.c +++ b/block.c @@ -5398,43 +5398,37 @@ int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options) return bs-drv-bdrv_amend_options(bs, options); } -/* Used to recurse on single child block filters. - * Single child block filter will store their child in bs-file. +/* This function will be called by the bdrv_recurse_is_first_non_filter method + * of block filter and by bdrv_is_first_non_filter. + * It is used to test if the given bs is the candidate or recurse more in the + * node graph. */ -bool bdrv_generic_is_first_non_filter(BlockDriverState *bs, +bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, BlockDriverState *candidate) { -if (!bs-drv) { -return false; -} - -if (!bs-drv-authorizations[BS_IS_A_FILTER]) { -if (bs == candidate) { -return true; -} else { -return false; -} -} - -if (!bs-drv-authorizations[BS_FILTER_PASS_DOWN]) { +/* return false if basic checks fails */ +if (!bs || !bs-drv) { return false; } -if (!bs-file) { -return false; +/* the code reached a non block filter driver - check if the bs is + * the same as the candidate. It's the recursion termination condition. + */ +if (!bs-drv-is_filter) { +return bs == candidate; } +/* Down this path the driver is a block filter driver */ -return bdrv_recurse_is_first_non_filter(bs-file, candidate); -} - -bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, - BlockDriverState *candidate) -{ -if (bs-drv bs-drv-bdrv_recurse_is_first_non_filter) { +/* If the block filter recursion method is defined use it to recurse down + * the node graph. + */ +if (bs-drv-bdrv_recurse_is_first_non_filter) { return bs-drv-bdrv_recurse_is_first_non_filter(bs, candidate); } -return bdrv_generic_is_first_non_filter(bs, candidate); +/* the driver is a block filter but don't allow to recurse - return false + */ +return false; } /* This function checks if the candidate is the first non filter bs down it's @@ -5449,6 +5443,7 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate) QTAILQ_FOREACH(bs, bdrv_states, device_list) { bool perm; +/* try to recurse in this top level bs */ perm = bdrv_recurse_is_first_non_filter(bs, candidate); /* candidate is the first non filter */ diff --git a/block/blkverify.c b/block/blkverify.c index b98b08b..e1c3117 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -288,6 +288,20 @@ static BlockDriverAIOCB *blkverify_aio_flush(BlockDriverState *bs, return bdrv_aio_flush(s-test_file, cb, opaque); } +static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs, + BlockDriverState *candidate) +{ +BDRVBlkverifyState *s = bs-opaque; + +bool perm = bdrv_recurse_is_first_non_filter(bs-file, candidate); + +if (perm) { +return true; +} + +return bdrv_recurse_is_first_non_filter(s-test_file, candidate); +} + static BlockDriver bdrv_blkverify = { .format_name= blkverify, .protocol_name = blkverify, @@ -302,7 +316,8 @@ static BlockDriver bdrv_blkverify = { .bdrv_aio_writev= blkverify_aio_writev, .bdrv_aio_flush = blkverify_aio_flush, -.authorizations = { true, false }, +.is_filter = true, +.bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter, }; static void bdrv_blkverify_init(void) diff --git a/block/quorum.c b/block/quorum.c index bd997b7..33bf2ae 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -852,8 +852,6 @@ static BlockDriver bdrv_quorum = { .bdrv_file_open = quorum_open,
[Qemu-devel] [PULL 08/24] rfifolock: add recursive FIFO lock
QemuMutex does not guarantee fairness and cannot be acquired recursively: Fairness means each locker gets a turn and the scheduler cannot cause starvation. Recursive locking is useful for composition, it allows a sequence of locking operations to be invoked atomically by acquiring the lock around them. This patch adds RFifoLock, a recursive lock that guarantees FIFO order. Its first user is added in the next patch. RFifoLock has one additional feature: it can be initialized with an optional contention callback. The callback is invoked whenever a thread must wait for the lock. For example, it can be used to poke the current owner so that they release the lock soon. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- include/qemu/rfifolock.h | 54 + tests/Makefile | 2 ++ tests/test-rfifolock.c | 90 util/Makefile.objs | 1 + util/rfifolock.c | 78 + 5 files changed, 225 insertions(+) create mode 100644 include/qemu/rfifolock.h create mode 100644 tests/test-rfifolock.c create mode 100644 util/rfifolock.c diff --git a/include/qemu/rfifolock.h b/include/qemu/rfifolock.h new file mode 100644 index 000..b23ab53 --- /dev/null +++ b/include/qemu/rfifolock.h @@ -0,0 +1,54 @@ +/* + * Recursive FIFO lock + * + * Copyright Red Hat, Inc. 2013 + * + * Authors: + * Stefan Hajnoczi stefa...@redhat.com + * + * 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_RFIFOLOCK_H +#define QEMU_RFIFOLOCK_H + +#include qemu/thread.h + +/* Recursive FIFO lock + * + * This lock provides more features than a plain mutex: + * + * 1. Fairness - enforces FIFO order. + * 2. Nesting - can be taken recursively. + * 3. Contention callback - optional, called when thread must wait. + * + * The recursive FIFO lock is heavyweight so prefer other synchronization + * primitives if you do not need its features. + */ +typedef struct { +QemuMutex lock; /* protects all fields */ + +/* FIFO order */ +unsigned int head; /* active ticket number */ +unsigned int tail; /* waiting ticket number */ +QemuCond cond; /* used to wait for our ticket number */ + +/* Nesting */ +QemuThread owner_thread;/* thread that currently has ownership */ +unsigned int nesting; /* amount of nesting levels */ + +/* Contention callback */ +void (*cb)(void *); /* called when thread must wait, with -lock + * held so it may not recursively lock/unlock + */ +void *cb_opaque; +} RFifoLock; + +void rfifolock_init(RFifoLock *r, void (*cb)(void *), void *opaque); +void rfifolock_destroy(RFifoLock *r); +void rfifolock_lock(RFifoLock *r); +void rfifolock_unlock(RFifoLock *r); + +#endif /* QEMU_RFIFOLOCK_H */ diff --git a/tests/Makefile b/tests/Makefile index b17d41e..78e9803 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -35,6 +35,7 @@ check-unit-y += tests/test-visitor-serialization$(EXESUF) check-unit-y += tests/test-iov$(EXESUF) gcov-files-test-iov-y = util/iov.c check-unit-y += tests/test-aio$(EXESUF) +check-unit-y += tests/test-rfifolock$(EXESUF) check-unit-y += tests/test-throttle$(EXESUF) gcov-files-test-aio-$(CONFIG_WIN32) = aio-win32.c gcov-files-test-aio-$(CONFIG_POSIX) = aio-posix.c @@ -172,6 +173,7 @@ tests/check-qjson$(EXESUF): tests/check-qjson.o libqemuutil.a libqemustub.a tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(qom-core-obj) libqemuutil.a libqemustub.a tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a libqemustub.a +tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o libqemuutil.a libqemustub.a tests/test-throttle$(EXESUF): tests/test-throttle.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-iov$(EXESUF): tests/test-iov.o libqemuutil.a diff --git a/tests/test-rfifolock.c b/tests/test-rfifolock.c new file mode 100644 index 000..440dbcb --- /dev/null +++ b/tests/test-rfifolock.c @@ -0,0 +1,90 @@ +/* + * RFifoLock tests + * + * Copyright Red Hat, Inc. 2013 + * + * Authors: + * Stefan Hajnoczistefa...@redhat.com + * + * This work is licensed under the terms of the GNU LGPL, version 2 or later. + * See the COPYING.LIB file in the top-level directory. + */ + +#include glib.h +#include qemu-common.h +#include qemu/rfifolock.h + +static void test_nesting(void) +{ +RFifoLock lock; + +/* Trivial test, ensure the lock is recursive */ +rfifolock_init(lock, NULL, NULL); +rfifolock_lock(lock); +rfifolock_lock(lock); +rfifolock_lock(lock); +
[Qemu-devel] [PULL 09/24] aio: add aio_context_acquire() and aio_context_release()
It can be useful to run an AioContext from a thread which normally does not own the AioContext. For example, request draining can be implemented by acquiring the AioContext and looping aio_poll() until all requests have been completed. The following pattern should work: /* Event loop thread */ while (running) { aio_context_acquire(ctx); aio_poll(ctx, true); aio_context_release(ctx); } /* Another thread */ aio_context_acquire(ctx); bdrv_read(bs, 0x1000, buf, 1); aio_context_release(ctx); This patch implements aio_context_acquire() and aio_context_release(). Note that existing aio_poll() callers do not need to worry about acquiring and releasing - it is only needed when multiple threads will call aio_poll() on the same AioContext. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- async.c | 18 + include/block/aio.h | 18 + tests/test-aio.c| 58 + 3 files changed, 94 insertions(+) diff --git a/async.c b/async.c index 5fb3fa6..6930185 100644 --- a/async.c +++ b/async.c @@ -214,6 +214,7 @@ aio_ctx_finalize(GSource *source) thread_pool_free(ctx-thread_pool); aio_set_event_notifier(ctx, ctx-notifier, NULL); event_notifier_cleanup(ctx-notifier); +rfifolock_destroy(ctx-lock); qemu_mutex_destroy(ctx-bh_lock); g_array_free(ctx-pollfds, TRUE); timerlistgroup_deinit(ctx-tlg); @@ -250,6 +251,12 @@ static void aio_timerlist_notify(void *opaque) aio_notify(opaque); } +static void aio_rfifolock_cb(void *opaque) +{ +/* Kick owner thread in case they are blocked in aio_poll() */ +aio_notify(opaque); +} + AioContext *aio_context_new(void) { AioContext *ctx; @@ -257,6 +264,7 @@ AioContext *aio_context_new(void) ctx-pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD)); ctx-thread_pool = NULL; qemu_mutex_init(ctx-bh_lock); +rfifolock_init(ctx-lock, aio_rfifolock_cb, ctx); event_notifier_init(ctx-notifier, false); aio_set_event_notifier(ctx, ctx-notifier, (EventNotifierHandler *) @@ -275,3 +283,13 @@ void aio_context_unref(AioContext *ctx) { g_source_unref(ctx-source); } + +void aio_context_acquire(AioContext *ctx) +{ +rfifolock_lock(ctx-lock); +} + +void aio_context_release(AioContext *ctx) +{ +rfifolock_unlock(ctx-lock); +} diff --git a/include/block/aio.h b/include/block/aio.h index 2efdf41..a92511b 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -19,6 +19,7 @@ #include qemu/queue.h #include qemu/event_notifier.h #include qemu/thread.h +#include qemu/rfifolock.h #include qemu/timer.h typedef struct BlockDriverAIOCB BlockDriverAIOCB; @@ -47,6 +48,9 @@ typedef void IOHandler(void *opaque); struct AioContext { GSource source; +/* Protects all fields from multi-threaded access */ +RFifoLock lock; + /* The list of registered AIO handlers */ QLIST_HEAD(, AioHandler) aio_handlers; @@ -104,6 +108,20 @@ void aio_context_ref(AioContext *ctx); */ void aio_context_unref(AioContext *ctx); +/* Take ownership of the AioContext. If the AioContext will be shared between + * threads, a thread must have ownership when calling aio_poll(). + * + * Note that multiple threads calling aio_poll() means timers, BHs, and + * callbacks may be invoked from a different thread than they were registered + * from. Therefore, code must use AioContext acquire/release or use + * fine-grained synchronization to protect shared state if other threads will + * be accessing it simultaneously. + */ +void aio_context_acquire(AioContext *ctx); + +/* Relinquish ownership of the AioContext. */ +void aio_context_release(AioContext *ctx); + /** * aio_bh_new: Allocate a new bottom half structure. * diff --git a/tests/test-aio.c b/tests/test-aio.c index 592721e..d384b0b 100644 --- a/tests/test-aio.c +++ b/tests/test-aio.c @@ -112,6 +112,63 @@ static void test_notify(void) g_assert(!aio_poll(ctx, false)); } +typedef struct { +QemuMutex start_lock; +bool thread_acquired; +} AcquireTestData; + +static void *test_acquire_thread(void *opaque) +{ +AcquireTestData *data = opaque; + +/* Wait for other thread to let us start */ +qemu_mutex_lock(data-start_lock); +qemu_mutex_unlock(data-start_lock); + +aio_context_acquire(ctx); +aio_context_release(ctx); + +data-thread_acquired = true; /* success, we got here */ + +return NULL; +} + +static void dummy_notifier_read(EventNotifier *unused) +{ +g_assert(false); /* should never be invoked */ +} + +static void test_acquire(void) +{ +QemuThread thread; +EventNotifier notifier; +AcquireTestData data; + +/* Dummy event notifier ensures aio_poll() will block */ +event_notifier_init(notifier, false); +aio_set_event_notifier(ctx, notifier, dummy_notifier_read); +g_assert(!aio_poll(ctx, false)); /* consume aio_notify() */ + +
[Qemu-devel] [PULL 07/24] object: add object_get_canonical_path_component()
It is often useful to find an object's child property name. Also use this new function to simplify the implementation of object_get_canonical_path(). Reviewed-by: Andreas Färber afaer...@suse.de Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- include/qom/object.h | 8 qom/object.c | 54 +++- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index 9c7c361..4cd7704 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -974,6 +974,14 @@ const char *object_property_get_type(Object *obj, const char *name, Object *object_get_root(void); /** + * object_get_canonical_path_component: + * + * Returns: The final component in the object's canonical path. The canonical + * path is the path within the composition tree starting from the root. + */ +gchar *object_get_canonical_path_component(Object *obj); + +/** * object_get_canonical_path: * * Returns: The canonical path for a object. This is the path within the diff --git a/qom/object.c b/qom/object.c index 660859c..3290375 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1102,39 +1102,49 @@ void object_property_add_link(Object *obj, const char *name, g_free(full_type); } +gchar *object_get_canonical_path_component(Object *obj) +{ +ObjectProperty *prop = NULL; + +g_assert(obj); +g_assert(obj-parent != NULL); + +QTAILQ_FOREACH(prop, obj-parent-properties, node) { +if (!object_property_is_child(prop)) { +continue; +} + +if (prop-opaque == obj) { +return g_strdup(prop-name); +} +} + +/* obj had a parent but was not a child, should never happen */ +g_assert_not_reached(); +return NULL; +} + gchar *object_get_canonical_path(Object *obj) { Object *root = object_get_root(); -char *newpath = NULL, *path = NULL; +char *newpath, *path = NULL; while (obj != root) { -ObjectProperty *prop = NULL; - -g_assert(obj-parent != NULL); - -QTAILQ_FOREACH(prop, obj-parent-properties, node) { -if (!object_property_is_child(prop)) { -continue; -} +char *component = object_get_canonical_path_component(obj); -if (prop-opaque == obj) { -if (path) { -newpath = g_strdup_printf(%s/%s, prop-name, path); -g_free(path); -path = newpath; -} else { -path = g_strdup(prop-name); -} -break; -} +if (path) { +newpath = g_strdup_printf(%s/%s, component, path); +g_free(component); +g_free(path); +path = newpath; +} else { +path = component; } -g_assert(prop != NULL); - obj = obj-parent; } -newpath = g_strdup_printf(/%s, path); +newpath = g_strdup_printf(/%s, path ? path : ); g_free(path); return newpath; -- 1.8.5.3
[Qemu-devel] [PULL 10/24] iothread: add I/O thread object
This is a stand-in for Michael Roth's QContext. I expect this to be replaced once QContext is completed. The IOThread object is an AioContext event loop thread. This patch adds the concept of multiple event loop threads, allowing users to define them. When SMP guests run on SMP hosts it makes sense to instantiate multiple IOThreads. This spreads event loop processing across multiple cores. Note that additional patches are required to actually bind a device to an IOThread. [Andreas Färber afaer...@suse.de pointed out that the embedded parent object instance should be called parent_obj and have a newline afterwards. This patch has been changed to reflect this. -- Stefan] Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- Makefile.objs | 1 + include/sysemu/iothread.h | 30 iothread.c| 120 ++ 3 files changed, 151 insertions(+) create mode 100644 include/sysemu/iothread.h create mode 100644 iothread.c diff --git a/Makefile.objs b/Makefile.objs index 5cd3d81..a6e0e2a 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -39,6 +39,7 @@ libcacard-y += libcacard/vcardt.o ifeq ($(CONFIG_SOFTMMU),y) common-obj-y = blockdev.o blockdev-nbd.o block/ +common-obj-y += iothread.o common-obj-y += net/ common-obj-y += qdev-monitor.o device-hotplug.o common-obj-$(CONFIG_WIN32) += os-win32.o diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h new file mode 100644 index 000..a32214a --- /dev/null +++ b/include/sysemu/iothread.h @@ -0,0 +1,30 @@ +/* + * Event loop thread + * + * Copyright Red Hat Inc., 2013 + * + * Authors: + * Stefan Hajnoczi stefa...@redhat.com + * + * 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 IOTHREAD_H +#define IOTHREAD_H + +#include block/aio.h + +#define TYPE_IOTHREAD iothread + +typedef struct IOThread IOThread; + +#define IOTHREAD(obj) \ + OBJECT_CHECK(IOThread, obj, TYPE_IOTHREAD) + +IOThread *iothread_find(const char *id); +char *iothread_get_id(IOThread *iothread); +AioContext *iothread_get_aio_context(IOThread *iothread); + +#endif /* IOTHREAD_H */ diff --git a/iothread.c b/iothread.c new file mode 100644 index 000..c2d7af7 --- /dev/null +++ b/iothread.c @@ -0,0 +1,120 @@ +/* + * Event loop thread + * + * Copyright Red Hat Inc., 2013 + * + * Authors: + * Stefan Hajnoczi stefa...@redhat.com + * + * 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 qom/object.h +#include qom/object_interfaces.h +#include qemu/module.h +#include qemu/thread.h +#include block/aio.h +#include sysemu/iothread.h + +#define IOTHREADS_PATH /objects + +typedef ObjectClass IOThreadClass; +struct IOThread { +Object parent_obj; + +QemuThread thread; +AioContext *ctx; +bool stopping; +}; + +#define IOTHREAD_GET_CLASS(obj) \ + OBJECT_GET_CLASS(IOThreadClass, obj, TYPE_IOTHREAD) +#define IOTHREAD_CLASS(klass) \ + OBJECT_CLASS_CHECK(IOThreadClass, klass, TYPE_IOTHREAD) + +static void *iothread_run(void *opaque) +{ +IOThread *iothread = opaque; + +while (!iothread-stopping) { +aio_context_acquire(iothread-ctx); +while (!iothread-stopping aio_poll(iothread-ctx, true)) { +/* Progress was made, keep going */ +} +aio_context_release(iothread-ctx); +} +return NULL; +} + +static void iothread_instance_finalize(Object *obj) +{ +IOThread *iothread = IOTHREAD(obj); + +iothread-stopping = true; +aio_notify(iothread-ctx); +qemu_thread_join(iothread-thread); +aio_context_unref(iothread-ctx); +} + +static void iothread_complete(UserCreatable *obj, Error **errp) +{ +IOThread *iothread = IOTHREAD(obj); + +iothread-stopping = false; +iothread-ctx = aio_context_new(); + +/* This assumes we are called from a thread with useful CPU affinity for us + * to inherit. + */ +qemu_thread_create(iothread-thread, iothread_run, + iothread, QEMU_THREAD_JOINABLE); +} + +static void iothread_class_init(ObjectClass *klass, void *class_data) +{ +UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass); +ucc-complete = iothread_complete; +} + +static const TypeInfo iothread_info = { +.name = TYPE_IOTHREAD, +.parent = TYPE_OBJECT, +.class_init = iothread_class_init, +.instance_size = sizeof(IOThread), +.instance_finalize = iothread_instance_finalize, +.interfaces = (InterfaceInfo[]) { +{TYPE_USER_CREATABLE}, +{} +}, +}; + +static void iothread_register_types(void) +{ +type_register_static(iothread_info); +} + +type_init(iothread_register_types) + +IOThread *iothread_find(const char *id) +{ +Object *container = container_get(object_get_root(), IOTHREADS_PATH); +Object *child; + +child = object_property_get_link(container,
[Qemu-devel] [PULL 12/24] iothread: add iothread qdev property type
Add a iothread qdev property type so devices can be hooked up to an IOThread from the comand-line: qemu -object iothread,id=iothread0 \ -device some-device,x-iothread=iothread0 Note that Paolo Bonzini pbonz...@redhat.com has suggested using QOM links instead. This way the relationship between the objects is reflected in QOM. There are currently shortcomings of object_property_add_link() which prevent this use case. I will attempt to fix them and move to QOM links in a separate series. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/core/qdev-properties-system.c | 51 include/hw/qdev-properties.h | 3 +++ 2 files changed, 54 insertions(+) diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 878c3bc..de83561 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -18,6 +18,7 @@ #include net/hub.h #include qapi/visitor.h #include sysemu/char.h +#include sysemu/iothread.h static void get_pointer(Object *obj, Visitor *v, Property *prop, char *(*print)(void *ptr), @@ -385,6 +386,56 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) nd-instantiated = 1; } +/* --- iothread --- */ + +static char *print_iothread(void *ptr) +{ +return iothread_get_id(ptr); +} + +static int parse_iothread(DeviceState *dev, const char *str, void **ptr) +{ +IOThread *iothread; + +iothread = iothread_find(str); +if (!iothread) { +return -ENOENT; +} +object_ref(OBJECT(iothread)); +*ptr = iothread; +return 0; +} + +static void get_iothread(Object *obj, struct Visitor *v, void *opaque, + const char *name, Error **errp) +{ +get_pointer(obj, v, opaque, print_iothread, name, errp); +} + +static void set_iothread(Object *obj, struct Visitor *v, void *opaque, + const char *name, Error **errp) +{ +set_pointer(obj, v, opaque, parse_iothread, name, errp); +} + +static void release_iothread(Object *obj, const char *name, void *opaque) +{ +DeviceState *dev = DEVICE(obj); +Property *prop = opaque; +IOThread **ptr = qdev_get_prop_ptr(dev, prop); + +if (*ptr) { +object_unref(OBJECT(*ptr)); +} +} + +PropertyInfo qdev_prop_iothread = { +.name = iothread, +.get = get_iothread, +.set = set_iothread, +.release = release_iothread, +}; + static int qdev_add_one_global(QemuOpts *opts, void *opaque) { GlobalProperty *g; diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 0c0babf..3c000ee 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -22,6 +22,7 @@ extern PropertyInfo qdev_prop_bios_chs_trans; extern PropertyInfo qdev_prop_drive; extern PropertyInfo qdev_prop_netdev; extern PropertyInfo qdev_prop_vlan; +extern PropertyInfo qdev_prop_iothread; extern PropertyInfo qdev_prop_pci_devfn; extern PropertyInfo qdev_prop_blocksize; extern PropertyInfo qdev_prop_pci_host_devaddr; @@ -142,6 +143,8 @@ extern PropertyInfo qdev_prop_arraylen; DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NICPeers) #define DEFINE_PROP_DRIVE(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *) +#define DEFINE_PROP_IOTHREAD(_n, _s, _f) \ +DEFINE_PROP(_n, _s, _f, qdev_prop_iothread, IOThread *) #define DEFINE_PROP_MACADDR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr) #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \ -- 1.8.5.3
[Qemu-devel] [PULL 14/24] iothread: stash thread ID away
Keep the thread ID around so we can report it via QMP. There's only one problem: qemu_get_thread_id() (gettid() wrapper on Linux) must be called from the thread itself. There is no way to get the thread ID outside the thread. This patch uses a condvar to wait for iothread_run() to populate the thread_id inside the thread. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- iothread.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/iothread.c b/iothread.c index c2d7af7..ff46ea9 100644 --- a/iothread.c +++ b/iothread.c @@ -26,7 +26,10 @@ struct IOThread { QemuThread thread; AioContext *ctx; +QemuMutex init_done_lock; +QemuCond init_done_cond;/* is thread initialization done? */ bool stopping; +int thread_id; }; #define IOTHREAD_GET_CLASS(obj) \ @@ -38,6 +41,11 @@ static void *iothread_run(void *opaque) { IOThread *iothread = opaque; +qemu_mutex_lock(iothread-init_done_lock); +iothread-thread_id = qemu_get_thread_id(); +qemu_cond_signal(iothread-init_done_cond); +qemu_mutex_unlock(iothread-init_done_lock); + while (!iothread-stopping) { aio_context_acquire(iothread-ctx); while (!iothread-stopping aio_poll(iothread-ctx, true)) { @@ -55,6 +63,8 @@ static void iothread_instance_finalize(Object *obj) iothread-stopping = true; aio_notify(iothread-ctx); qemu_thread_join(iothread-thread); +qemu_cond_destroy(iothread-init_done_cond); +qemu_mutex_destroy(iothread-init_done_lock); aio_context_unref(iothread-ctx); } @@ -64,12 +74,24 @@ static void iothread_complete(UserCreatable *obj, Error **errp) iothread-stopping = false; iothread-ctx = aio_context_new(); +iothread-thread_id = -1; + +qemu_mutex_init(iothread-init_done_lock); +qemu_cond_init(iothread-init_done_cond); /* This assumes we are called from a thread with useful CPU affinity for us * to inherit. */ qemu_thread_create(iothread-thread, iothread_run, iothread, QEMU_THREAD_JOINABLE); + +/* Wait for initialization to complete */ +qemu_mutex_lock(iothread-init_done_lock); +while (iothread-thread_id == -1) { +qemu_cond_wait(iothread-init_done_cond, + iothread-init_done_lock); +} +qemu_mutex_unlock(iothread-init_done_lock); } static void iothread_class_init(ObjectClass *klass, void *class_data) -- 1.8.5.3
[Qemu-devel] [PULL 05/24] iotests: Test corruption during COW request
From: Max Reitz mre...@redhat.com Extend test file 060 by a test case for corruption occuring concurrently to a COW request. QEMU should not crash but rather return an appropriate error message. Signed-off-by: Max Reitz mre...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- tests/qemu-iotests/060 | 26 ++ tests/qemu-iotests/060.out | 15 +++ 2 files changed, 41 insertions(+) diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index af8ed9f..f0116aa 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -138,6 +138,32 @@ $QEMU_IMG snapshot -a foo $TEST_IMG _check_test_img $QEMU_IO -c $OPEN_RO -c read -P 1 0 512 | _filter_qemu_io +echo +echo === Testing overlap while COW is in flight === +echo +# compat=0.10 is required in order to make the following discard actually +# unallocate the sector rather than make it a zero sector - we want COW, after +# all. +IMGOPTS='compat=0.10' _make_test_img 1G +# Write two clusters, the second one enforces creation of an L2 table after +# the first data cluster. +$QEMU_IO -c 'write 0k 64k' -c 'write 512M 64k' $TEST_IMG | _filter_qemu_io +# Discard the first cluster. This cluster will soon enough be reallocated and +# used for COW. +$QEMU_IO -c 'discard 0k 64k' $TEST_IMG | _filter_qemu_io +# Now, corrupt the image by marking the second L2 table cluster as free. +poke_file $TEST_IMG '131084' \x00\x00 # 0x2000c +# Start a write operation requiring COW on the image stopping it right before +# doing the read; then, trigger the corruption prevention by writing anything to +# any unallocated cluster, leading to an attempt to overwrite the second L2 +# table. Finally, resume the COW write and see it fail (but not crash). +echo open -o file.driver=blkdebug $TEST_IMG +break cow_read 0 +aio_write 0k 1k +wait_break 0 +write 64k 64k +resume 0 | $QEMU_IO | _filter_qemu_io + # success, all done echo *** done rm -f $seq.full diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index 6c7bdbb..a517948 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -78,4 +78,19 @@ read 512/512 bytes at offset 0 No errors were found on the image. read 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=== Testing overlap while COW is in flight === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 65536/65536 bytes at offset 536870912 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +discard 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qcow2: Preventing invalid write on metadata (overlaps with active L2 table); image marked as corrupt. +blkdebug: Suspended request '0' +write failed: Input/output error +blkdebug: Resuming request '0' +aio_write failed: No medium found *** done -- 1.8.5.3
[Qemu-devel] [PULL 17/24] qcow2: Don't write with BDRV_O_INCOMING
From: Kevin Wolf kw...@redhat.com qcow2_open() causes writes when repairing an image with the dirty flag set and when clearing autoclear flags. It shouldn't do this when another qemu instance is still actively working on this image file. One effect of the bug is that images may have a cleared dirty flag while the migration source host still has it in use with lazy refcounts enabled, so refcounts are not accurate and the dirty flag must remain set. Signed-off-by: Kevin Wolf kw...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block/qcow2.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index ec23cc4..945c9d6 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -644,7 +644,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags, } /* Clear unknown autoclear feature bits */ -if (!bs-read_only s-autoclear_features != 0) { +if (!bs-read_only !(flags BDRV_O_INCOMING) s-autoclear_features) { s-autoclear_features = 0; ret = qcow2_update_header(bs); if (ret 0) { @@ -657,7 +657,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags, qemu_co_mutex_init(s-lock); /* Repair image if dirty */ -if (!(flags BDRV_O_CHECK) !bs-read_only +if (!(flags (BDRV_O_CHECK | BDRV_O_INCOMING)) !bs-read_only (s-incompatible_features QCOW2_INCOMPAT_DIRTY)) { BdrvCheckResult result = {0}; @@ -1137,10 +1137,12 @@ static void qcow2_close(BlockDriverState *bs) /* else pre-write overlap checks in cache_destroy may crash */ s-l1_table = NULL; -qcow2_cache_flush(bs, s-l2_table_cache); -qcow2_cache_flush(bs, s-refcount_block_cache); +if (!(bs-open_flags BDRV_O_INCOMING)) { +qcow2_cache_flush(bs, s-l2_table_cache); +qcow2_cache_flush(bs, s-refcount_block_cache); -qcow2_mark_clean(bs); +qcow2_mark_clean(bs); +} qcow2_cache_destroy(bs, s-l2_table_cache); qcow2_cache_destroy(bs, s-refcount_block_cache); -- 1.8.5.3
[Qemu-devel] [PULL 11/24] qdev: make get_pointer() handle temporary strings
From: Igor Mammedov imamm...@redhat.com get_pointer()'s print() callback might return a heap allocated string, to avoid adding dedicated get_pointer_foo for this case convert current print() callbacks to return temporary heap allocated string and make get_pointer() free it. Reviewed-by: Andreas Färber afaer...@suse.de Signed-off-by: Igor Mammedov imamm...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/core/qdev-properties-system.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 5f5957e..878c3bc 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -20,15 +20,16 @@ #include sysemu/char.h static void get_pointer(Object *obj, Visitor *v, Property *prop, -const char *(*print)(void *ptr), +char *(*print)(void *ptr), const char *name, Error **errp) { DeviceState *dev = DEVICE(obj); void **ptr = qdev_get_prop_ptr(dev, prop); char *p; -p = (char *) (*ptr ? print(*ptr) : ); +p = *ptr ? print(*ptr) : g_strdup(); visit_type_str(v, p, name, errp); +g_free(p); } static void set_pointer(Object *obj, Visitor *v, Property *prop, @@ -91,9 +92,9 @@ static void release_drive(Object *obj, const char *name, void *opaque) } } -static const char *print_drive(void *ptr) +static char *print_drive(void *ptr) { -return bdrv_get_device_name(ptr); +return g_strdup(bdrv_get_device_name(ptr)); } static void get_drive(Object *obj, Visitor *v, void *opaque, @@ -145,11 +146,12 @@ static void release_chr(Object *obj, const char *name, void *opaque) } -static const char *print_chr(void *ptr) +static char *print_chr(void *ptr) { CharDriverState *chr = ptr; +const char *val = chr-label ? chr-label : ; -return chr-label ? chr-label : ; +return g_strdup(val); } static void get_chr(Object *obj, Visitor *v, void *opaque, @@ -224,11 +226,12 @@ err: return ret; } -static const char *print_netdev(void *ptr) +static char *print_netdev(void *ptr) { NetClientState *netdev = ptr; +const char *val = netdev-name ? netdev-name : ; -return netdev-name ? netdev-name : ; +return g_strdup(val); } static void get_netdev(Object *obj, Visitor *v, void *opaque, -- 1.8.5.3
[Qemu-devel] [PULL 15/24] qmp: add query-iothreads command
The query-iothreads command returns a list of information about iothreads. See the patch for API documentation. Reviewed-by: Eric Blake ebl...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- iothread.c | 36 qapi-schema.json | 29 + qmp-commands.hx | 39 +++ 3 files changed, 104 insertions(+) diff --git a/iothread.c b/iothread.c index ff46ea9..0c38ebc 100644 --- a/iothread.c +++ b/iothread.c @@ -17,6 +17,7 @@ #include qemu/thread.h #include block/aio.h #include sysemu/iothread.h +#include qmp-commands.h #define IOTHREADS_PATH /objects @@ -140,3 +141,38 @@ AioContext *iothread_get_aio_context(IOThread *iothread) { return iothread-ctx; } + +static int query_one_iothread(Object *object, void *opaque) +{ +IOThreadInfoList ***prev = opaque; +IOThreadInfoList *elem; +IOThreadInfo *info; +IOThread *iothread; + +iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD); +if (!iothread) { +return 0; +} + +info = g_new0(IOThreadInfo, 1); +info-id = iothread_get_id(iothread); +info-thread_id = iothread-thread_id; + +elem = g_new0(IOThreadInfoList, 1); +elem-value = info; +elem-next = NULL; + +**prev = elem; +*prev = elem-next; +return 0; +} + +IOThreadInfoList *qmp_query_iothreads(Error **errp) +{ +IOThreadInfoList *head = NULL; +IOThreadInfoList **prev = head; +Object *container = container_get(object_get_root(), IOTHREADS_PATH); + +object_child_foreach(container, query_one_iothread, prev); +return head; +} diff --git a/qapi-schema.json b/qapi-schema.json index 6c381b7..be18642 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -883,6 +883,35 @@ { 'command': 'query-cpus', 'returns': ['CpuInfo'] } ## +# @IOThreadInfo: +# +# Information about an iothread +# +# @id: the identifier of the iothread +# +# @thread-id: ID of the underlying host thread +# +# Since: 2.0 +## +{ 'type': 'IOThreadInfo', + 'data': {'id': 'str', 'thread-id': 'int'} } + +## +# @query-iothreads: +# +# Returns a list of information about each iothread. +# +# Note this list excludes the QEMU main loop thread, which is not declared +# using the -object iothread command-line option. It is always the main thread +# of the process. +# +# Returns: a list of @IOThreadInfo for each iothread +# +# Since: 2.0 +## +{ 'command': 'query-iothreads', 'returns': ['IOThreadInfo'] } + +## # @BlockDeviceInfo: # # Information about the backing device for a block device. diff --git a/qmp-commands.hx b/qmp-commands.hx index d982cd6..a22621f 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2327,6 +2327,45 @@ EQMP }, SQMP +query-iothreads +--- + +Returns a list of information about each iothread. + +Note this list excludes the QEMU main loop thread, which is not declared +using the -object iothread command-line option. It is always the main thread +of the process. + +Return a json-array. Each iothread is represented by a json-object, which contains: + +- id: name of iothread (json-str) +- thread-id: ID of the underlying host thread (json-int) + +Example: + +- { execute: query-iothreads } +- { + return:[ + { +id:iothread0, +thread-id:3134 + }, + { +id:iothread1, +thread-id:3135 + } + ] + } + +EQMP + +{ +.name = query-iothreads, +.args_type = , +.mhandler.cmd_new = qmp_marshal_input_query_iothreads, +}, + +SQMP query-pci - -- 1.8.5.3
[Qemu-devel] [PULL 21/24] block/raw-posix: bdrv_parse_filename() for floppy
From: Max Reitz mre...@redhat.com The host_floppy protocol driver should strip the host_floppy: prefix from filenames if present. Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Benoit Canet ben...@irqsave.net Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block/raw-posix.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/block/raw-posix.c b/block/raw-posix.c index ab32ff9..4b8c183 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1844,6 +1844,15 @@ static BlockDriver bdrv_host_device = { }; #ifdef __linux__ +static void floppy_parse_filename(const char *filename, QDict *options, + Error **errp) +{ +/* The prefix is optional, just as for file. */ +strstart(filename, host_floppy:, filename); + +qdict_put_obj(options, filename, QOBJECT(qstring_from_str(filename))); +} + static int floppy_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -1949,6 +1958,7 @@ static BlockDriver bdrv_host_floppy = { .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, .bdrv_probe_device = floppy_probe_device, +.bdrv_parse_filename = floppy_parse_filename, .bdrv_file_open = floppy_open, .bdrv_close = raw_close, .bdrv_reopen_prepare = raw_reopen_prepare, -- 1.8.5.3
Re: [Qemu-devel] [PULL 0/6] acpi,pc,test bug fixes
On 11 March 2014 12:32, Michael S. Tsirkin m...@redhat.com wrote: The following changes since commit 220c8ed536491315b4040d820328b8dfd60d67a7: qemu: x86: ignore ioapic polarity (2014-03-09 21:09:38 +0200) are available in the git repository at: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream for you to fetch changes up to 13f65b2e1073cf7e2c8fb3880c77d8a53fa2f95e: acpi-test: update expected SSDT files (2014-03-11 13:27:27 +0200) Applied, thanks. -- PMM
Re: [Qemu-devel] [Qemu-stable] Patch Round-up for stable 1.7.1, freeze on 2013-02-27
04.03.2014 21:54, Michael Roth wrote: Sorry, it's been tagged for release already. The tarball/announcement should go out soon. Has it been released? Thanks, /mjt
[Qemu-devel] [PATCH] input: activate legacy kbd
Restores traditional behavior: Keyboard input will be routed to the most recently added keyboard. Without this all kbd input goes to the ps/2 keyboard, even if you add a usb keyboard to your guest. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/input-legacy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 7dc486b..1aa2605 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -333,6 +333,7 @@ QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) entry-opaque = opaque; entry-s = qemu_input_handler_register((DeviceState *)entry, legacy_kbd_handler); +qemu_input_handler_activate(entry-s); return entry; } -- 1.8.3.1
[Qemu-devel] [PULL 19/24] qemu-io: Fix warnings from static code analysis
From: Stefan Weil s...@weilnetz.de Smatch complains about several global symbols which should be local. Add the missing 'static' attributes and move the 'extern' declaration of variable qemuio_misalign to qemu-io.h. This variable also changes the type from 'int' to 'bool' which better fits documents its use. Signed-off-by: Stefan Weil s...@weilnetz.de Acked-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- include/qemu-io.h | 2 ++ qemu-io-cmds.c| 2 +- qemu-io.c | 7 +++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/qemu-io.h b/include/qemu-io.h index 7e7c07c..5d6006f 100644 --- a/include/qemu-io.h +++ b/include/qemu-io.h @@ -38,6 +38,8 @@ typedef struct cmdinfo { helpfunc_t help; } cmdinfo_t; +extern bool qemuio_misalign; + bool qemuio_command(BlockDriverState *bs, const char *cmd); void qemuio_add_command(const cmdinfo_t *ci); diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index f1de24c..fb1db53 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -16,7 +16,7 @@ #define CMD_NOFILE_OK 0x01 -int qemuio_misalign; +bool qemuio_misalign; static cmdinfo_t *cmdtab; static int ncmds; diff --git a/qemu-io.c b/qemu-io.c index fc38608..2d119c2 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -24,10 +24,9 @@ #define CMD_NOFILE_OK 0x01 -char *progname; +static char *progname; -BlockDriverState *qemuio_bs; -extern int qemuio_misalign; +static BlockDriverState *qemuio_bs; /* qemu-io commands passed using -c */ static int ncmdline; @@ -408,7 +407,7 @@ int main(int argc, char **argv) readonly = 1; break; case 'm': -qemuio_misalign = 1; +qemuio_misalign = true; break; case 'g': growable = 1; -- 1.8.5.3
[Qemu-devel] [PULL 24/24] block/raw-win32: bdrv_parse_filename() for hdev
From: Max Reitz mre...@redhat.com The host_device protocol driver should strip the host_device: prefix from filenames if present. Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Benoit Canet ben...@irqsave.net Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block/raw-win32.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/block/raw-win32.c b/block/raw-win32.c index 9954748..48cb2c2 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -593,6 +593,15 @@ static int hdev_probe_device(const char *filename) return 0; } +static void hdev_parse_filename(const char *filename, QDict *options, +Error **errp) +{ +/* The prefix is optional, just as for file. */ +strstart(filename, host_device:, filename); + +qdict_put_obj(options, filename, QOBJECT(qstring_from_str(filename))); +} + static int hdev_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -663,6 +672,7 @@ static BlockDriver bdrv_host_device = { .protocol_name = host_device, .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, +.bdrv_parse_filename = hdev_parse_filename, .bdrv_probe_device = hdev_probe_device, .bdrv_file_open= hdev_open, .bdrv_close= raw_close, -- 1.8.5.3
[Qemu-devel] [PULL 16/24] qcow2: Keep option in qcow2_invalidate_cache()
From: Kevin Wolf kw...@redhat.com Instead of manually building a list of all options from BDRVQcowState values just reuse the options that were used to open the image. qcow2_open() won't fully use all of the options in the QDict, but that's okay. This fixes all of the driver-specific options in qcow2, except for lazy-refcounts, which was special cased before. Signed-off-by: Kevin Wolf kw...@redhat.com Reviewed-by: Max Reitz mre...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block/qcow2.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index b5b1e8c..ec23cc4 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1178,11 +1178,8 @@ static void qcow2_invalidate_cache(BlockDriverState *bs) bdrv_invalidate_cache(bs-file); -options = qdict_new(); -qdict_put(options, QCOW2_OPT_LAZY_REFCOUNTS, - qbool_from_int(s-use_lazy_refcounts)); - memset(s, 0, sizeof(BDRVQcowState)); +options = qdict_clone_shallow(bs-options); qcow2_open(bs, options, flags, NULL); QDECREF(options); -- 1.8.5.3
Re: [Qemu-devel] WIP: Migration format: ASN.1/BER schema
On Fri, Mar 07, 2014 at 04:55:03PM +, Dr. David Alan Gilbert wrote: Hi, I've been looking at reviving the migration-as-ber work that Michael and Stefan looked at a while ago, and have stuff starting to work, but not ready yet, so I thought I'd start by posting my current view of an ASN.1 schema. Note this is my 1st attempt at ASN.1 so feel free to pick holes! This schema successfully passes asn1c and libtasn1's asn1Parser. I've currently got a visitor modified Qemu that generated apparently valid BER output (and compatible old-format) - unber and openssl asn1parse dump it apparently happily, but I've not been able to find a tool to verify it against the schema - suggestions welcome. (* libtasn1's asn1Decoder OOMs my laptop/and or spits out a DER error, not that I'm trying to encode as DER) Some notes: * I'm using the universal type codes for most things except the larger scale structures/sequences where I've given them our own types. * ASN type codes are disgustingly decimal, and even more disgustingly encoded in BER, so having things readable in a hex dump is difficult; although the values I've used end up with the last byte as an appropriate ASCII letter and the other bytes would be if the top bit wasn't set. * The 'shape' of it corresponds pretty closely to the shape of the existing migration format; although I intend to clean it up a bit - RAMSecEntry has the same flags that currently go into our binary format but those can become more of an enum, and sima). - I think SecFull/SecMin can probably merge together. * Most things are just sequences, including most of VMState; I don't really want to go around every VMState structure in the whole of QEMU allocating a type ID, however I'm thinking about making it an optional VMState field which I'd use if it was set. * The only thing that worries me in terms of efficiency so far is the 'page is all 0' compression encoding which is rather verbose, for everything else it seems that although it's chatty it's not that much of an overhead. * I've not looked at block migration or spapr yet, (the only other iterative migrate users) * anything with a .get/.put or using the old style migration registration gets bundled up into a blob as an octet-string - this means I don't have to fix everything before it can start working. As soon as I get the corresponding BER input visitor working and sweep the sawdust out of my code I'll post it; probably a week or two. Thoughts welcome, Dave I think this is already useful. For example this will make input parser more robust against unexpected input as octet string blobs are bounded, so if we fail to parse one we at least will not interpret it as beginning of the next one. I think it's a good idea to merge this gradually, even if this means changing format several times: as long as we can stay compatible with old machine types. Qemu {} DEFINITIONS IMPLICIT TAGS ::= BEGIN -- Some basic types used in multiple places -- QemuString ::= UTF8String (SIZE (1..255)) -- TODO: 4096 is actually page size whatever that is FullPage ::= OCTET STRING (SIZE (4096)) RAMBlockID ::= SEQUENCE { name QemuString, lenINTEGER is len needed here? } RAMSecEntry ::= [ APPLICATION 8914 ] SEQUENCE { addr INTEGER, -- Address or offset or size hmm so which one? flagsINTEGER, -- maybe more explicit type? name QemuString OPTIONAL, body CHOICE { bl SEQUENCE OF RAMBlockID, compr INTEGER (0..255), -- Page filled with this value page FullPage -- TODO xbzrle -- this one confused me. I expected RAMBlockID followed by a sequence of pages } } RAMSecList ::= [ APPLICATION 9810 ] SEQUENCE OF RAMSecEntry SubSection ::= [ APPLICATION 10707 ] SEQUENCE { name QemuString, versionidINTEGER, contents SEQUENCE OF VMStateEntries } SubSecList ::= [ APPLICATION 10700 ] SEQUENCE OF SubSection VMStateEntries ::= CHOICE { -- Hmm need to think more -- I'm guessing individual devices will have tagged entries here? dummyINTEGER, why is this here? subsecl SubSecList, oldblob OCTET STRING } VMState ::= SEQUENCE OF VMStateEntries -- Restrict to unsigned? SectionID ::= INTEGER SecFull ::= [ APPLICATION 2003 ] SEQUENCE { name QemuString, sectionidSectionID, what is this id exactly? instanceid INTEGER, versionidINTEGER, contents CHOICE { ramsec RAMSecList, -- TODO other iterator initial stuff -- vmstateVMState } } SecMin ::= [ APPLICATION 211 ] SEQUENCE { sectionid SectionID, contents CHOICE { ramsec SEQUENCE OF RAMSecEntry -- TODO other iterator general/end stuff --
[Qemu-devel] [PULL 02/24] block: Update image size in bdrv_invalidate_cache()
From: Kevin Wolf kw...@redhat.com After migration has completed, we call bdrv_invalidate_cache() so that drivers which cache some data drop their stale copy of the data and reread it from the image file to get a new version of data that the source modified while the migration was running. Reloading metadata from the image file is useless, though, if the size of the image file stays stale (this is a value that is cached for all image formats in block.c). Reads from (meta)data after the old EOF return only zeroes, causing image corruption. We need to update bs-total_sectors in all layers that could potentially have changed their size (i.e. backing files are not a concern - if they are changed, we're in bigger trouble) Signed-off-by: Kevin Wolf kw...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block.c | 10 +- block/qcow2.c | 2 ++ block/qed.c | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/block.c b/block.c index f1ef4b0..7b306fb 100644 --- a/block.c +++ b/block.c @@ -4776,9 +4776,17 @@ flush_parent: void bdrv_invalidate_cache(BlockDriverState *bs) { -if (bs-drv bs-drv-bdrv_invalidate_cache) { +if (!bs-drv) { +return; +} + +if (bs-drv-bdrv_invalidate_cache) { bs-drv-bdrv_invalidate_cache(bs); +} else if (bs-file) { +bdrv_invalidate_cache(bs-file); } + +refresh_total_sectors(bs, bs-total_sectors); } void bdrv_invalidate_cache_all(void) diff --git a/block/qcow2.c b/block/qcow2.c index cfe80be..b5b1e8c 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1176,6 +1176,8 @@ static void qcow2_invalidate_cache(BlockDriverState *bs) qcow2_close(bs); +bdrv_invalidate_cache(bs-file); + options = qdict_new(); qdict_put(options, QCOW2_OPT_LAZY_REFCOUNTS, qbool_from_int(s-use_lazy_refcounts)); diff --git a/block/qed.c b/block/qed.c index 8802ad3..837accd 100644 --- a/block/qed.c +++ b/block/qed.c @@ -1563,6 +1563,9 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs) BDRVQEDState *s = bs-opaque; bdrv_qed_close(bs); + +bdrv_invalidate_cache(bs-file); + memset(s, 0, sizeof(BDRVQEDState)); bdrv_qed_open(bs, NULL, bs-open_flags, NULL); } -- 1.8.5.3
[Qemu-devel] [PULL 18/24] block: Unlink temporary file
From: Max Reitz mre...@redhat.com If the image file cannot be opened and was created as a temporary file, it should be deleted; thus, in this case, we should jump to the unlink_and_fail label and not just to fail. Reported-by: Benoît Canet ben...@irqsave.net Signed-off-by: Max Reitz mre...@redhat.com Acked-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block.c b/block.c index cf5645a..fae50c9 100644 --- a/block.c +++ b/block.c @@ -1321,7 +1321,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, bdrv_open_flags(bs, flags | BDRV_O_UNMAP) | BDRV_O_PROTOCOL, true, local_err); if (ret 0) { -goto fail; +goto unlink_and_fail; } /* Find the right image format driver */ -- 1.8.5.3
[Qemu-devel] [PULL 20/24] block/raw-posix: bdrv_parse_filename() for hdev
From: Max Reitz mre...@redhat.com The host_device protocol driver should strip the host_device: prefix from filenames if present. Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Benoit Canet ben...@irqsave.net Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block/raw-posix.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/block/raw-posix.c b/block/raw-posix.c index e6b4c1f..ab32ff9 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1561,6 +1561,15 @@ static int check_hdev_writable(BDRVRawState *s) return 0; } +static void hdev_parse_filename(const char *filename, QDict *options, +Error **errp) +{ +/* The prefix is optional, just as for file. */ +strstart(filename, host_device:, filename); + +qdict_put_obj(options, filename, QOBJECT(qstring_from_str(filename))); +} + static int hdev_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -1805,6 +1814,7 @@ static BlockDriver bdrv_host_device = { .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, .bdrv_probe_device = hdev_probe_device, +.bdrv_parse_filename = hdev_parse_filename, .bdrv_file_open = hdev_open, .bdrv_close = raw_close, .bdrv_reopen_prepare = raw_reopen_prepare, -- 1.8.5.3
[Qemu-devel] [PULL 22/24] block/raw-posix: bdrv_parse_filename() for cdrom
From: Max Reitz mre...@redhat.com The host_cdrom protocol drivers should strip the host_cdrom: prefix from filenames if present. Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Benoit Canet ben...@irqsave.net Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block/raw-posix.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/block/raw-posix.c b/block/raw-posix.c index 4b8c183..697cd2e 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1983,7 +1983,20 @@ static BlockDriver bdrv_host_floppy = { .bdrv_media_changed = floppy_media_changed, .bdrv_eject = floppy_eject, }; +#endif +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +static void cdrom_parse_filename(const char *filename, QDict *options, + Error **errp) +{ +/* The prefix is optional, just as for file. */ +strstart(filename, host_cdrom:, filename); + +qdict_put_obj(options, filename, QOBJECT(qstring_from_str(filename))); +} +#endif + +#ifdef __linux__ static int cdrom_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -2070,6 +2083,7 @@ static BlockDriver bdrv_host_cdrom = { .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, .bdrv_probe_device = cdrom_probe_device, +.bdrv_parse_filename = cdrom_parse_filename, .bdrv_file_open = cdrom_open, .bdrv_close = raw_close, .bdrv_reopen_prepare = raw_reopen_prepare, @@ -2200,6 +2214,7 @@ static BlockDriver bdrv_host_cdrom = { .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, .bdrv_probe_device = cdrom_probe_device, +.bdrv_parse_filename = cdrom_parse_filename, .bdrv_file_open = cdrom_open, .bdrv_close = raw_close, .bdrv_reopen_prepare = raw_reopen_prepare, -- 1.8.5.3
[Qemu-devel] [PULL 03/24] qcow2: Check bs-drv in copy_sectors()
From: Max Reitz mre...@redhat.com Before dereferencing bs-drv for a call to its member bdrv_co_readv(), copy_sectors() should check whether that pointer is indeed valid, since it may have been set to NULL by e.g. a concurrent write triggering the corruption prevention mechanism. Signed-off-by: Max Reitz mre...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block/qcow2-cluster.c | 4 1 file changed, 4 insertions(+) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 36c1bed..9499df9 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -380,6 +380,10 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs, BLKDBG_EVENT(bs-file, BLKDBG_COW_READ); +if (!bs-drv) { +return -ENOMEDIUM; +} + /* Call .bdrv_co_readv() directly instead of using the public block-layer * interface. This avoids double I/O throttling and request tracking, * which can lead to deadlock when block layer copy-on-read is enabled. -- 1.8.5.3
Re: [Qemu-devel] [PATCH] block: do not allow read-only=on and snapshot=on to be used together
Am 24.01.2014 um 14:48 hat Jeff Cody geschrieben: On Fri, Jan 24, 2014 at 02:33:19PM +0100, Kevin Wolf wrote: Am 14.01.2014 um 20:12 hat Jeff Cody geschrieben: Having both read-only=on and snapshot=on together does not make sense; currently, the read-only argument is effectively ignored for the temporary snapshot. To prevent confusion, disallow the usage of both 'snapshot=on' and 'read-only=on'. Signed-off-by: Jeff Cody jc...@redhat.com This breaks in a surprising way: $ softmmu/qemu-system-x86_64 -drive file=~/images/hd.img,snapshot=on ... works fine ... $ qemu-system-x86_64 -drive file=~/images/hd.img -snapshot qemu-system-x86_64: invalid option combination: read-only and snapshot qemu-iotests case 051 catches this. I'll have to remove this patch and the follow-up from the queue for now. Odd - OK, I'll follow up on this and submit a series with both patches (well, likely squashed together), and whatever is needed to fix this as well. Jeff, what happened with this? I found the two patches in an old git branch and wondered why they didn't disappear in the rebase. But apparently we still allow read-only and snapshot at the same time. Kevin
[Qemu-devel] [PULL 23/24] block/raw-posix: Strip protocol prefix on creation
From: Max Reitz mre...@redhat.com The hdev_create() implementation in block/raw-posix.c is used by the host_device, host_cdrom and host_floppy protocol block drivers together. Thus, any of the associated prefixes may occur and exactly one should should be stripped, if it does (thus, host_device:host_cdrom:/dev/cdrom is not shortened to /dev/cdrom). Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Benoit Canet ben...@irqsave.net Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- block/raw-posix.c | 12 1 file changed, 12 insertions(+) diff --git a/block/raw-posix.c b/block/raw-posix.c index 697cd2e..1688e16 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1776,6 +1776,18 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options, int ret = 0; struct stat stat_buf; int64_t total_size = 0; +bool has_prefix; + +/* This function is used by all three protocol block drivers and therefore + * any of these three prefixes may be given. + * The return value has to be stored somewhere, otherwise this is an error + * due to -Werror=unused-value. */ +has_prefix = +strstart(filename, host_device:, filename) || +strstart(filename, host_cdrom: , filename) || +strstart(filename, host_floppy:, filename); + +(void)has_prefix; /* Read out options */ while (options options-name) { -- 1.8.5.3
[Qemu-devel] [PULL 13/24] dataplane: replace internal thread with IOThread
Today virtio-blk dataplane uses a 1:1 device-per-thread model. Now that IOThreads have been introduced we can generalize this to N:M devices per threads. This patch drops thread code from dataplane in favor of running inside an IOThread AioContext. As a bonus we solve the case where a guest keeps submitting I/O requests while dataplane is trying to stop. Previously the dataplane thread would continue to process requests until the request gave it a break. Now we can shut down in bounded time thanks to aio_context_acquire/release. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/block/dataplane/virtio-blk.c | 96 +++-- include/hw/virtio/virtio-blk.h | 8 +++- 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 2237edb..a5afc21 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -23,6 +23,7 @@ #include virtio-blk.h #include block/aio.h #include hw/virtio/virtio-bus.h +#include monitor/monitor.h /* for object_add() */ enum { SEG_MAX = 126, /* maximum number of I/O segments */ @@ -44,8 +45,6 @@ struct VirtIOBlockDataPlane { bool started; bool starting; bool stopping; -QEMUBH *start_bh; -QemuThread thread; VirtIOBlkConf *blk; int fd; /* image file descriptor */ @@ -59,12 +58,14 @@ struct VirtIOBlockDataPlane { * (because you don't own the file descriptor or handle; you just * use it). */ +IOThread *iothread; +bool internal_iothread; AioContext *ctx; EventNotifier io_notifier; /* Linux AIO completion */ EventNotifier host_notifier;/* doorbell */ IOQueue ioqueue;/* Linux AIO queue (should really be per - dataplane thread) */ + IOThread) */ VirtIOBlockRequest requests[REQ_MAX]; /* pool of requests, managed by the queue */ @@ -342,26 +343,7 @@ static void handle_io(EventNotifier *e) } } -static void *data_plane_thread(void *opaque) -{ -VirtIOBlockDataPlane *s = opaque; - -while (!s-stopping || s-num_reqs 0) { -aio_poll(s-ctx, true); -} -return NULL; -} - -static void start_data_plane_bh(void *opaque) -{ -VirtIOBlockDataPlane *s = opaque; - -qemu_bh_delete(s-start_bh); -s-start_bh = NULL; -qemu_thread_create(s-thread, data_plane_thread, - s, QEMU_THREAD_JOINABLE); -} - +/* Context: QEMU global mutex held */ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk, VirtIOBlockDataPlane **dataplane, Error **errp) @@ -408,12 +390,33 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk, s-fd = fd; s-blk = blk; +if (blk-iothread) { +s-internal_iothread = false; +s-iothread = blk-iothread; +object_ref(OBJECT(s-iothread)); +} else { +/* Create per-device IOThread if none specified */ +Error *local_err = NULL; + +s-internal_iothread = true; +object_add(TYPE_IOTHREAD, vdev-name, NULL, NULL, local_err); +if (error_is_set(local_err)) { +error_propagate(errp, local_err); +g_free(s); +return; +} +s-iothread = iothread_find(vdev-name); +assert(s-iothread); +} +s-ctx = iothread_get_aio_context(s-iothread); + /* Prevent block operations that conflict with data plane thread */ bdrv_set_in_use(blk-conf.bs, 1); *dataplane = s; } +/* Context: QEMU global mutex held */ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s) { if (!s) { @@ -422,9 +425,14 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s) virtio_blk_data_plane_stop(s); bdrv_set_in_use(s-blk-conf.bs, 0); +object_unref(OBJECT(s-iothread)); +if (s-internal_iothread) { +object_unparent(OBJECT(s-iothread)); +} g_free(s); } +/* Context: QEMU global mutex held */ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s) { BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s-vdev))); @@ -448,8 +456,6 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s) return; } -s-ctx = aio_context_new(); - /* Set up guest notifier (irq) */ if (k-set_guest_notifiers(qbus-parent, 1, true) != 0) { fprintf(stderr, virtio-blk failed to set guest notifier, @@ -464,7 +470,6 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s) exit(1); } s-host_notifier = *virtio_queue_get_host_notifier(vq); -aio_set_event_notifier(s-ctx, s-host_notifier, handle_notify); /* Set up ioqueue */ ioq_init(s-ioqueue, s-fd, REQ_MAX); @@ -472,7 +477,6 @@ void
Re: [Qemu-devel] 9pfs troubles (was Re: [PATCH 1/4] hw/9pfs: fix error handing in local_ioc_getversion())
On Fri, Feb 07, 2014 at 10:02:52AM +0100, Greg Kurz wrote: On Wed, 5 Feb 2014 23:31:11 +0200 Michael S. Tsirkin m...@redhat.com wrote: On Tue, Feb 04, 2014 at 12:51:25PM +0530, Aneesh Kumar K.V wrote: Michael S. Tsirkin m...@redhat.com writes: On Mon, Feb 03, 2014 at 03:05:10PM +0530, Aneesh Kumar K.V wrote: Michael S. Tsirkin m...@redhat.com writes: Haven't used 9pfs in a while. I thought these patches are a good time to play with it some more. I have encountered two issues. What I'm doing: host: qemu a75143eda2ddf581b51e96c000974bcdfe2cbd10. /scm/qemu/x86_64-softmmu/qemu-system-x86_64 -enable-kvm -m 1g -cpu kvm64 -smp 2 f20-x64.qcow2 -netdev user,id=foo -redir tcp:8022::22 -device virtio-net,netdev=foo -serial stdio -fsdev local,security_model=none,id=fsdev0,path=/lib/modules/ -device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=libmodulesshare -fsdev local,security_model=none,id=fsdev1,path=/boot -device virtio-9p-pci,id=fs1,fsdev=fsdev0,mount_tag=bootshare -no-reboot -snapshot guest: Fedora 20 added this in /etc/fstab: bootshare /share/boot 9p trans=virtio,version=9p2000.L 0 0 libmodulesshare /share/lib/modules 9p trans=virtio,version=9p2000.L 0 0 I have encountered two issues: 1. mount failure on boot If I try to mount on boot through fstab, I get: [2.270157] 9pnet: Could not find request transport: virtio [2.270158] 9pnet: Could not find request transport: virtio Missing 9pnet_virtio.ko module ? Maybe it's loaded too late. But when I get to plymouth prompt it's loaded fine. Any idea about this one? Do you have guests with 9pfs and virtio as modules and 9pfs mounted from /etc/fstab? Hi Michael, I had the very same problem. You probably need to add 9pnet_virtio to the initramfs. # mkinitrd -f --with=9pnet_virtio /boot/initramfs-$(uname -r).img $(uname -r) # gzip -dc /boot/initramfs-$(uname -r).img | cpio -t | grep 9pnet usr/lib/modules/3.11.7-200.fc19.ppc64p7/kernel/net/9p/9pnet_virtio.ko usr/lib/modules/3.11.7-200.fc19.ppc64p7/kernel/net/9p/9pnet.ko Cheers. This seems to help but why is this necessary in the initrd? After all I am not trying to boot from 9pfs. -- Gregory Kurz kurzg...@fr.ibm.com gk...@linux.vnet.ibm.com Software Engineer @ IBM/Meiosys http://www.ibm.com Tel +33 (0)562 165 496 Anarchy is about taking complete responsibility for yourself. Alan Moore.
Re: [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC)
On 03/09/2014 09:02 AM, Paolo Bonzini wrote: Il 07/03/2014 00:33, Alexander Graf ha scritto: From: Fabien Chouteau chout...@adacore.com This implementation doesn't include ring priority, TCP/IP Off-Load, QoS. Signed-off-by: Fabien Chouteau chout...@adacore.com Signed-off-by: Alexander Graf ag...@suse.de --- Is this code dead? Who uses it? A quick git grep etsec_create gave no results. I guess it could be integrated in hw/ppc/mpc8544ds.c
Re: [Qemu-devel] [PULL for-2.0 00/11] QMP queue
On 11 March 2014 13:41, Luiz Capitulino lcapitul...@redhat.com wrote: The following changes since commit c57ec3249e9839c7ea2e3789f6e40f9ec1c92f55: Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-5' into staging (2014-03-11 12:52:08 +) are available in the git repository at: git://repo.or.cz/qemu/qmp-unstable.git queue/qmp for you to fetch changes up to 2a7a1a56d1e30de07cf7d7636a35bf7706b9500e: tests: test-qmp-commands: Fix double free (2014-03-11 09:07:42 -0400) Applied, thanks. -- PMM
[Qemu-devel] [PATCH 1/1] Detect pthread_setname_np at configure time
From: Dr. David Alan Gilbert dgilb...@redhat.com Warn if no way of setting thread name is available. Signed-off-by: Dr. David Alan Gilbert dgilb...@redhat.com --- configure| 28 util/qemu-thread-posix.c | 21 ++--- util/qemu-thread-win32.c | 2 ++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 9539979..d349ba2 100755 --- a/configure +++ b/configure @@ -2709,6 +2709,24 @@ if test $mingw32 != yes -a $pthread = no; then Make sure to have the pthread libs and headers installed. fi +# check for pthread_setname_np +pthread_setname_np=no +cat $TMPC EOF +#include pthread.h + +static void *f(void *p) { return NULL; } +int main(void) +{ +pthread_t thread; +pthread_create(thread, 0, f, 0); +pthread_setname_np(thread, QEMU); +return 0; +} +EOF +if compile_prog $pthread_lib ; then + pthread_setname_np=yes +fi + ## # rbd probe if test $rbd != no ; then @@ -4636,6 +4654,16 @@ if test $rdma = yes ; then echo CONFIG_RDMA=y $config_host_mak fi +# Hold two types of flag: +# CONFIG_THREAD_SETNAME_BYTHREAD - we've got a way of setting the name on +# a thread we have a handle to +# CONFIG_PTHREAD_SETNAME_NP - A way of doing it on a particular +# platform +if test $pthread_setname_np = yes ; then + echo CONFIG_THREAD_SETNAME_BYTHREAD=y $config_host_mak + echo CONFIG_PTHREAD_SETNAME_NP=y $config_host_mak +fi + if test $tcg_interpreter = yes; then QEMU_INCLUDES=-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES elif test $ARCH = sparc64 ; then diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 960d7f5..d05a649 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -32,6 +32,13 @@ static bool name_threads; void qemu_thread_naming(bool enable) { name_threads = enable; + +#ifndef CONFIG_THREAD_SETNAME_BYTHREAD +/* This is a debugging option, not fatal */ +if (enable) { +fprintf(stderr, qemu: thread naming not supported on this host\n); +} +#endif } static void error_exit(int err, const char *msg) @@ -394,6 +401,16 @@ void qemu_event_wait(QemuEvent *ev) } } +/* Attempt to set the threads name; note that this is for debug, so + * we're not going to fail if we can't set it. + */ +static void qemu_thread_set_name(QemuThread *thread, const char *name) +{ +#ifdef CONFIG_PTHREAD_SETNAME_NP +pthread_setname_np(thread-thread, name); +#endif +} + void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void*), void *arg, int mode) @@ -420,11 +437,9 @@ void qemu_thread_create(QemuThread *thread, const char *name, if (err) error_exit(err, __func__); -#if defined(__GLIBC__) (__GLIBC__ 2 || (__GLIBC__ == 2 __GLIBC_MINOR__ = 12)) if (name_threads) { -pthread_setname_np(thread-thread, name); +qemu_thread_set_name(thread, name); } -#endif pthread_sigmask(SIG_SETMASK, oldset, NULL); diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index b9c957b..c405c9b 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -22,6 +22,8 @@ void qemu_thread_naming(bool enable) { /* But note we don't actually name them on Windows yet */ name_threads = enable; + +fprintf(stderr, qemu: thread naming not supported on this host\n); } static void error_exit(int err, const char *msg) -- 1.8.5.3
[Qemu-devel] [PATCH 0/1] configure time fix for thread naming on old glibc
From: Dr. David Alan Gilbert dgilb...@redhat.com Peter was preferring configure time detection of pthread_setname_np to guard against my recent breaking of builds on old libc. I've tested this on: Fedora 20 - modern glibc - works as before RHEL 5 - glibc 2.5: [dgilbert@davidgil-rhel5 try]$ ./bin/qemu-system-x86_64 -nographic -name debug-threads=on qemu: thread naming not supported on this host and checked a mingw windows cross build builds. A check on SLES11 is probably worth a try if someone has one to hand. Dr. David Alan Gilbert (1): Detect pthread_setname_np at configure time configure| 28 util/qemu-thread-posix.c | 21 ++--- util/qemu-thread-win32.c | 2 ++ 3 files changed, 48 insertions(+), 3 deletions(-) -- 1.8.5.3
Re: [Qemu-devel] [PATCH qom-next v2] qom-test: Test QOM properties
Am 12.03.2014 10:09, schrieb Markus Armbruster: Andreas Färber afaer...@suse.de writes: Recursively walk all properties under /machine and try to retrieve their value. This is a regression test for link properties and the DeviceState::hotpluggable property. Cf. be2f78b6b062eec5170e2612299fb8953046993f and 1a37eca107cece3ed454bae29eef0bd1fac4a244 I'm afraid the last sentence is too terse for me to understand. Commit hashes of a) link property bug fix and b) hotpluggable property introduction. Both were about segfaults. Signed-off-by: Andreas Färber afaer...@suse.de --- v2: Added g_test_message()s. Applying to qom-next. tests/qom-test.c | 43 +++ 1 file changed, 43 insertions(+) diff --git a/tests/qom-test.c b/tests/qom-test.c index b6671fb..4909258 100644 --- a/tests/qom-test.c +++ b/tests/qom-test.c @@ -10,6 +10,7 @@ #include glib.h #include string.h +#include qemu-common.h #include libqtest.h #include qemu/osdep.h #include qapi/qmp/types.h @@ -43,6 +44,44 @@ static bool is_blacklisted(const char *arch, const char *mach) return false; } +static void test_properties(const char *path) +{ +char *cmd, *child_path; +QDict *response, *tuple; +QList *list; +QListEntry *entry; + +g_test_message(Obtaining properties of %s, path); +cmd = g_strdup_printf({ 'execute': 'qom-list', +'arguments': { 'path': '%s' } }, path); +response = qmp(cmd); +g_free(cmd); +g_assert(response); + +g_assert(qdict_haskey(response, return)); +list = qobject_to_qlist(qdict_get(response, return)); +QLIST_FOREACH_ENTRY(list, entry) { +tuple = qobject_to_qdict(qlist_entry_obj(entry)); +if (strstart(qdict_get_str(tuple, type), child, NULL)) { +child_path = g_strdup_printf(%s/%s, + path, qdict_get_str(tuple, name)); +test_properties(child_path); +g_free(child_path); +} else { +const char *prop = qdict_get_str(tuple, name); +g_test_message(Testing property %s.%s, path, prop); +cmd = g_strdup_printf({ 'execute': 'qom-get', +'arguments': { 'path': '%s', + 'property': '%s' } }, + path, prop); +response = qmp(cmd); +g_free(cmd); +/* This may fail but should not, e.g., segfault. */ +g_assert(response); I'm not sure I get your comment. Executing qom-get may return a QMP error when accessing a property, but it may not crash. Therefore not much we can assert in the response. If a segfault occurs, the process is gone at this point. +} +} +} + static void test_machine(gconstpointer data) { const char *machine = data; @@ -51,8 +90,12 @@ static void test_machine(gconstpointer data) args = g_strdup_printf(-machine %s, machine); qtest_start(args); + +test_properties(/machine); + response = qmp({ 'execute': 'quit' }); g_assert(qdict_haskey(response, return)); + qtest_end(); g_free(args); } Looks like an excellent addition to the test suite. Thanks! Unfortunately adds to the main-loop warnings. 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] Disk I/O in QEMU
Hi Stefan, Thanks for your help. I find that the source code of qemu-1.2.0 doesn't have hw/block/. So I download the qemu-1.6.2. However it doesn't work. I run the configure like this: ./configure --enable-kvm --x86_64-softmmu then make and make install. I can start the vm using this command: qemu-system-x86_64 -m 1024 -smp 2 -hda my.img But the qemu is not using the kvm to accelerate. Then I add the -enable-kvm in the command. I connect to the vm via VNC. However, the vnc-viewer is just black and displays nothing. It used to work fine with qemu-1.2.0 (qemu-kvm). Of course, with qemu-kvm, there is no need to add the -enable-kvm option. So with qemu-1.6.2, did I miss any options? Thanks! 2014-03-11 20:23 GMT+08:00 Stefan Hajnoczi stefa...@gmail.com: On Tue, Mar 11, 2014 at 03:08:52PM +0800, Le Tan wrote: Hi, I am now studying the disk I/O in QEMU, but I know little about QEMU. I want to know how QEMU implements or emulates the disk I/O? Where to find some materials about this? And if I can get all the disk I/O request from the guest in QEMU? Thanks! QEMU emulates hardware including IDE or SCSI controllers. I/O requests go through QEMU. Look at hw/block/. Stefan
[Qemu-devel] [PATCH] MAINTAINERS: add self as MACHINE maintainer
'Machine as QOM object' feature produced a new file (machine.c). I am taking responsibility to maintain it (and others as needed). Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- MAINTAINERS | 5 + 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7efaccf..60b7e00 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -682,6 +682,11 @@ F: qom/cpu.c F: include/qom/cpu.h F: target-i386/cpu.c +MACHINE +M: Marcel Apfelbaum marce...@redhat.com +S: Supported +F: hw/core/machine.c + ICC Bus M: Igor Mammedov imamm...@redhat.com S: Supported -- 1.8.3.1
Re: [Qemu-devel] [PATCH v22 05/25] add some QemuOpts functions for replace work
On 03/11/2014 09:10 PM, Chunyan Liu wrote: Could be if changing qemu_opt_get return value type, but just as said before, that will affect many codes. Also, changing an existing function that returns 'const char *' into now returning 'char *' will NOT break any callers if the semantics remain unchanged (what WILL break is if the semantics change where the callers must now free the result) Yes, that's the only change, we need to free the result. There are more than 200 places using qemu_opt_get in existing code, we need to checkout the related files and free the result one by one. You can still write your helper function so that if 'del' is true, you strdup, if 'del' is false, you return the in-place memory. You'll have to cast away const in the helper, but qemu_opt_get can then restore the const and you don't have to adjust any existing callers, while still sharing the underlying implementation rather than duplicating code. But I guess I'll wait for v23 to see what you actually do in response to my suggestions. If nothing else, please document design decisions in your commit message (for example, if you choose to duplicate code rather than share code in a common helper, explain that the duplication is because one function returns malloc'd memory while the other returns in-place memory). -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH v3 2/2] virtio-serial-port: Convert to QOM realize/unrealize
Hi, I haven't really followed the whole discussion, so can't say much about it -- overall looks alright. A couple of minor nits: max_nr_ports = tswap32(port-vser-config.max_nr_ports); if (port-id = max_nr_ports) { -error_report(virtio-serial-bus: Out-of-range port id specified, max. allowed: %u, - max_nr_ports - 1); -return -1; +error_setg(errp, virtio-serial-bus: Out-of-range port id specified, + max. allowed: %u, + max_nr_ports - 1); indentation looks off. Just put this last line on the line above? diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h index 1d2040b..b1bc9e5 100644 --- a/include/hw/virtio/virtio-serial.h +++ b/include/hw/virtio/virtio-serial.h @@ -77,19 +77,19 @@ typedef struct VirtIOSerialPort VirtIOSerialPort; typedef struct VirtIOSerialPortClass { DeviceClass parent_class; -/* Is this a device that binds with hvc in the guest? */ -bool is_console; - /* - * The per-port (or per-app) init function that's called when a + * The per-port (or per-app) realize function that's called when a * new device is found on the bus. */ -int (*init)(VirtIOSerialPort *port); +DeviceRealize realize; /* - * Per-port exit function that's called when a port gets + * Per-port unrealize function that's called when a port gets * hot-unplugged or removed. */ -int (*exit)(VirtIOSerialPort *port); +DeviceUnrealize unrealize; + +/* Is this a device that binds with hvc in the guest? */ +bool is_console; is_console is moved unnecessarily? Amit
Re: [Qemu-devel] [PULL] target-sparc: Add and use CPU_FEATURE_CASA
On 12 March 2014 07:25, Mark Cave-Ayland mark.cave-ayl...@ilande.co.uk wrote: Hi Peter, This request contains just a single patch to add CPU_FEATURE_CASA for target-sparc. Please pull for 2.0. Applied, thanks. -- PMM
Re: [Qemu-devel] [PATCH] linux-user: Don't reserve space for commpage for AArch64
On Mon, Mar 10, 2014 at 12:59:17PM +, Peter Maydell wrote: AArch64 Linux, unlike AArch32, doesn't use a commpage. This means we should not be reserving room in the guest address space for one. Fixes LP:1287195. Looks good, Reviewed-by: Riku Voipio riku.voi...@linaro.org Reported-by: Amanieu d'Antras aman...@gmail.com Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- linux-user/elfload.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index c0687e3..cabfc14 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -352,6 +352,9 @@ enum ARM_HWCAP_ARM_VFPv3D16 = 1 13, }; +#ifndef TARGET_AARCH64 +/* The commpage only exists for 32 bit kernels */ + #define TARGET_HAS_VALIDATE_GUEST_SPACE /* Return 1 if the proposed guest space is suitable for the guest. * Return 0 if the proposed guest space isn't suitable, but another @@ -411,7 +414,7 @@ static int validate_guest_space(unsigned long guest_base, return 1; /* All good */ } - +#endif #define ELF_HWCAP get_elf_hwcap() -- 1.9.0
[Qemu-devel] [PATCH 1/4] vga: allow non-global vmstate
Need a way to opt-out from vga.vram being global vmstate, for secondary vga cards. Add a bool parameter to vga_common_init to support this. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/display/cirrus_vga.c | 4 ++-- hw/display/qxl.c| 2 +- hw/display/vga-isa-mm.c | 2 +- hw/display/vga-isa.c| 2 +- hw/display/vga-pci.c| 2 +- hw/display/vga.c| 4 ++-- hw/display/vga_int.h| 2 +- hw/display/vmware_vga.c | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 0d3127d..d1afc76 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -2913,7 +2913,7 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp) ISACirrusVGAState *d = ISA_CIRRUS_VGA(dev); VGACommonState *s = d-cirrus_vga.vga; -vga_common_init(s, OBJECT(dev)); +vga_common_init(s, OBJECT(dev), true); cirrus_init_common(d-cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0, isa_address_space(isadev), isa_address_space_io(isadev)); @@ -2960,7 +2960,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) int16_t device_id = pc-device_id; /* setup VGA */ - vga_common_init(s-vga, OBJECT(dev)); + vga_common_init(s-vga, OBJECT(dev), true); cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev), pci_address_space_io(dev)); s-vga.con = graphic_console_init(DEVICE(dev), 0, s-vga.hw_ops, s-vga); diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 47bbf1f..e9c54d7 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2061,7 +2061,7 @@ static int qxl_init_primary(PCIDevice *dev) qxl-id = 0; qxl_init_ramsize(qxl); vga-vram_size_mb = qxl-vga.vram_size 20; -vga_common_init(vga, OBJECT(dev)); +vga_common_init(vga, OBJECT(dev), true); vga_init(vga, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev), false); portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list, diff --git a/hw/display/vga-isa-mm.c b/hw/display/vga-isa-mm.c index afc46b8..4efc222 100644 --- a/hw/display/vga-isa-mm.c +++ b/hw/display/vga-isa-mm.c @@ -132,7 +132,7 @@ int isa_vga_mm_init(hwaddr vram_base, s = g_malloc0(sizeof(*s)); s-vga.vram_size_mb = VGA_RAM_SIZE 20; -vga_common_init(s-vga, NULL); +vga_common_init(s-vga, NULL, true); vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space); s-vga.con = graphic_console_init(NULL, 0, s-vga.hw_ops, s); diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c index 1d9ea6b..2b480bd 100644 --- a/hw/display/vga-isa.c +++ b/hw/display/vga-isa.c @@ -56,7 +56,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp) MemoryRegion *vga_io_memory; const MemoryRegionPortio *vga_ports, *vbe_ports; -vga_common_init(s, OBJECT(dev)); +vga_common_init(s, OBJECT(dev), true); s-legacy_address_space = isa_address_space(isadev); vga_io_memory = vga_init_io(s, OBJECT(dev), vga_ports, vbe_ports); isa_register_portio_list(isadev, 0x3b0, vga_ports, s, vga); diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index 574ea0e..ad49156 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -147,7 +147,7 @@ static int pci_std_vga_initfn(PCIDevice *dev) VGACommonState *s = d-vga; /* vga + console init */ -vga_common_init(s, OBJECT(dev)); +vga_common_init(s, OBJECT(dev), true); vga_init(s, OBJECT(dev), pci_address_space(dev), pci_address_space_io(dev), true); diff --git a/hw/display/vga.c b/hw/display/vga.c index 063319d..8891e0a 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -2252,7 +2252,7 @@ static const GraphicHwOps vga_ops = { .text_update = vga_update_text, }; -void vga_common_init(VGACommonState *s, Object *obj) +void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate) { int i, j, v, b; @@ -2289,7 +2289,7 @@ void vga_common_init(VGACommonState *s, Object *obj) s-is_vbe_vmstate = 1; memory_region_init_ram(s-vram, obj, vga.vram, s-vram_size); -vmstate_register_ram_global(s-vram); +vmstate_register_ram(s-vram, global_vmstate ? NULL : DEVICE(obj)); xen_register_framebuffer(s-vram); s-vram_ptr = memory_region_get_ram_ptr(s-vram); s-get_bpp = vga_get_bpp; diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index e641890..d42ac92 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -177,7 +177,7 @@ static inline int c6_to_8(int v) return (v 2) | (b 1) | b; } -void vga_common_init(VGACommonState *s, Object *obj); +void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate); void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space, MemoryRegion *address_space_io, bool init_vga_ports); MemoryRegion *vga_init_io(VGACommonState *s, Object *obj, diff
[Qemu-devel] [PATCH 0/4] vga: new display devices
Hi, This patch series adds new display devices. Number one is secondary-vga. That is identical to VGA (aka -vga std), except that it doesn't occupy all the legacy vga stuff (ioports, memory window @ 0xa), so you can have more than one of these in the system. It has one pci memory bar for the framebuffer and one mmio bar for registers. OVMF can drive it. Doesn't use it as console for some reason, but initializes it and the linux kernel will see it as efifb. Cutting edge linux kernels can drive it too (bochs-drm driver in 3.14+). Number two is virtio-gpu-pci. That is the virtio graphics card written by Dave Airlie. Only 2d for now, 3d support is to be tackled later on. Linux kernel driver: http://www.kraxel.org/cgit/linux/log/?h=virtio-vga-3d.kraxel http://cgit.freedesktop.org/~airlied/linux/log/?h=virtio-vga-3d Number three is virtio-vga. That is virtio-gpu-pci with all the vga compatibility fluff added. Firmware builder has cutting edge seavgabios.git packages which include a virtio vgabios for it, see http://www.kraxel.org/repos/ cheers, Gerd Dave Airlie (2): virtio-gpu: v0.3 of the virtio based GPU code. virtio-vga: v1 Gerd Hoffmann (2): vga: allow non-global vmstate vga: add secondary stdvga variant Makefile | 2 +- default-configs/x86_64-softmmu.mak | 2 + docs/specs/standard-vga.txt| 13 +- docs/specs/virtio-gpu.txt | 89 + hw/display/Makefile.objs | 4 + hw/display/cirrus_vga.c| 4 +- hw/display/qxl.c | 2 +- hw/display/vga-isa-mm.c| 2 +- hw/display/vga-isa.c | 2 +- hw/display/vga-pci.c | 63 +++- hw/display/vga.c | 8 +- hw/display/vga_int.h | 2 +- hw/display/virtgpu_hw.h| 149 hw/display/virtio-gpu-pci.c| 80 + hw/display/virtio-gpu.c| 689 + hw/display/virtio-vga.c| 169 + hw/display/vmware_vga.c| 2 +- hw/pci/pci.c | 2 + hw/virtio/virtio-pci.h | 15 + include/hw/pci/pci.h | 1 + include/hw/virtio/virtio-gpu.h | 91 + include/sysemu/sysemu.h| 2 +- pc-bios/vgabios-virtio.bin | Bin 0 - 40448 bytes roms/Makefile | 2 +- roms/config.vga.virtio | 6 + vl.c | 13 + 26 files changed, 1398 insertions(+), 16 deletions(-) create mode 100644 docs/specs/virtio-gpu.txt create mode 100644 hw/display/virtgpu_hw.h create mode 100644 hw/display/virtio-gpu-pci.c create mode 100644 hw/display/virtio-gpu.c create mode 100644 hw/display/virtio-vga.c create mode 100644 include/hw/virtio/virtio-gpu.h create mode 100644 pc-bios/vgabios-virtio.bin create mode 100644 roms/config.vga.virtio -- 1.8.3.1
[Qemu-devel] [PATCH 2/4] vga: add secondary stdvga variant
Add a standard vga variant which doesn't occupy any legacy ressources and thus can easily be used as secondary (or legacy-free) graphics adapter. Programming must be done using the MMIO bar. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- docs/specs/standard-vga.txt | 13 +++--- hw/display/vga-pci.c| 61 + hw/display/vga.c| 4 +++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/docs/specs/standard-vga.txt b/docs/specs/standard-vga.txt index 8a4c1e9..f82773e 100644 --- a/docs/specs/standard-vga.txt +++ b/docs/specs/standard-vga.txt @@ -5,9 +5,10 @@ QEMU Standard VGA Exists in two variants, for isa and pci. command line switches: --vga std[ picks isa for -M isapc, otherwise pci ] --device VGA [ pci variant ] --device isa-vga [ isa variant ] +-vga std [ picks isa for -M isapc, otherwise pci ] +-device VGA[ pci variant ] +-device isa-vga[ isa variant ] +-device secondary-vga [ legacy-free pci variant ] PCI spec @@ -31,9 +32,15 @@ PCI ROM Region: Holds the vgabios (qemu 0.14+). +The legacy-free variant has no ROM and has PCI_CLASS_DISPLAY_OTHER +instead of PCI_CLASS_DISPLAY_VGA. + + IO ports used - +Doesn't apply to the legacy-free pci variant, use the MMIO bar instead. + 03c0 - 03df : standard vga ports 01ce: bochs vbe interface index port 01cf: bochs vbe interface data port (x86 only) diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index ad49156..0865dc4 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -179,12 +179,51 @@ static int pci_std_vga_initfn(PCIDevice *dev) return 0; } +static int pci_secondary_vga_initfn(PCIDevice *dev) +{ +PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev); +VGACommonState *s = d-vga; + +/* vga + console init */ +vga_common_init(s, OBJECT(dev), false); +s-con = graphic_console_init(DEVICE(dev), 0, s-hw_ops, s); + +/* mmio bar */ +memory_region_init(d-mmio, OBJECT(dev), vga.mmio, 4096); +memory_region_init_io(d-ioport, OBJECT(dev), pci_vga_ioport_ops, d, + vga ioports remapped, PCI_VGA_IOPORT_SIZE); +memory_region_init_io(d-bochs, OBJECT(dev), pci_vga_bochs_ops, d, + bochs dispi interface, PCI_VGA_BOCHS_SIZE); + +memory_region_add_subregion(d-mmio, PCI_VGA_IOPORT_OFFSET, +d-ioport); +memory_region_add_subregion(d-mmio, PCI_VGA_BOCHS_OFFSET, +d-bochs); + +pci_register_bar(d-dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, s-vram); +pci_register_bar(d-dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, d-mmio); + +return 0; +} + +static void pci_secondary_vga_reset(DeviceState *dev) +{ +PCIVGAState *d = DO_UPCAST(PCIVGAState, dev.qdev, dev); + +vga_common_reset(d-vga); +} + static Property vga_pci_properties[] = { DEFINE_PROP_UINT32(vgamem_mb, PCIVGAState, vga.vram_size_mb, 16), DEFINE_PROP_BIT(mmio, PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, true), DEFINE_PROP_END_OF_LIST(), }; +static Property secondary_pci_properties[] = { +DEFINE_PROP_UINT32(vgamem_mb, PCIVGAState, vga.vram_size_mb, 16), +DEFINE_PROP_END_OF_LIST(), +}; + static void vga_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -201,6 +240,20 @@ static void vga_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_DISPLAY, dc-categories); } +static void secondary_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + +k-init = pci_secondary_vga_initfn; +k-vendor_id = PCI_VENDOR_ID_QEMU; +k-device_id = PCI_DEVICE_ID_QEMU_VGA; +k-class_id = PCI_CLASS_DISPLAY_OTHER; +dc-vmsd = vmstate_vga_pci; +dc-props = secondary_pci_properties; +dc-reset = pci_secondary_vga_reset; +} + static const TypeInfo vga_info = { .name = VGA, .parent= TYPE_PCI_DEVICE, @@ -208,9 +261,17 @@ static const TypeInfo vga_info = { .class_init= vga_class_init, }; +static const TypeInfo secondary_info = { +.name = secondary-vga, +.parent= TYPE_PCI_DEVICE, +.instance_size = sizeof(PCIVGAState), +.class_init= secondary_class_init, +}; + static void vga_register_types(void) { type_register_static(vga_info); +type_register_static(secondary_info); } type_init(vga_register_types) diff --git a/hw/display/vga.c b/hw/display/vga.c index 8891e0a..c4c3238 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -171,6 +171,10 @@ static void vga_update_memory_access(VGACommonState *s) MemoryRegion *region, *old_region = s-chain4_alias; hwaddr base, offset, size; +if (s-legacy_address_space == NULL) { +return; +} + s-chain4_alias =
[Qemu-devel] [PATCH 3/4] virtio-gpu: v0.3 of the virtio based GPU code.
From: Dave Airlie airl...@redhat.com This is the basic virtio-gpu which is multi-head capable, ARGB cursor support, unaccelerated. Some more info is in docs/specs/virtio-gpu.txt. Signed-off-by: Dave Airlie airl...@redhat.com changes by kraxel: * adapt to changes in master. * move from hw/virtio to hw/display. * codestyle cleanups. * misc minor fixes. Signed-off-by: Gerd Hoffmann kra...@redhat.com virtio-gpu codestyle --- default-configs/x86_64-softmmu.mak | 1 + docs/specs/virtio-gpu.txt | 89 + hw/display/Makefile.objs | 3 + hw/display/virtgpu_hw.h| 149 hw/display/virtio-gpu-pci.c| 80 + hw/display/virtio-gpu.c| 689 + hw/virtio/virtio-pci.h | 15 + include/hw/pci/pci.h | 1 + include/hw/virtio/virtio-gpu.h | 91 + 9 files changed, 1118 insertions(+) create mode 100644 docs/specs/virtio-gpu.txt create mode 100644 hw/display/virtgpu_hw.h create mode 100644 hw/display/virtio-gpu-pci.c create mode 100644 hw/display/virtio-gpu.c create mode 100644 include/hw/virtio/virtio-gpu.h diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 31bddce..1a00b78 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -9,6 +9,7 @@ CONFIG_VGA_PCI=y CONFIG_VGA_ISA=y CONFIG_VGA_CIRRUS=y CONFIG_VMWARE_VGA=y +CONFIG_VIRTIO_GPU=y CONFIG_VMMOUSE=y CONFIG_SERIAL=y CONFIG_PARALLEL=y diff --git a/docs/specs/virtio-gpu.txt b/docs/specs/virtio-gpu.txt new file mode 100644 index 000..987d807 --- /dev/null +++ b/docs/specs/virtio-gpu.txt @@ -0,0 +1,89 @@ +Initial info on virtio-gpu: + +virtio-gpu is a virtio based graphics adapter. The initial version provides support for: + +- ARGB Hardware cursors +- multiple outputs + +There are no acceleration features available in the first release of this device, 3D acceleration features will be provided later via an interface to an external renderer. + +The virtio-gpu exposes 3 vqs to the guest, + +1) control vq - guest-host queue for sending commands and getting responses when required. +2) cursor vq - guest-host queue for sending cursor position and resource updates +3) event vq - host-guest queue for sending async events like display topography updates and errors (todo). + +How to use the virtio-gpu: + +The virtio-gpu is based around the concept of resources private to the host, the guest must DMA transfer into these resources. This is a design requirement in order to interface with future 3D rendering. In the unaccelerated there is no support for DMA transfers from resources, just to them. + +Resources are initially simple 2D resources, consisting of a width, height and format along with an identifier. The guest must then attach backing store to the resources in order for DMA transfers to work. This is like a GART in a real GPU. + +A typical guest user would create a 2D resource using VIRTGPU_CMD_RESOURCE_CREATE_2D, attach backing store using VIRTGPU_CMD_RESOURCE_ATTACH_BACKING, then attach the resource to a scanout using VIRTGPU_CMD_SET_SCANOUT, then use VIRTGPU_CMD_TRANSFER_SEND_2D to send updates to the resource, and finally VIRTGPU_CMD_RESOURCE_FLUSH to flush the scanout buffers to screen. + +Command queue: + +VIRTGPU_CMD_GET_DISPLAY_INFO: +Retrieve the current output configuration. + +This sends a response in the same queue slot. The response contains the max number of scanouts the host can support, +along with a list of per-scanout information. The info contains whether the +scanout is enabled, what its preferred x, y, width and height are and some future flags. + +VIRTGPU_CMD_RESOURCE_CREATE_2D: +Create a 2D resource on the host. + +This creates a 2D resource on the host with the specified width, height and format. Only a small subset of formats are support. The resource ids are generated by the guest. + +VIRTGPU_CMD_RESOURCE_UNREF: +Destroy a resource. + +This informs the host that a resource is no longer required by the guest. + +VIRTGPU_CMD_SET_SCANOUT: +Set the scanout parameters for a single output. + +This sets the scanout parameters for a single scanout. The resource_id is the +resource to be scanned out from, along with a rectangle specified by x, y, width and height. + +VIRTGPU_CMD_RESOURCE_FLUSH: +Flush a scanout resource + +This flushes a resource to screen, it takes a rectangle and a resource id, +and flushes any scanouts the resource is being used on. + +VIRTGPU_CMD_TRANSFER_TO_HOST_2D: +Transfer from guest memory to host resource. + +This takes a resource id along with an destination offset into the resource, +and a box to transfer from the host backing for the resource. + +VIRTGPU_CMD_RESOURCE_ATTACH_BACKING: +Assign backing pages to a resource. + +This assign an array of guest pages as the backing store for a resource. These +pages are then used for the transfer operations for that resource from that