Re: [Qemu-devel] [PATCH V2 06/11] virtio-s390: switch to bus specific queue limit
On Fri, Feb 27, 2015 at 5:49 PM, Cornelia Huck cornelia.h...@de.ibm.com wrote: On Fri, 27 Feb 2015 06:42:57 +0008 Jason Wang jasow...@redhat.com wrote: On Thu, Feb 26, 2015 at 9:05 PM, Cornelia Huck cornelia.h...@de.ibm.com wrote: On Thu, 26 Feb 2015 15:04:41 +0800 Jason Wang jasow...@redhat.com wrote: typedef struct AdapterRoutes { AdapterInfo adapter; int num_routes; -int gsi[VIRTIO_PCI_QUEUE_MAX]; +int gsi[VIRTIO_S390_QUEUE_MAX]; Adapter routes are only applicable for the ccw transport, not for the old s390 transport. Sure, will fix this. (I'm also wondering whether this should be the generic limit instead.) As you pointed out in V1, there will be more issues if we just increase the generic limit. So I switch to use per transport limit. Since the limit was not changed for both s390 and ccw, it should be ok. I'm just wondering how many gsis we want to support for adapter routes. They were introduced for virtio-ccw, but recently s390 pci has started to use them as well, so a virtio limit seems silly here. I'll switch them to some kind of generic limit instead, I think. Get your point. My understanding is you can do this on top of this series. Thanks
Re: [Qemu-devel] [PATCH V2 04/11] virtio-ccw: introduce ccw specific queue limit
On Fri, Feb 27, 2015 at 5:41 PM, Cornelia Huck cornelia.h...@de.ibm.com wrote: On Fri, 27 Feb 2015 03:46:25 +0008 Jason Wang jasow...@redhat.com wrote: On Thu, Feb 26, 2015 at 9:02 PM, Cornelia Huck cornelia.h...@de.ibm.com wrote: On Thu, 26 Feb 2015 15:04:39 +0800 Jason Wang jasow...@redhat.com wrote: Instead of depending on marco, using a bus specific limit. Cc: Alexander Graf ag...@suse.de Cc: Cornelia Huck cornelia.h...@de.ibm.com Cc: Christian Borntraeger borntrae...@de.ibm.com Cc: Richard Henderson r...@twiddle.net Signed-off-by: Jason Wang jasow...@redhat.com --- hw/s390x/s390-virtio-ccw.c | 7 +-- hw/s390x/virtio-ccw.c | 13 +++-- include/hw/virtio/virtio.h | 1 + 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 71bafe0..6aeb815 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -43,6 +43,7 @@ void io_subsystem_reset(void) static int virtio_ccw_hcall_notify(const uint64_t *args) { +VirtIODevice *vdev; uint64_t subch_id = args[0]; uint64_t queue = args[1]; SubchDev *sch; @@ -55,10 +56,12 @@ static int virtio_ccw_hcall_notify(const uint64_t *args) if (!sch || !css_subch_visible(sch)) { return -EINVAL; } -if (queue = VIRTIO_PCI_QUEUE_MAX) { + +vdev = virtio_ccw_get_vdev(sch); +if (queue = virtio_get_queue_max(vdev)) { But we already know we have a virtio_ccw device, right? So why not just check against VIRTIO_CCW_QUEUE_MAX? The problem is whether or not you want to increase the max queue for ccw. If yes, for migration compatibility, you could not just use a marco here since legacy machine type will also get increased. Confused. With legacy machine type, do you mean s390-virtio? It does not register this hcall. Ok, I thought s390 may have something like pc had to keep the migration compatibility for migration. But seems not. Something dynamically like this is need so the machine initialization code can change this limit. I fear I don't understand how the machine code comes into play here. Is the virtio-ccw device code supposed to inherit the limit from the machine? As I said in the previous reply. The machine code is used to keep migration compatibility. We don't want to break the migration from 2.3 to 2.2. If the limit of ccw will be increased in the future and we want to keep migration compatibility. The machine codes may do something similar to virtio pci. Anyway, if we move the queue limit to the VirtIODevice, checking the limit there instead of using a #define should work out fine.
Re: [Qemu-devel] [PATCH v2] migration: Convert 'status' of MigrationInfo to use an enum type
On 2015/2/28 1:42, Eric Blake wrote: On 02/27/2015 10:07 AM, Dr. David Alan Gilbert wrote: Rather than pollute the user-exposed enum with a state that we will never report, can we come up with some internal-only method for tracking cancelling separate from the enum? Well I guess we could just report it; but would that break any external tools? It might - I seem to recall in the past that when we added a new state string, that at least libvirt choked when encountering the unknown string (but I don't recall if it was migration or something else). At least libvirt already has an enum tracking: enum { QEMU_MONITOR_MIGRATION_STATUS_INACTIVE, QEMU_MONITOR_MIGRATION_STATUS_ACTIVE, QEMU_MONITOR_MIGRATION_STATUS_COMPLETED, QEMU_MONITOR_MIGRATION_STATUS_ERROR, QEMU_MONITOR_MIGRATION_STATUS_CANCELLED, QEMU_MONITOR_MIGRATION_STATUS_SETUP, QEMU_MONITOR_MIGRATION_STATUS_LAST }; and a string mapping of just the following states: VIR_ENUM_IMPL(qemuMonitorMigrationStatus, QEMU_MONITOR_MIGRATION_STATUS_LAST, inactive, active, completed, failed, cancelled, setup) Furthermore, the function qemuMigrationUpdateJobStatus() is doing various things depending on the observed state, where the current trick of treating 'cancelling' like 'active' would mean that changing 'cancelling' to be an independent state WOULD have observable behavior change in libvirt. But I don't know if the change would break things, Er, i have tested with returning 'cancelling' to users, and only when we try to cancel a migration, libvirt sometimes will report : Migration: [ 69 %]^Cerror: internal error: unexpected migration status in cancelling. But the cancelling process is still completed. And, yes, it is very rare, depend on the time window. (In my test, i add a sleep of 5s to extend the time between cancelling and cancelled.) or if it would still end up resolving nicely (after all, cancelling only occurs for a short window before the migration aborts anyway, so it might just sort itself out when it finally gets to cancelled). On the other hand, we can argue that clients that are unprepared to handle new enum states gracefully are broken, and we also have the argument that it is okay for a new qemu to require a new libvirt release (the other direction is not okay - a new libvirt must not require Agreed, upgrade libvirt is reasonable. So, should i send v3 with exposing 'cancelling'to user, and CC libvirt ? Thanks. upgrading to a new qemu). So exposing 'cancelling' may make this patch easier.
Re: [Qemu-devel] [PATCH 1/6 v4] target-tilegx: Firstly add to qemu with minimized features
On 2/27/2015 9:10 PM, Chen Gang S wrote: By the way, does Gx8000 mean 8000 core count? It's marketing, so it doesn't have to mean anything. The TILE-Gx 8036 is the 36-core part, the 8072 is the 72-core part, 8009 is the 9-core part, etc. There is no 8000 chip, it's just a way of describing the TILE-Gx chip series. -- Chris Metcalf, EZChip Semiconductor http://www.ezchip.com
Re: [Qemu-devel] [PATCH v4 05/11] block: Move BDS close notifiers into BB
On Fri, 02/27 11:43, Max Reitz wrote: static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -763,12 +794,26 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, SCSIDevice *sd = SCSI_DEVICE(dev); if (s-ctx !s-dataplane_disabled) { +VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier; + +insert_notifier = g_new0(VirtIOSCSIBlkChangeNotifier, 1); +insert_notifier-n.notify = virtio_scsi_blk_insert_notifier; +insert_notifier-s = s; +insert_notifier-sd = sd; +blk_add_insert_bs_notifier(sd-conf.blk, insert_notifier-n); +QTAILQ_INSERT_TAIL(s-insert_notifiers, insert_notifier, next); Could you instead embed a Notifier into SCSIDevice, similarly? That way there is no need to maintain a list in VirtIOSCSI. + +remove_notifier = g_new0(VirtIOSCSIBlkChangeNotifier, 1); +remove_notifier-n.notify = virtio_scsi_blk_remove_notifier; +remove_notifier-s = s; +remove_notifier-sd = sd; +blk_add_remove_bs_notifier(sd-conf.blk, remove_notifier-n); +QTAILQ_INSERT_TAIL(s-remove_notifiers, remove_notifier, next); + if (blk_op_is_blocked(sd-conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { return; } -assert(!s-blocker); -error_setg(s-blocker, block device is in use by data plane); -blk_op_block_all(sd-conf.blk, s-blocker); +virtio_scsi_set_up_op_blockers(s, sd); } Fam
Re: [Qemu-devel] [PATCH v2] migration: Convert 'status' of MigrationInfo to use an enum type
On 2015/2/28 0:48, Eric Blake wrote: On 02/26/2015 11:19 PM, zhanghailiang wrote: The original 'status' is an open-coded 'str' type, convert it to use an enum type. This conversion is backwards compatible, better documented and more convenient for future extensibility. In addition, Fix a typo for qapi-schema.json: comppleted - completed Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- v2: - Remove '(since xyz)' strings. (Eric Blake) --- hmp.c | 7 --- migration/migration.c | 37 +++-- qapi-schema.json | 37 - 3 files changed, 51 insertions(+), 30 deletions(-) case MIG_STATE_ACTIVE: case MIG_STATE_CANCELLING: info-has_status = true; -info-status = g_strdup(active); +/* Note: when the real state of migration is 'cancelling', + we still return 'active' status to user, it makes no difference + for user. */ Rather than pollute the user-exposed enum with a state that we will never report, can we come up with some internal-only method for tracking cancelling separate from the enum? +++ b/qapi-schema.json @@ -411,18 +411,45 @@ 'overflow': 'int' } } ## +# @MigState: Do we have to abbreviate? I guess leaving it like this makes the rest of the existing code base have less churn (since it matches the spelling of the enum that was previous interanl only), but it might look nicer as Yes, this is the reason ..., agreed, i don't like the abbreviate, But there is already a 'MigrationState' type defined: typedef struct MigrationState MigrationState; struct MigrationState { int64_t bandwidth_limit; size_t bytes_xfer; size_t xfer_limit; QemuThread thread; QEMUBH *cleanup_bh; QEMUFile *file; ... So, what about MigrationStatus ? ;) MigrationState. If you do decide to go with a longer name, it might be nice to split this into a series, one patch that does only renames to migration.c (but no code additions outside of that file), and the other that moves the (now-correctly-named) enum into the public qapi file. +# +# An enumeration of migration status. +# +# @failed: some error occurred during migration process. +# +# @none: no migration has ever happened. +# +# @setup: migration process has been initiated. +# +# @cancelling: in the process of cancelling migration. +# If the user can never see this state, I'd rather we think about a solution that avoids advertising the state in the public api... +# @cancelled: cancelling migration is finished. +# +# @active: in the process of doing migration. +# +# @completed: migration is finished. +# +# Since: 2.3 +# +# Notes: @cancelling is only used internally, and return @active to user +#instead of @cancelling, it make no difference for users. ...rather than needing this note to air our dirty laundry.
Re: [Qemu-devel] [PATCH V2 03/11] virito: introduce bus specific queue limit
On Fri, Feb 27, 2015 at 5:34 PM, Cornelia Huck cornelia.h...@de.ibm.com wrote: On Fri, 27 Feb 2015 03:42:00 +0008 Jason Wang jasow...@redhat.com wrote: On Thu, Feb 26, 2015 at 8:57 PM, Cornelia Huck cornelia.h...@de.ibm.com wrote: On Thu, 26 Feb 2015 15:04:38 +0800 Jason Wang jasow...@redhat.com wrote: This patch introduces a bus specific queue limitation. It will be useful for increasing the limit for one of the bus without disturbing other buses. diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index ffc22e8..5a806b5 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -541,6 +541,14 @@ void virtio_update_irq(VirtIODevice *vdev) virtio_notify_vector(vdev, VIRTIO_NO_VECTOR); } +int virtio_get_queue_max(VirtIODevice *vdev) +{ +BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); +VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); + +return k-queue_max; +} + Are all callers of this in the slow path? So we don't introduce processing overhead. Looks not. For overhead, do you mean one introduced by VIRTIO_BUS_GET_CLASS()? Not sure how much it will affact but we've already used something like this in the datapath, e.g virtio_notify_vector(). I may have misremembered how much overhead those types of operation introduce. But it made me think: This function is basically introducing a per-VirtIODevice queue limit. We set it once in the VirtioBusClass during initialization, but don't expect it to change. Why don't we just propagate it to a new member of VirtIODevice during initialization instead? The limit may be changed. Consider that patch 9 increases the pci limit from 64 to 513. But we want to keep the migration compatibility for legacy machine types e.g machines earlier than pc-q35-2.3 or pc-i440fx-2.3, so the limit was changed back to 64 in pc_compat_2_2(). More work will be done if we want to propagate it to VirtIODevice, and it looks unnecessary.
Re: [Qemu-devel] [PATCH 1/6 v4] target-tilegx: Firstly add to qemu with minimized features
On 2/28/15 10:09, Chris Metcalf wrote: On 2/27/2015 9:10 PM, Chen Gang S wrote: By the way, does Gx8000 mean 8000 core count? It's marketing, so it doesn't have to mean anything. The TILE-Gx 8036 is the 36-core part, the 8072 is the 72-core part, 8009 is the 9-core part, etc. There is no 8000 chip, it's just a way of describing the TILE-Gx chip series. OK, thanks. -- Chen Gang Open, share, and attitude like air, water, and life which God blessed
Re: [Qemu-devel] [PATCH 1/6 v4] target-tilegx: Firstly add to qemu with minimized features
Firstly, thank you very much for your patient work! On 2/28/15 01:36, Andreas Färber wrote: Hi, target-tilegx: Initial stub or ...support? No need to mention QEMU (spelling!) in a QEMU commit. OK, thanks. Am 22.02.2015 um 14:33 schrieb Chen Gang S: It almost likes a template for adding an architecture target. That's a comment that's not really descriptive of what the patch does. Instead, maybe mention that this is the configure and build system support etc. and what name to use for enabling it from configure, that it's linux-user only for now, ...? OK, thanks. Signed-off-by: Chen Gang gang.chen.5...@gmail.com --- configure | 7 ++ default-configs/tilegx-linux-user.mak | 1 + target-tilegx/Makefile.objs | 1 + target-tilegx/cpu-qom.h | 72 +++ target-tilegx/cpu.c | 162 ++ target-tilegx/cpu.h | 85 ++ target-tilegx/helper.h| 0 target-tilegx/translate.c | 54 8 files changed, 382 insertions(+) create mode 100644 default-configs/tilegx-linux-user.mak create mode 100644 target-tilegx/Makefile.objs create mode 100644 target-tilegx/cpu-qom.h create mode 100644 target-tilegx/cpu.c create mode 100644 target-tilegx/cpu.h create mode 100644 target-tilegx/helper.h create mode 100644 target-tilegx/translate.c diff --git a/configure b/configure index 7ba4bcb..23aa8f6 100755 --- a/configure +++ b/configure @@ -5191,6 +5191,9 @@ case $target_name in s390x) gdb_xml_files=s390x-core64.xml s390-acr.xml s390-fpr.xml ;; + tilegx) +TARGET_ARCH=tilegx + ;; unicore32) ;; xtensa|xtensaeb) @@ -5363,6 +5366,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo CONFIG_SPARC_DIS=y $config_target_mak echo CONFIG_SPARC_DIS=y config-all-disas.mak ;; + tilegx*) +echo CONFIG_TILEGX_DIS=y $config_target_mak +echo CONFIG_TILEGX_DIS=y config-all-disas.mak + ;; Hadn't you been asked to drop these lines, as you are not yet adding any disassembler code that uses it? NO. And next, I shall drop them. xtensa*) echo CONFIG_XTENSA_DIS=y $config_target_mak echo CONFIG_XTENSA_DIS=y config-all-disas.mak [...] diff --git a/target-tilegx/cpu-qom.h b/target-tilegx/cpu-qom.h new file mode 100644 index 000..e15a8b8 --- /dev/null +++ b/target-tilegx/cpu-qom.h @@ -0,0 +1,72 @@ +/* + * QEMU Tilegx CPU TILE-Gx according to http://www.tilera.com/products/?ezchip=585spage=614 - please fix wherever used in textual form. OK, thanks. + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * http://www.gnu.org/licenses/lgpl-2.1.html + */ +#ifndef QEMU_TILEGX_CPU_QOM_H +#define QEMU_TILEGX_CPU_QOM_H + +#include qom/cpu.h + +#define TYPE_TILEGX_CPU tilegx-cpu + +#define TILEGX_CPU_CLASS(klass) \ +OBJECT_CLASS_CHECK(TilegxCPUClass, (klass), TYPE_TILEGX_CPU) +#define TILEGX_CPU(obj) \ +OBJECT_CHECK(TilegxCPU, (obj), TYPE_TILEGX_CPU) +#define TILEGX_CPU_GET_CLASS(obj) \ +OBJECT_GET_CLASS(TilegxCPUClass, (obj), TYPE_TILEGX_CPU) + +/** + * TilegxCPUClass: + * @parent_realize: The parent class' realize handler. + * @parent_reset: The parent class' reset handler. + * + * A Tilegx CPU model. + */ +typedef struct TilegxCPUClass { For the benefit of readers, please call this TileGXCPUClass ... OK, thanks. +/* private */ +CPUClass parent_class; +/* public */ + +DeviceRealize parent_realize; +void (*parent_reset)(CPUState *cpu); +} TilegxCPUClass; + +/** + * TilegxCPU: + * @env: #CPUTLState + * + * A Tilegx CPU. + */ +typedef struct TilegxCPU { ... and TileGXCPU. (or TileGx...) OK, thanks. I shall call it TileGXCPU. +/* private */ +CPUState parent_obj; +uint64_t base_vectors; This should not be in here, the private section serves to hide the parent field from documentation. base_vectors should also probably be after env, for performance reasons. rth? OK, thanks. At present, we do not use base_vectors, so I guess, we can just remove it, and the related implementation will be: typedef struct TileGXCPU { /* private */ CPUState parent_obj; /* public */
[Qemu-devel] Announcement: Patchew server is online now
Hello, everyone I'm glad to announce the fresh Patchew server deployment: http://qemu.patchew.org/ The mission of this project is to help identify obvious defects (coding style, compiling, etc.) of posted patches. Follow the green passed or red failed button in the page and you'll see the testing log. You can also see which series have got reviews or comments. Q: How will this impact patch submission and merging process? Nothing is affected (at least for now), use this as an auxiliary. Q: What exactly are tested for each patch? * scripts/checkpatch.pl * git am (on top of qemu.git) * ./configure --target-list=x86_64-softmmu * make * make check Q: No different architectures, compilers or targets? Not yet. A simple script does the test in a docker instance. A bigger coverage is possible though, by adding steps to the script: [1]: https://github.com/famz/patchew/blob/master/tests/qemu-devel.sh Q: Where is the said email notification? The email notification feature is ready. In a few days I will enable automatic replying to the list, once the web interface and testing are both running smoothly and up to speed. Currently the only recipient is Fam :) Q: Where is the source code? https://github.com/famz/patchew (Pull requests very welcome!) Enjoy, and feel free to make comments! Thank you! --- Fam Zheng
Re: [Qemu-devel] [RFC PATCH 0/7] hw/arm/virt: Add cpu-add way cpu hotplug support
On 02/26/2015 01:32 AM, Shannon Zhao wrote: On 2015/2/19 1:19, Wei Huang wrote: Nice work. I will help review the patches. Thanks for your help :-) Other than the CPU hotplug support, we are also seeking the guest VM powerdown support via ACPI. This feature is important for management tool to control guest VMs. In fact I had a similar GPIO patch for powerdown recently. Given that you already posted a more complete version, I wonder if you can add this feature to your patchset? FYI, I attached my powerdown patch in this email. Here is a brief list of items: * DSDT description of power button (to-be-done) * Hook up with qemu_qemu_register_powerdown_notifier() with the GPIO IRQ Feel free to add my name as signed-off-by in this feature if you decide to add it. Yes, I think the powerdown support is very useful, but maybe this feature can be added by a new patchset as this patchset cares about CPU hotplug. We can add powerdown, memory hotplug, cpu remove and memory remove support step by step if the approach of this patchset is accepted. I can make a patch to add powerdown support based on this patchset and your attached patch if you want to test this feature. How do you think about this? That sounds good to me. It does make sense to separate them. Keep me in loop. Thanks, -Wei
[Qemu-devel] [Bug 1426593] [NEW] qem-user arm cortex-a8 printf out-of-memory hang
Public bug reported: using the latest build from git (hash 041ccc922ee474693a2869d4e3b59e920c739bc0 ) and all older versions i have tested. i am using an amd64 host with an arm chroot using qemu-user arm cortex-a8 cpu emulation to run it building coreutils hangs on checking whether printf survives out-of- memory conditions i have not had time to dig into the build system to isolate the test yet, there were old reports of this bug but i can no longer find them on google. ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1426593 Title: qem-user arm cortex-a8 printf out-of-memory hang Status in QEMU: New Bug description: using the latest build from git (hash 041ccc922ee474693a2869d4e3b59e920c739bc0 ) and all older versions i have tested. i am using an amd64 host with an arm chroot using qemu-user arm cortex-a8 cpu emulation to run it building coreutils hangs on checking whether printf survives out-of- memory conditions i have not had time to dig into the build system to isolate the test yet, there were old reports of this bug but i can no longer find them on google. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1426593/+subscriptions
Re: [Qemu-devel] [PATCH 1/6 v4] target-tilegx: Firstly add to qemu with minimized features
On 2/28/15 05:49, Chris Metcalf wrote: On 2/27/2015 12:36 PM, Andreas Färber wrote: TILE-Gx according to http://www.tilera.com/products/?ezchip=585spage=614 - please fix wherever used in textual form. Yes, really only tilegx or TILE-Gx should be used. In type names I agree that TileGX is probably clearer than any alternatives. OK, thanks. I shall use TILE-Gx for it. And next, for the type names, I shall use TileGX. What about CPU models? Do the Gx72, Gx36, etc. differ only in core count or also in instruction set features? From a userspace perspective, it's mostly the core count. They also have a different set of on-chip hardware accelerators, etc., but that's out of scope for this project. OK, thanks. I guess your meaning is For qemu, we needn't consider about Gx72, Gx36 ..., we can treat all of them as TILE-Gx. By the way, does Gx8000 mean 8000 core count? Thanks. -- Chen Gang Open, share, and attitude like air, water, and life which God blessed
[Qemu-devel] [RFC PATCH v10 00/24] Deterministic replay core
This set of patches is related to the reverse execution and deterministic replay of qemu execution. This implementation of deterministic replay can be used for deterministic debugging of guest code through gdb remote interface. These patches include only core function of the replay, excluding the support for replaying serial, audio, network, and USB devices' operations. Reverse debugging and monitor commands were also excluded to be submitted later as separate patches. Execution recording writes non-deterministic events log, which can be later used for replaying the execution anywhere and for unlimited number of times. It also supports checkpointing for faster rewinding during reverse debugging. Execution replaying reads the log and replays all non-deterministic events including external input, hardware clocks, and interrupts. Deterministic replay has the following features: * Deterministically replays whole system execution and all contents of the memory, state of the hadrware devices, clocks, and screen of the VM. * Writes execution log into the file for latter replaying for multiple times on different machines. * Supports i386, x86_64, and ARM hardware platforms. * Performs deterministic replay of all operations with keyboard and mouse input devices. * Supports auto-checkpointing for convenient reverse debugging. Usage of the record/replay: * First, record the execution, by adding the following string to the command line: '-icount shift=7,rr=record,rrfile=replay.bin -net none'. Block devices' images are not actually changed in the recording mode, because all of the changes are written to the temporary overlay file. * Then you can replay it for the multiple times by using another command line option: '-icount shift=7,rr=replay,rrfile=replay.bin -net none' * '-net none' option should also be specified if network replay patches are not applied. Paper with short description of deterministic replay implementation: http://www.computer.org/csdl/proceedings/csmr/2012/4666/00/4666a553-abs.html Modifications of qemu include: * wrappers for clock and time functions to save their return values in the log * saving different asynchronous events (e.g. system shutdown) into the log * synchronization of the bottom halves execution * synchronization of the threads from thread pool * recording/replaying user input (mouse and keyboard) * adding internal events for cpu and io synchronization v10 changes: * Fixed queue processing for bottom halves (as suggested by Paolo Bonzini) * Rewritten several replay functions (as suggested by Paolo Bonzini) * Some minor fixes. v9 changes: * Replaced fwrite/fread with putc/getc (as suggested by Paolo Bonzini) * Stopping virtual machine in case of replay file end (as suggested by Paolo Bonzini) * Removed one of the replay mutexes (as suggested by Paolo Bonzini) * Fixed RCU queue for bottom halves (as suggested by Paolo Bonzini) * Updated command line options' names (as suggested by Paolo Bonzini) * Added design document for record/replay (as suggested by Paolo Bonzini) * Simplified checkpoints for the timers * Added cloning InputEvent objects for replay (as suggested by Paolo Bonzini) * Added replay blockers instead of checking the command line (as suggested by Paolo Bonzini) * Some functions renaming and extracting. v8 changes: * Simplified processing of the shutdown event (as suggested by Paolo Bonzini) * Replaced stack of bottom halves in AIO context with QSIMPLEQ (as suggested by Paolo Bonzini) * Moved replay_submode out of the series (as suggested by Paolo Bonzini) * Moved suffix option out of the series * Converted some of the defines into enums (as suggested by Paolo Bonzini) * Encapsulated save_tm/read_tm calls into the single function (as suggested by Paolo Bonzini) * Moved record/replay options to icount group (as suggested by Paolo Bonzini) * Updated mutex protection for the events queue (as suggested by Paolo Bonzini) * Added mutex to protect replay log file (as suggested by Paolo Bonzini) * Minor cleanups v7 changes: * Removed patches that were applied to upstream. v6 changes: * Fixed replay stub return value (as suggested by Eric Blake) * Fixed icount warping. * Virtual rt clock now uses cpu_get_clock() (as suggested by Paolo Bonzini) * Replated get_clock_realtime and get_clock calls with qemu clock requests (as suggested by Paolo Bonzini) * Modified can_do_io logic to allow requesting icount from cpu_exec function (as suggested by Paolo Bonzini) * Removed applied patches. v5 changes: * Minor changes. * Used fixed-width integer types for read/write functions (as suggested by Alex Bennee) * Moved savevm-related code out of the core. * Added new traced clock for deterministic virtual clock warping (as suggested by Paolo Bonzini) * Fixed exception_index reset for user mode (as suggested by Paolo Bonzini) * Adopted Paolo's icount patches * Fixed hardware interrupts
[Qemu-devel] [RFC PATCH v10 02/24] replay: global variables and function stubs
This patch adds global variables, defines, functions declarations, and function stubs for deterministic VM replay used by external modules. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- Makefile.target |1 docs/replay.txt | 161 ++ qapi-schema.json | 18 ++ replay/Makefile.objs |1 replay/replay.c | 14 replay/replay.h | 19 ++ stubs/Makefile.objs |1 stubs/replay.c |3 + 8 files changed, 218 insertions(+), 0 deletions(-) create mode 100755 docs/replay.txt create mode 100755 replay/Makefile.objs create mode 100755 replay/replay.c create mode 100755 replay/replay.h create mode 100755 stubs/replay.c diff --git a/Makefile.target b/Makefile.target index 58c6ae1..cd939c1 100644 --- a/Makefile.target +++ b/Makefile.target @@ -84,6 +84,7 @@ all: $(PROGS) stap # cpu emulator library obj-y = exec.o translate-all.o cpu-exec.o obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o +obj-y += replay/ obj-$(CONFIG_TCG_INTERPRETER) += tci.o obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o obj-y += fpu/softfloat.o diff --git a/docs/replay.txt b/docs/replay.txt new file mode 100755 index 000..084ca65 --- /dev/null +++ b/docs/replay.txt @@ -0,0 +1,161 @@ +Record/replay +- + +Record/replay functions are used for the reverse execution and deterministic +replay of qemu execution. This implementation of deterministic replay can +be used for deterministic debugging of guest code through gdb remote +interface. + +Execution recording writes non-deterministic events log, which can be later +used for replaying the execution anywhere and for unlimited number of times. +It also supports checkpointing for faster rewinding during reverse debugging. +Execution replaying reads the log and replays all non-deterministic events +including external input, hardware clocks, and interrupts. + +Deterministic replay has the following features: + * Deterministically replays whole system execution and all contents of + the memory, state of the hadrware devices, clocks, and screen of the VM. + * Writes execution log into the file for latter replaying for multiple times + on different machines. + * Supports i386, x86_64, and ARM hardware platforms. + * Performs deterministic replay of all operations with keyboard and mouse + input devices. + +Usage of the record/replay: + * First, record the execution, by adding the following string to the command line: + '-icount shift=7,rr=record,rrfile=replay.bin -net none'. + Block devices' images are not actually changed in the recording mode, + because all of the changes are written to the temporary overlay file. + * Then you can replay it for the multiple times by using another command + line option: '-icount shift=7,rr=replay,rrfile=replay.bin -net none' + * '-net none' option should also be specified if network replay patches + are not applied. + +Paper with short description of deterministic replay implementation: +http://www.computer.org/csdl/proceedings/csmr/2012/4666/00/4666a553-abs.html + +Modifications of qemu include: + * wrappers for clock and time functions to save their return values in the log + * saving different asynchronous events (e.g. system shutdown) into the log + * synchronization of the bottom halves execution + * synchronization of the threads from thread pool + * recording/replaying user input (mouse and keyboard) + * adding internal checkpoints for cpu and io synchronization + +Non-deterministic events + + +Our record/replay system is based on saving and replaying non-deterministic +events (e.g. keyboard input) and simulating deterministic ones (e.g. reading +from HDD or memory of the VM). Saving only non-deterministic events makes +log file smaller, simulation faster, and allows using reverse debugging even +for realtime applications. + +The following non-deterministic data from peripheral devices is saved into +the log: mouse and keyboard input, network packets, audio controller input, +USB packets, serial port input, and hardware clocks (they are non-deterministic +too, because their values are taken from the host machine). Inputs from +simulated hardware, memory of VM, software interrupts, and execution of +instructions are not saved into the log, because they are deterministic and +can be replayed by simulating the behavior of virtual machine starting from +initial state. + +We had to solve three tasks to implement deterministic replay: recording +non-deterministic events, replaying non-deterministic events, and checking +that there is no divergence between record and replay modes. + +We changed several parts of QEMU to make event log recording and replaying. +Devices' models that have non-deterministic input from external devices were +changed to write every external event into
[Qemu-devel] [RFC PATCH v10 05/24] replay: introduce mutex to protect the replay log
This mutex will protect read/write operations for replay log. Using mutex is necessary because most of the events consist of several fields stored in the log. The mutex will help to avoid races. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- replay/replay-internal.c | 27 +++ replay/replay-internal.h |7 +++ 2 files changed, 34 insertions(+), 0 deletions(-) diff --git a/replay/replay-internal.c b/replay/replay-internal.c index c2bbf5f..f7c03bc 100755 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -15,6 +15,13 @@ unsigned int replay_data_kind = -1; static unsigned int replay_has_unread_data; +/* Mutex to protect reading and writing events to the log. + replay_data_kind and replay_has_unread_data are also protected + by this mutex. + It also protects replay events queue which stores events to be + written or read to the log. */ +static QemuMutex lock; + /* File for replay writing */ FILE *replay_file; @@ -147,3 +154,23 @@ void replay_finish_event(void) replay_has_unread_data = 0; replay_fetch_data_kind(); } + +void replay_mutex_init(void) +{ +qemu_mutex_init(lock); +} + +void replay_mutex_destroy(void) +{ +qemu_mutex_destroy(lock); +} + +void replay_mutex_lock(void) +{ +qemu_mutex_lock(lock); +} + +void replay_mutex_unlock(void) +{ +qemu_mutex_unlock(lock); +} diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 17600de..8a0de0d 100755 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -33,6 +33,13 @@ int64_t replay_get_qword(void); void replay_get_array(uint8_t *buf, size_t *size); void replay_get_array_alloc(uint8_t **buf, size_t *size); +/* Mutex functions for protecting replay log file */ + +void replay_mutex_init(void); +void replay_mutex_destroy(void); +void replay_mutex_lock(void); +void replay_mutex_unlock(void); + /*! Checks error status of the file. */ void replay_check_error(void);
[Qemu-devel] [RFC PATCH v10 22/24] replay: replay blockers for devices
Some devices are not supported by record/replay subsystem. This patch introduces replay blocker which denies starting record/replay if such devices are included into the configuration. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- hw/bt/hci.c |7 +++ include/qapi/qmp/qerror.h |3 +++ replay/replay.c | 13 + replay/replay.h |3 +++ vl.c |9 + 5 files changed, 35 insertions(+), 0 deletions(-) diff --git a/hw/bt/hci.c b/hw/bt/hci.c index 7ea3dc6..9be30e1 100644 --- a/hw/bt/hci.c +++ b/hw/bt/hci.c @@ -23,6 +23,8 @@ #include hw/usb.h #include sysemu/bt.h #include hw/bt.h +#include qapi/qmp/qerror.h +#include replay/replay.h struct bt_hci_s { uint8_t *(*evt_packet)(void *opaque); @@ -72,6 +74,8 @@ struct bt_hci_s { struct HCIInfo info; struct bt_device_s device; + +Error *replay_blocker; }; #define DEFAULT_RSSI_DBM 20 @@ -2191,6 +2195,9 @@ struct HCIInfo *bt_new_hci(struct bt_scatternet_s *net) s-device.handle_destroy = bt_hci_destroy; +error_set(s-replay_blocker, QERR_REPLAY_NOT_SUPPORTED, bt hci); +replay_add_blocker(s-replay_blocker); + return s-info; } diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h index 986260f..a9f5e24 100644 --- a/include/qapi/qmp/qerror.h +++ b/include/qapi/qmp/qerror.h @@ -136,4 +136,7 @@ void qerror_report_err(Error *err); #define QERR_UNSUPPORTED \ ERROR_CLASS_GENERIC_ERROR, this feature or command is not currently supported +#define QERR_REPLAY_NOT_SUPPORTED \ +ERROR_CLASS_GENERIC_ERROR, Record/replay feature is not supported for '%s' + #endif /* QERROR_H */ diff --git a/replay/replay.c b/replay/replay.c index 98b5e2f..a5ae58b 100755 --- a/replay/replay.c +++ b/replay/replay.c @@ -14,6 +14,7 @@ #include replay-internal.h #include qemu/timer.h #include sysemu/sysemu.h +#include qemu/error-report.h /* Current version of the replay mechanism. Increase it when file format changes. */ @@ -26,6 +27,7 @@ ReplayMode replay_mode = REPLAY_MODE_NONE; /* Name of replay file */ static char *replay_filename; ReplayState replay_state; +static GSList *replay_blockers; bool replay_next_event_is(int event) { @@ -285,6 +287,12 @@ void replay_start(void) return; } +if (replay_blockers) { +error_report(Record/replay: %s, + error_get_pretty(replay_blockers-data)); +exit(1); +} + /* Timer for snapshotting will be set up here. */ replay_enable_events(); @@ -324,3 +332,8 @@ void replay_finish(void) replay_finish_events(); replay_mutex_destroy(); } + +void replay_add_blocker(Error *reason) +{ +replay_blockers = g_slist_prepend(replay_blockers, reason); +} diff --git a/replay/replay.h b/replay/replay.h index e0b08c6..1bded8a 100755 --- a/replay/replay.h +++ b/replay/replay.h @@ -15,6 +15,7 @@ #include stdbool.h #include stdint.h #include qapi-types.h +#include qapi/error.h #include qemu/typedefs.h /* replay clock kinds */ @@ -48,6 +49,8 @@ void replay_configure(struct QemuOpts *opts); void replay_start(void); /*! Closes replay log file and frees other resources. */ void replay_finish(void); +/*! Adds replay blocker with the specified error description */ +void replay_add_blocker(Error *reason); /* Processing the instructions */ diff --git a/vl.c b/vl.c index bad9bee..f9c345d 100644 --- a/vl.c +++ b/vl.c @@ -800,7 +800,11 @@ static void configure_rtc(QemuOpts *opts) if (!strcmp(value, utc)) { rtc_utc = 1; } else if (!strcmp(value, localtime)) { +Error *blocker = NULL; rtc_utc = 0; +error_set(blocker, QERR_REPLAY_NOT_SUPPORTED, + -rtc base=localtime); +replay_add_blocker(blocker); } else { configure_rtc_date_offset(value, 0); } @@ -1206,6 +1210,11 @@ static void smp_parse(QemuOpts *opts) exit(1); } +if (smp_cpus 1 || smp_cores 1 || smp_threads 1) { +Error *blocker = NULL; +error_set(blocker, QERR_REPLAY_NOT_SUPPORTED, smp); +replay_add_blocker(blocker); +} } static void realtime_init(void)
[Qemu-devel] [RFC PATCH v10 16/24] aio: replace stack of bottom halves with queue
Bottom halves in AIO context are stored and removes in LIFO order. It makes their execution non-deterministic. This patch replaces the stack with queue to preserve the order of bottom halves processing. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- async.c | 26 +++--- include/block/aio.h |4 ++-- include/qemu/queue.h | 18 ++ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/async.c b/async.c index 2be88cc..d83b7c8 100644 --- a/async.c +++ b/async.c @@ -35,7 +35,7 @@ struct QEMUBH { AioContext *ctx; QEMUBHFunc *cb; void *opaque; -QEMUBH *next; +QSIMPLEQ_ENTRY(QEMUBH) next; bool scheduled; bool idle; bool deleted; @@ -51,10 +51,7 @@ QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque) .opaque = opaque, }; qemu_mutex_lock(ctx-bh_lock); -bh-next = ctx-first_bh; -/* Make sure that the members are ready before putting bh into list */ -smp_wmb(); -ctx-first_bh = bh; +QSIMPLEQ_INSERT_TAIL_RCU(ctx-bh_queue, bh, next); qemu_mutex_unlock(ctx-bh_lock); return bh; } @@ -62,16 +59,15 @@ QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque) /* Multiple occurrences of aio_bh_poll cannot be called concurrently */ int aio_bh_poll(AioContext *ctx) { -QEMUBH *bh, **bhp, *next; +QEMUBH *bh, *next, *prev; int ret; ctx-walking_bh++; ret = 0; -for (bh = ctx-first_bh; bh; bh = next) { +QSIMPLEQ_FOREACH(bh, ctx-bh_queue, next) { /* Make sure that fetching bh happens before accessing its members */ smp_read_barrier_depends(); -next = bh-next; if (!bh-deleted bh-scheduled) { bh-scheduled = 0; /* Paired with write barrier in bh schedule to ensure reading for @@ -90,14 +86,13 @@ int aio_bh_poll(AioContext *ctx) /* remove deleted bhs */ if (!ctx-walking_bh) { qemu_mutex_lock(ctx-bh_lock); -bhp = ctx-first_bh; -while (*bhp) { -bh = *bhp; +prev = NULL; +QSIMPLEQ_FOREACH_SAFE(bh, ctx-bh_queue, next, next) { if (bh-deleted) { -*bhp = bh-next; +QSIMPLEQ_REMOVE_AFTER(ctx-bh_queue, prev, QEMUBH, next); g_free(bh); } else { -bhp = bh-next; +prev = bh; } } qemu_mutex_unlock(ctx-bh_lock); @@ -161,7 +156,7 @@ aio_compute_timeout(AioContext *ctx) int timeout = -1; QEMUBH *bh; -for (bh = ctx-first_bh; bh; bh = bh-next) { +QSIMPLEQ_FOREACH(bh, ctx-bh_queue, next) { if (!bh-deleted bh-scheduled) { if (bh-idle) { /* idle bottom halves will be polled at least @@ -204,7 +199,7 @@ aio_ctx_check(GSource *source) AioContext *ctx = (AioContext *) source; QEMUBH *bh; -for (bh = ctx-first_bh; bh; bh = bh-next) { +QSIMPLEQ_FOREACH(bh, ctx-bh_queue, next) { if (!bh-deleted bh-scheduled) { return true; } @@ -311,6 +306,7 @@ AioContext *aio_context_new(Error **errp) qemu_mutex_init(ctx-bh_lock); rfifolock_init(ctx-lock, aio_rfifolock_cb, ctx); timerlistgroup_init(ctx-tlg, aio_timerlist_notify, ctx); +QSIMPLEQ_INIT(ctx-bh_queue); return ctx; } diff --git a/include/block/aio.h b/include/block/aio.h index 7d1e26b..82cdf78 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -71,8 +71,8 @@ struct AioContext { /* lock to protect between bh's adders and deleter */ QemuMutex bh_lock; -/* Anchor of the list of Bottom Halves belonging to the context */ -struct QEMUBH *first_bh; +/* List of Bottom Halves belonging to the context */ +QSIMPLEQ_HEAD(, QEMUBH) bh_queue; /* A simple lock used to protect the first_bh list, and ensure that * no callbacks are removed while we're walking and dispatching callbacks. diff --git a/include/qemu/queue.h b/include/qemu/queue.h index c602797..ba7efeb 100644 --- a/include/qemu/queue.h +++ b/include/qemu/queue.h @@ -281,6 +281,13 @@ struct { \ (head)-sqh_last = (elm)-field.sqe_next; \ } while (/*CONSTCOND*/0) +#define QSIMPLEQ_INSERT_TAIL_RCU(head, elm, field) do { \ +(elm)-field.sqe_next = NULL; \ +smp_wmb(); \ +atomic_rcu_set((head)-sqh_last, (elm));\ +(head)-sqh_last = (elm)-field.sqe_next; \ +} while (/*CONSTCOND*/0) + #define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ if (((elm)-field.sqe_next = (listelm)-field.sqe_next) == NULL)\ (head)-sqh_last = (elm)-field.sqe_next; \ @@ -316,6 +323,17 @@ struct {
Re: [Qemu-devel] [RfC PATCH 08/15] virtio-gpu-pci: virtio-1.0 adaptions [fixup]
On 2015-02-27 at 06:18, Gerd Hoffmann wrote: Hi, This seems to be in line with the changes made in patch 1; however, I fail to see where VirtIODevice.device_id is set so that virtio_bus_get_vdev_id() returns it when called from virtio_pci_device_plugged()... Maybe I'll find it yet. virtio_gpu_device_realize() calls virtio_init() with the id as one of the parameters. Right. Thanks! Max
[Qemu-devel] [RFC PATCH v10 19/24] replay: thread pool
This patch modifies thread pool to allow replaying asynchronous thread tasks synchronously in replay mode. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- block/raw-posix.c |6 - block/raw-win32.c |4 +++- include/block/thread-pool.h |4 +++- replay/replay-events.c | 11 ++ replay/replay-internal.h|1 + replay/replay.h |2 ++ stubs/replay.c |4 tests/test-thread-pool.c|7 -- thread-pool.c | 49 ++- 9 files changed, 66 insertions(+), 22 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index e474c17..4636b95 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1136,7 +1136,9 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, int fd, trace_paio_submit(acb, opaque, sector_num, nb_sectors, type); pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); -return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque); +return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque, + qiov ? qiov-replay : false, + qiov ? qiov-replay_step : 0); } static BlockAIOCB *raw_aio_submit(BlockDriverState *bs, @@ -2062,7 +2064,7 @@ static BlockAIOCB *hdev_aio_ioctl(BlockDriverState *bs, acb-aio_ioctl_buf = buf; acb-aio_ioctl_cmd = req; pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); -return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque); +return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque, false, 0); } #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) diff --git a/block/raw-win32.c b/block/raw-win32.c index 06243d7..7ac693b 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -158,7 +158,9 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile, trace_paio_submit(acb, opaque, sector_num, nb_sectors, type); pool = aio_get_thread_pool(bdrv_get_aio_context(bs)); -return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque); +return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque, + qiov ? qiov-replay : false, + qiov ? qiov-replay_step : 0); } int qemu_ftruncate64(int fd, int64_t length) diff --git a/include/block/thread-pool.h b/include/block/thread-pool.h index 42eb5e8..801ac00 100644 --- a/include/block/thread-pool.h +++ b/include/block/thread-pool.h @@ -29,9 +29,11 @@ void thread_pool_free(ThreadPool *pool); BlockAIOCB *thread_pool_submit_aio(ThreadPool *pool, ThreadPoolFunc *func, void *arg, -BlockCompletionFunc *cb, void *opaque); +BlockCompletionFunc *cb, void *opaque, +bool replay, uint64_t replay_step); int coroutine_fn thread_pool_submit_co(ThreadPool *pool, ThreadPoolFunc *func, void *arg); void thread_pool_submit(ThreadPool *pool, ThreadPoolFunc *func, void *arg); +void thread_pool_work(ThreadPool *pool, void *r); #endif diff --git a/replay/replay-events.c b/replay/replay-events.c index ec15683..485a440 100755 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -13,6 +13,7 @@ #include qemu/error-report.h #include replay.h #include replay-internal.h +#include block/thread-pool.h typedef struct Event { ReplayAsyncEventKind event_kind; @@ -38,6 +39,9 @@ static void replay_run_event(Event *event) case REPLAY_ASYNC_EVENT_BH: aio_bh_call(event-opaque); break; +case REPLAY_ASYNC_EVENT_THREAD: +thread_pool_work((ThreadPool *)event-opaque, event-opaque2); +break; default: error_report(Replay: invalid async event ID (%d) in the queue, event-event_kind); @@ -137,6 +141,7 @@ static void replay_save_event(Event *event, int checkpoint) /* save event-specific data */ switch (event-event_kind) { case REPLAY_ASYNC_EVENT_BH: +case REPLAY_ASYNC_EVENT_THREAD: replay_put_qword(event-id); break; } @@ -148,6 +153,11 @@ void replay_add_bh_event(void *bh, uint64_t id) replay_add_event_internal(REPLAY_ASYNC_EVENT_BH, bh, NULL, id); } +void replay_add_thread_event(void *opaque, void *opaque2, uint64_t id) +{ +replay_add_event_internal(REPLAY_ASYNC_EVENT_THREAD, opaque, opaque2, id); +} + /* Called with replay mutex locked */ void replay_save_events(int checkpoint) { @@ -180,6 +190,7 @@ static Event *replay_read_event(int checkpoint) /* Events that has not to be in the queue */ switch (read_event_kind) { case REPLAY_ASYNC_EVENT_BH: +case REPLAY_ASYNC_EVENT_THREAD: if (read_id == -1) { read_id = replay_get_qword(); } diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 29722cf..2f557a6 100755 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -40,6 +40,7 @@
[Qemu-devel] [RFC PATCH v10 04/24] replay: internal functions for replay log
This patch adds functions to perform read and write operations with replay log. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- replay/Makefile.objs |1 replay/replay-internal.c | 149 ++ replay/replay-internal.h | 46 ++ 3 files changed, 196 insertions(+), 0 deletions(-) create mode 100755 replay/replay-internal.c create mode 100755 replay/replay-internal.h diff --git a/replay/Makefile.objs b/replay/Makefile.objs index 7ea860f..1148f45 100755 --- a/replay/Makefile.objs +++ b/replay/Makefile.objs @@ -1 +1,2 @@ obj-y += replay.o +obj-y += replay-internal.o diff --git a/replay/replay-internal.c b/replay/replay-internal.c new file mode 100755 index 000..c2bbf5f --- /dev/null +++ b/replay/replay-internal.c @@ -0,0 +1,149 @@ +/* + * replay-internal.c + * + * Copyright (c) 2010-2015 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include qemu-common.h +#include replay-internal.h + +unsigned int replay_data_kind = -1; +static unsigned int replay_has_unread_data; + +/* File for replay writing */ +FILE *replay_file; + +void replay_put_byte(uint8_t byte) +{ +if (replay_file) { +putc(byte, replay_file); +} +} + +void replay_put_event(uint8_t event) +{ +replay_put_byte(event); +} + + +void replay_put_word(uint16_t word) +{ +replay_put_byte(word 8); +replay_put_byte(word); +} + +void replay_put_dword(uint32_t dword) +{ +replay_put_word(dword 16); +replay_put_word(dword); +} + +void replay_put_qword(int64_t qword) +{ +replay_put_dword(qword 32); +replay_put_dword(qword); +} + +void replay_put_array(const uint8_t *buf, size_t size) +{ +if (replay_file) { +replay_put_dword(size); +fwrite(buf, 1, size, replay_file); +} +} + +uint8_t replay_get_byte(void) +{ +uint8_t byte = 0; +if (replay_file) { +byte = getc(replay_file); +} +return byte; +} + +uint16_t replay_get_word(void) +{ +uint16_t word = 0; +if (replay_file) { +word = replay_get_byte(); +word = (word 8) + replay_get_byte(); +} + +return word; +} + +uint32_t replay_get_dword(void) +{ +uint32_t dword = 0; +if (replay_file) { +dword = replay_get_word(); +dword = (dword 16) + replay_get_word(); +} + +return dword; +} + +int64_t replay_get_qword(void) +{ +int64_t qword = 0; +if (replay_file) { +qword = replay_get_dword(); +qword = (qword 32) + replay_get_dword(); +} + +return qword; +} + +void replay_get_array(uint8_t *buf, size_t *size) +{ +if (replay_file) { +*size = replay_get_dword(); +fread(buf, 1, *size, replay_file); +} +} + +void replay_get_array_alloc(uint8_t **buf, size_t *size) +{ +if (replay_file) { +*size = replay_get_dword(); +*buf = g_malloc(*size); +fread(*buf, 1, *size, replay_file); +} +} + +void replay_check_error(void) +{ +if (replay_file) { +if (feof(replay_file)) { +error_report(replay file is over); +qemu_system_vmstop_request_prepare(); +qemu_system_vmstop_request(RUN_STATE_PAUSED); +} else if (ferror(replay_file)) { +error_report(replay file is over or something goes wrong); +qemu_system_vmstop_request_prepare(); +qemu_system_vmstop_request(RUN_STATE_INTERNAL_ERROR); +} +} +} + +void replay_fetch_data_kind(void) +{ +if (replay_file) { +if (!replay_has_unread_data) { +replay_data_kind = replay_get_byte(); +replay_check_error(); +replay_has_unread_data = 1; +} +} +} + +void replay_finish_event(void) +{ +replay_has_unread_data = 0; +replay_fetch_data_kind(); +} diff --git a/replay/replay-internal.h b/replay/replay-internal.h new file mode 100755 index 000..17600de --- /dev/null +++ b/replay/replay-internal.h @@ -0,0 +1,46 @@ +#ifndef REPLAY_INTERNAL_H +#define REPLAY_INTERNAL_H + +/* + * replay-internal.h + * + * Copyright (c) 2010-2015 Institute for System Programming + * of the Russian Academy of Sciences. + * + * 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 stdio.h + +extern unsigned int replay_data_kind; + +/* File for replay writing */ +extern FILE *replay_file; + +void replay_put_byte(uint8_t byte); +void replay_put_event(uint8_t event); +void replay_put_word(uint16_t word); +void replay_put_dword(uint32_t dword); +void replay_put_qword(int64_t qword); +void replay_put_array(const uint8_t *buf, size_t size); + +uint8_t replay_get_byte(void); +uint16_t
[Qemu-devel] [RFC PATCH v10 12/24] replay: recording and replaying clock ticks
Clock ticks are considered as the sources of non-deterministic data for virtual machine. This patch implements saving the clock values when they are acquired (virtual, host clock). When replaying the execution corresponding values are read from log and transfered to the module, which wants to read the values. Such a design required the clock polling to be synchronized. Sometimes it is not true - e.g. when timeouts for timer lists are checked. In this case we use a cached value of the clock, passing it to the client code. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- cpus.c |3 +- qemu-timer.c |7 +++-- replay/Makefile.objs |1 + replay/replay-internal.h | 11 replay/replay-time.c | 64 ++ replay/replay.h | 23 + stubs/replay.c |9 ++ 7 files changed, 114 insertions(+), 4 deletions(-) create mode 100755 replay/replay-time.c diff --git a/cpus.c b/cpus.c index 511a0c5..b40b48c 100644 --- a/cpus.c +++ b/cpus.c @@ -336,7 +336,8 @@ static void icount_warp_rt(void *opaque) seqlock_write_lock(timers_state.vm_clock_seqlock); if (runstate_is_running()) { -int64_t clock = cpu_get_clock_locked(); +int64_t clock = REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT, + cpu_get_clock_locked()); int64_t warp_delta; warp_delta = clock - vm_clock_warp_start; diff --git a/qemu-timer.c b/qemu-timer.c index 5741f0d..d605afd 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -24,6 +24,7 @@ #include qemu/main-loop.h #include qemu/timer.h +#include replay/replay.h #ifdef CONFIG_POSIX #include pthread.h @@ -570,15 +571,15 @@ int64_t qemu_clock_get_ns(QEMUClockType type) return cpu_get_clock(); } case QEMU_CLOCK_HOST: -now = get_clock_realtime(); +now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime()); last = clock-last; clock-last = now; -if (now last) { +if (now last replay_mode == REPLAY_MODE_NONE) { notifier_list_notify(clock-reset_notifiers, now); } return now; case QEMU_CLOCK_VIRTUAL_RT: -return cpu_get_clock(); +return REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT, cpu_get_clock()); } } diff --git a/replay/Makefile.objs b/replay/Makefile.objs index 56da09c..257c320 100755 --- a/replay/Makefile.objs +++ b/replay/Makefile.objs @@ -1,3 +1,4 @@ obj-y += replay.o obj-y += replay-internal.o obj-y += replay-events.o +obj-y += replay-time.o diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 35c615a..a79f4af 100755 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -23,6 +23,10 @@ enum ReplayEvents { EVENT_EXCEPTION, /* for async events */ EVENT_ASYNC, +/* for clock read/writes */ +/* some of grteater codes are reserved for clocks */ +EVENT_CLOCK, +EVENT_CLOCK_LAST = EVENT_CLOCK + REPLAY_CLOCK_COUNT - 1, EVENT_COUNT }; @@ -35,6 +39,8 @@ enum ReplayAsyncEventKind { typedef enum ReplayAsyncEventKind ReplayAsyncEventKind; typedef struct ReplayState { +/*! Cached clock values. */ +int64_t cached_clock[REPLAY_CLOCK_COUNT]; /*! Current step - number of processed instructions and timer events. */ uint64_t current_step; /*! Number of instructions to be executed before other events happen. */ @@ -85,6 +91,11 @@ void replay_save_instructions(void); \return true, if event was found */ bool replay_next_event_is(int event); +/*! Reads next clock value from the file. +If clock kind read from the file is different from the parameter, +the value is not used. */ +void replay_read_next_clock(unsigned int kind); + /* Asynchronous events queue */ /*! Initializes events' processing internals */ diff --git a/replay/replay-time.c b/replay/replay-time.c new file mode 100755 index 000..2740901 --- /dev/null +++ b/replay/replay-time.c @@ -0,0 +1,64 @@ +/* + * replay-time.c + * + * Copyright (c) 2010-2015 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include qemu-common.h +#include replay.h +#include replay-internal.h + + +int64_t replay_save_clock(ReplayClockKind kind, int64_t clock) +{ +replay_save_instructions(); + +if (replay_file) { +replay_mutex_lock(); +replay_put_event(EVENT_CLOCK + kind); +replay_put_qword(clock); +replay_mutex_unlock(); +} + +return clock; +} + +void replay_read_next_clock(ReplayClockKind kind) +{ +unsigned int read_kind = replay_data_kind - EVENT_CLOCK; + +assert(read_kind == kind); + +int64_t clock = replay_get_qword(); + +replay_check_error(); +replay_finish_event(); + +
Re: [Qemu-devel] [PATCH] spapr_vio: Convert to realize()
On 27.02.15 11:52, Markus Armbruster wrote: Bonus fix: always set an error on failure. Some failures were silent before, except for the generic error set by device_realize(). Signed-off-by: Markus Armbruster arm...@redhat.com Thanks, applied to ppc-next. Alex
[Qemu-devel] [PATCH v4 03/11] iotests: Add test for eject under NBD server
This patch adds a test for ejecting the BlockBackend an NBD server is connected to (the NBD server is supposed to stop). Signed-off-by: Max Reitz mre...@redhat.com --- tests/qemu-iotests/096 | 90 ++ tests/qemu-iotests/096.out | 16 + tests/qemu-iotests/group | 1 + 3 files changed, 107 insertions(+) create mode 100755 tests/qemu-iotests/096 create mode 100644 tests/qemu-iotests/096.out diff --git a/tests/qemu-iotests/096 b/tests/qemu-iotests/096 new file mode 100755 index 000..bcba0ec --- /dev/null +++ b/tests/qemu-iotests/096 @@ -0,0 +1,90 @@ +#!/bin/bash +# +# Test case for ejecting a BB with an NBD server attached to it +# +# Copyright (C) 2015 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +# creator +owner=mre...@redhat.com + +seq=$(basename $0) +echo QA output created by $seq + +here=$PWD +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap _cleanup; exit \$status 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.qemu + +_supported_fmt generic +_supported_proto file +_supported_os Linux + +_make_test_img 64k + +$QEMU_IO -c 'write -P 42 0 64k' $TEST_IMG | _filter_qemu_io + +keep_stderr=y \ +_launch_qemu -drive if=ide,media=cdrom,id=drv,file=$TEST_IMG,format=$IMGFMT \ +2 (_filter_nbd) + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'qmp_capabilities' } \ +'return' + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'nbd-server-start', + 'arguments': { 'addr': { 'type': 'inet', +'data': { 'host': '127.0.0.1', + 'port': '10809' \ +'return' + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'nbd-server-add', + 'arguments': { 'device': 'drv' }} \ +'return' + +$QEMU_IO_PROG -f raw -c 'read -P 42 0 64k' 'nbd://127.0.0.1:10809/drv' 21 \ +| _filter_qemu_io | _filter_nbd + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'eject', + 'arguments': { 'device': 'drv' }} \ +'return' + +$QEMU_IO_PROG -f raw -c close 'nbd://127.0.0.1:10809/drv' 21 \ +| _filter_qemu_io | _filter_nbd + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'quit' } \ +'return' + +wait=1 _cleanup_qemu + +# success, all done +echo '*** done' +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/096.out b/tests/qemu-iotests/096.out new file mode 100644 index 000..cc10e51 --- /dev/null +++ b/tests/qemu-iotests/096.out @@ -0,0 +1,16 @@ +QA output created by 096 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536 +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{return: {}} +{return: {}} +{return: {}} +read 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: DEVICE_TRAY_MOVED, data: {device: drv, tray-open: true}} +{return: {}} +qemu-io: can't open device nbd://127.0.0.1:PORT/drv: Failed to read export length +no file open, try 'help open' +{return: {}} +{timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: SHUTDOWN} +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index ea43ebb..06d0485 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -102,6 +102,7 @@ 093 auto 094 rw auto quick 095 rw auto quick +096 rw auto quick 097 rw auto backing 098 rw auto backing quick 099 rw auto quick -- 2.1.0
[Qemu-devel] [PATCH v4 10/11] block: Eject BDS tree from BB at bdrv_close_all()
When bdrv_close_all() is called, instead of force-closing all root BlockDriverStates, it is better to just drop the reference from all BlockBackends and let them be closed automatically. This prevents BDS from getting closed that are still referenced by other BDS, which may result in loss of cached data. Signed-off-by: Max Reitz mre...@redhat.com --- block.c| 11 +-- block/block-backend.c | 13 + include/sysemu/block-backend.h | 1 + 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/block.c b/block.c index 0b0792c..a2637b6 100644 --- a/block.c +++ b/block.c @@ -1941,17 +1941,8 @@ static void bdrv_close(BlockDriverState *bs) void bdrv_close_all(void) { -BlockDriverState *bs; - blockdev_close_all_bdrv_states(); - -QTAILQ_FOREACH(bs, bdrv_states, device_list) { -AioContext *aio_context = bdrv_get_aio_context(bs); - -aio_context_acquire(aio_context); -bdrv_close(bs); -aio_context_release(aio_context); -} +blk_remove_all_bs(); } /* Check if any requests are in-flight (including throttled requests) */ diff --git a/block/block-backend.c b/block/block-backend.c index 7e9d53a..2e820fe 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -207,6 +207,19 @@ void blk_unref(BlockBackend *blk) } } +void blk_remove_all_bs(void) +{ +BlockBackend *blk; + +QTAILQ_FOREACH(blk, blk_backends, link) { +AioContext *ctx = blk_get_aio_context(blk); + +aio_context_acquire(ctx); +blk_remove_bs(blk); +aio_context_release(ctx); +} +} + /* * Return the BlockBackend after @blk. * If @blk is null, return the first one. diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index e0a2749..ab765a7 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -67,6 +67,7 @@ BlockBackend *blk_new_open(const char *name, const char *filename, Error **errp); void blk_ref(BlockBackend *blk); void blk_unref(BlockBackend *blk); +void blk_remove_all_bs(void); const char *blk_name(BlockBackend *blk); BlockBackend *blk_by_name(const char *name); BlockBackend *blk_next(BlockBackend *blk); -- 2.1.0
[Qemu-devel] [PATCH v4 04/11] quorum: Fix close path
bdrv_unref() can lead to bdrv_close(), which in turn will result in bdrv_drain_all(). This function will later be called blk_drain_all() and iterate only over the BlockBackends for which blk_is_inserted() holds true; therefore, bdrv_is_inserted() and thus quorum_is_inserted() will probably be called. This patch makes quorum_is_inserted() aware of the fact that some children may have been closed already. Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com --- block/quorum.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block/quorum.c b/block/quorum.c index 7a75cea..5ae2398 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -1005,6 +1005,7 @@ static void quorum_close(BlockDriverState *bs) for (i = 0; i s-num_children; i++) { bdrv_unref(s-bs[i]); +s-bs[i] = NULL; } g_free(s-bs); @@ -1070,7 +1071,7 @@ static bool quorum_is_inserted(BlockDriverState *bs) int i; for (i = 0; i s-num_children; i++) { -if (!bdrv_is_inserted(s-bs[i])) { +if (s-bs[i] !bdrv_is_inserted(s-bs[i])) { return false; } } -- 2.1.0
[Qemu-devel] [PULL v2 11/11] rocker: timestamp on the debug logs helps correlate with events in the VM
From: David Ahern dsah...@gmail.com Signed-off-by: David Ahern dsah...@gmail.com Signed-off-by: Scott Feldman sfel...@gmail.com Signed-off-by: Jiri Pirko j...@resnulli.us Message-id: 1424123271-7656-11-git-send-email-sfel...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/net/rocker/rocker.h | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hw/net/rocker/rocker.h b/hw/net/rocker/rocker.h index a164625..656d722 100644 --- a/hw/net/rocker/rocker.h +++ b/hw/net/rocker/rocker.h @@ -25,7 +25,16 @@ #if defined(DEBUG_ROCKER) # define DPRINTF(fmt, ...) \ -do { fprintf(stderr, ROCKER: fmt, ## __VA_ARGS__); } while (0) +do { \ +struct timeval tv; \ +char timestr[64]; \ +time_t now;\ +gettimeofday(tv, NULL); \ +now = tv.tv_sec; \ +strftime(timestr, sizeof(timestr), %T, localtime(now)); \ +fprintf(stderr, %s.%06ld , timestr, tv.tv_usec); \ +fprintf(stderr, ROCKER: fmt, ## __VA_ARGS__); \ +} while (0) #else static inline GCC_FMT_ATTR(1, 2) int DPRINTF(const char *fmt, ...) { -- 2.1.0
Re: [Qemu-devel] [PATCH v2] migration: Convert 'status' of MigrationInfo to use an enum type
* Eric Blake (ebl...@redhat.com) wrote: On 02/26/2015 11:19 PM, zhanghailiang wrote: The original 'status' is an open-coded 'str' type, convert it to use an enum type. This conversion is backwards compatible, better documented and more convenient for future extensibility. In addition, Fix a typo for qapi-schema.json: comppleted - completed Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- v2: - Remove '(since xyz)' strings. (Eric Blake) --- hmp.c | 7 --- migration/migration.c | 37 +++-- qapi-schema.json | 37 - 3 files changed, 51 insertions(+), 30 deletions(-) case MIG_STATE_ACTIVE: case MIG_STATE_CANCELLING: info-has_status = true; -info-status = g_strdup(active); +/* Note: when the real state of migration is 'cancelling', + we still return 'active' status to user, it makes no difference + for user. */ Rather than pollute the user-exposed enum with a state that we will never report, can we come up with some internal-only method for tracking cancelling separate from the enum? Well I guess we could just report it; but would that break any external tools? IMHO this change is a sensible change, the legacy of 'cancelling' is already there and it doesn't seem right to fix that at the same time as cleaning this up. Dave +++ b/qapi-schema.json @@ -411,18 +411,45 @@ 'overflow': 'int' } } ## +# @MigState: Do we have to abbreviate? I guess leaving it like this makes the rest of the existing code base have less churn (since it matches the spelling of the enum that was previous interanl only), but it might look nicer as MigrationState. If you do decide to go with a longer name, it might be nice to split this into a series, one patch that does only renames to migration.c (but no code additions outside of that file), and the other that moves the (now-correctly-named) enum into the public qapi file. +# +# An enumeration of migration status. +# +# @failed: some error occurred during migration process. +# +# @none: no migration has ever happened. +# +# @setup: migration process has been initiated. +# +# @cancelling: in the process of cancelling migration. +# If the user can never see this state, I'd rather we think about a solution that avoids advertising the state in the public api... +# @cancelled: cancelling migration is finished. +# +# @active: in the process of doing migration. +# +# @completed: migration is finished. +# +# Since: 2.3 +# +# Notes: @cancelling is only used internally, and return @active to user +#instead of @cancelling, it make no difference for users. ...rather than needing this note to air our dirty laundry. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
Re: [Qemu-devel] [PATCH 1/6 v4] target-tilegx: Firstly add to qemu with minimized features
Hi, target-tilegx: Initial stub or ...support? No need to mention QEMU (spelling!) in a QEMU commit. Am 22.02.2015 um 14:33 schrieb Chen Gang S: It almost likes a template for adding an architecture target. That's a comment that's not really descriptive of what the patch does. Instead, maybe mention that this is the configure and build system support etc. and what name to use for enabling it from configure, that it's linux-user only for now, ...? Signed-off-by: Chen Gang gang.chen.5...@gmail.com --- configure | 7 ++ default-configs/tilegx-linux-user.mak | 1 + target-tilegx/Makefile.objs | 1 + target-tilegx/cpu-qom.h | 72 +++ target-tilegx/cpu.c | 162 ++ target-tilegx/cpu.h | 85 ++ target-tilegx/helper.h| 0 target-tilegx/translate.c | 54 8 files changed, 382 insertions(+) create mode 100644 default-configs/tilegx-linux-user.mak create mode 100644 target-tilegx/Makefile.objs create mode 100644 target-tilegx/cpu-qom.h create mode 100644 target-tilegx/cpu.c create mode 100644 target-tilegx/cpu.h create mode 100644 target-tilegx/helper.h create mode 100644 target-tilegx/translate.c diff --git a/configure b/configure index 7ba4bcb..23aa8f6 100755 --- a/configure +++ b/configure @@ -5191,6 +5191,9 @@ case $target_name in s390x) gdb_xml_files=s390x-core64.xml s390-acr.xml s390-fpr.xml ;; + tilegx) +TARGET_ARCH=tilegx + ;; unicore32) ;; xtensa|xtensaeb) @@ -5363,6 +5366,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo CONFIG_SPARC_DIS=y $config_target_mak echo CONFIG_SPARC_DIS=y config-all-disas.mak ;; + tilegx*) +echo CONFIG_TILEGX_DIS=y $config_target_mak +echo CONFIG_TILEGX_DIS=y config-all-disas.mak + ;; Hadn't you been asked to drop these lines, as you are not yet adding any disassembler code that uses it? xtensa*) echo CONFIG_XTENSA_DIS=y $config_target_mak echo CONFIG_XTENSA_DIS=y config-all-disas.mak [...] diff --git a/target-tilegx/cpu-qom.h b/target-tilegx/cpu-qom.h new file mode 100644 index 000..e15a8b8 --- /dev/null +++ b/target-tilegx/cpu-qom.h @@ -0,0 +1,72 @@ +/* + * QEMU Tilegx CPU TILE-Gx according to http://www.tilera.com/products/?ezchip=585spage=614 - please fix wherever used in textual form. + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * http://www.gnu.org/licenses/lgpl-2.1.html + */ +#ifndef QEMU_TILEGX_CPU_QOM_H +#define QEMU_TILEGX_CPU_QOM_H + +#include qom/cpu.h + +#define TYPE_TILEGX_CPU tilegx-cpu + +#define TILEGX_CPU_CLASS(klass) \ +OBJECT_CLASS_CHECK(TilegxCPUClass, (klass), TYPE_TILEGX_CPU) +#define TILEGX_CPU(obj) \ +OBJECT_CHECK(TilegxCPU, (obj), TYPE_TILEGX_CPU) +#define TILEGX_CPU_GET_CLASS(obj) \ +OBJECT_GET_CLASS(TilegxCPUClass, (obj), TYPE_TILEGX_CPU) + +/** + * TilegxCPUClass: + * @parent_realize: The parent class' realize handler. + * @parent_reset: The parent class' reset handler. + * + * A Tilegx CPU model. + */ +typedef struct TilegxCPUClass { For the benefit of readers, please call this TileGXCPUClass ... +/* private */ +CPUClass parent_class; +/* public */ + +DeviceRealize parent_realize; +void (*parent_reset)(CPUState *cpu); +} TilegxCPUClass; + +/** + * TilegxCPU: + * @env: #CPUTLState + * + * A Tilegx CPU. + */ +typedef struct TilegxCPU { ... and TileGXCPU. (or TileGx...) +/* private */ +CPUState parent_obj; +uint64_t base_vectors; This should not be in here, the private section serves to hide the parent field from documentation. base_vectors should also probably be after env, for performance reasons. rth? +/* public */ + +CPUTLState env; Can this be more telling than TL please? +} TilegxCPU; + +static inline TilegxCPU *tilegx_env_get_cpu(CPUTLState *env) +{ +return container_of(env, TilegxCPU, env); +} + +#define ENV_GET_CPU(e) CPU(tilegx_env_get_cpu(e)) + +#endif diff --git a/target-tilegx/cpu.c b/target-tilegx/cpu.c new file mode 100644 index 000..3dd66b5 --- /dev/null +++ b/target-tilegx/cpu.c @@ -0,0 +1,162 @@ +/* + * QEMU Tilegx
Re: [Qemu-devel] [PATCH 4/6 v4] linux-user: Support tilegx architecture in syscall
Am 22.02.2015 um 14:36 schrieb Chen Gang S: Add tilegx architecture in syscall_defs.h, all related features (ioctrl, and stat) are based on Linux kernel tilegx 64-bit implementation. Signed-off-by: Chen Gang gang.chen.5...@gmail.com --- linux-user/syscall_defs.h | 38 ++ 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 9ed6de8..a0d9d77 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h [...] @@ -2312,7 +2340,9 @@ struct target_flock { struct target_flock64 { short l_type; short l_whence; -#if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) || defined(TARGET_SPARC) || defined(TARGET_HPPA) || defined (TARGET_MICROBLAZE) +#if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) || \ +defined(TARGET_SPARC) || defined(TARGET_HPPA) \ +|| defined(TARGET_MICROBLAZE) || defined(TARGET_TILEGX) Nit: You're inconsistent as to where you're placing ||. Regards, Andreas int __pad; #endif unsigned long long l_start; -- SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu, Graham Norton; HRB 21284 (AG Nürnberg)
Re: [Qemu-devel] [PATCH] gitignore: Track common.env in iotests gitignore
On 02/27/2015 08:21 AM, Cole Robinson wrote: Rather than track it in the toplevel gitignore Signed-off-by: Cole Robinson crobi...@redhat.com --- .gitignore| 1 - tests/qemu-iotests/.gitignore | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) I think that the fact that we have multiple .gitignore is confusing, and would personally lean towards a patch that consolidates ALL ignores into a single top-level file, instead of having to hunt multiple files for patterns. But my opinion on this matter is not strong enough for me to provide a patch at this time... -- 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 v2 6/9] qtest/ahci: add migrate dma test
On 02/27/2015 09:30 AM, Paolo Bonzini wrote: On 27/02/2015 00:50, John Snow wrote: +/* Write, migrate, then read. */ +ahci_io(src, px, CMD_WRITE_DMA, tx, bufsize, 0); +ahci_migrate(src, dst, uri); +ahci_io(dst, px, CMD_READ_DMA, rx, bufsize, 0); IIUC, tests for READ_FPDMA_QUEUED and WRITE_FPDMA_QUEUED are going to be in a separate patch series, right? Paolo I can keep more tests coming. I don't have a big suite for NCQ or ATAPI at the moment, but it's planned. Migration is about as far as I got in my downstream development before I switched focus to other things while I let the dust settle on all the patches I sent out. Now that my backlog is cleared more, I can go back to writing more tests here and there. Should be a lot easier now that there's a boatload of primitives to make the process a lot quicker. --js
[Qemu-devel] [PATCH v4 07/11] blockdev: Use blk_remove_bs() in do_drive_del()
Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com --- blockdev.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/blockdev.c b/blockdev.c index f198be6..e5f5ebc 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2229,11 +2229,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) } /* quiesce block driver; prevent further io */ -bdrv_drain_all(); -if (bs) { -bdrv_flush(bs); -bdrv_close(bs); -} +blk_remove_bs(blk); /* if we have a device attached to this BlockDriverState * then we need to make the drive anonymous until the device -- 2.1.0
Re: [Qemu-devel] [PATCH v2] migration: Convert 'status' of MigrationInfo to use an enum type
On 02/26/2015 11:19 PM, zhanghailiang wrote: The original 'status' is an open-coded 'str' type, convert it to use an enum type. This conversion is backwards compatible, better documented and more convenient for future extensibility. In addition, Fix a typo for qapi-schema.json: comppleted - completed Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- v2: - Remove '(since xyz)' strings. (Eric Blake) --- hmp.c | 7 --- migration/migration.c | 37 +++-- qapi-schema.json | 37 - 3 files changed, 51 insertions(+), 30 deletions(-) case MIG_STATE_ACTIVE: case MIG_STATE_CANCELLING: info-has_status = true; -info-status = g_strdup(active); +/* Note: when the real state of migration is 'cancelling', + we still return 'active' status to user, it makes no difference + for user. */ Rather than pollute the user-exposed enum with a state that we will never report, can we come up with some internal-only method for tracking cancelling separate from the enum? +++ b/qapi-schema.json @@ -411,18 +411,45 @@ 'overflow': 'int' } } ## +# @MigState: Do we have to abbreviate? I guess leaving it like this makes the rest of the existing code base have less churn (since it matches the spelling of the enum that was previous interanl only), but it might look nicer as MigrationState. If you do decide to go with a longer name, it might be nice to split this into a series, one patch that does only renames to migration.c (but no code additions outside of that file), and the other that moves the (now-correctly-named) enum into the public qapi file. +# +# An enumeration of migration status. +# +# @failed: some error occurred during migration process. +# +# @none: no migration has ever happened. +# +# @setup: migration process has been initiated. +# +# @cancelling: in the process of cancelling migration. +# If the user can never see this state, I'd rather we think about a solution that avoids advertising the state in the public api... +# @cancelled: cancelling migration is finished. +# +# @active: in the process of doing migration. +# +# @completed: migration is finished. +# +# Since: 2.3 +# +# Notes: @cancelling is only used internally, and return @active to user +#instead of @cancelling, it make no difference for users. ...rather than needing this note to air our dirty laundry. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
[Qemu-devel] [PATCH v4 01/11] iotests: Move _filter_nbd into common.filter
_filter_nbd can be useful for other NBD tests, too, therefore it should reside in common.filter, and it should support URLs of the nbd:// format and export names. The NBD log lines (/your/source/dir/nbd.c:function():line: error) should not be converted to empty lines but removed altogether. Signed-off-by: Max Reitz mre...@redhat.com --- tests/qemu-iotests/083 | 13 + tests/qemu-iotests/083.out | 10 -- tests/qemu-iotests/common.filter | 12 3 files changed, 13 insertions(+), 22 deletions(-) diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083 index 1b2d3f1..aa99278 100755 --- a/tests/qemu-iotests/083 +++ b/tests/qemu-iotests/083 @@ -49,17 +49,6 @@ wait_for_tcp_port() { done } -filter_nbd() { - # nbd.c error messages contain function names and line numbers that are prone - # to change. Message ordering depends on timing between send and receive - # callbacks sometimes, making them unreliable. - # - # Filter out the TCP port number since this changes between runs. - sed -e 's#^.*nbd\.c:.*##g' \ - -e 's#nbd:127\.0\.0\.1:[^:]*:#nbd:127\.0\.0\.1:PORT:#g' \ --e 's#\(exportname=foo\|PORT\): Failed to .*$#\1#' -} - check_disconnect() { event=$1 when=$2 @@ -84,7 +73,7 @@ EOF $PYTHON nbd-fault-injector.py $extra_args 127.0.0.1:$port $TEST_DIR/nbd-fault-injector.conf 21 /dev/null wait_for_tcp_port 127\\.0\\.0\\.1:$port - $QEMU_IO -c read 0 512 $nbd_url 21 | _filter_qemu_io | filter_nbd + $QEMU_IO -c read 0 512 $nbd_url 21 | _filter_qemu_io | _filter_nbd echo } diff --git a/tests/qemu-iotests/083.out b/tests/qemu-iotests/083.out index 8c1441b..5c9141b 100644 --- a/tests/qemu-iotests/083.out +++ b/tests/qemu-iotests/083.out @@ -51,7 +51,6 @@ no file open, try 'help open' === Check disconnect after neg2 === - read failed: Input/output error === Check disconnect 8 neg2 === @@ -66,42 +65,34 @@ no file open, try 'help open' === Check disconnect before request === - read failed: Input/output error === Check disconnect after request === - read failed: Input/output error === Check disconnect before reply === - read failed: Input/output error === Check disconnect after reply === - read failed: Input/output error === Check disconnect 4 reply === - read failed: Input/output error === Check disconnect 8 reply === - read failed: Input/output error === Check disconnect before data === - read failed: Input/output error === Check disconnect after data === - read 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -132,7 +123,6 @@ no file open, try 'help open' === Check disconnect after neg-classic === - read failed: Input/output error *** done diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index 012a812..99a1fc2 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -225,5 +225,17 @@ _filter_qemu_img_map() -e 's/Mapped to *//' | _filter_testdir | _filter_imgfmt } +_filter_nbd() +{ +# nbd.c error messages contain function names and line numbers that are +# prone to change. Message ordering depends on timing between send and +# receive callbacks sometimes, making them unreliable. +# +# Filter out the TCP port number since this changes between runs. +sed -e '/nbd\.c:/d' \ +-e 's#nbd:\(//\)\?127\.0\.0\.1:[0-9]*#nbd:\1127.0.0.1:PORT#g' \ +-e 's#\(exportname=foo\|PORT\): Failed to .*$#\1#' +} + # make sure this script returns success true -- 2.1.0
[Qemu-devel] [PULL v2 05/11] rocker: add register programming guide
From: Scott Feldman sfel...@gmail.com This is the register programming guide for the Rocker device. It's intended for driver writers and device writers. It covers the device's PCI space, the register set, DMA interface, and interrupts. Signed-off-by: Scott Feldman sfel...@gmail.com Signed-off-by: Jiri Pirko j...@resnulli.us Message-id: 1424123271-7656-4-git-send-email-sfel...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- docs/specs/rocker.txt | 1009 + 1 file changed, 1009 insertions(+) create mode 100644 docs/specs/rocker.txt diff --git a/docs/specs/rocker.txt b/docs/specs/rocker.txt new file mode 100644 index 000..1e7e1e1 --- /dev/null +++ b/docs/specs/rocker.txt @@ -0,0 +1,1009 @@ +Rocker Network Switch Register Programming Guide +Copyright (c) Scott Feldman sfel...@gmail.com +Copyright (c) Neil Horman nhor...@tuxdriver.com +Version 0.11, 12/29/2014 + +LICENSE +=== + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +SECTION 1: Introduction +=== + +Overview + + +This document describes the hardware/software interface for the Rocker switch +device. The intended audience is authors of OS drivers and device emulation +software. + +Notations and Conventions +- + +o In register descriptions, [n:m] indicates a range from bit n to bit m, +inclusive. +o Use of leading 0x indicates a hexadecimal number. +o Use of leading 0b indicates a binary number. +o The use of RSVD or Reserved indicates that a bit or field is reserved for +future use. +o Field width is in bytes, unless otherwise noted. +o Register are (R) read-only, (R/W) read/write, (W) write-only, or (COR) clear +on read +o TLV values in network-byte-order are designated with (N). + + +SECTION 2: PCI Configuration Registers +== + +PCI Configuration Space +--- + +Each switch instance registers as a PCI device with PCI configuration space: + + offset width description value + - + 0x0 2 Vendor ID 0x1b36 + 0x2 2 Device ID 0x0006 + 0x4 4 Command/Status + 0x8 1 Revision ID 0x01 + 0x9 3 Class code 0x2800 + 0xC 1 Cache line size + 0xD 1 Latency timer + 0xE 1 Header type + 0xF 1 Built-in self test + 0x104 Base address low + 0x144 Base address high + 0x18-28 Reserved + 0x2C2 Subsystem vendor ID * + 0x2E2 Subsystem ID* + 0x30-38 Reserved + 0x3C1 Interrupt line + 0x3D1 Interrupt pin 0x00 + 0x3E1 Min grant 0x00 + 0x3D1 Max latency 0x00 + 0x401 TRDY timeout + 0x411 Retry count + 0x422 Reserved + + +* Assigned by sub-system implementation + +SECTION 3: Memory-Mapped Register Space +=== + +There are two memory-mapped BARs. BAR0 maps device register space and is +0x2000 in size. BAR1 maps MSI-X vector and PBA tables and is also 0x2000 in +size, allowing for 256 MSI-X vectors. + +All registers are 4 or 8 bytes long. It is assumed host software will access 4 +byte registers with one 4-byte access, and 8 byte registers with either two +4-byte accesses or a single 8-byte access. In the case of two 4-byte accesses, +access must be lower and then upper 4-bytes, in that order. + +BAR0 device register space is organized as follows: + + offset description + -- + 0x-0x000f Bogus registers to catch misbehaving + drivers. Writes do nothing. Reads + back as 0xDEADBABE. + 0x0010-0x00ff Test registers + 0x0300-0x03ff General purpose registers + 0x1000-0x1fff Descriptor control + +Holes in register space are reserved. Writes to reserved registers do nothing. +Reads to reserved registers read back as 0. + +No fancy stuff like write-combining is enabled on any of the registers. + +BAR1 MSI-X register space is organized as follows: + + offset description + -- + 0x-0x0fff MSI-X vector
[Qemu-devel] [PULL v2 01/11] net: synchronize net_host_device_remove with host_net_remove_completion
From: Paolo Bonzini pbonz...@redhat.com Using net_host_check_device is unnecessary. qemu_del_net_client asserts for the non-peer case that it can only process NIC type NetClientStates, and that assertion is valid for the peered case as well, so move it and use the same check in net_host_device_remove. host_net_remove_completion is already checking the type. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Reviewed-by: Jason Wang jasow...@redhat.com Message-id: 1419353600-30519-2-git-send-email-pbonz...@redhat.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- net/net.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/net.c b/net/net.c index 5146361..3201516 100644 --- a/net/net.c +++ b/net/net.c @@ -324,6 +324,8 @@ void qemu_del_net_client(NetClientState *nc) NetClientState *ncs[MAX_QUEUE_NUM]; int queues, i; +assert(nc-info-type != NET_CLIENT_OPTIONS_KIND_NIC); + /* If the NetClientState belongs to a multiqueue backend, we will change all * other NetClientStates also. */ @@ -355,8 +357,6 @@ void qemu_del_net_client(NetClientState *nc) return; } -assert(nc-info-type != NET_CLIENT_OPTIONS_KIND_NIC); - for (i = 0; i queues; i++) { qemu_cleanup_net_client(ncs[i]); qemu_free_net_client(ncs[i]); @@ -991,7 +991,7 @@ void hmp_host_net_remove(Monitor *mon, const QDict *qdict) device, vlan_id); return; } -if (!net_host_check_device(nc-model)) { +if (nc-info-type == NET_CLIENT_OPTIONS_KIND_NIC) { error_report(invalid host network device '%s', device); return; } -- 2.1.0
[Qemu-devel] [PATCH 4/4] hw/mips: Do not clear BEV for MIPS malta kernel load
From: Matthew Fortune matthew.fort...@imgtec.com The BEV flag controls whether the boot exception vector is still in place when starting a kernel. When cleared the exception vector at EBASE (or hard coded address of 0x8000) is used instead. The early stages of the linux kernel would benefit from BEV still being set to ensure any faults get handled by the boot rom exception handlers. This is a moot point for system qemu as there aren't really any BEV handlers, but there are other good reasons to change this... The UHI (semi-hosting interface) defines special behaviours depending on whether an application starts in an environment with BEV set or cleared. When BEV is set then UHI assumes that a bootloader is relatively dumb and has no advanced exception handling logic. However, when BEV is cleared then UHI assumes that the bootloader has the ability to handle UHI exceptions with its exception handlers and will unwind and forward UHI SYSCALL exceptions to the exception vector that was installed prior to running the application. Signed-off-by: Matthew Fortune matthew.fort...@imgtec.com Signed-off-by: Leon Alrae leon.al...@imgtec.com --- hw/mips/mips_malta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 2dfe964..79fd671 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -890,7 +890,7 @@ static void main_cpu_reset(void *opaque) read only location. The kernel location and the arguments table location does not change. */ if (loaderparams.kernel_filename) { -env-CP0_Status = ~((1 CP0St_BEV) | (1 CP0St_ERL)); +env-CP0_Status = ~(1 CP0St_ERL); } malta_mips_config(cpu); -- 2.1.0
Re: [Qemu-devel] [PATCH v2] block/vdi: Add locking for parallel requests
Am 27.02.2015 um 17:57 schrieb Stefan Hajnoczi: On Fri, Feb 27, 2015 at 09:05:47AM -0500, Max Reitz wrote: Concurrently modifying the bmap does not seem to be a good idea; this patch adds a lock for it. See https://bugs.launchpad.net/qemu/+bug/1422307 for what can go wrong without. Cc: qemu-stable qemu-sta...@nongnu.org Signed-off-by: Max Reitz mre...@redhat.com --- v2: - Make the mutex cover vdi_co_write() completely [Kevin] - Add a TODO comment [Kevin] [...] If we don't know why bmap_lock works, it would be more approprate to take the same approach as VMDK and VHDX where there is a simply s-lock that protects all reads and writes. That way we know for sure there is no parallel I/O going on. (Since the problem is not understood, maybe reads in parallel with writes could also cause problems. Better to really do a coarse lock instead of just bmap_lock in write.) Stefan block/vdi.c was never written for multi-threaded access, see my comment in the header of block/vdi.c: * The code is not thread safe (missing locks for changes in header and * block table, no problem with current QEMU). This was true in the past, but obviously later multi-threaded access was introduced for QEMU. Locking was added for qcow2 and other drivers in 2012 and 2013, but never for vdi. I must admit that I don't know which parts of the block filesystem drivers potentially run in parallel threads. Ideally there would be one or more test cases which test multi-threaded operations and which trigger a failure with the current vdi code. If I had a simple test scenario, I could have a look on the problem. The VMDK approach is fine as an intermediate work around, but please use conditional compilation to allow easy tests without coarse locks (and update the comments :-)). Regards Stefan (Weil)
Re: [Qemu-devel] [PATCH v2] block/vdi: Add locking for parallel requests
On 2015-02-27 at 12:25, Stefan Weil wrote: Am 27.02.2015 um 17:57 schrieb Stefan Hajnoczi: On Fri, Feb 27, 2015 at 09:05:47AM -0500, Max Reitz wrote: Concurrently modifying the bmap does not seem to be a good idea; this patch adds a lock for it. See https://bugs.launchpad.net/qemu/+bug/1422307 for what can go wrong without. Cc: qemu-stable qemu-sta...@nongnu.org Signed-off-by: Max Reitz mre...@redhat.com --- v2: - Make the mutex cover vdi_co_write() completely [Kevin] - Add a TODO comment [Kevin] [...] If we don't know why bmap_lock works, it would be more approprate to take the same approach as VMDK and VHDX where there is a simply s-lock that protects all reads and writes. That way we know for sure there is no parallel I/O going on. (Since the problem is not understood, maybe reads in parallel with writes could also cause problems. Better to really do a coarse lock instead of just bmap_lock in write.) Stefan block/vdi.c was never written for multi-threaded access, see my comment in the header of block/vdi.c: * The code is not thread safe (missing locks for changes in header and * block table, no problem with current QEMU). This was true in the past, but obviously later multi-threaded access was introduced for QEMU. Locking was added for qcow2 and other drivers in 2012 and 2013, but never for vdi. I must admit that I don't know which parts of the block filesystem drivers potentially run in parallel threads.Ideally there would be one or more test cases which test multi-threaded operations and which trigger a failure with the current vdi code. If I had a simple test scenario, I could have a look on the problem. I have one for you. See the attached ruby script. (If there are no Pattern verification failed messages, everything is good) The VMDK approach is fine as an intermediate work around, but please use conditional compilation to allow easy tests without coarse locks (and update the comments :-)). Will a macro defined in vdi.c be enough? Max test.rb Description: application/ruby
Re: [Qemu-devel] [PATCH v2] block/vdi: Add locking for parallel requests
On 27/02/2015 18:25, Stefan Weil wrote: block/vdi.c was never written for multi-threaded access, see my comment in the header of block/vdi.c: It is not using threads, only coroutines. Preemption points of coroutines are well defined, and I think that the bug could be present even in the initial AIO-based version. * The code is not thread safe (missing locks for changes in header and * block table, no problem with current QEMU). This was true in the past, but obviously later multi-threaded access was introduced for QEMU. Locking was added for qcow2 and other drivers in 2012 and 2013, but never for vdi. qcow2 already had locking (based on AsyncContexts) before the conversion to coroutines. Other drivers implicitly had locking because they were synchronous; locking was added because the conversion to coroutines made them asynchronous. vdi never got its locking because it was already asynchronous. Paolo
Re: [Qemu-devel] [PULL 08/11] linux-user: Check for cpu_init() errors
On Fri, Feb 27, 2015 at 08:23:12AM +0900, Peter Maydell wrote: On 27 February 2015 at 08:11, Eduardo Habkost ehabk...@redhat.com wrote: On Fri, Feb 27, 2015 at 08:00:25AM +0900, Peter Maydell wrote: On 27 February 2015 at 07:51, Eduardo Habkost ehabk...@redhat.com wrote: I have never seen it in practice, but in x86 it will fail if we try to create more than 254 VCPUs. That's bad -- it's not hard to imagine a program with 256 threads. Why does x86 have this limitation and can we fix it? That seems like the better course than this patch. I don't think *-user or any x86-specific code has any hard requirement of having all VCPUs with different APIC IDs. But right now we set APIC ID = cpu_index for every VCPU, so the current code has this limitation. But the -user code doesn't have an APIC at all, so it shouldn't have to live with this limitation. Yes. I don't know yet if we can safely set apic_id=0 on all usermode VCPUs (maybe some existing code will break if we do that), but we should be able to do it eventually. I would be glad to send a patch adding an assert() instead of an error message, but I don't think I will be able to audit every single cpu_init() function soon (to ensure they really never fail). So, while we don't audit all cpu_init() functions, do you prefer to live with an error message, or an assert() that may or may not be triggered by existing code? I would prefer: (1) that we fix the error handling properly so you return an error indication from cpu_copy() and we propagate it back to the guest (2) that we fix x86-64 so it can create more than 254 CPUs for usermode I would rather not paper over this by adding a let qemu assert or fatally exit on a recoverable error condition code path we'd just have to revert when we fixed (1) properly. (2) is not really important to deal with right now, since we don't actually support multiple threads yet. But it would be nice eventually. So, I have taken a look at the cpu_init() implementations, and all of them seem to never fail unless an invalid CPU model string is used, except for i386. So it looks like there's no compelling reason to write extra code for (1) right now if we fix (2). On the other hand, we will always have the possibility of somebody introducing additional cpu_init() error conditions in some architecture in the future (that's why I suggested adding an assert()). Personally, I don't mind either way. I will just leave this for the developers interested in linux-user. -- Eduardo
Re: [Qemu-devel] [PATCH v2] migration: Convert 'status' of MigrationInfo to use an enum type
On 02/27/2015 10:07 AM, Dr. David Alan Gilbert wrote: Rather than pollute the user-exposed enum with a state that we will never report, can we come up with some internal-only method for tracking cancelling separate from the enum? Well I guess we could just report it; but would that break any external tools? It might - I seem to recall in the past that when we added a new state string, that at least libvirt choked when encountering the unknown string (but I don't recall if it was migration or something else). At least libvirt already has an enum tracking: enum { QEMU_MONITOR_MIGRATION_STATUS_INACTIVE, QEMU_MONITOR_MIGRATION_STATUS_ACTIVE, QEMU_MONITOR_MIGRATION_STATUS_COMPLETED, QEMU_MONITOR_MIGRATION_STATUS_ERROR, QEMU_MONITOR_MIGRATION_STATUS_CANCELLED, QEMU_MONITOR_MIGRATION_STATUS_SETUP, QEMU_MONITOR_MIGRATION_STATUS_LAST }; and a string mapping of just the following states: VIR_ENUM_IMPL(qemuMonitorMigrationStatus, QEMU_MONITOR_MIGRATION_STATUS_LAST, inactive, active, completed, failed, cancelled, setup) Furthermore, the function qemuMigrationUpdateJobStatus() is doing various things depending on the observed state, where the current trick of treating 'cancelling' like 'active' would mean that changing 'cancelling' to be an independent state WOULD have observable behavior change in libvirt. But I don't know if the change would break things, or if it would still end up resolving nicely (after all, cancelling only occurs for a short window before the migration aborts anyway, so it might just sort itself out when it finally gets to cancelled). On the other hand, we can argue that clients that are unprepared to handle new enum states gracefully are broken, and we also have the argument that it is okay for a new qemu to require a new libvirt release (the other direction is not okay - a new libvirt must not require upgrading to a new qemu). So exposing 'cancelling' may make this patch easier. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
[Qemu-devel] [Bug 1426472] [NEW] Recent regression: segfault on startup with -snapshot
Public bug reported: As of git revision 041ccc922ee474693a2869d4e3b59e920c739bc0, qemu segfaults on startup when I try to boot a hard disk image with the -snapshot option. To reproduce: wget http://wiki.qemu.org/download/linux-0.2.img.bz2 bunzip2 linux-0.2.img.bz2 qemu-system-i386 -hda linux-0.2.img -snapshot When I run this, qemu-system-i386 crashes with a segmentation fault. This is on a Debian 7 amd64 host. git bisect implicates the following commit: commit a464982499b2f637f6699e3d03e0a9d2e0b5288b Author: Paolo Bonzini pbonz...@redhat.com Date: Wed Feb 11 17:15:18 2015 +0100 rcu: run RCU callbacks under the BQL This needs to go away sooner or later, but one complication is the complex VFIO data structures that are modified in instance_finalize. Take a shortcut for now. Reviewed-by: Michael Roth mdr...@linux.vnet.ibm.com Tested-by: Michael Roth mdr...@linux.vnet.ibm.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1426472 Title: Recent regression: segfault on startup with -snapshot Status in QEMU: New Bug description: As of git revision 041ccc922ee474693a2869d4e3b59e920c739bc0, qemu segfaults on startup when I try to boot a hard disk image with the -snapshot option. To reproduce: wget http://wiki.qemu.org/download/linux-0.2.img.bz2 bunzip2 linux-0.2.img.bz2 qemu-system-i386 -hda linux-0.2.img -snapshot When I run this, qemu-system-i386 crashes with a segmentation fault. This is on a Debian 7 amd64 host. git bisect implicates the following commit: commit a464982499b2f637f6699e3d03e0a9d2e0b5288b Author: Paolo Bonzini pbonz...@redhat.com Date: Wed Feb 11 17:15:18 2015 +0100 rcu: run RCU callbacks under the BQL This needs to go away sooner or later, but one complication is the complex VFIO data structures that are modified in instance_finalize. Take a shortcut for now. Reviewed-by: Michael Roth mdr...@linux.vnet.ibm.com Tested-by: Michael Roth mdr...@linux.vnet.ibm.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1426472/+subscriptions
Re: [Qemu-devel] [PATCH] iscsi: Handle write protected case in reopen
Am 27.02.2015 um 15:20 schrieb Paolo Bonzini: On 25/02/2015 05:40, Fam Zheng wrote: Save the write protected flag and check before reopen. Signed-off-by: Fam Zheng f...@redhat.com --- block/iscsi.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 12ddbfb..00041bf 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -65,6 +65,7 @@ typedef struct IscsiLun { unsigned long *allocationmap; int cluster_sectors; bool use_16_for_rw; +bool write_proteced; Corrected to write_protecTed and applied. Is this a bug fix? qemu-stable? Peter
Re: [Qemu-devel] [PATCH v7 5/5] BlockConf: Call backend functions to detect geometry and blocksizes
On 2015-02-16 at 06:47, Ekaterina Tumanova wrote: geometry: hd_geometry_guess function autodetects the drive geometry. This patch adds a block backend call, that probes the backing device geometry. If the inner driver method is implemented and succeeds (currently only for DASDs), the blkconf_geometry will pass-through the backing device geometry. Otherwise will fallback to old logic. blocksize: This patch initializes blocksize properties to 0. In order to set the property a blkconf_blocksizes was introduced. If user didn't set physical or logical blocksize, it will retrieve its value from a driver (only succeeds for DASD), otherwise it will set default 512 value. The blkconf_blocksizes call was added to all users of BlkConf. Signed-off-by: Ekaterina Tumanova tuman...@linux.vnet.ibm.com Reviewed-by: Markus Armbruster arm...@redhat.com Reviewed-by: Stefan Hajnoczi stefa...@redhat.com --- hw/block/block.c | 24 hw/block/hd-geometry.c | 10 +- hw/block/nvme.c | 1 + hw/block/virtio-blk.c| 1 + hw/core/qdev-properties.c| 3 ++- hw/ide/qdev.c| 1 + hw/scsi/scsi-disk.c | 2 ++ hw/usb/dev-storage.c | 1 + include/hw/block/block.h | 5 +++-- include/hw/qdev-properties.h | 4 ++-- 10 files changed, 46 insertions(+), 6 deletions(-) This patch makes qemu segfault if the drive property is not set for a scsi-hd device: $ x86_64-softmmu/qemu-system-x86_64 -device virtio-scsi-pci -device scsi-hd [1]13368 segmentation fault (core dumped) x86_64-softmmu/qemu-system-x86_64 -device virtio-scsi-pci -device scsi-hd (gdb) bt #0 0x7f0a77620f50 in blk_probe_blocksizes (blk=0x0, bsz=0x7fffd989f110) at block/block-backend.c:898 #1 0x7f0a774eb943 in blkconf_blocksizes (conf=conf@entry=0x7f0a7b1e71c0) at hw/block/block.c:34 #2 0x7f0a7755e5a8 in scsi_hd_realize (dev=0x7f0a7b1e7130, errp=0x7fffd989f150) at hw/scsi/scsi-disk.c:2294 #3 0x7f0a77564671 in scsi_qdev_realize (errp=0x7fffd989f150, s=0x7f0a7b1e7130) at hw/scsi/scsi-bus.c:50 #4 0x7f0a77564671 in scsi_qdev_realize (qdev=optimized out, errp=0x7fffd989f190) at hw/scsi/scsi-bus.c:197 #5 0x7f0a77502b71 in device_set_realized (obj=0x7f0a7b1e7130, value=optimized out, errp=0x7fffd989f2c8) at hw/core/qdev.c:1047 #6 0x7f0a775b1e0e in property_set_bool (obj=0x7f0a7b1e7130, v=optimized out, opaque=0x7f0a7b1e73e0, name=optimized out, errp=0x7fffd989f2c8) at qom/object.c:1514 #7 0x7f0a775b4707 in object_property_set_qobject (obj=0x7f0a7b1e7130, value=optimized out, name=0x7f0a7769e3cd realized, errp=0x7fffd989f2c8) at qom/qom-qobject.c:24 #8 0x7f0a775b32a0 in object_property_set_bool (obj=obj@entry=0x7f0a7b1e7130, value=value@entry=true, name=name@entry=0x7f0a7769e3cd realized, errp=errp@entry=0x7fffd989f2c8) at qom/object.c:905 #9 0x7f0a774a8ca5 in qdev_device_add (opts=0x7f0a799fa3f0) at qdev-monitor.c:574 #10 0x7f0a774b1df9 in device_init_func (opts=optimized out, opaque=optimized out) at qemu/vl.c:2127 #11 0x7f0a7766803b in qemu_opts_foreach (list=optimized out, func=0x7f0a774b1df0 device_init_func, opaque=0x0, abort_on_failure=optimized out) at util/qemu-option.c:1057 #12 0x7f0a773b96ec in main (argc=optimized out, argv=optimized out, envp=optimized out) at vl.c:4239 Before this patch: $ x86_64-softmmu/qemu-system-x86_64 -device virtio-scsi-pci -device scsi-hd qemu-system-x86_64: -device scsi-hd: drive property not set qemu-system-x86_64: -device scsi-hd: Device 'scsi-hd' could not be initialized Max
[Qemu-devel] [PATCH v4 02/11] iotests: Make redirecting qemu's stderr optional
Redirecting qemu's stderr to stdout makes working with the stderr output difficult due to the other file descriptor magic performed in _launch_qemu (ambiguous redirect). Add an option which specifies whether stderr should be redirected to stdout or not (allowing for other modes to be added in the future). Signed-off-by: Max Reitz mre...@redhat.com --- tests/qemu-iotests/common.qemu | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu index 4e1996c..1b5a554 100644 --- a/tests/qemu-iotests/common.qemu +++ b/tests/qemu-iotests/common.qemu @@ -131,6 +131,8 @@ function _send_qemu_cmd() # $qemu_comm_method: set this variable to 'monitor' (case insensitive) #to use the QEMU HMP monitor for communication. #Otherwise, the default of QMP is used. +# $keep_stderr: Set this variable to 'y' to keep QEMU's stderr output on stderr. +# If this variable is empty, stderr will be redirected to stdout. # Returns: # $QEMU_HANDLE: set to a handle value to communicate with this QEMU instance. # @@ -153,10 +155,18 @@ function _launch_qemu() mkfifo ${fifo_out} mkfifo ${fifo_in} -${QEMU} -nographic -serial none ${comm} -machine accel=qtest ${@} \ +if [ -z $keep_stderr ]; then +${QEMU} -nographic -serial none ${comm} -machine accel=qtest ${@} \ ${fifo_out} \ 21 \ ${fifo_in} +elif [ $keep_stderr = y ]; then +${QEMU} -nographic -serial none ${comm} -machine accel=qtest ${@} \ +${fifo_out} \ +${fifo_in} +else +exit 1 +fi QEMU_PID[${_QEMU_HANDLE}]=$! if [[ ${BASH_VERSINFO[0]} -ge 5 || -- 2.1.0
Re: [Qemu-devel] [patch qemu] rocker: fix 32bit build
On Fri, Feb 27, 2015 at 03:07:17PM +0100, Jiri Pirko wrote: For printf format of uint64_t and size_t use TARGET_FMT_plx and %zu Signed-off-by: Jiri Pirko j...@resnulli.us --- hw/net/rocker/rocker.c | 32 +--- hw/net/rocker/rocker_desc.c | 6 +++--- 2 files changed, 20 insertions(+), 18 deletions(-) Thanks! In the future, please send a new revision of the original series instead of a fix-up patch. Adding a patch on top will break git-bisect(1) since there are a couple of commits with the build failure before your fix. I am squashing this into the rocker: add new rocker switch device commit so that git-bisect(1) continues to work. diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index 672cf5a..4105275 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -774,8 +774,8 @@ static void rocker_io_writel(void *opaque, hwaddr addr, uint32_t val) } break; default: -DPRINTF(not implemented dma reg write(l) addr=0x%lx -val=0x%08x (ring %d, addr=0x%02x)\n, +DPRINTF(not implemented dma reg write(l) addr=0x TARGET_FMT_plx + val=0x%08x (ring %d, addr=0x%02x)\n, addr, val, index, offset); break; } @@ -816,7 +816,8 @@ static void rocker_io_writel(void *opaque, hwaddr addr, uint32_t val) r-lower32 = 0; break; default: -DPRINTF(not implemented write(l) addr=0x%lx val=0x%08x\n, addr, val); +DPRINTF(not implemented write(l) addr=0x TARGET_FMT_plx + val=0x%08x\n, addr, val); break; } } @@ -834,8 +835,8 @@ static void rocker_io_writeq(void *opaque, hwaddr addr, uint64_t val) desc_ring_set_base_addr(r-rings[index], val); break; default: -DPRINTF(not implemented dma reg write(q) addr=0x%lx -val=0x%016lx (ring %d, offset=0x%02x)\n, +DPRINTF(not implemented dma reg write(q) addr=0x TARGET_FMT_plx + val=0x TARGET_FMT_plx (ring %d, offset=0x%02x)\n, addr, val, index, offset); break; } @@ -853,8 +854,8 @@ static void rocker_io_writeq(void *opaque, hwaddr addr, uint64_t val) rocker_port_phys_enable_write(r, val); break; default: -DPRINTF(not implemented write(q) addr=0x%lx val=0x%016lx\n, -addr, val); +DPRINTF(not implemented write(q) addr=0x TARGET_FMT_plx + val=0x TARGET_FMT_plx \n, addr, val); break; } } @@ -945,7 +946,8 @@ static const char *rocker_reg_name(void *opaque, hwaddr addr) static void rocker_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { -DPRINTF(Write %s addr %lx, size %u, val %lx\n, +DPRINTF(Write %s addr TARGET_FMT_plx +, size %u, val TARGET_FMT_plx \n, rocker_reg_name(opaque, addr), addr, size, val); switch (size) { @@ -1017,8 +1019,8 @@ static uint32_t rocker_io_readl(void *opaque, hwaddr addr) ret = desc_ring_get_credits(r-rings[index]); break; default: -DPRINTF(not implemented dma reg read(l) addr=0x%lx -(ring %d, addr=0x%02x)\n, addr, index, offset); +DPRINTF(not implemented dma reg read(l) addr=0x TARGET_FMT_plx + (ring %d, addr=0x%02x)\n, addr, index, offset); ret = 0; break; } @@ -1072,7 +1074,7 @@ static uint32_t rocker_io_readl(void *opaque, hwaddr addr) ret = (uint32_t)(r-switch_id 32); break; default: -DPRINTF(not implemented read(l) addr=0x%lx\n, addr); +DPRINTF(not implemented read(l) addr=0x TARGET_FMT_plx \n, addr); ret = 0; break; } @@ -1093,8 +1095,8 @@ static uint64_t rocker_io_readq(void *opaque, hwaddr addr) ret = desc_ring_get_base_addr(r-rings[index]); break; default: -DPRINTF(not implemented dma reg read(q) addr=0x%lx -(ring %d, addr=0x%02x)\n, addr, index, offset); +DPRINTF(not implemented dma reg read(q) addr=0x TARGET_FMT_plx + (ring %d, addr=0x%02x)\n, addr, index, offset); ret = 0; break; } @@ -1122,7 +1124,7 @@ static uint64_t rocker_io_readq(void *opaque, hwaddr addr) ret = r-switch_id; break; default: -DPRINTF(not implemented read(q) addr=0x%lx\n, addr); +DPRINTF(not implemented read(q) addr=0x TARGET_FMT_plx \n, addr); ret = 0; break; } @@ -1131,7 +1133,7 @@ static uint64_t rocker_io_readq(void *opaque, hwaddr addr) static uint64_t rocker_mmio_read(void *opaque, hwaddr
Re: [Qemu-devel] [PATCH v2] block/vdi: Add locking for parallel requests
On 2015-02-27 at 11:57, Stefan Hajnoczi wrote: On Fri, Feb 27, 2015 at 09:05:47AM -0500, Max Reitz wrote: Concurrently modifying the bmap does not seem to be a good idea; this patch adds a lock for it. See https://bugs.launchpad.net/qemu/+bug/1422307 for what can go wrong without. Cc: qemu-stable qemu-sta...@nongnu.org Signed-off-by: Max Reitz mre...@redhat.com --- v2: - Make the mutex cover vdi_co_write() completely [Kevin] - Add a TODO comment [Kevin] --- block/vdi.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/block/vdi.c b/block/vdi.c index 74030c6..f5f42ef 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -51,6 +51,7 @@ #include qemu-common.h #include block/block_int.h +#include block/coroutine.h #include qemu/module.h #include migration/migration.h @@ -196,6 +197,8 @@ typedef struct { /* VDI header (converted to host endianness). */ VdiHeader header; +CoMutex bmap_lock; + Error *migration_blocker; } BDRVVdiState; @@ -498,6 +501,8 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags, goto fail_free_bmap; } +qemu_co_mutex_init(s-bmap_lock); + /* Disable migration when vdi images are used */ error_set(s-migration_blocker, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, @@ -607,6 +612,9 @@ static int vdi_co_write(BlockDriverState *bs, logout(\n); +/* TODO: Figure out why this is necessary */ +qemu_co_mutex_lock(s-bmap_lock); If we don't know why bmap_lock works, it would be more approprate to take the same approach as VMDK and VHDX where there is a simply s-lock that protects all reads and writes. That way we know for sure there is no parallel I/O going on. (Since the problem is not understood, maybe reads in parallel with writes could also cause problems. Better to really do a coarse lock instead of just bmap_lock in write.) OK, will do. Max
[Qemu-devel] [PATCH 3/4] target-mips: add -semihosting-arg option and implement UHI Arg* ops
Add new command line option -semihosting-arg. It is used for passing input arguments to the guest in semihosting mode. The option can be used multiple times. If n arguments are passed, then argument count (semihosting_argc) will be equal to n+1 as semihosting_argv[0] points at the program name. However, if no arguments are passed then argument count will be 0. Also tweak Malta's pseudo-bootloader. On CPU reset the $4 register is set to -1 when semihosting is enabled in order to indicate that the UHI operations should be used to obtain input arguments. Signed-off-by: Leon Alrae leon.al...@imgtec.com --- hw/mips/mips_malta.c| 8 +++- include/sysemu/sysemu.h | 2 ++ qemu-options.hx | 8 target-mips/mips-semi.c | 38 +- target-mips/translate.c | 7 +++ vl.c| 28 6 files changed, 89 insertions(+), 2 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 5845158..2dfe964 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -634,7 +634,13 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, /* Second part of the bootloader */ p = (uint32_t *) (base + 0x580); -stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */ + +if (semihosting_enabled) { +/* Preserve a0 content when semihosting is enabled. */ +stl_p(p++, 0x); /* nop */ +} else { +stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */ +} stl_p(p++, 0x3c1d | (((ENVP_ADDR - 64) 16) 0x)); /* lui sp, high(ENVP_ADDR) */ stl_p(p++, 0x37bd | ((ENVP_ADDR - 64) 0x));/* ori sp, sp, low(ENVP_ADDR) */ stl_p(p++, 0x3c05 | ((ENVP_ADDR 16) 0x)); /* lui a1, high(ENVP_ADDR) */ diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 1ab7063..7d63da2 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -125,6 +125,8 @@ extern int graphic_rotate; extern int no_quit; extern int no_shutdown; extern int semihosting_enabled; +extern const char **semihosting_argv; +extern int semihosting_argc; extern int old_param; extern int boot_menu; extern bool boot_strict; diff --git a/qemu-options.hx b/qemu-options.hx index 99ad1ae..bd058d0 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3240,6 +3240,14 @@ Enable semihosting and define where the semihosting calls will be addressed, to QEMU (@code{native}) or to GDB (@code{gdb}). The default is @code{auto}, which means @code{gdb} during debug sessions and @code{native} otherwise (ARM, M68K, Xtensa only). ETEXI +DEF(semihosting-arg, HAS_ARG, QEMU_OPTION_semihosting_arg, +-semihosting-argarguments passed to the guest program\n, +QEMU_ARCH_MIPS) +STEXI +@item -semihosting-arg +@findex -semihosting-arg +Arguments passed to the guest program (MIPS only). +ETEXI DEF(old-param, 0, QEMU_OPTION_old_param, -old-param old param mode\n, QEMU_ARCH_ARM) STEXI diff --git a/target-mips/mips-semi.c b/target-mips/mips-semi.c index 3bf7b2a..63f2700 100644 --- a/target-mips/mips-semi.c +++ b/target-mips/mips-semi.c @@ -21,6 +21,9 @@ #include cpu.h #include exec/helper-proto.h #include exec/softmmu-semi.h +#ifndef CONFIG_USER_ONLY +#include sysemu/sysemu.h +#endif typedef enum UHIOp { UHI_exit = 1, @@ -71,6 +74,12 @@ enum UHIOpenFlags { UHIOpen_EXCL = 0x800 }; +#ifdef CONFIG_USER_ONLY +/* Suppress compiler errors in linux-user. */ +static const char **semihosting_argv; +static int semihosting_argc; +#endif + static int copy_stat_to_target(CPUMIPSState *env, const struct stat *src, target_ulong vaddr) { @@ -169,6 +178,21 @@ static int read_from_file(CPUMIPSState *env, target_ulong fd, return num_of_bytes; } +static int copy_argn_to_target(CPUMIPSState *env, int arg_num, + target_ulong vaddr) +{ +int strsize = strlen(semihosting_argv[arg_num]) + 1; +char *dst = lock_user(VERIFY_WRITE, vaddr, strsize, 0); +if (!dst) { +return -1; +} + +strcpy(dst, semihosting_argv[arg_num]); + +unlock_user(dst, vaddr, strsize); +return 0; +} + #define GET_TARGET_STRING(p, addr) \ do {\ p = lock_user_string(addr); \ @@ -248,9 +272,21 @@ void helper_do_semihosting(CPUMIPSState *env) } break; case UHI_argc: +gpr[2] = semihosting_argc; +break; case UHI_argnlen: +if (gpr[4] = semihosting_argc) { +gpr[2] = -1; +goto uhi_done; +} +gpr[2] = strlen(semihosting_argv[gpr[4]]); +break; case UHI_argn: -/* TODO */ +if (gpr[4] = semihosting_argc) { +gpr[2] = -1; +goto uhi_done; +} +gpr[2] =
[Qemu-devel] [Bug 918791] Re: qemu-kvm dies when using vmvga driver and unity in the guest
This bug still exists with Ubuntu 12.04.5 LTS as host and Ubuntu Mate 14.04.01 in the VM. Using Mate in the VM with cirrus as video driver does work, but the screen resolution is limited to 1290x104 - insufficient for some graphics work. For vga it is even worse. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/918791 Title: qemu-kvm dies when using vmvga driver and unity in the guest Status in QEMU: New Status in qemu-kvm package in Ubuntu: Fix Released Status in xserver-xorg-video-vmware package in Ubuntu: Invalid Status in qemu-kvm source package in Oneiric: Won't Fix Status in xserver-xorg-video-vmware source package in Oneiric: Invalid Status in qemu-kvm source package in Precise: Fix Released Status in xserver-xorg-video-vmware source package in Precise: Invalid Bug description: = SRU Justification: 1. impact: kvm crashes 2. Development fix: don't allow attempts to set_bit to negative offsets 3. Stable fix: same as development fix 4. Test case (see below) 5. Regression potential: if the patch is wrong, graphics for vmware vga over vnc could get messed up = 12.04's qemu-kvm has been unstable for me and Marc Deslauriers and I figured out it has something to do with the interaction of qemu-kvm, unity and the vmvga driver. This is a regression over qemu-kvm in 11.10. TEST CASE: 1. start a VM that uses unity (eg, 11.04, 11.10 or 12.04). My tests use unity-2d on an amd64 host and amd64 guests 2. on 11.04 and 11.10, open empathy via the messaging indicator and click 'Chat'. On 12.04, open empathy via the messaging indicator and click 'Chat', close the empathy wizard, move the empathy window over the unity luancher (so it autohides), then do 'ctrl+alt+t' to open a terminal When the launcher tries to auto(un)hide, qemu-kvm dies with this: [10574.958149] do_general_protection: 132 callbacks suppressed [10574.958154] kvm[13192] general protection ip:7fab9680ea0f sp:74440148 error:0 in qemu-system-x86_64[7fab966c4000+2c9000] Relevant libvirt xml: video model type='vmvga' vram='9216' heads='1'/ address type='pci' domain='0x' bus='0x00' slot='0x02' function='0x0'/ /video If I change to using 'cirrus', then qemu-kvm no longer crashes. Eg: video model type='cirrus' vram='9216' heads='1'/ alias name='video0'/ address type='pci' domain='0x' bus='0x00' slot='0x02' function='0x0'/ /video The workaround is therefore to use the cirrus driver instead of vmvga, however being able to kill qemu-kvm in this manner is not ideal. Also, unfortunately unity-2d does not run with with cirrus driver under 11.04, so the security and SRU teams are unable to properly test updates in GUI applications under unity when using the current 12.04 qemu-kvm. I tried to report this via apport, but apport complained about a CRC error, so I could not. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/918791/+subscriptions
[Qemu-devel] [PULL v2 06/11] pci: add rocker device ID
From: Scott Feldman sfel...@gmail.com Signed-off-by: Scott Feldman sfel...@gmail.com Signed-off-by: Jiri Pirko j...@resnulli.us Message-id: 1424123271-7656-5-git-send-email-sfel...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- docs/specs/pci-ids.txt | 1 + include/hw/pci/pci.h | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/specs/pci-ids.txt b/docs/specs/pci-ids.txt index c6732fe..e4a4490 100644 --- a/docs/specs/pci-ids.txt +++ b/docs/specs/pci-ids.txt @@ -45,6 +45,7 @@ PCI devices (other than virtio): 1b36:0003 PCI Dual-port 16550A adapter (docs/specs/pci-serial.txt) 1b36:0004 PCI Quad-port 16550A adapter (docs/specs/pci-serial.txt) 1b36:0005 PCI test device (docs/specs/pci-testdev.txt) +1b36:0006 PCI Rocker Ethernet switch device 1b36:0007 PCI SD Card Host Controller Interface (SDHCI) All these devices are documented in docs/specs. diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index bdee464..ec1bfbb 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -88,6 +88,7 @@ #define PCI_DEVICE_ID_REDHAT_SERIAL2 0x0003 #define PCI_DEVICE_ID_REDHAT_SERIAL4 0x0004 #define PCI_DEVICE_ID_REDHAT_TEST0x0005 +#define PCI_DEVICE_ID_REDHAT_ROCKER 0x0006 #define PCI_DEVICE_ID_REDHAT_SDHCI 0x0007 #define PCI_DEVICE_ID_REDHAT_PCIE_HOST 0x0008 #define PCI_DEVICE_ID_REDHAT_QXL 0x0100 -- 2.1.0
[Qemu-devel] [PATCH 1/4] include/softmmu-semi.h: Make semihosting support 64-bit clean
From: Maciej W. Rozycki ma...@codesourcery.com Correct addresses passed around in semihosting to use a data type suitable for both 32-bit and 64-bit targets. Signed-off-by: Maciej W. Rozycki ma...@codesourcery.com Signed-off-by: Leon Alrae leon.al...@imgtec.com --- Maciej, I kept the same fix locally. I'm replacing it in this patchset with your patch since you submitted it first :) Leon --- include/exec/softmmu-semi.h | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h index 8401f7d..1819cc2 100644 --- a/include/exec/softmmu-semi.h +++ b/include/exec/softmmu-semi.h @@ -9,14 +9,14 @@ #ifndef SOFTMMU_SEMI_H #define SOFTMMU_SEMI_H 1 -static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr) +static inline uint32_t softmmu_tget32(CPUArchState *env, target_ulong addr) { uint32_t val; cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)val, 4, 0); return tswap32(val); } -static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr) +static inline uint32_t softmmu_tget8(CPUArchState *env, target_ulong addr) { uint8_t val; @@ -28,7 +28,8 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr) #define get_user_u8(arg, p) ({ arg = softmmu_tget8(env, p) ; 0; }) #define get_user_ual(arg, p) get_user_u32(arg, p) -static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val) +static inline void softmmu_tput32(CPUArchState *env, + target_ulong addr, uint32_t val) { val = tswap32(val); cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)val, 4, 1); @@ -36,8 +37,8 @@ static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val #define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; }) #define put_user_ual(arg, p) put_user_u32(arg, p) -static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len, - int copy) +static void *softmmu_lock_user(CPUArchState *env, + target_ulong addr, target_ulong len, int copy) { uint8_t *p; /* TODO: Make this something that isn't fixed size. */ @@ -48,7 +49,7 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len, return p; } #define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy) -static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr) +static char *softmmu_lock_user_string(CPUArchState *env, target_ulong addr) { char *p; char *s; -- 2.1.0
[Qemu-devel] [PULL v2 09/11] rocker: add tests
From: Scott Feldman sfel...@gmail.com Add some basic test for rocker to test L2/L3/L4 functionality. Requires an external test environment, simp, located here: https://github.com/scottfeldman/simp To run tests, simp environment must be installed and a suitable VM image built and installed with a Linux 3.18 (or greater) kernel with rocker driver support enabled. Signed-off-by: Scott Feldman sfel...@gmail.com Message-id: 1424123271-7656-9-git-send-email-sfel...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- tests/rocker/README | 5 tests/rocker/all | 19 tests/rocker/bridge | 48 ++ tests/rocker/bridge-stp | 57 tests/rocker/bridge-vlan | 57 tests/rocker/bridge-vlan-stp | 69 tests/rocker/port| 22 ++ tests/rocker/tut.dot | 8 + 8 files changed, 285 insertions(+) create mode 100644 tests/rocker/README create mode 100755 tests/rocker/all create mode 100755 tests/rocker/bridge create mode 100755 tests/rocker/bridge-stp create mode 100755 tests/rocker/bridge-vlan create mode 100755 tests/rocker/bridge-vlan-stp create mode 100755 tests/rocker/port create mode 100644 tests/rocker/tut.dot diff --git a/tests/rocker/README b/tests/rocker/README new file mode 100644 index 000..531e673 --- /dev/null +++ b/tests/rocker/README @@ -0,0 +1,5 @@ +Tests require simp (simple network simulator) found here: + +https://github.com/scottfeldman/simp + +Run 'all' to run all tests. diff --git a/tests/rocker/all b/tests/rocker/all new file mode 100755 index 000..d5ae963 --- /dev/null +++ b/tests/rocker/all @@ -0,0 +1,19 @@ +echo -n Running port test... +./port +if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi + +echo -n Running bridge test... +./bridge +if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi + +echo -n Running bridge STP test... +./bridge-stp +if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi + +echo -n Running bridge VLAN test... +./bridge-vlan +if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi + +echo -n Running bridge VLAN STP test... +./bridge-vlan-stp +if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi diff --git a/tests/rocker/bridge b/tests/rocker/bridge new file mode 100755 index 000..7a03f9a --- /dev/null +++ b/tests/rocker/bridge @@ -0,0 +1,48 @@ +simp destroy .* +simp create -o sw1:rocker:sw1 tut tut.dot +simp start tut +sleep 10 +while ! simp ssh tut sw1 --cmd ping -c 1 localhost /dev/null; do sleep 1; done +while ! simp ssh tut h1 --cmd ping -c 1 localhost /dev/null; do sleep 1; done +while ! simp ssh tut h2 --cmd ping -c 1 localhost /dev/null; do sleep 1; done + +# configure a 2-port bridge + +simp ssh tut sw1 --cmd sudo /sbin/ip link add name br0 type bridge +simp ssh tut sw1 --cmd sudo /sbin/ip link set dev swp1 master br0 +simp ssh tut sw1 --cmd sudo /sbin/ip link set dev swp2 master br0 + +# turn off vlan default_pvid on br0 + +simp ssh tut sw1 --cmd echo 0 | sudo dd of=/sys/class/net/br0/bridge/default_pvid 2 /dev/null + +# turn off learning and flooding in SW + +simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp1 learning off +simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp2 learning off + +simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp1 flood off +simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp2 flood off + +# turn on learning in HW + +simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp1 learning on self +simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp2 learning on self + +# bring up bridge and ports + +simp ssh tut sw1 --cmd sudo ifconfig br0 up +simp ssh tut sw1 --cmd sudo ifconfig swp1 up +simp ssh tut sw1 --cmd sudo ifconfig swp2 up +simp ssh tut sw1 --cmd sudo ifconfig br0 11.0.0.3/24 + +# config IP on hosts + +simp ssh tut h1 --cmd sudo ifconfig swp1 11.0.0.1/24 +simp ssh tut h2 --cmd sudo ifconfig swp1 11.0.0.2/24 + +# test... + +simp ssh tut h1 --cmd ping -c10 11.0.0.2 /dev/null +if [ $? -ne 0 ]; then exit 1; fi +simp ssh tut h1 --cmd ping -c10 11.0.0.3 /dev/null diff --git a/tests/rocker/bridge-stp b/tests/rocker/bridge-stp new file mode 100755 index 000..4a111a1 --- /dev/null +++ b/tests/rocker/bridge-stp @@ -0,0 +1,57 @@ +simp destroy .* +simp create -o sw1:rocker:sw1 tut tut.dot +simp start tut +sleep 10 +while ! simp ssh tut sw1 --cmd ping -c 1 localhost /dev/null; do sleep 1; done +while ! simp ssh tut h1 --cmd ping -c 1 localhost /dev/null; do sleep 1; done +while ! simp ssh tut h2 --cmd ping -c 1 localhost /dev/null; do sleep 1; done + +# configure a 2-port bridge + +simp ssh tut sw1 --cmd sudo /sbin/ip link add name br0 type bridge +simp ssh tut sw1 --cmd sudo brctl stp br0 on +simp ssh tut sw1 --cmd sudo /sbin/ip link set dev swp1
Re: [Qemu-devel] [PATCH v5 07/16] spapr_rtas: add ibm, configure-connector RTAS interface
Quoting David Gibson (2015-02-26 23:31:20) On Thu, Feb 26, 2015 at 04:21:55PM -0600, Michael Roth wrote: Quoting David Gibson (2015-02-24 18:48:23) On Tue, Feb 24, 2015 at 02:43:45PM -0600, Michael Roth wrote: Quoting David Gibson (2015-02-24 00:40:32) On Mon, Feb 16, 2015 at 08:27:43AM -0600, Michael Roth wrote: [snip] +uint64_t wa_offset; +uint32_t drc_index; +sPAPRDRConnector *drc; +sPAPRDRConnectorClass *drck; +sPAPRDRCCResponse resp; +const struct fdt_property *prop = NULL; +char *prop_name = NULL; +int prop_len, rc; + +drc_index = rtas_ld(wa_addr, 0); +drc = spapr_dr_connector_by_index(drc_index); +if (!drc) { +DPRINTF(rtas_ibm_configure_connector: invalid sensor/DRC index: %xh\n, +drc_index); +rc = RTAS_OUT_PARAM_ERROR; +goto out; +} +drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); +resp = drck-configure_connector(drc, prop_name, prop, prop_len); You may have answered this last time round, but if so I forgot the reason. Why does the awkward iteration need to go down to the drck callback? Coudln't the drck callback part just supply the fdt fragment blob, then have generic code which streams it out via iteration? Obviously we have to support the horrid PAPR interface, but it would be nice to confine the PAPR derived horridness to as small an area as we can. That horrid interface percolates all the way up the QEMU stack, unfortunately :) Upon successfully having it's device tree node received, a DRC transitions to a 'configured' state that's defined in the DR state machine (PAPR+ 13.4). We need to track that state, since it's used to differentiate between a case where a device is set to 'isolated' as part of entity-sense/device configuration, as opposed to 'isolated' as part the unplug path. The overlap between the 2 can occur if we do device_add followed by an immediate device_del, but since the 'configured' transition must occur before the latter, it becomes unambiguous. It's also possible that a guest might be reset in the middle of a series of calls to configure-connector, in which case that state needs to be reset. This is currently handled by sPAPRDRConnector's reset hook, so if we moved that aspect out I think we'd need to wire up a reset hook for the configure-connector state, which is kinda messy. We'd also need a list of some sort, keyed by the DRC indexes, to handle the subsequent call-per-iteration's (no guarantee only one device configuration is 'in-flight' at a time), so we end up duplicating a lot of tracking/functionality. Hmm. You should still be able to handle that with just 2 hooks and 1 bit of state right? Say start_configuration and end_configuration or similar. start_configuration gets the blob from the backend, then end_configuration is called once RTAS has finished streaming it out to the guest and updates to the cnofigured state. {start,end}_configuration callbacks would work for handling the normal 'configured' state transitions induced by the call, but we'd also need hooks in the other direction for a couple cases: This scenario for instance: qemu: guest: add device0 to drc0 drmgr0: rtas-configure-connector drc0 drc0-start_configuration... drmgr0: rtas-configure-connector drc0 drmgr0: rtas-configure-connector drc0 ... drmgr0: rtas-configure-connector drc0 del device0 device0 removal pending drmgr0: rtas-configure-connector drc0 system_reset device0 removed by drc0 reset hook add device1 to drc0 drmgr0: rtas-configure-connector drc0 begins fetching stale FDT So I think we'd need at least a reset hook wired up to the RTAS state. It's also possible for the guest to force a transition out of the configured state by ISOLATE'ing the device. This can happen in the middle of the guests configure-connector calls if there's an error. If rtas-configure-connector is the one generating the error, it can anticipate this and automatically reset the state, but in some cases the error is guest internal: the get_node() in src/drmgr/rtas_calls.c can fail for memory allocation errors, or unexpected workarea structure, after which point it simply stops calling rtas-configure-connector and ISOLATEs the device. If we don't
[Qemu-devel] [PATCH v4 09/11] blockdev: Keep track of monitor-owned BDS
...and release the reference on bdrv_close_all(). Signed-off-by: Max Reitz mre...@redhat.com --- block.c| 5 + blockdev.c | 18 ++ include/block/block_int.h | 4 stubs/Makefile.objs| 1 + stubs/blockdev-close-all-bdrv-states.c | 5 + 5 files changed, 33 insertions(+) create mode 100644 stubs/blockdev-close-all-bdrv-states.c diff --git a/block.c b/block.c index 819c54d..0b0792c 100644 --- a/block.c +++ b/block.c @@ -1943,6 +1943,8 @@ void bdrv_close_all(void) { BlockDriverState *bs; +blockdev_close_all_bdrv_states(); + QTAILQ_FOREACH(bs, bdrv_states, device_list) { AioContext *aio_context = bdrv_get_aio_context(bs); @@ -2090,6 +2092,9 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest, /* keep the same entry in bdrv_states */ bs_dest-device_list = bs_src-device_list; +/* keep the same entry in the list of monitor-owned BDS */ +bs_dest-monitor_list = bs_src-monitor_list; + bs_dest-blk = bs_src-blk; memcpy(bs_dest-op_blockers, bs_src-op_blockers, diff --git a/blockdev.c b/blockdev.c index e5f5ebc..535e83f 100644 --- a/blockdev.c +++ b/blockdev.c @@ -47,6 +47,9 @@ #include trace.h #include sysemu/arch_init.h +static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states = +QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states); + static const char *const if_name[IF_COUNT] = { [IF_NONE] = none, [IF_IDE] = ide, @@ -648,6 +651,19 @@ fail: return NULL; } +void blockdev_close_all_bdrv_states(void) +{ +BlockDriverState *bs, *next_bs; + +QTAILQ_FOREACH_SAFE(bs, monitor_bdrv_states, monitor_list, next_bs) { +AioContext *ctx = bdrv_get_aio_context(bs); + +aio_context_acquire(ctx); +bdrv_unref(bs); +aio_context_release(ctx); +} +} + static void qemu_opt_rename(QemuOpts *opts, const char *from, const char *to, Error **errp) { @@ -3166,6 +3182,8 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) if (!bs) { goto fail; } + +QTAILQ_INSERT_TAIL(monitor_bdrv_states, bs, monitor_list); } if (bs bdrv_key_required(bs)) { diff --git a/include/block/block_int.h b/include/block/block_int.h index b2c1d87..1b01f45 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -399,6 +399,8 @@ struct BlockDriverState { QTAILQ_ENTRY(BlockDriverState) node_list; /* element of the list of drives the guest sees */ QTAILQ_ENTRY(BlockDriverState) device_list; +/* element of the list of monitor-owned BDS */ +QTAILQ_ENTRY(BlockDriverState) monitor_list; QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps; int refcnt; @@ -622,4 +624,6 @@ bool blk_dev_is_tray_open(BlockBackend *blk); bool blk_dev_is_medium_locked(BlockBackend *blk); void blk_dev_resize_cb(BlockBackend *blk); +void blockdev_close_all_bdrv_states(void); + #endif /* BLOCK_INT_H */ diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 5e347d0..9169a09 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -1,5 +1,6 @@ stub-obj-y += arch-query-cpu-def.o stub-obj-y += bdrv-commit-all.o +stub-obj-y += blockdev-close-all-bdrv-states.o stub-obj-y += chr-baum-init.o stub-obj-y += chr-msmouse.o stub-obj-y += chr-testdev.o diff --git a/stubs/blockdev-close-all-bdrv-states.c b/stubs/blockdev-close-all-bdrv-states.c new file mode 100644 index 000..12d2442 --- /dev/null +++ b/stubs/blockdev-close-all-bdrv-states.c @@ -0,0 +1,5 @@ +#include block/block_int.h + +void blockdev_close_all_bdrv_states(void) +{ +} -- 2.1.0
[Qemu-devel] [PATCH v4 08/11] block: Make bdrv_close() static
There are no users of bdrv_close() left, except for one of bdrv_open()'s failure paths, bdrv_close_all() and bdrv_delete(), and that is good. Make bdrv_close() static so nobody makes the mistake of directly using bdrv_close() again. Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com --- block.c | 4 +++- include/block/block.h | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 41a9d24..819c54d 100644 --- a/block.c +++ b/block.c @@ -104,6 +104,8 @@ static void bdrv_reset_dirty(BlockDriverState *bs, int64_t cur_sector, /* If non-zero, use only whitelisted block drivers */ static int use_bdrv_whitelist; +static void bdrv_close(BlockDriverState *bs); + #ifdef _WIN32 static int is_windows_drive_prefix(const char *filename) { @@ -1882,7 +1884,7 @@ void bdrv_reopen_abort(BDRVReopenState *reopen_state) } -void bdrv_close(BlockDriverState *bs) +static void bdrv_close(BlockDriverState *bs) { BdrvAioNotifier *ban, *ban_next; diff --git a/include/block/block.h b/include/block/block.h index dc94084..eadb25f 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -206,7 +206,6 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, Error **errp); void bdrv_reopen_commit(BDRVReopenState *reopen_state); void bdrv_reopen_abort(BDRVReopenState *reopen_state); -void bdrv_close(BlockDriverState *bs); int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors); int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num, -- 2.1.0
Re: [Qemu-devel] [PATCH v2] block/vdi: Add locking for parallel requests
On Fri, Feb 27, 2015 at 09:05:47AM -0500, Max Reitz wrote: Concurrently modifying the bmap does not seem to be a good idea; this patch adds a lock for it. See https://bugs.launchpad.net/qemu/+bug/1422307 for what can go wrong without. Cc: qemu-stable qemu-sta...@nongnu.org Signed-off-by: Max Reitz mre...@redhat.com --- v2: - Make the mutex cover vdi_co_write() completely [Kevin] - Add a TODO comment [Kevin] --- block/vdi.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/block/vdi.c b/block/vdi.c index 74030c6..f5f42ef 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -51,6 +51,7 @@ #include qemu-common.h #include block/block_int.h +#include block/coroutine.h #include qemu/module.h #include migration/migration.h @@ -196,6 +197,8 @@ typedef struct { /* VDI header (converted to host endianness). */ VdiHeader header; +CoMutex bmap_lock; + Error *migration_blocker; } BDRVVdiState; @@ -498,6 +501,8 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags, goto fail_free_bmap; } +qemu_co_mutex_init(s-bmap_lock); + /* Disable migration when vdi images are used */ error_set(s-migration_blocker, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, @@ -607,6 +612,9 @@ static int vdi_co_write(BlockDriverState *bs, logout(\n); +/* TODO: Figure out why this is necessary */ +qemu_co_mutex_lock(s-bmap_lock); If we don't know why bmap_lock works, it would be more approprate to take the same approach as VMDK and VHDX where there is a simply s-lock that protects all reads and writes. That way we know for sure there is no parallel I/O going on. (Since the problem is not understood, maybe reads in parallel with writes could also cause problems. Better to really do a coarse lock instead of just bmap_lock in write.) Stefan pgp7LjNaaoemZ.pgp Description: PGP signature
[Qemu-devel] [PULL v2 03/11] net: add MAC address string printer
From: Scott Feldman sfel...@gmail.com We can use this in virtio-net code as well as new Rocker driver code, so up-level this. Signed-off-by: Scott Feldman sfel...@gmail.com Reviewed-by: Eric Blake ebl...@redhat.com Message-id: 1424123271-7656-2-git-send-email-sfel...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- include/net/net.h | 1 + net/net.c | 7 +++ 2 files changed, 8 insertions(+) diff --git a/include/net/net.h b/include/net/net.h index 50ffcb9..e66ca03 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -97,6 +97,7 @@ typedef struct NICState { bool peer_deleted; } NICState; +char *qemu_mac_strdup_printf(const uint8_t *macaddr); NetClientState *qemu_find_netdev(const char *id); int qemu_find_net_clients_except(const char *id, NetClientState **ncs, NetClientOptionsKind type, int max); diff --git a/net/net.c b/net/net.c index 3201516..cede10b 100644 --- a/net/net.c +++ b/net/net.c @@ -151,6 +151,13 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str) return 0; } +char *qemu_mac_strdup_printf(const uint8_t *macaddr) +{ +return g_strdup_printf(%.2x:%.2x:%.2x:%.2x:%.2x:%.2x, + macaddr[0], macaddr[1], macaddr[2], + macaddr[3], macaddr[4], macaddr[5]); +} + void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]) { snprintf(nc-info_str, sizeof(nc-info_str), -- 2.1.0
[Qemu-devel] [PULL v2 04/11] virtio-net: use qemu_mac_strdup_printf
From: Scott Feldman sfel...@gmail.com Signed-off-by: Scott Feldman sfel...@gmail.com Reviewed-by: Eric Blake ebl...@redhat.com Message-id: 1424123271-7656-3-git-send-email-sfel...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/net/virtio-net.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 45da34a..698156f 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -226,12 +226,6 @@ static void rxfilter_notify(NetClientState *nc) } } -static char *mac_strdup_printf(const uint8_t *mac) -{ -return g_strdup_printf(%.2x:%.2x:%.2x:%.2x:%.2x:%.2x, mac[0], -mac[1], mac[2], mac[3], mac[4], mac[5]); -} - static intList *get_vlan_table(VirtIONet *n) { intList *list, *entry; @@ -284,12 +278,12 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc) info-multicast_overflow = n-mac_table.multi_overflow; info-unicast_overflow = n-mac_table.uni_overflow; -info-main_mac = mac_strdup_printf(n-mac); +info-main_mac = qemu_mac_strdup_printf(n-mac); str_list = NULL; for (i = 0; i n-mac_table.first_multi; i++) { entry = g_malloc0(sizeof(*entry)); -entry-value = mac_strdup_printf(n-mac_table.macs + i * ETH_ALEN); +entry-value = qemu_mac_strdup_printf(n-mac_table.macs + i * ETH_ALEN); entry-next = str_list; str_list = entry; } @@ -298,7 +292,7 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc) str_list = NULL; for (i = n-mac_table.first_multi; i n-mac_table.in_use; i++) { entry = g_malloc0(sizeof(*entry)); -entry-value = mac_strdup_printf(n-mac_table.macs + i * ETH_ALEN); +entry-value = qemu_mac_strdup_printf(n-mac_table.macs + i * ETH_ALEN); entry-next = str_list; str_list = entry; } -- 2.1.0
[Qemu-devel] [PATCH v2] virtio-scsi: Allocate op blocker reason before blocking
s-blocker is really only used in hw/scsi/virtio-scsi.c; the only places where it is used in hw/scsi/virtio-scsi-dataplane.c is when it is allocated and when it is freed. That does not make a whole lot of sense (and is actually wrong because this leads to s-blocker potentially being NULL when blk_op_block_all() is called in virtio-scsi.c), so move the allocation and destruction of s-blocker to the device realization and unrealization in virtio-scsi.c, respectively. Case in point: $ echo -e 'eject drv\nquit' | \ x86_64-softmmu/qemu-system-x86_64 \ -monitor stdio -machine accel=qtest -display none \ -object iothread,id=thr -device virtio-scsi-pci,iothread=thr \ -drive if=none,file=test.qcow2,format=qcow2,id=drv \ -device scsi-cd,drive=drv Without this patch: (qemu) eject drv [1]10102 done 10103 segmentation fault (core dumped) With this patch: (qemu) eject drv Device 'drv' is busy: block device is in use by data plane (qemu) quit Signed-off-by: Max Reitz mre...@redhat.com --- v2: - Put the reproducer into the commit message [Markus] and modified its wording to be more fitting of a commit message (Case in point instead of the imperative Try). - As noted by Fam on my bdrv_close_all() series, there can be multiple block devices per virtio-scsi bus; therefore, it's wrong to delete the blocker if one of these is unplugged. Instead, just allocate the blocker with the virtio-scsi device itself and free it when the device is unrealized. --- hw/scsi/virtio-scsi-dataplane.c | 4 hw/scsi/virtio-scsi.c | 4 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c index 03a1e8c..9b775d4 100644 --- a/hw/scsi/virtio-scsi-dataplane.c +++ b/hw/scsi/virtio-scsi-dataplane.c @@ -211,8 +211,6 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s) s-dataplane_starting = true; -assert(!s-blocker); -error_setg(s-blocker, block device is in use by data plane); /* Set up guest notifier (irq) */ rc = k-set_guest_notifiers(qbus-parent, vs-conf.num_queues + 2, true); if (rc != 0) { @@ -279,8 +277,6 @@ void virtio_scsi_dataplane_stop(VirtIOSCSI *s) if (!s-dataplane_started || s-dataplane_stopping) { return; } -error_free(s-blocker); -s-blocker = NULL; s-dataplane_stopping = true; assert(s-ctx == iothread_get_aio_context(vs-conf.iothread)); diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 9e2c718..9c2a272 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -904,6 +904,8 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp) virtio_scsi_save, virtio_scsi_load, s); s-migration_state_notifier.notify = virtio_scsi_migration_state_changed; add_migration_state_change_notifier(s-migration_state_notifier); + +error_setg(s-blocker, block device is in use by data plane); } static void virtio_scsi_instance_init(Object *obj) @@ -929,6 +931,8 @@ static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp) { VirtIOSCSI *s = VIRTIO_SCSI(dev); +error_free(s-blocker); + unregister_savevm(dev, virtio-scsi, s); remove_migration_state_change_notifier(s-migration_state_notifier); -- 2.1.0
[Qemu-devel] [PULL v2 10/11] MAINTAINERS: add rocker
From: Scott Feldman sfel...@gmail.com Signed-off-by: Scott Feldman sfel...@gmail.com Signed-off-by: Jiri Pirko j...@resnulli.us Message-id: 1424123271-7656-10-git-send-email-sfel...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- MAINTAINERS | 6 ++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8c06739..2ea3625 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -741,6 +741,12 @@ S: Maintained F: hw/net/vmxnet* F: hw/scsi/vmw_pvscsi* +Rocker +M: Scott Feldman sfel...@gmail.com +M: Jiri Pirko j...@resnulli.us +S: Maintained +F: hw/net/rocker/ + Subsystems -- Audio -- 2.1.0
[Qemu-devel] [PATCH 0/4] target-mips: add UHI semihosting support
Hi, This patch series introduces the Unified Hosting Interface [1] support to QEMU. UHI is a common bare metal semi-hosting interface for the MIPS architecture and in QEMU it comes down to reserving SDBBP 1 instruction which triggers semi-hosting syscalls. Since we are already in soft-freeze these patches are not intended for 2.3. I'm submitting it now as I would like to get your feedback. I'm particularly interested in your opinion about the new command line option for semihosting input arguments. When QEMU is executed with -semihosting option the SDBBP instruction with code = 1 will not cause a debug exception, but instead it will call one of the UHI operations which are handled in target-mips/mips-semi.c file. Input arguments as well as return values are passed via GPRs as specified in the manual. UHI provides 3 operations allowing to construct argv and argc: * Argc: returns number of arguments. * Argnlen: returns the length of the n'th argument. * Argn: copies the n'th argument to the provided buffer. In order to keep it simple it would be ideal to be able to pass multiple input arguments which can contain any character to the guest program without having to care about separators and escape characters (they might be quite unintuitive if we also consider Windows environment). Therefore rather than using existing -append I would like to introduce -semihosting-arg option which can occur multiple times in the command line. For those who want to test the implementation -- here are the steps for building simple hello world bare metal program and running it on Malta board. Bare Metal Toolchain containing UHI support can be obtained from: http://codescape-mips-sdk.imgtec.com/components/toolchain/2014.07-1/ * Source file: $ cat main.c #include stdio.h int main() { printf(Hello world!\n); return 0; } * Build: $ mips-mti-elf-gcc -T mti32-uhi.ld -mips32r2 -EL main.c * Run: $ qemu-system-mipsel -cpu 24Kf -M malta -semihosting -nographic -kernel a.out Hello world! References: [1] MIPS Toolchain, MD01069 UHI Reference Manual, Version: 1.0.14 The manual is available here: http://prplfoundation.org/wiki/MIPS_documentation Regards, Leon Leon Alrae (2): target-mips: add Unified Hosting Interface (UHI) support target-mips: add -semihosting-arg option and implement UHI Arg* ops Maciej W. Rozycki (1): include/softmmu-semi.h: Make semihosting support 64-bit clean Matthew Fortune (1): hw/mips: Do not clear BEV for MIPS malta kernel load hw/mips/mips_malta.c| 10 +- include/exec/softmmu-semi.h | 13 +- include/sysemu/sysemu.h | 2 + qemu-options.hx | 13 +- target-mips/Makefile.objs | 2 +- target-mips/helper.h| 2 + target-mips/mips-semi.c | 340 target-mips/translate.c | 82 +++ vl.c| 28 9 files changed, 456 insertions(+), 36 deletions(-) create mode 100644 target-mips/mips-semi.c -- 2.1.0
Re: [Qemu-devel] [PATCH v2] block/vdi: Add locking for parallel requests
On 27/02/2015 15:05, Max Reitz wrote: Concurrently modifying the bmap does not seem to be a good idea; this patch adds a lock for it. See https://bugs.launchpad.net/qemu/+bug/1422307 for what can go wrong without. Cc: qemu-stable qemu-sta...@nongnu.org Signed-off-by: Max Reitz mre...@redhat.com --- v2: - Make the mutex cover vdi_co_write() completely [Kevin] - Add a TODO comment [Kevin] I think I know what the bug is. Suppose you have two concurrent writes to a non-allocated block, one at 16K...32K (in bytes) and one at 32K...48K. The first write is enlarged to contain zeros, the second is not. Then you have two writes in flight: 0 zeros ... zeros 16K data1 ... data1 32K zeros data2 ... zeros data2 48K zeros ... zeros 64K And the contents of 32K...48K are undefined. If the above diagnosis is correct, I'm not even sure why Max's v1 patch worked... An optimized fix could be to use a CoRwLock, then: - take it shared (read) around the write in the VDI_IS_ALLOCATED(bmap_entry) path - take it exclusive (write) around the write in the !VDI_IS_ALLOCATED(bmap_entry) path Paolo --- block/vdi.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/block/vdi.c b/block/vdi.c index 74030c6..f5f42ef 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -51,6 +51,7 @@ #include qemu-common.h #include block/block_int.h +#include block/coroutine.h #include qemu/module.h #include migration/migration.h @@ -196,6 +197,8 @@ typedef struct { /* VDI header (converted to host endianness). */ VdiHeader header; +CoMutex bmap_lock; + Error *migration_blocker; } BDRVVdiState; @@ -498,6 +501,8 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags, goto fail_free_bmap; } +qemu_co_mutex_init(s-bmap_lock); + /* Disable migration when vdi images are used */ error_set(s-migration_blocker, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, @@ -607,6 +612,9 @@ static int vdi_co_write(BlockDriverState *bs, logout(\n); +/* TODO: Figure out why this is necessary */ +qemu_co_mutex_lock(s-bmap_lock); + while (ret = 0 nb_sectors 0) { block_index = sector_num / s-block_sectors; sector_in_block = sector_num % s-block_sectors; @@ -656,6 +664,7 @@ static int vdi_co_write(BlockDriverState *bs, logout(finished data write\n); if (ret 0) { +qemu_co_mutex_unlock(s-bmap_lock); return ret; } @@ -674,6 +683,7 @@ static int vdi_co_write(BlockDriverState *bs, block = NULL; if (ret 0) { +qemu_co_mutex_unlock(s-bmap_lock); return ret; } @@ -690,6 +700,7 @@ static int vdi_co_write(BlockDriverState *bs, ret = bdrv_write(bs-file, offset, base, n_sectors); } +qemu_co_mutex_unlock(s-bmap_lock); return ret; }
[Qemu-devel] [PATCH v4 11/11] iotests: Add test for multiple BB on BDS tree
This adds a test for having multiple BlockBackends in one BDS tree. In this case, there is one BB for the protocol BDS and one BB for the format BDS in a simple two-BDS tree (with the protocol BDS and BB added first). When bdrv_close_all() is executed, no cached data from any BDS should be lost; the protocol BDS may not be closed until the format BDS is closed. Otherwise, metadata updates may be lost. Signed-off-by: Max Reitz mre...@redhat.com --- tests/qemu-iotests/117 | 86 ++ tests/qemu-iotests/117.out | 14 tests/qemu-iotests/group | 1 + 3 files changed, 101 insertions(+) create mode 100755 tests/qemu-iotests/117 create mode 100644 tests/qemu-iotests/117.out diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117 new file mode 100755 index 000..7881fc7 --- /dev/null +++ b/tests/qemu-iotests/117 @@ -0,0 +1,86 @@ +#!/bin/bash +# +# Test case for shared BDS between backend trees +# +# Copyright (C) 2015 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +# creator +owner=mre...@redhat.com + +seq=$(basename $0) +echo QA output created by $seq + +here=$PWD +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap _cleanup; exit \$status 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.qemu + +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux + +_make_test_img 64k + +_launch_qemu + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'qmp_capabilities' } \ +'return' + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'blockdev-add', + 'arguments': { 'options': { 'id': 'protocol', + 'driver': 'file', + 'filename': '$TEST_IMG' } } } \ +'return' + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'blockdev-add', + 'arguments': { 'options': { 'id': 'format', + 'driver': '$IMGFMT', + 'file': 'protocol' } } } \ +'return' + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'human-monitor-command', + 'arguments': { 'command-line': 'qemu-io format \write -P 42 0 64k\' } } \ +'return' + +_send_qemu_cmd $QEMU_HANDLE \ +{ 'execute': 'quit' } \ +'return' + +wait=1 _cleanup_qemu + +_check_test_img + +$QEMU_IO -c 'read -P 42 0 64k' $TEST_IMG | _filter_qemu_io + +# success, all done +echo '*** done' +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/117.out b/tests/qemu-iotests/117.out new file mode 100644 index 000..f52dc1a --- /dev/null +++ b/tests/qemu-iotests/117.out @@ -0,0 +1,14 @@ +QA output created by 117 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536 +{return: {}} +{return: {}} +{return: {}} +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{return: } +{return: {}} +{timestamp: {seconds: TIMESTAMP, microseconds: TIMESTAMP}, event: SHUTDOWN} +No errors were found on the image. +read 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 06d0485..7436300 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -121,5 +121,6 @@ 113 rw auto quick 114 rw auto quick 116 rw auto quick +117 rw auto 118 rw auto 123 rw auto quick -- 2.1.0
[Qemu-devel] [PATCH v4 00/11] block: Rework bdrv_close_all()
Currently, bdrv_close_all() force-closes all BDSs with a BlockBackend, which can lead to data corruption (see the iotest added in the final patch of this series) and is most certainly very ugly. This series reworks bdrv_close_all() to instead eject the BDS trees from all BlockBackends and then close the monitor-owned BDS trees, which are the only BDSs without a BB. In effect, all BDSs are closed just by getting closed automatically due to their reference count becoming 0. The benefit over the approach taken in v1 and v2 is that in device models we often cannot simply drop the reference to a BB because there may be some user which we forgot about. By ejecting the BDS trees from the BB, the BB itself becomes unusable, but in a clean way (it will return errors when accessed, but nothing will crash). Also, it is much simpler (no reference tracking necessary). The only disadvantage (I can see) is that the BBs are leaked; but this does not matter because the qemu process is about to exit anyway. This series depends on v2 of my series blockdev: BlockBackend and media (or any later version), and on my patch virtio-scsi: Allocate op blocker reason before blocking. v4: - Patch 1: Simpler regex for removing nbd: lines [Fam] - Patch 2: Made the non-redirection optional instead of mandatory; still ugly, but at least much less invasive - Patch 3: Additional line due to the mechanism introduced in patch 2 being optional - Patch 5: - Embedded the Notifier objects in VirtIOBlockDataPlane and NBDExport [Fam] - Put the notifiers for the block devices on a virtio-scsi bus into a list, because there can be more than one device [Fam] To demonstrate the difference, try: $ x86_64-softmmu/qemu-system-x86_64 \ -object iothread,id=thr -device virtio-scsi-pci,iothread=thr \ -drive if=none,file=foo.qcow2,format=qcow2,id=foo \ -device scsi-hd,drive=foo \ -drive if=none,file=bar.qcow2,format=qcow2,id=bar \ -device scsi-hd,drive=bar With v3, the !s-blocker assertion in virtio_scsi_set_up_op_blockers() will fail. With v4, everything works fine. git-backport-diff against v3: 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/11:[0002] [FC] 'iotests: Move _filter_nbd into common.filter' 002/11:[down] 'iotests: Make redirecting qemu's stderr optional' 003/11:[0001] [FC] 'iotests: Add test for eject under NBD server' 004/11:[] [--] 'quorum: Fix close path' 005/11:[0159] [FC] 'block: Move BDS close notifiers into BB' 006/11:[] [--] 'block: Use blk_remove_bs() in blk_delete()' 007/11:[] [--] 'blockdev: Use blk_remove_bs() in do_drive_del()' 008/11:[] [--] 'block: Make bdrv_close() static' 009/11:[] [--] 'blockdev: Keep track of monitor-owned BDS' 010/11:[] [--] 'block: Eject BDS tree from BB at bdrv_close_all()' 011/11:[] [--] 'iotests: Add test for multiple BB on BDS tree' Max Reitz (11): iotests: Move _filter_nbd into common.filter iotests: Make redirecting qemu's stderr optional iotests: Add test for eject under NBD server quorum: Fix close path block: Move BDS close notifiers into BB block: Use blk_remove_bs() in blk_delete() blockdev: Use blk_remove_bs() in do_drive_del() block: Make bdrv_close() static blockdev: Keep track of monitor-owned BDS block: Eject BDS tree from BB at bdrv_close_all() iotests: Add test for multiple BB on BDS tree block.c| 25 +++--- block/block-backend.c | 41 block/quorum.c | 3 +- blockdev-nbd.c | 36 +- blockdev.c | 24 +++-- hw/block/dataplane/virtio-blk.c| 77 ++--- hw/scsi/virtio-scsi.c | 87 ++-- include/block/block.h | 2 - include/block/block_int.h | 6 ++- include/hw/virtio/virtio-scsi.h| 10 include/sysemu/block-backend.h | 4 +- nbd.c | 13 + stubs/Makefile.objs| 1 + stubs/blockdev-close-all-bdrv-states.c | 5 ++ tests/qemu-iotests/083 | 13 + tests/qemu-iotests/083.out | 10 tests/qemu-iotests/096 | 90 ++ tests/qemu-iotests/096.out | 16 ++ tests/qemu-iotests/117 | 86 tests/qemu-iotests/117.out | 14 ++ tests/qemu-iotests/common.filter | 12 + tests/qemu-iotests/common.qemu | 12 - tests/qemu-iotests/group | 2 + 23 files changed, 470 insertions(+), 119 deletions(-) create mode 100644 stubs/blockdev-close-all-bdrv-states.c create mode
[Qemu-devel] [PATCH v4 05/11] block: Move BDS close notifiers into BB
The only remaining user of the BDS close notifiers is NBD which uses them to determine when a BDS tree is being ejected. This patch removes the BDS-level close notifiers and adds a notifier list to the BlockBackend structure that is invoked whenever a BDS is removed. Symmetrically to that, another notifier list is added that is invoked whenever a BDS is inserted. The dataplane implementations for virtio-blk and virtio-scsi use both notifier types for setting up and removing op blockers. This is not only important for setting up the op blockers on insertion, but also for removing them on ejection since bdrv_delete() asserts that there are no op blockers set up. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 7 block/block-backend.c | 19 +++-- blockdev-nbd.c | 36 + hw/block/dataplane/virtio-blk.c | 77 +++- hw/scsi/virtio-scsi.c | 87 ++--- include/block/block.h | 1 - include/block/block_int.h | 2 - include/hw/virtio/virtio-scsi.h | 10 + include/sysemu/block-backend.h | 3 +- nbd.c | 13 ++ 10 files changed, 182 insertions(+), 73 deletions(-) diff --git a/block.c b/block.c index 7b912c6..41a9d24 100644 --- a/block.c +++ b/block.c @@ -371,7 +371,6 @@ BlockDriverState *bdrv_new(void) for (i = 0; i BLOCK_OP_TYPE_MAX; i++) { QLIST_INIT(bs-op_blockers[i]); } -notifier_list_init(bs-close_notifiers); notifier_with_return_list_init(bs-before_write_notifiers); qemu_co_queue_init(bs-throttled_reqs[0]); qemu_co_queue_init(bs-throttled_reqs[1]); @@ -381,11 +380,6 @@ BlockDriverState *bdrv_new(void) return bs; } -void bdrv_add_close_notifier(BlockDriverState *bs, Notifier *notify) -{ -notifier_list_add(bs-close_notifiers, notify); -} - BlockDriver *bdrv_find_format(const char *format_name) { BlockDriver *drv1; @@ -1898,7 +1892,6 @@ void bdrv_close(BlockDriverState *bs) bdrv_drain_all(); /* complete I/O */ bdrv_flush(bs); bdrv_drain_all(); /* in case flush left pending I/O */ -notifier_list_notify(bs-close_notifiers, bs); if (bs-drv) { if (bs-backing_hd) { diff --git a/block/block-backend.c b/block/block-backend.c index 82ced04..254fde4 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -47,6 +47,8 @@ struct BlockBackend { BlockdevOnError on_read_error, on_write_error; bool iostatus_enabled; BlockDeviceIoStatus iostatus; + +NotifierList remove_bs_notifiers, insert_bs_notifiers; }; typedef struct BlockBackendAIOCB { @@ -97,6 +99,8 @@ BlockBackend *blk_new(const char *name, Error **errp) blk = g_new0(BlockBackend, 1); blk-name = g_strdup(name); blk-refcnt = 1; +notifier_list_init(blk-remove_bs_notifiers); +notifier_list_init(blk-insert_bs_notifiers); QTAILQ_INSERT_TAIL(blk_backends, blk, link); return blk; } @@ -320,6 +324,8 @@ void blk_remove_bs(BlockBackend *blk) return; } +notifier_list_notify(blk-remove_bs_notifiers, blk); + blk_update_root_state(blk); bdrv_unref(blk-bs); @@ -345,6 +351,8 @@ void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs) } bs-blk = blk; + +notifier_list_notify(blk-insert_bs_notifiers, blk); } /* @@ -1067,11 +1075,14 @@ void blk_remove_aio_context_notifier(BlockBackend *blk, } } -void blk_add_close_notifier(BlockBackend *blk, Notifier *notify) +void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify) { -if (blk-bs) { -bdrv_add_close_notifier(blk-bs, notify); -} +notifier_list_add(blk-remove_bs_notifiers, notify); +} + +void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify) +{ +notifier_list_add(blk-insert_bs_notifiers, notify); } void blk_io_plug(BlockBackend *blk) diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 22e95d1..eb5f9a0 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -47,36 +47,11 @@ void qmp_nbd_server_start(SocketAddress *addr, Error **errp) } } -/* Hook into the BlockDriverState notifiers to close the export when - * the file is closed. - */ -typedef struct NBDCloseNotifier { -Notifier n; -NBDExport *exp; -QTAILQ_ENTRY(NBDCloseNotifier) next; -} NBDCloseNotifier; - -static QTAILQ_HEAD(, NBDCloseNotifier) close_notifiers = -QTAILQ_HEAD_INITIALIZER(close_notifiers); - -static void nbd_close_notifier(Notifier *n, void *data) -{ -NBDCloseNotifier *cn = DO_UPCAST(NBDCloseNotifier, n, n); - -notifier_remove(cn-n); -QTAILQ_REMOVE(close_notifiers, cn, next); - -nbd_export_close(cn-exp); -nbd_export_put(cn-exp); -g_free(cn); -} - void qmp_nbd_server_add(const char *device, bool has_writable, bool writable, Error **errp) { BlockBackend *blk; NBDExport *exp; -NBDCloseNotifier *n; if
[Qemu-devel] [PATCH v4 06/11] block: Use blk_remove_bs() in blk_delete()
Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Eric Blake ebl...@redhat.com --- block/block-backend.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index 254fde4..7e9d53a 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -163,12 +163,7 @@ static void blk_delete(BlockBackend *blk) { assert(!blk-refcnt); assert(!blk-dev); -if (blk-bs) { -assert(blk-bs-blk == blk); -blk-bs-blk = NULL; -bdrv_unref(blk-bs); -blk-bs = NULL; -} +blk_remove_bs(blk); /* Avoid double-remove after blk_hide_on_behalf_of_do_drive_del() */ if (blk-name[0]) { QTAILQ_REMOVE(blk_backends, blk, link); @@ -324,6 +319,8 @@ void blk_remove_bs(BlockBackend *blk) return; } +assert(blk-bs-blk == blk); + notifier_list_notify(blk-remove_bs_notifiers, blk); blk_update_root_state(blk); -- 2.1.0
[Qemu-devel] [PULL v2 07/11] pci: add network device class 'other' for network switches
From: Scott Feldman sfel...@gmail.com Rocker is an ethernet switch device, so add 'other' network device class as defined by PCI to cover these types of devices. Signed-off-by: Scott Feldman sfel...@gmail.com Signed-off-by: Jiri Pirko j...@resnulli.us Message-id: 1424123271-7656-6-git-send-email-sfel...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- include/hw/pci/pci_ids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index d7be386..c6de710 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -23,6 +23,7 @@ #define PCI_CLASS_STORAGE_OTHER 0x0180 #define PCI_CLASS_NETWORK_ETHERNET 0x0200 +#define PCI_CLASS_NETWORK_OTHER 0x0280 #define PCI_CLASS_DISPLAY_VGA0x0300 #define PCI_CLASS_DISPLAY_OTHER 0x0380 -- 2.1.0
[Qemu-devel] [PULL v2 00/11] Net patches
v2: * Squash in Jiri's fix for rocker format string specifiers [Peter] * Squash in Windows build fix [Peter] * Both build fixes are described in rocker: add new rocker switch device The following changes since commit 041ccc922ee474693a2869d4e3b59e920c739bc0: Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into staging (2015-02-26 12:16:46 +) are available in the git repository at: git://github.com/stefanha/qemu.git tags/net-pull-request for you to fetch changes up to 988c93209f304c76d9955ed8f7c7a18dba8ff506: rocker: timestamp on the debug logs helps correlate with events in the VM (2015-02-27 16:59:04 +) David Ahern (1): rocker: timestamp on the debug logs helps correlate with events in the VM Frediano Ziglio (1): tests: rtl8139: test timers and interrupt Paolo Bonzini (1): net: synchronize net_host_device_remove with host_net_remove_completion Scott Feldman (8): net: add MAC address string printer virtio-net: use qemu_mac_strdup_printf rocker: add register programming guide pci: add rocker device ID pci: add network device class 'other' for network switches rocker: add new rocker switch device rocker: add tests MAINTAINERS: add rocker MAINTAINERS |6 + default-configs/pci.mak |1 + docs/specs/pci-ids.txt|1 + docs/specs/rocker.txt | 1009 ++ hw/net/Makefile.objs |4 + hw/net/rocker/rocker.c| 1480 ++ hw/net/rocker/rocker.h| 85 ++ hw/net/rocker/rocker_desc.c | 379 +++ hw/net/rocker/rocker_desc.h | 57 + hw/net/rocker/rocker_fp.c | 234 + hw/net/rocker/rocker_fp.h | 53 + hw/net/rocker/rocker_hw.h | 491 + hw/net/rocker/rocker_of_dpa.c | 2314 + hw/net/rocker/rocker_of_dpa.h | 25 + hw/net/rocker/rocker_tlv.h| 244 + hw/net/rocker/rocker_world.c | 108 ++ hw/net/rocker/rocker_world.h | 63 ++ hw/net/virtio-net.c | 12 +- include/hw/pci/pci.h |1 + include/hw/pci/pci_ids.h |1 + include/net/net.h |1 + net/net.c | 13 +- tests/Makefile|2 +- tests/rocker/README |5 + tests/rocker/all | 19 + tests/rocker/bridge | 48 + tests/rocker/bridge-stp | 57 + tests/rocker/bridge-vlan | 57 + tests/rocker/bridge-vlan-stp | 69 ++ tests/rocker/port | 22 + tests/rocker/tut.dot |8 + tests/rtl8139-test.c | 181 32 files changed, 7037 insertions(+), 13 deletions(-) create mode 100644 docs/specs/rocker.txt create mode 100644 hw/net/rocker/rocker.c create mode 100644 hw/net/rocker/rocker.h create mode 100644 hw/net/rocker/rocker_desc.c create mode 100644 hw/net/rocker/rocker_desc.h create mode 100644 hw/net/rocker/rocker_fp.c create mode 100644 hw/net/rocker/rocker_fp.h create mode 100644 hw/net/rocker/rocker_hw.h create mode 100644 hw/net/rocker/rocker_of_dpa.c create mode 100644 hw/net/rocker/rocker_of_dpa.h create mode 100644 hw/net/rocker/rocker_tlv.h create mode 100644 hw/net/rocker/rocker_world.c create mode 100644 hw/net/rocker/rocker_world.h create mode 100644 tests/rocker/README create mode 100755 tests/rocker/all create mode 100755 tests/rocker/bridge create mode 100755 tests/rocker/bridge-stp create mode 100755 tests/rocker/bridge-vlan create mode 100755 tests/rocker/bridge-vlan-stp create mode 100755 tests/rocker/port create mode 100644 tests/rocker/tut.dot -- 2.1.0
[Qemu-devel] [PULL v2 02/11] tests: rtl8139: test timers and interrupt
From: Frediano Ziglio fredd...@gmail.com Test behaviour of timers and interrupts related to timeouts. Signed-off-by: Frediano Ziglio fredd...@gmail.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com Message-id: 1420742303-3030-1-git-send-email-fredd...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- tests/Makefile | 2 +- tests/rtl8139-test.c | 181 +++ 2 files changed, 182 insertions(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index 307035c..a635a9c 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -332,7 +332,7 @@ tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y) tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y) tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y) tests/e1000-test$(EXESUF): tests/e1000-test.o -tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o +tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y) tests/pcnet-test$(EXESUF): tests/pcnet-test.o tests/eepro100-test$(EXESUF): tests/eepro100-test.o tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c index f6a1be3..4e0bf02 100644 --- a/tests/rtl8139-test.c +++ b/tests/rtl8139-test.c @@ -10,19 +10,200 @@ #include glib.h #include string.h #include libqtest.h +#include libqos/pci-pc.h #include qemu/osdep.h +#include qemu-common.h /* Tests only initialization so far. TODO: Replace with functional tests */ static void nop(void) { } +#define CLK 3300 +#define NS_PER_SEC 10ULL + +static QPCIBus *pcibus; +static QPCIDevice *dev; +static void *dev_base; + +static void save_fn(QPCIDevice *dev, int devfn, void *data) +{ +QPCIDevice **pdev = (QPCIDevice **) data; + +*pdev = dev; +} + +static QPCIDevice *get_device(void) +{ +QPCIDevice *dev; + +pcibus = qpci_init_pc(); +qpci_device_foreach(pcibus, 0x10ec, 0x8139, save_fn, dev); +g_assert(dev != NULL); + +return dev; +} + +#define PORT(name, len, val) \ +static unsigned __attribute__((unused)) in_##name(void) \ +{ \ +unsigned res = qpci_io_read##len(dev, dev_base+(val)); \ +g_test_message(*%s - %x\n, #name, res); \ +return res; \ +} \ +static void out_##name(unsigned v) \ +{ \ +g_test_message(%x - *%s\n, v, #name); \ +qpci_io_write##len(dev, dev_base+(val), v); \ +} + +PORT(Timer, l, 0x48) +PORT(IntrMask, w, 0x3c) +PORT(IntrStatus, w, 0x3E) +PORT(TimerInt, l, 0x54) + +#define fatal(...) do { g_test_message(__VA_ARGS__); g_assert(0); } while (0) + +static void test_timer(void) +{ +const unsigned from = 0.95 * CLK; +const unsigned to = 1.6 * CLK; +unsigned prev, curr, next; +unsigned cnt, diff; + +out_IntrMask(0); + +in_IntrStatus(); +in_Timer(); +in_Timer(); + +/* Test 1. test counter continue and continue */ +out_TimerInt(0); /* disable timer */ +out_IntrStatus(0x4000); +out_Timer(12345); /* reset timer to 0 */ +curr = in_Timer(); +if (curr 0.1 * CLK) { +fatal(time too big %u\n, curr); +} +for (cnt = 0; ; ) { +clock_step(1 * NS_PER_SEC); +prev = curr; +curr = in_Timer(); + +/* test skip is in a specific range */ +diff = (curr-prev) 0xu; +if (diff from || diff to) { +fatal(Invalid diff %u (%u-%u)\n, diff, from, to); +} +if (curr prev ++cnt == 3) { +break; +} +} + +/* Test 2. Check we didn't get an interrupt with TimerInt == 0 */ +if (in_IntrStatus() 0x4000) { +fatal(got an interrupt\n); +} + +/* Test 3. Setting TimerInt to 1 and Timer to 0 get interrupt */ +out_TimerInt(1); +out_Timer(0); +clock_step(40); +if ((in_IntrStatus() 0x4000) == 0) { +fatal(we should have an interrupt here!\n); +} + +/* Test 3. Check acknowledge */ +out_IntrStatus(0x4000); +if (in_IntrStatus() 0x4000) { +fatal(got an interrupt\n); +} + +/* Test. Status set after Timer reset */ +out_Timer(0); +out_TimerInt(0); +out_IntrStatus(0x4000); +curr = in_Timer(); +out_TimerInt(curr + 0.5 * CLK); +clock_step(1 * NS_PER_SEC); +out_Timer(0); +if ((in_IntrStatus() 0x4000) == 0) { +fatal(we should have an interrupt here!\n); +} + +/* Test. Status set after TimerInt reset */ +out_Timer(0); +out_TimerInt(0); +out_IntrStatus(0x4000); +curr = in_Timer(); +out_TimerInt(curr + 0.5 * CLK); +clock_step(1 * NS_PER_SEC); +out_TimerInt(0); +if ((in_IntrStatus() 0x4000) == 0) { +fatal(we should have an interrupt here!\n); +} + +/* Test 4. Increment TimerInt we should see an interrupt */ +curr = in_Timer(); +next = curr + 5.0 * CLK; +out_TimerInt(next); +for (cnt = 0; ; ) { +clock_step(1 * NS_PER_SEC); +prev = curr; +curr = in_Timer(); +diff = (curr-prev)
[Qemu-devel] [PATCH 2/4] target-mips: add Unified Hosting Interface (UHI) support
Add UHI semihosting support for MIPS. QEMU run with -semihosting option will alter the behaviour of SDBBP 1 instruction -- UHI operation will be called instead of generating a debug exception. This commit implements all UHI operations apart from Argc, Argnlen and Argn. Signed-off-by: Leon Alrae leon.al...@imgtec.com --- qemu-options.hx | 5 +- target-mips/Makefile.objs | 2 +- target-mips/helper.h | 2 + target-mips/mips-semi.c | 304 ++ target-mips/translate.c | 75 5 files changed, 360 insertions(+), 28 deletions(-) create mode 100644 target-mips/mips-semi.c diff --git a/qemu-options.hx b/qemu-options.hx index 85ca3ad..99ad1ae 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3223,11 +3223,12 @@ Set OpenBIOS nvram @var{variable} to given @var{value} (PPC, SPARC only). ETEXI DEF(semihosting, 0, QEMU_OPTION_semihosting, -semihostingsemihosting mode\n, -QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32) +QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 | +QEMU_ARCH_MIPS) STEXI @item -semihosting @findex -semihosting -Enable semihosting mode (ARM, M68K, Xtensa only). +Enable semihosting mode (ARM, M68K, Xtensa, MIPS only). ETEXI DEF(semihosting-config, HAS_ARG, QEMU_OPTION_semihosting_config, -semihosting-config [enable=on|off,]target=native|gdb|auto semihosting configuration\n, diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs index 108fd9b..bc5ed85 100644 --- a/target-mips/Makefile.objs +++ b/target-mips/Makefile.objs @@ -1,4 +1,4 @@ obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o -obj-y += gdbstub.o msa_helper.o +obj-y += gdbstub.o msa_helper.o mips-semi.o obj-$(CONFIG_SOFTMMU) += machine.o obj-$(CONFIG_KVM) += kvm.o diff --git a/target-mips/helper.h b/target-mips/helper.h index 3bd0b02..7c7582f 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -1,6 +1,8 @@ DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int) DEF_HELPER_2(raise_exception, noreturn, env, i32) +DEF_HELPER_1(do_semihosting, void, env) + #ifdef TARGET_MIPS64 DEF_HELPER_4(sdl, void, env, tl, tl, int) DEF_HELPER_4(sdr, void, env, tl, tl, int) diff --git a/target-mips/mips-semi.c b/target-mips/mips-semi.c new file mode 100644 index 000..3bf7b2a --- /dev/null +++ b/target-mips/mips-semi.c @@ -0,0 +1,304 @@ +/* + * Unified Hosting Interface syscalls. + * + * Copyright (c) 2014 Imagination Technologies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/. + */ + +#include sys/stat.h +#include cpu.h +#include exec/helper-proto.h +#include exec/softmmu-semi.h + +typedef enum UHIOp { +UHI_exit = 1, +UHI_open = 2, +UHI_close = 3, +UHI_read = 4, +UHI_write = 5, +UHI_lseek = 6, +UHI_unlink = 7, +UHI_fstat = 8, +UHI_argc = 9, +UHI_argnlen = 10, +UHI_argn = 11, +UHI_plog = 13, +UHI_assert = 14, +UHI_pread = 19, +UHI_pwrite = 20, +UHI_link = 22 +} UHIOp; + +typedef struct UHIStat { +int16_t uhi_st_dev; +uint16_t uhi_st_ino; +uint32_t uhi_st_mode; +uint16_t uhi_st_nlink; +uint16_t uhi_st_uid; +uint16_t uhi_st_gid; +int16_t uhi_st_rdev; +uint64_t uhi_st_size; +uint64_t uhi_st_atime; +uint64_t uhi_st_spare1; +uint64_t uhi_st_mtime; +uint64_t uhi_st_spare2; +uint64_t uhi_st_ctime; +uint64_t uhi_st_spare3; +uint64_t uhi_st_blksize; +uint64_t uhi_st_blocks; +uint64_t uhi_st_spare4[2]; +} UHIStat; + +enum UHIOpenFlags { +UHIOpen_RDONLY = 0x0, +UHIOpen_WRONLY = 0x1, +UHIOpen_RDWR = 0x2, +UHIOpen_APPEND = 0x8, +UHIOpen_CREAT = 0x200, +UHIOpen_TRUNC = 0x400, +UHIOpen_EXCL = 0x800 +}; + +static int copy_stat_to_target(CPUMIPSState *env, const struct stat *src, +target_ulong vaddr) +{ +hwaddr len = sizeof(struct UHIStat); +UHIStat *dst = lock_user(VERIFY_WRITE, vaddr, len, 0); +if (!dst) { +return -1; +} + +dst-uhi_st_dev = tswap16(src-st_dev); +dst-uhi_st_ino = tswap16(src-st_ino); +dst-uhi_st_mode = tswap32(src-st_mode); +dst-uhi_st_nlink = tswap16(src-st_nlink); +dst-uhi_st_uid = tswap16(src-st_uid); +dst-uhi_st_gid = tswap16(src-st_gid); +dst-uhi_st_rdev =
Re: [Qemu-devel] [PATCH v2] block/vdi: Add locking for parallel requests
Am 27.02.2015 um 18:28 schrieb Max Reitz: On 2015-02-27 at 12:25, Stefan Weil wrote: block/vdi.c was never written for multi-threaded access, see my comment in the header of block/vdi.c: * The code is not thread safe (missing locks for changes in header and * block table, no problem with current QEMU). This was true in the past, but obviously later multi-threaded access was introduced for QEMU. Locking was added for qcow2 and other drivers in 2012 and 2013, but never for vdi. I must admit that I don't know which parts of the block filesystem drivers potentially run in parallel threads.Ideally there would be one or more test cases which test multi-threaded operations and which trigger a failure with the current vdi code. If I had a simple test scenario, I could have a look on the problem. I have one for you. See the attached ruby script. (If there are no Pattern verification failed messages, everything is good) The VMDK approach is fine as an intermediate work around, but please use conditional compilation to allow easy tests without coarse locks (and update the comments :-)). Will a macro defined in vdi.c be enough? Yes, that would be fine. vdi.c already has several locally defined CONFIG_VDI_... macros. Stefan
Re: [Qemu-devel] [PATCH v2] virtio-scsi: Allocate op blocker reason before blocking
On 02/27/2015 10:11 AM, Max Reitz wrote: s-blocker is really only used in hw/scsi/virtio-scsi.c; the only places where it is used in hw/scsi/virtio-scsi-dataplane.c is when it is allocated and when it is freed. That does not make a whole lot of sense (and is actually wrong because this leads to s-blocker potentially being NULL when blk_op_block_all() is called in virtio-scsi.c), so move the allocation and destruction of s-blocker to the device realization and unrealization in virtio-scsi.c, respectively. Signed-off-by: Max Reitz mre...@redhat.com --- v2: - Put the reproducer into the commit message [Markus] and modified its wording to be more fitting of a commit message (Case in point instead of the imperative Try). - As noted by Fam on my bdrv_close_all() series, there can be multiple block devices per virtio-scsi bus; therefore, it's wrong to delete the blocker if one of these is unplugged. Instead, just allocate the blocker with the virtio-scsi device itself and free it when the device is unrealized. --- hw/scsi/virtio-scsi-dataplane.c | 4 hw/scsi/virtio-scsi.c | 4 2 files changed, 4 insertions(+), 4 deletions(-) Reviewed-by: Eric Blake ebl...@redhat.com -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
[Qemu-devel] [RFC PATCH v10 18/24] replay: replay aio requests
This patch adds identifier to aio requests. ID is used for creating bottom halves and identifying them while replaying. The patch also introduces several functions that make possible replaying of the aio requests. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- block.c| 82 block/block-backend.c | 30 ++- block/qcow2.c |4 ++ dma-helpers.c |6 ++- hw/block/virtio-blk.c | 10 ++--- hw/ide/atapi.c | 10 +++-- hw/ide/core.c | 14 --- include/block/block.h | 15 +++ include/qemu-common.h |2 + include/sysemu/block-backend.h | 10 + qemu-io-cmds.c |2 - stubs/replay.c |5 ++ trace-events |2 + util/iov.c |4 ++ 14 files changed, 168 insertions(+), 28 deletions(-) diff --git a/block.c b/block.c index 210fd5f..bfd8332 100644 --- a/block.c +++ b/block.c @@ -36,6 +36,7 @@ #include qmp-commands.h #include qemu/timer.h #include qapi-event.h +#include replay/replay.h #ifdef CONFIG_BSD #include sys/types.h @@ -83,7 +84,8 @@ static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque, - bool is_write); + bool is_write, + bool aio_replay); static void coroutine_fn bdrv_co_do_rw(void *opaque); static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, int64_t sector_num, int nb_sectors, BdrvRequestFlags flags); @@ -4435,7 +4437,19 @@ BlockAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num, trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque); return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0, - cb, opaque, false); + cb, opaque, false, false); +} + +BlockAIOCB *bdrv_aio_readv_replay(BlockDriverState *bs, + int64_t sector_num, + QEMUIOVector *qiov, int nb_sectors, + BlockCompletionFunc *cb, + void *opaque) +{ +trace_bdrv_aio_readv_replay(bs, sector_num, nb_sectors, opaque); + +return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0, + cb, opaque, false, true); } BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, @@ -4445,7 +4459,19 @@ BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num, trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque); return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0, - cb, opaque, true); + cb, opaque, true, false); +} + +BlockAIOCB *bdrv_aio_writev_replay(BlockDriverState *bs, + int64_t sector_num, + QEMUIOVector *qiov, int nb_sectors, + BlockCompletionFunc *cb, + void *opaque) +{ +trace_bdrv_aio_writev_replay(bs, sector_num, nb_sectors, opaque); + +return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0, + cb, opaque, true, true); } BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, @@ -4456,7 +4482,7 @@ BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs, return bdrv_co_aio_rw_vector(bs, sector_num, NULL, nb_sectors, BDRV_REQ_ZERO_WRITE | flags, - cb, opaque, true); + cb, opaque, true, true); } @@ -4605,7 +4631,8 @@ static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs, * requests. However, the fields opaque and error are left unmodified as they * are used to signal failure for a single request to the caller. */ -int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) +int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs, +bool replay) { MultiwriteCB *mcb; int i; @@ -4643,7 +4670,7 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) bdrv_co_aio_rw_vector(bs, reqs[i].sector, reqs[i].qiov, reqs[i].nb_sectors, reqs[i].flags, multiwrite_cb, mcb, - true); + true, replay); } return 0; @@ -4788,7 +4815,12 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque)
[Qemu-devel] [RFC PATCH v10 14/24] replay: shutdown event
This patch records and replays simulator shutdown event. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- replay/replay-internal.h |2 ++ replay/replay.c | 12 replay/replay.h |5 + vl.c |1 + 4 files changed, 20 insertions(+), 0 deletions(-) diff --git a/replay/replay-internal.h b/replay/replay-internal.h index a79f4af..92d4749 100755 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -23,6 +23,8 @@ enum ReplayEvents { EVENT_EXCEPTION, /* for async events */ EVENT_ASYNC, +/* for shutdown request */ +EVENT_SHUTDOWN, /* for clock read/writes */ /* some of grteater codes are reserved for clocks */ EVENT_CLOCK, diff --git a/replay/replay.c b/replay/replay.c index fa4b27d..6e6fa1b 100755 --- a/replay/replay.c +++ b/replay/replay.c @@ -13,6 +13,7 @@ #include replay.h #include replay-internal.h #include qemu/timer.h +#include sysemu/sysemu.h ReplayMode replay_mode = REPLAY_MODE_NONE; @@ -33,6 +34,10 @@ bool replay_next_event_is(int event) res = true; } switch (replay_data_kind) { +case EVENT_SHUTDOWN: +replay_finish_event(); +qemu_system_shutdown_request(); +break; case EVENT_INSTRUCTION: replay_state.instructions_count = replay_get_dword(); return res; @@ -141,3 +146,10 @@ bool replay_has_interrupt(void) } return res; } + +void replay_shutdown_request(void) +{ +if (replay_mode == REPLAY_MODE_RECORD) { +replay_put_event(EVENT_SHUTDOWN); +} +} diff --git a/replay/replay.h b/replay/replay.h index 2398509..fcc93d1 100755 --- a/replay/replay.h +++ b/replay/replay.h @@ -66,6 +66,11 @@ int64_t replay_read_clock(ReplayClockKind kind); ? replay_save_clock((clock), (value)) \ : (value)) +/* Events */ + +/*! Called when qemu shutdown is requested. */ +void replay_shutdown_request(void); + /* Asynchronous events queue */ /*! Disables storing events in the queue */ diff --git a/vl.c b/vl.c index 00161f4..58b9dd5 100644 --- a/vl.c +++ b/vl.c @@ -1710,6 +1710,7 @@ void qemu_system_killed(int signal, pid_t pid) void qemu_system_shutdown_request(void) { trace_qemu_system_shutdown_request(); +replay_shutdown_request(); shutdown_requested = 1; qemu_notify_event(); }
[Qemu-devel] [RFC PATCH v10 06/24] replay: introduce icount event
This patch adds icount event to the replay subsystem. This event corresponds to execution of several instructions and used to synchronize input events in the replay phase. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- replay/replay-internal.c | 21 + replay/replay-internal.h | 21 + replay/replay.c | 37 + replay/replay.h |7 +++ 4 files changed, 86 insertions(+), 0 deletions(-) diff --git a/replay/replay-internal.c b/replay/replay-internal.c index f7c03bc..269fcc0 100755 --- a/replay/replay-internal.c +++ b/replay/replay-internal.c @@ -10,6 +10,7 @@ */ #include qemu-common.h +#include replay.h #include replay-internal.h unsigned int replay_data_kind = -1; @@ -34,6 +35,7 @@ void replay_put_byte(uint8_t byte) void replay_put_event(uint8_t event) { +assert(event EVENT_COUNT); replay_put_byte(event); } @@ -145,6 +147,10 @@ void replay_fetch_data_kind(void) replay_data_kind = replay_get_byte(); replay_check_error(); replay_has_unread_data = 1; +if (replay_data_kind = EVENT_COUNT) { +error_report(Replay: unknown event kind %d, replay_data_kind); +exit(1); +} } } } @@ -174,3 +180,18 @@ void replay_mutex_unlock(void) { qemu_mutex_unlock(lock); } + +/*! Saves cached instructions. */ +void replay_save_instructions(void) +{ +if (replay_file replay_mode == REPLAY_MODE_RECORD) { +int diff = (int)(replay_get_current_step() - replay_state.current_step); +if (first_cpu != NULL diff 0) { +replay_mutex_lock(); +replay_put_event(EVENT_INSTRUCTION); +replay_put_dword(diff); +replay_state.current_step += diff; +replay_mutex_unlock(); +} +} +} diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 8a0de0d..acae7ac 100755 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -14,6 +14,20 @@ #include stdio.h +enum ReplayEvents { +/* for instruction event */ +EVENT_INSTRUCTION, +EVENT_COUNT +}; + +typedef struct ReplayState { +/*! Current step - number of processed instructions and timer events. */ +uint64_t current_step; +/*! Number of instructions to be executed before other events happen. */ +int instructions_count; +} ReplayState; +extern ReplayState replay_state; + extern unsigned int replay_data_kind; /* File for replay writing */ @@ -50,4 +64,11 @@ void replay_finish_event(void); replay_data_kind variable. */ void replay_fetch_data_kind(void); +/*! Saves queued events (like instructions and sound). */ +void replay_save_instructions(void); + +/*! Skips async events until some sync event will be found. +\return true, if event was found */ +bool replay_next_event_is(int event); + #endif diff --git a/replay/replay.c b/replay/replay.c index 5ce066f..8b0fee5 100755 --- a/replay/replay.c +++ b/replay/replay.c @@ -9,6 +9,43 @@ * */ +#include qemu-common.h #include replay.h +#include replay-internal.h +#include qemu/timer.h ReplayMode replay_mode = REPLAY_MODE_NONE; + +ReplayState replay_state; + +bool replay_next_event_is(int event) +{ +bool res = false; + +/* nothing to skip - not all instructions used */ +if (replay_state.instructions_count != 0) { +assert(replay_data_kind == EVENT_INSTRUCTION); +return event == EVENT_INSTRUCTION; +} + +while (true) { +replay_fetch_data_kind(); +if (event == replay_data_kind) { +res = true; +} +switch (replay_data_kind) { +case EVENT_INSTRUCTION: +replay_state.instructions_count = replay_get_dword(); +return res; +default: +/* clock, time_t, checkpoint and other events */ +return res; +} +} +return res; +} + +uint64_t replay_get_current_step(void) +{ +return cpu_get_icount_raw(); +} diff --git a/replay/replay.h b/replay/replay.h index d6b73c3..a03c748 100755 --- a/replay/replay.h +++ b/replay/replay.h @@ -12,8 +12,15 @@ * */ +#include stdbool.h +#include stdint.h #include qapi-types.h extern ReplayMode replay_mode; +/* Processing the instructions */ + +/*! Returns number of executed instructions. */ +uint64_t replay_get_current_step(void); + #endif
[Qemu-devel] [RFC PATCH v10 24/24] replay: recording of the user input
This records user input (keyboard and mouse events) in record mode and replays these input events in replay mode. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- include/ui/input.h |2 + replay/Makefile.objs |1 replay/replay-events.c | 31 + replay/replay-input.c| 159 ++ replay/replay-internal.h | 13 replay/replay.h |4 + ui/input.c | 27 +--- 7 files changed, 229 insertions(+), 8 deletions(-) create mode 100755 replay/replay-input.c diff --git a/include/ui/input.h b/include/ui/input.h index 5d5ac00..d06a12d 100644 --- a/include/ui/input.h +++ b/include/ui/input.h @@ -33,7 +33,9 @@ void qemu_input_handler_bind(QemuInputHandlerState *s, const char *device_id, int head, Error **errp); void qemu_input_event_send(QemuConsole *src, InputEvent *evt); +void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt); void qemu_input_event_sync(void); +void qemu_input_event_sync_impl(void); InputEvent *qemu_input_event_new_key(KeyValue *key, bool down); void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down); diff --git a/replay/Makefile.objs b/replay/Makefile.objs index 257c320..3936296 100755 --- a/replay/Makefile.objs +++ b/replay/Makefile.objs @@ -2,3 +2,4 @@ obj-y += replay.o obj-y += replay-internal.o obj-y += replay-events.o obj-y += replay-time.o +obj-y += replay-input.o diff --git a/replay/replay-events.c b/replay/replay-events.c index 485a440..ecda545 100755 --- a/replay/replay-events.c +++ b/replay/replay-events.c @@ -14,6 +14,7 @@ #include replay.h #include replay-internal.h #include block/thread-pool.h +#include ui/input.h typedef struct Event { ReplayAsyncEventKind event_kind; @@ -42,6 +43,13 @@ static void replay_run_event(Event *event) case REPLAY_ASYNC_EVENT_THREAD: thread_pool_work((ThreadPool *)event-opaque, event-opaque2); break; +case REPLAY_ASYNC_EVENT_INPUT: +qemu_input_event_send_impl(NULL, (InputEvent *)event-opaque); +qapi_free_InputEvent((InputEvent *)event-opaque); +break; +case REPLAY_ASYNC_EVENT_INPUT_SYNC: +qemu_input_event_sync_impl(); +break; default: error_report(Replay: invalid async event ID (%d) in the queue, event-event_kind); @@ -144,6 +152,9 @@ static void replay_save_event(Event *event, int checkpoint) case REPLAY_ASYNC_EVENT_THREAD: replay_put_qword(event-id); break; +case REPLAY_ASYNC_EVENT_INPUT: +replay_save_input_event(event-opaque); +break; } } } @@ -158,6 +169,16 @@ void replay_add_thread_event(void *opaque, void *opaque2, uint64_t id) replay_add_event_internal(REPLAY_ASYNC_EVENT_THREAD, opaque, opaque2, id); } +void replay_add_input_event(struct InputEvent *event) +{ +replay_add_event_internal(REPLAY_ASYNC_EVENT_INPUT, event, NULL, 0); +} + +void replay_add_input_sync_event(void) +{ +replay_add_event_internal(REPLAY_ASYNC_EVENT_INPUT_SYNC, NULL, NULL, 0); +} + /* Called with replay mutex locked */ void replay_save_events(int checkpoint) { @@ -195,6 +216,16 @@ static Event *replay_read_event(int checkpoint) read_id = replay_get_qword(); } break; +case REPLAY_ASYNC_EVENT_INPUT: +event = g_malloc0(sizeof(Event)); +event-event_kind = read_event_kind; +event-opaque = replay_read_input_event(); +return event; +case REPLAY_ASYNC_EVENT_INPUT_SYNC: +event = g_malloc0(sizeof(Event)); +event-event_kind = read_event_kind; +event-opaque = 0; +return event; default: error_report(Unknown ID %d of replay event, read_event_kind); exit(1); diff --git a/replay/replay-input.c b/replay/replay-input.c new file mode 100755 index 000..54923b9 --- /dev/null +++ b/replay/replay-input.c @@ -0,0 +1,159 @@ +/* + * replay-input.c + * + * Copyright (c) 2010-2015 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include qemu-common.h +#include replay.h +#include replay-internal.h +#include ui/input.h +#include qapi/qmp-output-visitor.h +#include qapi/qmp-input-visitor.h +#include qapi-visit.h + +static InputEvent *qapi_clone_InputEvent(InputEvent *src) +{ +QmpOutputVisitor *qov; +QmpInputVisitor *qiv; +Visitor *ov, *iv; +QObject *obj; +InputEvent *dst = NULL; + +qov = qmp_output_visitor_new(); +ov = qmp_output_get_visitor(qov); +visit_type_InputEvent(ov, src, NULL, error_abort); +obj = qmp_output_get_qobject(qov); +qmp_output_visitor_cleanup(qov); +if (!obj) { +return NULL; +} + +
[Qemu-devel] [PATCH] virtio-pci: Convert to realize()
Signed-off-by: Markus Armbruster arm...@redhat.com --- Depends on my [PATCH 00/10] pci: Partial conversion to realize, which is in Michael's latest pull request. hw/virtio/virtio-pci.c | 88 -- hw/virtio/virtio-pci.h | 2 +- 2 files changed, 36 insertions(+), 54 deletions(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 604cb5b..58fb14f 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -900,16 +900,13 @@ static void virtio_pci_vmstate_change(DeviceState *d, bool running) } #ifdef CONFIG_VIRTFS -static int virtio_9p_init_pci(VirtIOPCIProxy *vpci_dev) +static void virtio_9p_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { V9fsPCIState *dev = VIRTIO_9P_PCI(vpci_dev); DeviceState *vdev = DEVICE(dev-vdev); qdev_set_parent_bus(vdev, BUS(vpci_dev-bus)); -if (qdev_init(vdev) 0) { -return -1; -} -return 0; +object_property_set_bool(OBJECT(vdev), true, realized, errp); } static Property virtio_9p_pci_properties[] = { @@ -925,7 +922,7 @@ static void virtio_9p_pci_class_init(ObjectClass *klass, void *data) PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); -k-init = virtio_9p_init_pci; +k-realize = virtio_9p_pci_realize; pcidev_k-vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; pcidev_k-device_id = PCI_DEVICE_ID_VIRTIO_9P; pcidev_k-revision = VIRTIO_PCI_ABI_VERSION; @@ -1009,15 +1006,15 @@ static void virtio_pci_device_unplugged(DeviceState *d) virtio_pci_stop_ioeventfd(proxy); } -static int virtio_pci_init(PCIDevice *pci_dev) +static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp) { VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev); VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev); + virtio_pci_bus_new(dev-bus, sizeof(dev-bus), dev); -if (k-init != NULL) { -return k-init(dev); +if (k-realize) { +k-realize(dev, errp); } -return 0; } static void virtio_pci_exit(PCIDevice *pci_dev) @@ -1047,7 +1044,7 @@ static void virtio_pci_class_init(ObjectClass *klass, void *data) PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); dc-props = virtio_pci_properties; -k-init = virtio_pci_init; +k-realize = virtio_pci_realize; k-exit = virtio_pci_exit; k-vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; k-revision = VIRTIO_PCI_ABI_VERSION; @@ -1074,15 +1071,13 @@ static Property virtio_blk_pci_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static int virtio_blk_pci_init(VirtIOPCIProxy *vpci_dev) +static void virtio_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(vpci_dev); DeviceState *vdev = DEVICE(dev-vdev); + qdev_set_parent_bus(vdev, BUS(vpci_dev-bus)); -if (qdev_init(vdev) 0) { -return -1; -} -return 0; +object_property_set_bool(OBJECT(vdev), true, realized, errp); } static void virtio_blk_pci_class_init(ObjectClass *klass, void *data) @@ -1093,7 +1088,7 @@ static void virtio_blk_pci_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_STORAGE, dc-categories); dc-props = virtio_blk_pci_properties; -k-init = virtio_blk_pci_init; +k-realize = virtio_blk_pci_realize; pcidev_k-vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; pcidev_k-device_id = PCI_DEVICE_ID_VIRTIO_BLOCK; pcidev_k-revision = VIRTIO_PCI_ABI_VERSION; @@ -1131,7 +1126,7 @@ static Property virtio_scsi_pci_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static int virtio_scsi_pci_init_pci(VirtIOPCIProxy *vpci_dev) +static void virtio_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(vpci_dev); DeviceState *vdev = DEVICE(dev-vdev); @@ -1154,10 +1149,7 @@ static int virtio_scsi_pci_init_pci(VirtIOPCIProxy *vpci_dev) } qdev_set_parent_bus(vdev, BUS(vpci_dev-bus)); -if (qdev_init(vdev) 0) { -return -1; -} -return 0; +object_property_set_bool(OBJECT(vdev), true, realized, errp); } static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data) @@ -1165,7 +1157,8 @@ static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); -k-init = virtio_scsi_pci_init_pci; + +k-realize = virtio_scsi_pci_realize; set_bit(DEVICE_CATEGORY_STORAGE, dc-categories); dc-props = virtio_scsi_pci_properties; pcidev_k-vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; @@ -1201,7 +1194,7 @@ static Property vhost_scsi_pci_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static int vhost_scsi_pci_init_pci(VirtIOPCIProxy *vpci_dev) +static void vhost_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) { VHostSCSIPCI *dev = VHOST_SCSI_PCI(vpci_dev);
Re: [Qemu-devel] [PATCH v2 6/9] qtest/ahci: add migrate dma test
On 27/02/2015 00:50, John Snow wrote: +/* Write, migrate, then read. */ +ahci_io(src, px, CMD_WRITE_DMA, tx, bufsize, 0); +ahci_migrate(src, dst, uri); +ahci_io(dst, px, CMD_READ_DMA, rx, bufsize, 0); IIUC, tests for READ_FPDMA_QUEUED and WRITE_FPDMA_QUEUED are going to be in a separate patch series, right? Paolo
Re: [Qemu-devel] [Qemu-ppc] [PATCHv3 0/9] ppc: loadvm/savevm fixups for -M g3beige and -M mac99
On 09/02/15 22:40, Mark Cave-Ayland wrote: This patchset fixes up various bugs in loadvm/savevm for -M g3beige and -M mac99 so that it is becomes possible to save and restore image snapshots. The focus of this patchset is on -M g3beige since this matches the majority of my test images, but there were some easy fixes to be made to -M mac99 at the same time. With this patchset applied both -M g3beige and -M mac99 images can be saved/restored whilst booted into OpenBIOS with no issues. I tested -M g3beige with a paused, disk-inactive Darwin 6 image and was able to resume successfully which was good enough for my needs. I noticed some hangs can still occur when trying to restore an image where the disk is active which makes me believe that there is still some extra macio/dbdma state which needs to be included if someone is interested enough to pursue this further. Most of the patches are straightforward except for patch 4 which came out of a discussion on-list between Alex and Paolo, and patch 5 which is a similar error except this time for the MSR register. Ping? Just saw the other openpic patches go through the list and was wondering if this patchset needed any further work? ATB, Mark.
[Qemu-devel] [RFC PATCH v10 01/24] i386: partial revert of interrupt poll fix
Processing CPU_INTERRUPT_POLL requests in cpu_has_work functions break the determinism of cpu_exec. This patch is required to make interrupts processing deterministic. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- cpu-exec.c|6 ++ target-i386/cpu.c | 10 ++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 6738117..a048f85 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -335,6 +335,12 @@ int cpu_exec(CPUArchState *env) volatile bool have_tb_lock = false; if (cpu-halted) { +#ifdef TARGET_I386 +if (cpu-interrupt_request CPU_INTERRUPT_POLL) { +apic_poll_irq(x86_cpu-apic_state); +cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL); +} +#endif if (!cpu_has_work(cpu)) { return EXCP_HALTED; } diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 3a9b32e..e90464d 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2969,14 +2969,8 @@ static bool x86_cpu_has_work(CPUState *cs) X86CPU *cpu = X86_CPU(cs); CPUX86State *env = cpu-env; -#if !defined(CONFIG_USER_ONLY) -if (cs-interrupt_request CPU_INTERRUPT_POLL) { -apic_poll_irq(cpu-apic_state); -cpu_reset_interrupt(cs, CPU_INTERRUPT_POLL); -} -#endif - -return ((cs-interrupt_request CPU_INTERRUPT_HARD) +return ((cs-interrupt_request (CPU_INTERRUPT_HARD | + CPU_INTERRUPT_POLL)) (env-eflags IF_MASK)) || (cs-interrupt_request (CPU_INTERRUPT_NMI | CPU_INTERRUPT_INIT |
[Qemu-devel] [RFC PATCH v10 17/24] replay: bottom halves
This patch introduces bottom half event for replay queue. It saves the events into the queue and process them at the checkpoints and instructions execution. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- async.c | 24 +++- dma-helpers.c|4 +++- hw/ide/ahci.c|4 +++- hw/ide/core.c|4 +++- hw/timer/arm_timer.c |2 +- hw/usb/hcd-uhci.c|2 +- include/block/aio.h | 18 ++ include/qemu/main-loop.h |1 + main-loop.c |5 + replay/replay-events.c | 16 replay/replay-internal.h |1 + replay/replay.h |2 ++ stubs/replay.c |4 13 files changed, 81 insertions(+), 6 deletions(-) diff --git a/async.c b/async.c index d83b7c8..75368af 100644 --- a/async.c +++ b/async.c @@ -27,6 +27,7 @@ #include block/thread-pool.h #include qemu/main-loop.h #include qemu/atomic.h +#include replay/replay.h /***/ /* bottom halves (can be seen as timers which expire ASAP) */ @@ -39,6 +40,8 @@ struct QEMUBH { bool scheduled; bool idle; bool deleted; +bool replay; +uint64_t id; }; QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque) @@ -56,6 +59,21 @@ QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque) return bh; } +QEMUBH *aio_bh_new_replay(AioContext *ctx, QEMUBHFunc *cb, void *opaque, + uint64_t id) +{ +QEMUBH *bh = aio_bh_new(ctx, cb, opaque); +bh-replay = true; +bh-id = id; +return bh; +} + +void aio_bh_call(void *opaque) +{ +QEMUBH *bh = (QEMUBH *)opaque; +bh-cb(bh-opaque); +} + /* Multiple occurrences of aio_bh_poll cannot be called concurrently */ int aio_bh_poll(AioContext *ctx) { @@ -77,7 +95,11 @@ int aio_bh_poll(AioContext *ctx) if (!bh-idle) ret = 1; bh-idle = 0; -bh-cb(bh-opaque); +if (!bh-replay) { +aio_bh_call(bh); +} else { +replay_add_bh_event(bh, bh-id); +} } } diff --git a/dma-helpers.c b/dma-helpers.c index 6918572..357d7e9 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -13,6 +13,7 @@ #include qemu/range.h #include qemu/thread.h #include qemu/main-loop.h +#include replay/replay.h /* #define DEBUG_IOMMU */ @@ -96,7 +97,8 @@ static void continue_after_map_failure(void *opaque) { DMAAIOCB *dbs = (DMAAIOCB *)opaque; -dbs-bh = qemu_bh_new(reschedule_dma, dbs); +dbs-bh = qemu_bh_new_replay(reschedule_dma, dbs, + replay_get_current_step()); qemu_bh_schedule(dbs-bh); } diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 5651372..13d7f84 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -33,6 +33,7 @@ #include internal.h #include hw/ide/pci.h #include hw/ide/ahci.h +#include replay/replay.h #define DEBUG_AHCI 0 @@ -1243,7 +1244,8 @@ static void ahci_cmd_done(IDEDMA *dma) if (!ad-check_bh) { /* maybe we still have something to process, check later */ -ad-check_bh = qemu_bh_new(ahci_check_cmd_bh, ad); +ad-check_bh = qemu_bh_new_replay(ahci_check_cmd_bh, ad, + replay_get_current_step()); qemu_bh_schedule(ad-check_bh); } } diff --git a/hw/ide/core.c b/hw/ide/core.c index ac3f015..d6af700 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -32,6 +32,7 @@ #include sysemu/dma.h #include hw/block/block.h #include sysemu/block-backend.h +#include replay/replay.h #include hw/ide/internal.h @@ -448,7 +449,8 @@ BlockAIOCB *ide_issue_trim(BlockBackend *blk, iocb = blk_aio_get(trim_aiocb_info, blk, cb, opaque); iocb-blk = blk; -iocb-bh = qemu_bh_new(ide_trim_bh_cb, iocb); +iocb-bh = qemu_bh_new_replay(ide_trim_bh_cb, iocb, + replay_get_current_step()); iocb-ret = 0; iocb-qiov = qiov; iocb-i = -1; diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c index 1452910..97784a0 100644 --- a/hw/timer/arm_timer.c +++ b/hw/timer/arm_timer.c @@ -168,7 +168,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq) s-freq = freq; s-control = TIMER_CTRL_IE; -bh = qemu_bh_new(arm_timer_tick, s); +bh = qemu_bh_new_replay(arm_timer_tick, s, 0); s-timer = ptimer_init(bh); vmstate_register(NULL, -1, vmstate_arm_timer, s); return s; diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index f903de7..47ff9f4 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -1221,7 +1221,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev) USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); } } -s-bh = qemu_bh_new(uhci_bh, s); +s-bh = qemu_bh_new_replay(uhci_bh, s, 0); s-frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
[Qemu-devel] [RFC PATCH v10 21/24] replay: initialization and deinitialization
This patch introduces the functions for enabling the record/replay and for freeing the resources when simulator closes. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- exec.c |1 replay/replay-internal.h |2 + replay/replay.c | 138 ++ replay/replay.h | 10 +++ stubs/replay.c |5 ++ vl.c |4 + 6 files changed, 160 insertions(+), 0 deletions(-) diff --git a/exec.c b/exec.c index 6dff7bc..1d9094d 100644 --- a/exec.c +++ b/exec.c @@ -783,6 +783,7 @@ void cpu_abort(CPUState *cpu, const char *fmt, ...) } va_end(ap2); va_end(ap); +replay_finish(); #if defined(CONFIG_USER_ONLY) { struct sigaction act; diff --git a/replay/replay-internal.h b/replay/replay-internal.h index 2f557a6..776a30c 100755 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -33,6 +33,8 @@ enum ReplayEvents { /* some of grteater codes are reserved for checkpoints */ EVENT_CHECKPOINT, EVENT_CHECKPOINT_LAST = EVENT_CHECKPOINT + CHECKPOINT_COUNT - 1, +/* end of log event */ +EVENT_END, EVENT_COUNT }; diff --git a/replay/replay.c b/replay/replay.c index 8081681..98b5e2f 100755 --- a/replay/replay.c +++ b/replay/replay.c @@ -15,8 +15,16 @@ #include qemu/timer.h #include sysemu/sysemu.h +/* Current version of the replay mechanism. + Increase it when file format changes. */ +#define REPLAY_VERSION 0xe02002 +/* Size of replay log header */ +#define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t)) + ReplayMode replay_mode = REPLAY_MODE_NONE; +/* Name of replay file */ +static char *replay_filename; ReplayState replay_state; bool replay_next_event_is(int event) @@ -157,6 +165,10 @@ void replay_shutdown_request(void) bool replay_checkpoint(ReplayCheckpoint checkpoint) { bool res = false; +if (!replay_events_enabled()) { +return true; +} + replay_save_instructions(); if (!replay_file) { @@ -186,3 +198,129 @@ out: replay_mutex_unlock(); return res; } + +static void replay_enable(const char *fname, int mode) +{ +const char *fmode = NULL; +assert(!replay_file); + +switch (mode) { +case REPLAY_MODE_RECORD: +fmode = wb; +break; +case REPLAY_MODE_PLAY: +fmode = rb; +break; +default: +fprintf(stderr, Replay: internal error: invalid replay mode\n); +exit(1); +} + +atexit(replay_finish); + +replay_mutex_init(); + +replay_file = fopen(fname, fmode); +if (replay_file == NULL) { +fprintf(stderr, Replay: open %s: %s\n, fname, strerror(errno)); +exit(1); +} + +replay_filename = g_strdup(fname); + +replay_mode = mode; +replay_data_kind = -1; +replay_state.instructions_count = 0; +replay_state.current_step = 0; + +/* skip file header for RECORD and check it for PLAY */ +if (replay_mode == REPLAY_MODE_RECORD) { +fseek(replay_file, HEADER_SIZE, SEEK_SET); +} else if (replay_mode == REPLAY_MODE_PLAY) { +unsigned int version = replay_get_dword(); +uint64_t offset = replay_get_qword(); +if (version != REPLAY_VERSION) { +fprintf(stderr, Replay: invalid input log file version\n); +exit(1); +} +/* go to the beginning */ +fseek(replay_file, 12, SEEK_SET); +replay_fetch_data_kind(); +} + +replay_init_events(); +} + +void replay_configure(QemuOpts *opts) +{ +const char *fname; +const char *rr; +ReplayMode mode = REPLAY_MODE_NONE; + +rr = qemu_opt_get(opts, rr); +if (!rr) { +/* Just enabling icount */ +return; +} else if (!strcmp(rr, record)) { +mode = REPLAY_MODE_RECORD; +} else if (!strcmp(rr, replay)) { +mode = REPLAY_MODE_PLAY; +} else { +error_report(Invalid icount rr option: %s, rr); +exit(1); +} + +fname = qemu_opt_get(opts, rrfile); +if (!fname) { +error_report(File name not specified for replay); +exit(1); +} + +replay_enable(fname, mode); +} + +void replay_start(void) +{ +if (replay_mode == REPLAY_MODE_NONE) { +return; +} + +/* Timer for snapshotting will be set up here. */ + +replay_enable_events(); +} + +void replay_finish(void) +{ +if (replay_mode == REPLAY_MODE_NONE) { +return; +} + +replay_save_instructions(); + +/* finalize the file */ +if (replay_file) { +if (replay_mode == REPLAY_MODE_RECORD) { +uint64_t offset = 0; +/* write end event */ +replay_put_event(EVENT_END); + +/* write header */ +fseek(replay_file, 0, SEEK_SET); +replay_put_dword(REPLAY_VERSION); +/* Just zero in this version. + But will be
[Qemu-devel] [RFC PATCH v10 08/24] cpu: replay instructions sequence
This patch adds calls to replay functions into the icount setup block. In record mode number of executed instructions is written to the log. In replay mode number of istructions to execute is taken from the replay log. When replayed instructions counter is expired qemu_notify_event() function is called to wake up the iothread. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- cpus.c | 38 +- replay/replay.c | 31 ++- replay/replay.h |4 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/cpus.c b/cpus.c index 04124ca..511a0c5 100644 --- a/cpus.c +++ b/cpus.c @@ -41,6 +41,7 @@ #include qemu/seqlock.h #include qapi-event.h #include hw/nmi.h +#include replay/replay.h #ifndef _WIN32 #include qemu/compatfd.h @@ -1306,6 +1307,28 @@ int vm_stop_force_state(RunState state) } } +static int64_t tcg_get_icount_limit(void) +{ +int64_t deadline; + +if (replay_mode != REPLAY_MODE_PLAY) { +deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); + +/* Maintain prior (possibly buggy) behaviour where if no deadline + * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than + * INT32_MAX nanoseconds ahead, we still use INT32_MAX + * nanoseconds. + */ +if ((deadline 0) || (deadline INT32_MAX)) { +deadline = INT32_MAX; +} + +return qemu_icount_round(deadline); +} else { +return replay_get_instructions(); +} +} + static int tcg_cpu_exec(CPUArchState *env) { CPUState *cpu = ENV_GET_CPU(env); @@ -1319,24 +1342,12 @@ static int tcg_cpu_exec(CPUArchState *env) #endif if (use_icount) { int64_t count; -int64_t deadline; int decr; timers_state.qemu_icount -= (cpu-icount_decr.u16.low + cpu-icount_extra); cpu-icount_decr.u16.low = 0; cpu-icount_extra = 0; -deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); - -/* Maintain prior (possibly buggy) behaviour where if no deadline - * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than - * INT32_MAX nanoseconds ahead, we still use INT32_MAX - * nanoseconds. - */ -if ((deadline 0) || (deadline INT32_MAX)) { -deadline = INT32_MAX; -} - -count = qemu_icount_round(deadline); +count = tcg_get_icount_limit(); timers_state.qemu_icount += count; decr = (count 0x) ? 0x : count; count -= decr; @@ -1354,6 +1365,7 @@ static int tcg_cpu_exec(CPUArchState *env) + cpu-icount_extra); cpu-icount_decr.u32 = 0; cpu-icount_extra = 0; +replay_account_executed_instructions(); } return ret; } diff --git a/replay/replay.c b/replay/replay.c index 8b0fee5..bf0e27e 100755 --- a/replay/replay.c +++ b/replay/replay.c @@ -29,7 +29,6 @@ bool replay_next_event_is(int event) } while (true) { -replay_fetch_data_kind(); if (event == replay_data_kind) { res = true; } @@ -49,3 +48,33 @@ uint64_t replay_get_current_step(void) { return cpu_get_icount_raw(); } + +int replay_get_instructions(void) +{ +int res = 0; +replay_mutex_lock(); +if (replay_next_event_is(EVENT_INSTRUCTION)) { +res = replay_state.instructions_count; +} +replay_mutex_unlock(); +return res; +} + +void replay_account_executed_instructions(void) +{ +if (replay_mode == REPLAY_MODE_PLAY + replay_state.instructions_count 0) { +int count = (int)(replay_get_current_step() + - replay_state.current_step); +replay_state.instructions_count -= count; +replay_state.current_step += count; +if (replay_state.instructions_count == 0) { +assert(replay_data_kind == EVENT_INSTRUCTION); +replay_finish_event(); +/* Wake up iothread. This is required because + timers will not expire until clock counters + will be read from the log. */ +qemu_notify_event(); +} +} +} diff --git a/replay/replay.h b/replay/replay.h index a03c748..d19715f 100755 --- a/replay/replay.h +++ b/replay/replay.h @@ -22,5 +22,9 @@ extern ReplayMode replay_mode; /*! Returns number of executed instructions. */ uint64_t replay_get_current_step(void); +/*! Returns number of instructions to execute in replay mode. */ +int replay_get_instructions(void); +/*! Updates instructions counter in replay mode. */ +void replay_account_executed_instructions(void); #endif
[Qemu-devel] [PATCH 2/2] virtio-s390: Convert to realize()
Signed-off-by: Markus Armbruster arm...@redhat.com --- hw/s390x/s390-virtio-bus.c | 80 ++ hw/s390x/s390-virtio-bus.h | 2 +- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index f69ff11..55a5581 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -138,22 +138,24 @@ static void s390_virtio_device_init(VirtIOS390Device *dev, } } -static int s390_virtio_net_init(VirtIOS390Device *s390_dev) +static void s390_virtio_net_realize(VirtIOS390Device *s390_dev, Error **errp) { DeviceState *qdev = DEVICE(s390_dev); VirtIONetS390 *dev = VIRTIO_NET_S390(s390_dev); DeviceState *vdev = DEVICE(dev-vdev); +Error *err = NULL; virtio_net_set_config_size(dev-vdev, s390_dev-host_features); virtio_net_set_netclient_name(dev-vdev, qdev-id, object_get_typename(OBJECT(qdev))); qdev_set_parent_bus(vdev, BUS(s390_dev-bus)); -if (qdev_init(vdev) 0) { -return -1; +object_property_set_bool(OBJECT(vdev), true, realized, err); +if (err) { +error_propagate(errp, err); +return; } s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -return 0; } static void s390_virtio_net_instance_init(Object *obj) @@ -166,16 +168,19 @@ static void s390_virtio_net_instance_init(Object *obj) bootindex, error_abort); } -static int s390_virtio_blk_init(VirtIOS390Device *s390_dev) +static void s390_virtio_blk_realize(VirtIOS390Device *s390_dev, Error **errp) { VirtIOBlkS390 *dev = VIRTIO_BLK_S390(s390_dev); DeviceState *vdev = DEVICE(dev-vdev); +Error *err = NULL; + qdev_set_parent_bus(vdev, BUS(s390_dev-bus)); -if (qdev_init(vdev) 0) { -return -1; +object_property_set_bool(OBJECT(vdev), true, realized, err); +if (err) { +error_propagate(errp, err); +return; } s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -return 0; } static void s390_virtio_blk_instance_init(Object *obj) @@ -190,13 +195,13 @@ static void s390_virtio_blk_instance_init(Object *obj) bootindex, error_abort); } -static int s390_virtio_serial_init(VirtIOS390Device *s390_dev) +static void s390_virtio_serial_realize(VirtIOS390Device *s390_dev, Error **errp) { VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(s390_dev); DeviceState *vdev = DEVICE(dev-vdev); DeviceState *qdev = DEVICE(s390_dev); +Error *err = NULL; VirtIOS390Bus *bus; -int r; char *bus_name; bus = DO_UPCAST(VirtIOS390Bus, bus, qdev-parent_bus); @@ -212,13 +217,14 @@ static int s390_virtio_serial_init(VirtIOS390Device *s390_dev) } qdev_set_parent_bus(vdev, BUS(s390_dev-bus)); -if (qdev_init(vdev) 0) { -return -1; +object_property_set_bool(OBJECT(vdev), true, realized, err); +if (err) { +error_propagate(errp, err); +return; } s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); bus-console = s390_dev; -return 0; } static void s390_virtio_serial_instance_init(Object *obj) @@ -229,11 +235,12 @@ static void s390_virtio_serial_instance_init(Object *obj) TYPE_VIRTIO_SERIAL); } -static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev) +static void s390_virtio_scsi_realize(VirtIOS390Device *s390_dev, Error **errp) { VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(s390_dev); DeviceState *vdev = DEVICE(dev-vdev); DeviceState *qdev = DEVICE(s390_dev); +Error *err = NULL; char *bus_name; /* @@ -247,12 +254,13 @@ static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev) } qdev_set_parent_bus(vdev, BUS(s390_dev-bus)); -if (qdev_init(vdev) 0) { -return -1; +object_property_set_bool(OBJECT(vdev), true, realized, err); +if (err) { +error_propagate(errp, err); +return; } s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -return 0; } static void s390_virtio_scsi_instance_init(Object *obj) @@ -264,18 +272,20 @@ static void s390_virtio_scsi_instance_init(Object *obj) } #ifdef CONFIG_VHOST_SCSI -static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev) +static void s390_vhost_scsi_realize(VirtIOS390Device *s390_dev, Error **errp) { VHostSCSIS390 *dev = VHOST_SCSI_S390(s390_dev); DeviceState *vdev = DEVICE(dev-vdev); +Error *err = NULL; qdev_set_parent_bus(vdev, BUS(s390_dev-bus)); -if (qdev_init(vdev) 0) { -return -1; +object_property_set_bool(OBJECT(vdev), true, realized, err); +if (err) { +error_propagate(errp, err); +return; } s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -return 0; } static void s390_vhost_scsi_instance_init(Object *obj) @@ -288,14 +298,17 @@ static void
[Qemu-devel] [PATCH 0/2] virtio-s390: Convert to realize()
Markus Armbruster (2): virtio-s390: s390_virtio_device_init() can't fail, simplify virtio-s390: Convert to realize() hw/s390x/s390-virtio-bus.c | 97 ++ hw/s390x/s390-virtio-bus.h | 2 +- 2 files changed, 56 insertions(+), 43 deletions(-) -- 1.9.3
Re: [Qemu-devel] [PULL 04/11] target-i386: Rename cpu_x86_init() to cpu_x86_init_user()
Am 26.02.2015 um 16:59 schrieb Eduardo Habkost: On Wed, Feb 25, 2015 at 11:06:55PM +0100, Andreas Färber wrote: Am 25.02.2015 um 20:58 schrieb Eduardo Habkost: The function is used only for CONFIG_USER, so make its purpose clear. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Eduardo Habkost ehabk...@redhat.com --- target-i386/cpu.c | 2 +- target-i386/cpu.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) Please don't. I happily got all architectures aligned that it's at least cpu_something_init, and it only happens to be user-only for x86. It is rather the legacy function that was used in both system and user. If that's a legacy function, what are the steps you plan to follow to eliminate it? I would be glad to help eliminating legacy code. Initialization of CPUs in *-user and *-softmmu is different in i386, so we are going to have different code for both. How do you think I should name the *-user-specific CPU init function in target-i386, then? I would prefer to leave its name as it is (unless we are renaming all, which would probably be a waste of effort giving the next steps) and simply not use it in PC code. If you want to enforce this, you could #ifdef CONFIG_USER_ONLY it. For some targets - as can be seen in your uc32 patch - there is already a cpu_generic_init() that calls into the CPUClass hooks of the given CPU type. I would like to call that from linux-user directly (or from a lightweight wrapper to be shared between linux-user and bsd-user, I assume we're going need some target-specific #ifdefs) and drop cpu_init() in its current form. In particular I want to somehow move the realized=true part out of it, which means either inlining it into dozens of machines or finishing the recursive realization work so that we only need one central realized=true for /machine. My branch with the last realize_children code unfortunately ran into conflicts with hotplug handler code and recursive un-realization and hasn't been rebased in months. Paolo's comment had been that we would need to assure by reordering (or at least prove it not-yet-necessary by assertions) that the qdev-bus topology in addition to the QOM parents have been realized before a given child device gets realized. Additionally, /machine is its own type iirc, so will either need to become a device or have its own realized property implementation iterating over its direct, unassigned and peripheral children. Regards, Andreas -- SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu, Graham Norton; HRB 21284 (AG Nürnberg)
[Qemu-devel] [PATCH] pci: Convert pci_nic_init() to Error to avoid qdev_init()
qdev_init() is deprecated, and will be removed when its callers have been weaned off it. Signed-off-by: Markus Armbruster arm...@redhat.com --- Depends on my [PATCH 00/10] pci: Partial conversion to realize, which is in Michael's latest pull request, and on my [PATCH v2 2/2] pci: Give a few helpers internal linkage. hw/pci/pci.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index cc5d946..6941a82 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1613,9 +1613,11 @@ static const char * const pci_nic_names[] = { /* Initialize a PCI NIC. */ static PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus, const char *default_model, - const char *default_devaddr) + const char *default_devaddr, + Error **errp) { const char *devaddr = nd-devaddr ? nd-devaddr : default_devaddr; +Error *err = NULL; PCIBus *bus; int devfn; PCIDevice *pci_dev; @@ -1636,8 +1638,13 @@ static PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus, pci_dev = pci_create(bus, devfn, pci_nic_names[i]); dev = pci_dev-qdev; qdev_set_nic_properties(dev, nd); -if (qdev_init(dev) 0) + +object_property_set_bool(OBJECT(dev), true, realized, err); +if (err) { +error_propagate(errp, err); +object_unparent(OBJECT(dev)); return NULL; +} return pci_dev; } @@ -1645,14 +1652,17 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus, const char *default_model, const char *default_devaddr) { +Error *err = NULL; PCIDevice *res; if (qemu_show_nic_models(nd-model, pci_nic_models)) exit(0); -res = pci_nic_init(nd, rootbus, default_model, default_devaddr); -if (!res) +res = pci_nic_init(nd, rootbus, default_model, default_devaddr, err); +if (!res) { +error_report_err(err); exit(1); +} return res; } -- 1.9.3
Re: [Qemu-devel] [RFC PATCH v9 00/23] Deterministic replay core
On 27/02/2015 10:23, Pavel Dovgaluk wrote: From: Paolo Bonzini [mailto:paolo.bonz...@gmail.com] On Behalf Of Paolo Bonzini On 18/02/2015 12:55, Pavel Dovgalyuk wrote: This set of patches is related to the reverse execution and deterministic replay of qemu execution. This implementation of deterministic replay can be used for deterministic debugging of guest code through gdb remote interface. These patches include only core function of the replay, excluding the support for replaying serial, audio, network, and USB devices' operations. Reverse debugging and monitor commands were also excluded to be submitted later as separate patches. Execution recording writes non-deterministic events log, which can be later used for replaying the execution anywhere and for unlimited number of times. It also supports checkpointing for faster rewinding during reverse debugging. Execution replaying reads the log and replays all non-deterministic events including external input, hardware clocks, and interrupts. Deterministic replay has the following features: * Deterministically replays whole system execution and all contents of the memory, state of the hadrware devices, clocks, and screen of the VM. * Writes execution log into the file for latter replaying for multiple times on different machines. * Supports i386, x86_64, and ARM hardware platforms. * Performs deterministic replay of all operations with keyboard and mouse input devices. * Supports auto-checkpointing for convenient reverse debugging. Usage of the record/replay: * First, record the execution, by adding the following string to the command line: '-icount shift=7,rr=record,rrfile=replay.bin -net none'. Block devices' images are not actually changed in the recording mode, because all of the changes are written to the temporary overlay file. * Then you can replay it for the multiple times by using another command line option: '-icount shift=7,rr=replay,rrfile=replay.bin -net none' * '-net none' option should also be specified if network replay patches are not applied. Paper with short description of deterministic replay implementation: http://www.computer.org/csdl/proceedings/csmr/2012/4666/00/4666a553-abs.html Modifications of qemu include: * wrappers for clock and time functions to save their return values in the log * saving different asynchronous events (e.g. system shutdown) into the log * synchronization of the bottom halves execution * synchronization of the threads from thread pool * recording/replaying user input (mouse and keyboard) * adding internal events for cpu and io synchronization v9 changes: * Replaced fwrite/fread with putc/getc (as suggested by Paolo Bonzini) * Stopping virtual machine in case of replay file end (as suggested by Paolo Bonzini) * Removed one of the replay mutexes (as suggested by Paolo Bonzini) * Fixed RCU queue for bottom halves (as suggested by Paolo Bonzini) * Updated command line options' names (as suggested by Paolo Bonzini) * Added design document for record/replay (as suggested by Paolo Bonzini) * Simplified checkpoints for the timers * Added cloning InputEvent objects for replay (as suggested by Paolo Bonzini) * Added replay blockers instead of checking the command line (as suggested by Paolo Bonzini) * Some functions renaming and extracting. I haven't yet reviewed patch 23 completely, and I have to think (a lot :)) more about block devices. In the meanwhile I understand the replay code much better so I had some suggestions. Do you have more comments? I'm ready to submit a new version. 23 is fine. Block devices probably are best left as is for now. Paolo In general, the handling of replay_has_unread_data / replay_data_kind is a bit messy. It would be nice if you could call replay_fetch_data_kind() only when replay_has_unread_data == 0. Or, even, remove replay_has_unread_data altogether: just call replay_fetch_data_kind() when you'd set it to zero. That would simplify a lot the code for readers. Fixed. Pavel Dovgalyuk
[Qemu-devel] [RFC PATCH v10 23/24] replay: command line options
This patch introduces command line options for enabling recording or replaying virtual machine behavior. These options are added to icount command line parameter. They include 'rr' which switches between record and replay and 'rrfile' for specifying the filename for replay log. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- qemu-options.hx |8 ++-- replay/replay.c |4 vl.c| 15 +-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 85ca3ad..c62661a 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3038,11 +3038,11 @@ re-inject them. ETEXI DEF(icount, HAS_ARG, QEMU_OPTION_icount, \ --icount [shift=N|auto][,align=on|off]\n \ +-icount [shift=N|auto][,align=on|off][,rr=record|replay,rrfile=filename]\n \ enable virtual instruction counter with 2^N clock ticks per\n \ instruction and enable aligning the host and virtual clocks\n, QEMU_ARCH_ALL) STEXI -@item -icount [shift=@var{N}|auto] +@item -icount [shift=@var{N}|auto][,rr=record|replay,rrfile=@var{filename}] @findex -icount Enable virtual instruction counter. The virtual cpu will execute one instruction every 2^@var{N} ns of virtual time. If @code{auto} is specified @@ -3064,6 +3064,10 @@ Currently this option does not work when @option{shift} is @code{auto}. Note: The sync algorithm will work for those shift values for which the guest clock runs ahead of the host clock. Typically this happens when the shift value is high (how high depends on the host machine). + +When @option{rr} option is specified deterministic record/replay is enabled. +Replay log is written into @var{filename} file in record mode and +read from this file in replay mode. ETEXI DEF(watchdog, HAS_ARG, QEMU_OPTION_watchdog, \ diff --git a/replay/replay.c b/replay/replay.c index a5ae58b..b8fdef5 100755 --- a/replay/replay.c +++ b/replay/replay.c @@ -292,6 +292,10 @@ void replay_start(void) error_get_pretty(replay_blockers-data)); exit(1); } +if (!use_icount) { +error_report(Please enable icount to use record/replay); +exit(1); +} /* Timer for snapshotting will be set up here. */ diff --git a/vl.c b/vl.c index f9c345d..89d6da6 100644 --- a/vl.c +++ b/vl.c @@ -472,6 +472,12 @@ static QemuOptsList qemu_icount_opts = { }, { .name = align, .type = QEMU_OPT_BOOL, +}, { +.name = rr, +.type = QEMU_OPT_STRING, +}, { +.name = rrfile, +.type = QEMU_OPT_STRING, }, { /* end of list */ } }, @@ -2751,6 +2757,7 @@ int main(int argc, char **argv, char **envp) { int i; int snapshot, linux_boot; +const char *icount_option = NULL; const char *initrd_filename; const char *kernel_filename, *kernel_cmdline; const char *boot_order; @@ -3770,6 +3777,8 @@ int main(int argc, char **argv, char **envp) } } +replay_configure(icount_opts); + opts = qemu_get_machine_opts(); optarg = qemu_opt_get(opts, type); if (optarg) { @@ -4173,8 +4182,10 @@ int main(int argc, char **argv, char **envp) } /* open the virtual block devices */ -if (snapshot) -qemu_opts_foreach(qemu_find_opts(drive), drive_enable_snapshot, NULL, 0); +if (snapshot || replay_mode != REPLAY_MODE_NONE) { +qemu_opts_foreach(qemu_find_opts(drive), drive_enable_snapshot, + NULL, 0); +} if (qemu_opts_foreach(qemu_find_opts(drive), drive_init_func, machine_class-block_default_type, 1) != 0) { exit(1);
Re: [Qemu-devel] [Qemu-ppc] [PATCHv3 0/9] ppc: loadvm/savevm fixups for -M g3beige and -M mac99
On 27.02.15 14:09, Mark Cave-Ayland wrote: On 09/02/15 22:40, Mark Cave-Ayland wrote: This patchset fixes up various bugs in loadvm/savevm for -M g3beige and -M mac99 so that it is becomes possible to save and restore image snapshots. The focus of this patchset is on -M g3beige since this matches the majority of my test images, but there were some easy fixes to be made to -M mac99 at the same time. With this patchset applied both -M g3beige and -M mac99 images can be saved/restored whilst booted into OpenBIOS with no issues. I tested -M g3beige with a paused, disk-inactive Darwin 6 image and was able to resume successfully which was good enough for my needs. I noticed some hangs can still occur when trying to restore an image where the disk is active which makes me believe that there is still some extra macio/dbdma state which needs to be included if someone is interested enough to pursue this further. Most of the patches are straightforward except for patch 4 which came out of a discussion on-list between Alex and Paolo, and patch 5 which is a similar error except this time for the MSR register. Ping? Just saw the other openpic patches go through the list and was wondering if this patchset needed any further work? Sorry, LIFO for patch / mail queues probably just isn't the best way to handle them ;). Applied to ppc-next now, thanks a lot for your work! Alex
Re: [Qemu-devel] [PATCH] hmp: info spice: Show string channel name
On 02/27/2015 02:35 AM, Gerd Hoffmann wrote: On Do, 2015-02-26 at 13:48 -0700, Eric Blake wrote: On 02/26/2015 12:02 PM, Cole Robinson wrote: Useful for debugging. https://bugzilla.redhat.com/show_bug.cgi?id=822418 Signed-off-by: Cole Robinson crobi...@redhat.com --- hmp.c | 13 + 1 file changed, 13 insertions(+) diff --git a/hmp.c b/hmp.c index 735097c..93fd5cd 100644 --- a/hmp.c +++ b/hmp.c @@ -545,6 +545,11 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict) { SpiceChannelList *chan; SpiceInfo *info; +const char *channel_name; +/* String representations of SPICE_CHANNEL_* enum */ +const char * const channel_names[] = {main, display, input, cursor, +playback, record, tunnel, smartcard, usbredir, port, +webdav}; Hmm. I wonder if we should have a QAPI enum for this, instead of open-coding it here. But as this is already a strict improvement, These numbers are defined by spice not qemu, so a qapi enum isn't going to fly here. Nevertheless it would be great to declare the array using c99 syntax ... [ SPICE_CHANNEL_foo ] = foo, ... to make clear how we are mapping spice enums (or #defines?) to strings here. cheers, Gerd Good idea, I'll send a v2 Thanks, Cole
[Qemu-devel] [RFC PATCH v10 10/24] replay: interrupts and exceptions
This patch includes modifications of common cpu files. All interrupts and exceptions occured during recording are written into the replay log. These events allow correct replaying the execution by kicking cpu thread when one of these events is found in the log. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- cpu-exec.c | 48 +++ replay/replay-internal.h |4 +++ replay/replay.c | 63 ++ replay/replay.h | 17 4 files changed, 121 insertions(+), 11 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 71e9814..ff3d140 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -24,6 +24,7 @@ #include qemu/atomic.h #include sysemu/qtest.h #include qemu/timer.h +#include replay/replay.h /* -icount align implementation. */ @@ -335,22 +336,25 @@ int cpu_exec(CPUArchState *env) /* This must be volatile so it is not trashed by longjmp() */ volatile bool have_tb_lock = false; +/* replay_interrupt may need current_cpu */ +current_cpu = cpu; + if (cpu-halted) { #ifdef TARGET_I386 -if (cpu-interrupt_request CPU_INTERRUPT_POLL) { +if ((cpu-interrupt_request CPU_INTERRUPT_POLL) + replay_interrupt()) { apic_poll_irq(x86_cpu-apic_state); cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL); } #endif if (!cpu_has_work(cpu)) { +current_cpu = NULL; return EXCP_HALTED; } cpu-halted = 0; } -current_cpu = cpu; - /* As long as current_cpu is null, up to the assignment just above, * requests by other threads to exit the execution loop are expected to * be issued using the exit_request global. We must make sure that our @@ -397,10 +401,21 @@ int cpu_exec(CPUArchState *env) cpu-exception_index = -1; break; #else -cc-do_interrupt(cpu); -cpu-exception_index = -1; +if (replay_exception()) { +cc-do_interrupt(cpu); +cpu-exception_index = -1; +} else if (!replay_has_interrupt()) { +/* give a chance to iothread in replay mode */ +ret = EXCP_INTERRUPT; +break; +} #endif } +} else if (replay_has_exception() +cpu-icount_decr.u16.low + cpu-icount_extra == 0) { +/* try to cause an exception pending in the log */ +cpu_exec_nocache(env, 1, tb_find_fast(env), true); +break; } next_tb = 0; /* force lookup of first TB */ @@ -416,30 +431,40 @@ int cpu_exec(CPUArchState *env) cpu-exception_index = EXCP_DEBUG; cpu_loop_exit(cpu); } -if (interrupt_request CPU_INTERRUPT_HALT) { +if (replay_mode == REPLAY_MODE_PLAY + !replay_has_interrupt()) { +/* Do nothing */ +} else if (interrupt_request CPU_INTERRUPT_HALT) { +replay_interrupt(); cpu-interrupt_request = ~CPU_INTERRUPT_HALT; cpu-halted = 1; cpu-exception_index = EXCP_HLT; cpu_loop_exit(cpu); } #if defined(TARGET_I386) -if (interrupt_request CPU_INTERRUPT_INIT) { +else if (interrupt_request CPU_INTERRUPT_INIT) { +replay_interrupt(); cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0); do_cpu_init(x86_cpu); cpu-exception_index = EXCP_HALTED; cpu_loop_exit(cpu); } #else -if (interrupt_request CPU_INTERRUPT_RESET) { +else if (interrupt_request CPU_INTERRUPT_RESET) { +replay_interrupt(); cpu_reset(cpu); +cpu_loop_exit(cpu); } #endif /* The target hook has 3 exit conditions: False when the interrupt isn't processed, True when it is, and we should restart on a new TB, and via longjmp via cpu_loop_exit. */ -if (cc-cpu_exec_interrupt(cpu, interrupt_request)) { -next_tb = 0; +else { +replay_interrupt(); +if (cc-cpu_exec_interrupt(cpu, interrupt_request)) { +next_tb = 0; +} } /* Don't use the
[Qemu-devel] [RFC PATCH v10 03/24] sysemu: system functions for replay
This patch removes static specifier from several qemu function to make them visible to the replay module. It also invents several system functions that will be used by replay. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- cpus.c |4 ++-- include/exec/exec-all.h |1 + include/qom/cpu.h | 10 ++ include/sysemu/cpus.h |1 + translate-all.c |8 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/cpus.c b/cpus.c index 0cdd1d7..04124ca 100644 --- a/cpus.c +++ b/cpus.c @@ -88,7 +88,7 @@ static bool cpu_thread_is_idle(CPUState *cpu) return true; } -static bool all_cpu_threads_idle(void) +bool all_cpu_threads_idle(void) { CPUState *cpu; @@ -1104,7 +1104,7 @@ bool qemu_cpu_is_self(CPUState *cpu) return qemu_thread_is_self(cpu-thread); } -static bool qemu_in_vcpu_thread(void) +bool qemu_in_vcpu_thread(void) { return current_cpu qemu_cpu_is_self(current_cpu); } diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 4a6237f..63fb1a3 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -214,6 +214,7 @@ static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc) void tb_free(TranslationBlock *tb); void tb_flush(CPUArchState *env); +void tb_flush_all(void); void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); #if defined(USE_DIRECT_JUMP) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 16dc2f7..b5e1170 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -480,6 +480,16 @@ static inline bool cpu_has_work(CPUState *cpu) bool qemu_cpu_is_self(CPUState *cpu); /** + * qemu_in_vcpu_thread: + * + * Checks whether the caller is executing on the vCPU thread + * of the current vCPU. + * + * Returns: %true if called from vCPU's thread, %false otherwise. + */ +bool qemu_in_vcpu_thread(void); + +/** * qemu_cpu_kick: * @cpu: The vCPU to kick. * diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 3f162a9..86ae556 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -6,6 +6,7 @@ void qemu_init_cpu_loop(void); void resume_all_vcpus(void); void pause_all_vcpus(void); void cpu_stop_current(void); +bool all_cpu_threads_idle(void); void cpu_synchronize_all_states(void); void cpu_synchronize_all_post_reset(void); diff --git a/translate-all.c b/translate-all.c index 9f47ce7..cf30303 100644 --- a/translate-all.c +++ b/translate-all.c @@ -812,6 +812,14 @@ void tb_flush(CPUArchState *env1) tcg_ctx.tb_ctx.tb_flush_count++; } +void tb_flush_all(void) +{ +CPUState *cpu; +for (cpu = first_cpu ; cpu != NULL ; cpu = CPU_NEXT(cpu)) { +tb_flush(cpu-env_ptr); +} +} + #ifdef DEBUG_TB_CHECK static void tb_invalidate_check(target_ulong address)
[Qemu-devel] [RFC PATCH v10 11/24] replay: asynchronous events infrastructure
This patch adds module for saving and replaying asynchronous events. These events include network packets, keyboard and mouse input, USB packets, thread pool and bottom halves callbacks. All events are stored in the queue to be processed at synchronization points such as beginning of TB execution, or checkpoint in the iothread. Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru --- replay/Makefile.objs |1 replay/replay-events.c | 227 ++ replay/replay-internal.h | 31 ++ replay/replay.h |6 + 4 files changed, 265 insertions(+), 0 deletions(-) create mode 100755 replay/replay-events.c diff --git a/replay/Makefile.objs b/replay/Makefile.objs index 1148f45..56da09c 100755 --- a/replay/Makefile.objs +++ b/replay/Makefile.objs @@ -1,2 +1,3 @@ obj-y += replay.o obj-y += replay-internal.o +obj-y += replay-events.o diff --git a/replay/replay-events.c b/replay/replay-events.c new file mode 100755 index 000..409c9ad --- /dev/null +++ b/replay/replay-events.c @@ -0,0 +1,227 @@ +/* + * replay-events.c + * + * Copyright (c) 2010-2015 Institute for System Programming + * of the Russian Academy of Sciences. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include qemu-common.h +#include qemu/error-report.h +#include replay.h +#include replay-internal.h + +typedef struct Event { +ReplayAsyncEventKind event_kind; +void *opaque; +void *opaque2; +uint64_t id; + +QTAILQ_ENTRY(Event) events; +} Event; + +static QTAILQ_HEAD(, Event) events_list = QTAILQ_HEAD_INITIALIZER(events_list); +static unsigned int read_event_kind = -1; +static uint64_t read_id = -1; +static int read_checkpoint = -1; + +static bool events_enabled = false; + +/* Functions */ + +static void replay_run_event(Event *event) +{ +switch (event-event_kind) { +default: +error_report(Replay: invalid async event ID (%d) in the queue, +event-event_kind); +exit(1); +break; +} +} + +void replay_enable_events(void) +{ +events_enabled = true; +} + +bool replay_has_events(void) +{ +return !QTAILQ_EMPTY(events_list); +} + +void replay_flush_events(void) +{ +replay_mutex_lock(); +while (!QTAILQ_EMPTY(events_list)) { +Event *event = QTAILQ_FIRST(events_list); +replay_mutex_unlock(); +replay_run_event(event); +replay_mutex_lock(); +QTAILQ_REMOVE(events_list, event, events); +g_free(event); +} +replay_mutex_unlock(); +} + +void replay_disable_events(void) +{ +if (replay_mode != REPLAY_MODE_NONE) { +events_enabled = false; +/* Flush events queue before waiting of completion */ +replay_flush_events(); +} +} + +void replay_clear_events(void) +{ +replay_mutex_lock(); +while (!QTAILQ_EMPTY(events_list)) { +Event *event = QTAILQ_FIRST(events_list); +QTAILQ_REMOVE(events_list, event, events); + +g_free(event); +} +replay_mutex_unlock(); +} + +static void replay_add_event_internal(ReplayAsyncEventKind event_kind, + void *opaque, + void *opaque2, uint64_t id) +{ +if (event_kind = REPLAY_ASYNC_COUNT) { +error_report(Replay: invalid async event ID (%d), event_kind); +exit(1); +} +if (!replay_file || replay_mode == REPLAY_MODE_NONE +|| !events_enabled) { +Event e; +e.event_kind = event_kind; +e.opaque = opaque; +e.opaque2 = opaque2; +e.id = id; +replay_run_event(e); +return; +} + +Event *event = g_malloc0(sizeof(Event)); +event-event_kind = event_kind; +event-opaque = opaque; +event-opaque2 = opaque2; +event-id = id; + +replay_mutex_lock(); +QTAILQ_INSERT_TAIL(events_list, event, events); +replay_mutex_unlock(); +} + +void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque) +{ +replay_add_event_internal(event_kind, opaque, NULL, 0); +} + +static void replay_save_event(Event *event, int checkpoint) +{ +if (replay_mode != REPLAY_MODE_PLAY) { +/* put the event into the file */ +replay_put_event(EVENT_ASYNC); +replay_put_byte(checkpoint); +replay_put_byte(event-event_kind); + +/* save event-specific data */ +switch (event-event_kind) { +} +} +} + +/* Called with replay mutex locked */ +void replay_save_events(int checkpoint) +{ +while (!QTAILQ_EMPTY(events_list)) { +Event *event = QTAILQ_FIRST(events_list); +replay_save_event(event, checkpoint); + +replay_mutex_unlock(); +replay_run_event(event); +replay_mutex_lock(); +QTAILQ_REMOVE(events_list, event, events); +g_free(event); +} +} + +static Event *replay_read_event(int
[Qemu-devel] [PATCH 1/2] virtio-s390: s390_virtio_device_init() can't fail, simplify
Signed-off-by: Markus Armbruster arm...@redhat.com --- hw/s390x/s390-virtio-bus.c | 29 +++-- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 39dc201..f69ff11 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -111,7 +111,8 @@ VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size) return bus; } -static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev) +static void s390_virtio_device_init(VirtIOS390Device *dev, +VirtIODevice *vdev) { VirtIOS390Bus *bus; int dev_len; @@ -135,8 +136,6 @@ static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev) if (dev-qdev.hotplugged) { s390_virtio_irq(VIRTIO_PARAM_DEV_ADD, dev-dev_offs); } - -return 0; } static int s390_virtio_net_init(VirtIOS390Device *s390_dev) @@ -153,7 +152,8 @@ static int s390_virtio_net_init(VirtIOS390Device *s390_dev) return -1; } -return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +return 0; } static void s390_virtio_net_instance_init(Object *obj) @@ -174,7 +174,8 @@ static int s390_virtio_blk_init(VirtIOS390Device *s390_dev) if (qdev_init(vdev) 0) { return -1; } -return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +return 0; } static void s390_virtio_blk_instance_init(Object *obj) @@ -215,12 +216,9 @@ static int s390_virtio_serial_init(VirtIOS390Device *s390_dev) return -1; } -r = s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); -if (!r) { -bus-console = s390_dev; -} - -return r; +s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +bus-console = s390_dev; +return 0; } static void s390_virtio_serial_instance_init(Object *obj) @@ -253,7 +251,8 @@ static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev) return -1; } -return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +return 0; } static void s390_virtio_scsi_instance_init(Object *obj) @@ -275,7 +274,8 @@ static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev) return -1; } -return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +return 0; } static void s390_vhost_scsi_instance_init(Object *obj) @@ -302,7 +302,8 @@ static int s390_virtio_rng_init(VirtIOS390Device *s390_dev) OBJECT(dev-vdev.conf.rng), rng, NULL); -return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev)); +return 0; } static void s390_virtio_rng_instance_init(Object *obj) -- 1.9.3
Re: [Qemu-devel] [PULL 05/11] target-i386: Eliminate cpu_init() function
Am 26.02.2015 um 17:03 schrieb Eduardo Habkost: On Wed, Feb 25, 2015 at 11:08:56PM +0100, Andreas Färber wrote: Am 25.02.2015 um 20:58 schrieb Eduardo Habkost: Instead of putting extra logic inside cpu.h, just do everything inside cpu_x86_init_user(). Reviewed-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Eduardo Habkost ehabk...@redhat.com --- target-i386/cpu.c | 6 +++--- target-i386/cpu.h | 12 +++- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 8f18556..aee4d3e 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2135,7 +2135,7 @@ out: return cpu; } -X86CPU *cpu_x86_init_user(const char *cpu_model) +CPUX86State *cpu_x86_init_user(const char *cpu_model) { Error *error = NULL; X86CPU *cpu; @@ -2153,10 +2153,10 @@ out: error_free(error); if (cpu != NULL) { object_unref(OBJECT(cpu)); -cpu = NULL; } +return NULL; } -return cpu; +return cpu-env; } static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 41d7f0a..d5bd74e 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -982,7 +982,6 @@ typedef struct CPUX86State { #include cpu-qom.h -X86CPU *cpu_x86_init_user(const char *cpu_model); X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge, Error **errp); int cpu_x86_exec(CPUX86State *s); @@ -1171,14 +1170,9 @@ uint64_t cpu_get_tsc(CPUX86State *env); # define PHYS_ADDR_MASK 0xfLL # endif -static inline CPUX86State *cpu_init(const char *cpu_model) -{ -X86CPU *cpu = cpu_x86_init_user(cpu_model); -if (cpu == NULL) { -return NULL; -} -return cpu-env; -} +/* CPU creation function for *-user */ +CPUX86State *cpu_x86_init_user(const char *cpu_model); +#define cpu_init cpu_x86_init_user The very purpose of this lightweight glue code in cpu.h was to let us use X86CPU in cpu.c. It seems that you are needlessly reverting my change? I am not sure I understand what you mean by let us use X86CPU in cpu.c. I mean, more and more code is supposed to use *CPU, not CPU*State. Like your patch moving the APIC ID is adopting X86CPU, which is the right direction. Replacing X86CPU with CPUX86State however feels wrong to me. Since I changed cpu_x86_init() to return X86CPU, there will have been a non-user caller at the time making use of X86CPU or CPUState. Just as in some ARM use cases I assume that the current cpu_*_init() limitations lead to its code getting inlined. Andreas -- SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu, Graham Norton; HRB 21284 (AG Nürnberg)
Re: [Qemu-devel] [PATCH] iscsi: Handle write protected case in reopen
On 25/02/2015 05:40, Fam Zheng wrote: Save the write protected flag and check before reopen. Signed-off-by: Fam Zheng f...@redhat.com --- block/iscsi.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 12ddbfb..00041bf 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -65,6 +65,7 @@ typedef struct IscsiLun { unsigned long *allocationmap; int cluster_sectors; bool use_16_for_rw; +bool write_proteced; Corrected to write_protecTed and applied. Paolo } IscsiLun; typedef struct IscsiTask { @@ -1268,10 +1269,6 @@ out: /* * We support iscsi url's on the form * iscsi://[username%password@]host[:port]/targetname/lun - * - * Note: flags are currently not used by iscsi_open. If this function - * is changed such that flags are used, please examine iscsi_reopen_prepare() - * to see if needs to be changed as well. */ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) @@ -1385,9 +1382,10 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, scsi_free_scsi_task(task); task = NULL; +iscsilun-write_proteced = iscsi_is_write_protected(iscsilun); /* Check the write protect flag of the LUN if we want to write */ if (iscsilun-type == TYPE_DISK (flags BDRV_O_RDWR) -iscsi_is_write_protected(iscsilun)) { +iscsilun-write_proteced) { error_setg(errp, Cannot open a write protected LUN as read-write); ret = -EACCES; goto out; @@ -1541,13 +1539,17 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp) sector_limits_lun2qemu(iscsilun-bl.opt_xfer_len, iscsilun); } -/* Since iscsi_open() ignores bdrv_flags, there is nothing to do here in - * prepare. Note that this will not re-establish a connection with an iSCSI - * target - it is effectively a NOP. */ +/* Note that this will not re-establish a connection with an iSCSI target - it + * is effectively a NOP. */ static int iscsi_reopen_prepare(BDRVReopenState *state, BlockReopenQueue *queue, Error **errp) { -/* NOP */ +IscsiLun *iscsilun = state-bs-opaque; + +if (state-flags BDRV_O_RDWR iscsilun-write_proteced) { +error_setg(errp, Cannot open a write protected LUN as read-write); +return -EACCES; +} return 0; }
Re: [Qemu-devel] [PATCH] sheepdog: Fix misleading error messages in sd_snapshot_create()
Markus Armbruster arm...@redhat.com writes: If do_sd_create() fails, it first reports the error returned, then reports a another one with strerror(errno). errno is meaningless at that point. Report just one error combining the valid information from both messages. Reported-by: Eric Blake ebl...@redhat.com Signed-off-by: Markus Armbruster arm...@redhat.com --- Applies on top of my [PATCH v2 00/10] Clean up around error_get_pretty(), qerror_report_err(), but rebasing to master would be trivial. Applies cleanly on master now. Maintainers, please apply.