Re: [Qemu-devel] [Qemu-trivial] [PATCH] qapi: Fix comment for create-type to match code.
Thanks, applied to the trivial-patches queue. /mjt
Re: [Qemu-devel] [Qemu-trivial] [PATCH v2] pci-assign: Fix error_report of pci-stub message
On 10/11/2013 11:52 AM, Cole Robinson wrote: Using multiple calls to error_report here means every line is prefaced with the (potentially long) pci-assign command line arguments. Use a single error_printf to preserve the intended formatting. Since this code path is always preceded by an error_report call, we don't lose the command line reporting. Thanks, applied to the trivial-patches queue. /mjt
[Qemu-devel] C99 loop vars? [was: gtk: Fix compiler warnings with -Werror=sign-compare]
05.11.2013 00:38, Laszlo Ersek wrote: On 11/04/13 21:07, Peter Maydell wrote: On 4 November 2013 19:51, Stefan Weil s...@weilnetz.de wrote: With -Werror=sign-compare (not enabled by default), gcc shows these errors: ui/gtk.c: In function ‘gtk_release_modifiers’: ui/gtk.c:288:19: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] ui/gtk.c: In function ‘gd_key_event’: ui/gtk.c:746:19: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] If this warning is going to complain about entirely safe and idiomatic code like int i; static const int some_array[] = { 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8, 0xdb, 0xdd, }; for (i = 0; i ARRAY_SIZE(some_array); i++) { ... } (Entirely safe, and completely non-idiomatic: i should be size_t, as that is the type of the sizeof operator's result.) Maybe in some places we should switch to C99 which allows to declare a loop variable inside the loop header, like this: for(int i = 0; i ARRAY_SIZE(..); i++) { } ? This is much better than a per-unit (function-level) declaration because by changing type in one place we don't change it for other places which might become wrong in the result... But this requires compiling whole thing with gcc -std=c99, which might bit problematic. But as it is, the original patch from Stefan, -- I don't think it's a good idea to apply it. The code is obviously correct, ARRAY_SIZE is a fixed value, the compiler is able to determine this and shut pretty much up ;) Thanks, /mjt
[Qemu-devel] [PATCH] virtio-net: only delete bh that existed
We delete without check whether it existed during exit. This will lead NULL pointer deference since it was created conditionally depends on guest driver status and features. So add a check of existence before trying to delete it. Cc: qemu-sta...@nongnu.org Signed-off-by: Jason Wang jasow...@redhat.com --- hw/net/virtio-net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 22dbd05..ae51d96 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1601,7 +1601,7 @@ static int virtio_net_device_exit(DeviceState *qdev) if (q-tx_timer) { timer_del(q-tx_timer); timer_free(q-tx_timer); -} else { +} else if (q-tx_bh) { qemu_bh_delete(q-tx_bh); } } -- 1.8.3.2
Re: [Qemu-devel] [PATCH] migration: avoid starting a new migration task while the previous one still exist
Il 06/11/2013 02:50, Zhanghaoyu (A) ha scritto: Avoid starting a new migration task while the previous one still exist. Can you explain how to reproduce the problem? When network disconnection between source and destination happened, the migration thread stuck at below stack, Then I cancel the migration task, the migration state in qemu will be set to MIG_STATE_CANCELLED, so the migration job in libvirt quits. Then I perform migration again, at this time, the network reconnected successfully, since the TCP timeout retransmission, above stack will not return immediately, so two migration tasks exist at the same time. And still worse, source qemu will crash, because of accessing the NULL pointer in qemu_bh_schedule(s-cleanup_bh); statement in latter migration task, since the s-cleanup_bh had been deleted by previous migration task. Thanks for explaining. CANCELLING looks like a useful addition. Why do you need both CANCELLING and COMPLETING? The COMPLETED state should be set only after all I/O is done. There is a period of time from the timing of setting COMPLETED state to that of migration task exits, so it's problematic in COMPLETED-CANCELLED transition, but if applying your below proposal, the problem gone. do { old_state = s-state; if (old_state != MIG_STATE_SETUP old_state != MIG_STATE_ACTIVE) { break; } migrate_set_state(s, old_state, MIG_STATE_CANCELLED); } while (s-state != MIG_STATE_CANCELLED); Ok. I agree with Eric that the CANCELLING state should not be exposed via QMP. info migrate and query-migrate can keep showing active for maximum backwards compatibility. More comments below. -if (s-state != MIG_STATE_COMPLETED) { +if (s-state != MIG_STATE_COMPLETING) { qemu_savevm_state_cancel(); +if (s-state == MIG_STATE_CANCELLING) { +migrate_set_state(s, MIG_STATE_CANCELLING, MIG_STATE_CANCELLED); +} I think you can remove the if and unconditionally call migrate_set_state. Do you mean to remove the if (s-state == MIG_STATE_CANCELLING) ? The s-state probably is MIG_STATE_ERROR here, is it okay to unconditionally call migrate_set_state? migrate_set_state has atomic_cmpxchg so it has an implicit if, but you're right it's clearer this way. Paolo Thanks, Zhang Haoyu +}else { +migrate_set_state(s, MIG_STATE_COMPLETING, + MIG_STATE_COMPLETED); } notifier_list_notify(migration_state_notifiers, s); } -static void migrate_set_state(MigrationState *s, int old_state, int new_state) -{ -if (atomic_cmpxchg(s-state, old_state, new_state) == new_state) { -trace_migrate_set_state(new_state); -} -} - void migrate_fd_error(MigrationState *s) { DPRINTF(setting error state\n); @@ -328,7 +337,7 @@ static void migrate_fd_cancel(MigrationState *s) { DPRINTF(cancelling migration\n); -migrate_set_state(s, s-state, MIG_STATE_CANCELLED); +migrate_set_state(s, s-state, MIG_STATE_CANCELLING); Here probably we want something like do { old_state = s-state; if (old_state != MIG_STATE_SETUP old_state != MIG_STATE_ACTIVE) { break; } migrate_set_state(s, old_state, MIG_STATE_CANCELLING); } while (s-state != MIG_STATE_CANCELLING); to avoid a bogus COMPLETED-CANCELLED transition. Please separate the patch in two parts: (1) the first uses the above code, with CANCELLED instead of CANCELLING (2) the second, similar to the one you have posted, introduces the new CANCELLING state Thanks, Paolo
Re: [Qemu-devel] [PATCH v4] net: Adding netmap network backend
On Tue, Nov 05, 2013 at 04:17:23PM +0100, Vincenzo Maffione wrote: +err = ioctl(fd, NIOCREGIF, req); +if (err) { +error_report(Unable to register %s: %s, me-ifname, strerror(err)); Did you mean strerror(errno)? +me-mem = mmap(0, l, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); +if (me-mem == MAP_FAILED) { +error_report(Unable to mmap netmap shared memory: %s, strerror(err)); Same here.
Re: [Qemu-devel] [PATCH] ossaudio: do not enable by default
On Di, 2013-11-05 at 20:34 +, Peter Maydell wrote: On 5 November 2013 19:57, Anthony Liguori anth...@codemonkey.ws wrote: This patch just requires that you explicitly select oss so it's not breaking audio on BSD. That sounds to me like it's breaking audio for all the users for whom it previously worked out of the box without any particular configure or command line options. In fact I suspect it also breaks audio for all the *linux* users for whom it previously worked without special options. Yes, it does. Sound is broken by default now. Only oss is compiled by default, but it isn't used any more unless you explicitly request that. My suggestion has it problems too, when adding alsa that way without having alsa-devel package installed the build breaks. I think the audio backend handling needs a serious makeover. Detect sound libraries (pulse, esd, alsa, ...) via configure like any other library. Zap the whole can_be_default logic. Replace it by walking the list of backends, sorted by priority, take the first which initializes successfully. That is clearly 1.8 material though. I think for 1.7 we should simply leave things as-is. I have a custom --audio-drv-list in my build scripts for ages, and I suspect all distros and anyone who compiles itself and cares about audio has. cheers, Gerd
Re: [Qemu-devel] [PATCH] qga: Fix shutdown command of guest agent to work with SysV
06.11.2013 05:54, whitearchey wrote: For now guest agent uses following command to shutdown system: shutdown -P +0 blabla but this syntax works only with shutdown command from systemd or upstart, because SysV shutdown requires -h switch. Following patch changes the command so it works with systemd, upstart and SysV While the patch is one-liner indeed, it is a bit more than trivial. Because it changes things in a non-obvious way, especially when multiple systems are concerned. Cc'ing qemu-devel@ due to this. --- a/qga/commands-posix.c +++ b/qga/commands-posix.c -execle(/sbin/shutdown, shutdown, shutdown_flag, +0, +execle(/sbin/shutdown, shutdown, -h, shutdown_flag, +0, Note that shutdown command is not in POSIX, despite the fact that this is put into commands-posix.c Note also that even shutdown from sysvinit on linux has another option, -P, which mean poweroff, while -h means halt OR poweroff (the latter is a bit unclear). Does the same work on other *nixes? *BSD? Solaris? Thanks, /mjt
Re: [Qemu-devel] [PATCH v5 2/2] sheepdog: support user-defined redundancy option
On Tue, Nov 05, 2013 at 08:46:07AM -0700, Eric Blake wrote: On 11/05/2013 07:37 AM, Stefan Hajnoczi wrote: + +copy = strtol(n1, NULL, 10); +if (copy SD_MAX_COPIES) { +return -EINVAL; +} The string manipulation can be simplified using sscanf(3) and is_numeric() can be dropped: static int parse_redundancy(BDRVSheepdogState *s, const char *opt) { struct SheepdogInode *inode = s-inode; uint8_t copy, parity; int n; n = sscanf(opt, %hhu:%hhu, copy, parity); Personally, I detest the use of sscanf() to parse integers out of strings, because POSIX says that behavior is undefined if overflow occurs. For internal strings, you can get away with it. But for untrusted input that did not originate in your process, a user can mess you up by passing a string that parses larger than the integer you are trying to store into, where the behavior is unspecified whether it wraps around module 256, parses additional digits, or any other odd behavior. By the time you've added code to sanitize untrusted input, it's just as fast to use strtol() anyways. Hmm...I didn't know that overflow was undefined behavior in POSIX :(. In that case forget sscanf(3) can look at the strtol(3) result for errors. There's still no need for a custom is_numeric() function. Stefan
Re: [Qemu-devel] [PATCH 1.7] virtio-net: only delete bh that existed
Il 06/11/2013 09:58, Jason Wang ha scritto: We delete without check whether it existed during exit. This will lead NULL pointer deference since it was created conditionally depends on guest driver status and features. So add a check of existence before trying to delete it. Cc: qemu-sta...@nongnu.org Signed-off-by: Jason Wang jasow...@redhat.com --- hw/net/virtio-net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 22dbd05..ae51d96 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1601,7 +1601,7 @@ static int virtio_net_device_exit(DeviceState *qdev) if (q-tx_timer) { timer_del(q-tx_timer); timer_free(q-tx_timer); -} else { +} else if (q-tx_bh) { qemu_bh_delete(q-tx_bh); } } Please remember to add 1.7 in the subject at this time. Paolo
Re: [Qemu-devel] [PATCH 1.7] mips jazz: do not raise data bus exception when accessing invalid addresses
Il 04/11/2013 23:26, Hervé Poussineau ha scritto: MIPS Jazz chipset doesn't seem to raise data bus exceptions on invalid accesses. However, there is no easy way to prevent them. Creating a big memory region for the whole address space doesn't prevent memory core to directly call unassigned_mem_read/write which in turn call cpu-do_unassigned_access, which (for MIPS CPU) raise an data bus exception. Creating a big MMIO region would work, but it wouldn't let you trap execution accesses. This fixes a MIPS Jazz regression introduced in c658b94f6e8c206c59d02aa6fbac285b86b53d2c. Signed-off-by: Hervé Poussineau hpous...@reactos.org --- This fixes a known regression in QEMU 1.6. Let it be fixed as soon as possible. hw/mips/mips_jazz.c | 24 1 file changed, 24 insertions(+) diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 49bdd02..5f6dd9f 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -108,6 +108,18 @@ static void cpu_request_exit(void *opaque, int irq, int level) } } +static CPUUnassignedAccess real_do_unassigned_access; +static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr, + bool is_write, bool is_exec, + int opaque, unsigned size) +{ +if (!is_exec) { +/* ignore invalid access (ie do not raise exception) */ +return; +} +(*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size); +} + static void mips_jazz_init(MemoryRegion *address_space, MemoryRegion *address_space_io, ram_addr_t ram_size, @@ -117,6 +129,7 @@ static void mips_jazz_init(MemoryRegion *address_space, char *filename; int bios_size, n; MIPSCPU *cpu; +CPUClass *cc; CPUMIPSState *env; qemu_irq *rc4030, *i8259; rc4030_dma *dmas; @@ -154,6 +167,17 @@ static void mips_jazz_init(MemoryRegion *address_space, env = cpu-env; qemu_register_reset(main_cpu_reset, cpu); +/* Chipset returns 0 in invalid reads and do not raise data exceptions. + * However, we can't simply add a global memory region to catch + * everything, as memory core directly call unassigned_mem_read/write + * on some invalid accesses, which call do_unassigned_access on the + * CPU, which raise an exception. + * Handle that case by hijacking the do_unassigned_access method on + * the CPU, and do not raise exceptions for data access. */ +cc = CPU_GET_CLASS(cpu); +real_do_unassigned_access = cc-do_unassigned_access; +cc-do_unassigned_access = mips_jazz_do_unassigned_access; + /* allocate RAM */ memory_region_init_ram(ram, NULL, mips_jazz.ram, ram_size); vmstate_register_ram_global(ram); Reviewed-by: Paolo Bonzini pbonz...@redhat.com Please remember to add 1.7 in the subject at this time. Paolo
Re: [Qemu-devel] [PATCH v5] net: Adding netmap network backend
On Tue, Nov 05, 2013 at 05:42:06PM +0100, Vincenzo Maffione wrote: This patch adds support for a network backend based on netmap. netmap is a framework for high speed packet I/O. You can use it to build extremely fast traffic generators, monitors, software switches or network middleboxes. Its companion software switch VALE lets you interconnect virtual machines. netmap and VALE are implemented as a non-intrusive kernel module, support NICs from multiple vendors, are part of standard FreeBSD distributions and available in source format for Linux too. To compile QEMU with netmap support, use the following configure options: ./configure [...] --enable-netmap --extra-cflags=-I/path/to/netmap/sys where /path/to/netmap contains the netmap source code, available at http://info.iet.unipi.it/~luigi/netmap/ The same webpage contains more information about the netmap project (together with papers and presentations). Signed-off-by: Vincenzo Maffione v.maffi...@gmail.com --- In the future, please include a changelog after the --- line so reviewers know what to look for. I commented on v4, the strerror(error) code looks wrong, it should probably use the errno variable instead. Stefan
[Qemu-devel] TARGET_AARCH64
Hi All, Browsing the qemu 'latest' src, I see some #define TARGET_AARCH64, does it mean we can boot a qemu-system-arm64 ? Is there some experiment? Cheers, Phi
Re: [Qemu-devel] [PATCH v3 0/7] qdev and blockdev refcount leak fixes
On Wed, Oct 30, 2013 at 02:54:29PM +0100, Stefan Hajnoczi wrote: v3: * I lost track of this patch, now I'm pushing it again * Rebase onto qemu.git/master * Add Patch 7 to do s/qdev_free()/object_unparent()/ [afaerber] It started with a bug report along these lines: (qemu) device_add virtio-blk-pci,drive=drive0,x-data-plane=on device is incompatible with x-data-plane, use scsi=off Device initialization failed. Device initialization failed. Device 'virtio-blk-pci' could not be initialized (qemu) drive_del drive0 (qemu) drive_add 0 if=none,id=drive0 Duplicate ID 'drive0' for drive The drive_add command should succeed since the old drive0 was deleted. With the help of Andreas and Paolo we figured out that the problem is not virtio-blk or dataplane. There are actually two problems: 1. qdev_device_add() must release its DeviceState reference if qdev_init() failed. 2. blockdev_init() must release its QemuOpts on failure or early return when no file= option was specified. This series fixes these problems and then qtest test cases for both bugs. In order to do this we need to add QMP response objects to the libqtest API, which currently discards QMP responses. Patches 1 2 fix the leaks. Patches 2 3 add QMP response objects to libqtest. Patches 5 6 add qtest test cases for the bugs. Patch 7 replaces the confusing qdev_free() function with object_unparent() Stefan Hajnoczi (7): blockdev: fix drive_init() opts and bs_opts leaks qdev: unref qdev when device_add fails libqtest: rename qmp() to qmp_discard_response() libqtest: add qmp(fmt, ...) - QDict* function blockdev-test: add test case for drive_add duplicate IDs qdev-monitor-test: add device_add leak test cases qdev: drop misleading qdev_free() function blockdev.c| 27 +--- hw/acpi/piix4.c | 2 +- hw/core/qdev.c| 12 ++- hw/pci/pci-hotplug-old.c | 2 +- hw/pci/pci_bridge.c | 2 +- hw/pci/pcie.c | 2 +- hw/pci/shpc.c | 2 +- hw/s390x/virtio-ccw.c | 2 +- hw/scsi/scsi-bus.c| 6 ++-- hw/usb/bus.c | 7 ++-- hw/usb/dev-storage.c | 2 +- hw/usb/host-legacy.c | 2 +- hw/virtio/virtio-bus.c| 4 +-- hw/xen/xen_platform.c | 2 +- include/hw/qdev-core.h| 1 - qdev-monitor.c| 6 ++-- tests/Makefile| 4 +++ tests/blockdev-test.c | 59 ++ tests/boot-order-test.c | 4 +-- tests/fdc-test.c | 15 + tests/ide-test.c | 10 +++--- tests/libqtest.c | 72 +++-- tests/libqtest.h | 51 + tests/qdev-monitor-test.c | 81 +++ 24 files changed, 299 insertions(+), 78 deletions(-) create mode 100644 tests/blockdev-test.c create mode 100644 tests/qdev-monitor-test.c -- 1.8.3.1 Applied the remaining patches to my block tree: https://github.com/stefanha/qemu/commits/block Stefan
Re: [Qemu-devel] [PATCH] block: Save errno before error_setg_errno
On Tue, Nov 05, 2013 at 08:03:33PM +0100, Max Reitz wrote: error_setg_errno() may overwrite errno; therefore, its value should be read before calling that function and not afterwards. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan
Re: [Qemu-devel] [PATCH] block: Save errno before error_setg_errno
On Tue, Nov 05, 2013 at 12:26:41PM -0700, Eric Blake wrote: On 11/05/2013 12:03 PM, Max Reitz wrote: error_setg_errno() may overwrite errno; therefore, its value should be read before calling that function and not afterwards. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Reviewed-by: Eric Blake ebl...@redhat.com Still, wouldn't it be easier to patch error_setg_errno (and friends) to guarantee that errno is unchanged on exit compared to its value on entrance, rather than having to audit for other mistakes like this? Agreed, that can be done as a separate patch. Stefan
Re: [Qemu-devel] USB Passthrough not working for Windows 7 guest
-Original Message- From: qemu-devel-bounces+jens.frederich=vector@nongnu.org [mailto:qemu-devel-bounces+jens.frederich=vector@nongnu.org] On Behalf Of Jan Kiszka Sent: Wednesday, November 06, 2013 7:58 AM To: Jens Frederich; qemu-devel@nongnu.org Subject: Re: [Qemu-devel] USB Passthrough not working for Windows 7 guest On 2013-11-05 21:20, Jens Frederich wrote: On 2013-11-05 17:01, Frederich, Jens wrote: Hi all, we're currently evaluating different RTOS systems (Windows CE, Intime, RTX, etc.). One system is Linux RT + KVM/QEMU with a Windows 7 guest. Up to now all works fine, Linux RT has good latency and KVM/Qemu setup was easy. But one QEMU bug breaks my measurement setup and evaluation. I've some usb devices for the Windows 7 guest. I configure them as USB passthrough. The devices appears in the device manager of Windows 7, but with Error code 10: device cannot start. The Windows driver fails on USB set configuration. The driver creates a IRP and send it via IOCTRL to lower layer. The IOCTRL fails with invalid parameter. driver log: 0009 0.65470564 vnCDrvUsbControlRequestSetConfiguration, WdfUsbTargetDeviceSelectConfig single interface failed 0xc00d 0010 0.65472370 vnCDrvUsbIFPrepareHardwareState, vnCDrvUsbControlRequestSetConfiguration failed: 0xc00d 0011 0.65473646 vnCDrvDevConPrepareHardware, vnCDrvUsbIFPrepareHardwareState failed 0xc00d 0012 0.65474838 vnCDrvEvtDevicePrepareHardware, vnCDrvDevConPrepareHardware failed 0xc001 0013 0.6547 This bug breaks my latency measurement setup and Linux RT is out of the evaluationg race. Windows CE should not win :-), it there anyway workaround or hack to fix the issue? Workaround: Pass-through one of the (typically) many USB host controllers to the Windows guest (vfio or classic pci-assign). I did this back then when *HCI emulation was still pretty immature. But USB device pass-through should also work. Do you happen to pass a USB 2.0 device via an emulated UHCI? Or are you already using the EHCI emulation? I'm not sure which mode it has been. I've used the virt-manager to configure the device. A usb controller is already configured in mode 'default'. My steps on virt-manager: 1. add hardware 2. select usb host device 3. I can see my usb device, I select it 4. start guest and open Windows device manager Unfortunately, I do not know what virt-manager is configuring by default. It likely also depends on its version, so you should share this information as well. Maybe other folks here can comment on this. I don't know is this UHCI or EHCI? On the usb host device list are some controller listed e.q. xhci, ehci and so on. Should I map these controller to Windows 7 as well? Pick the host controller to which the USB device you want to give to the guest is attached to (lsusb and the bus number reported via /sys/bus/pci/devices/id/usbX can tell this - or trial and error). When doing this, you no longer need to pass through the USB device itself, it is implicitely passed. Okay, that sounds good. That's my lsusb output: Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 002 Device 005: ID 1248:1030 The last line is my usb device. I've used 'virsh edit' to map all controllers for Windows 7. I want to be on the safe side ;-). The libvirt xml fragment: hostdev mode='subsystem' type='usb' managed='yes' source address bus='1' device='2'/ /source /hostdev hostdev mode='subsystem' type='usb' managed='yes' source address bus='2' device='2'/ /source /hostdev hostdev mode='subsystem' type='usb' managed='yes' source address bus='1' device='1'/ /source /hostdev hostdev mode='subsystem' type='usb' managed='yes' source address bus='2' device='1'/ /source /hostdev hostdev mode='subsystem' type='usb' managed='yes' source address bus='3' device='1'/ /source /hostdev hostdev mode='subsystem' type='usb' managed='yes' source address bus='4' device='1'/ /source /hostdev On Win 7 I can see a new NEC USB Hub. I don't know why Win. 7 it initialized as USB Hub. But my device isn't there. I've plugged it to other USB ports, but nothing happend. I used prebuild Ubuntu 13.04 qemu 1.4.0. I think my next step is to build my on 1.6.x qemu from git with --enable-libusb and --enable-trace-backend=simpe. thanks Jens
[Qemu-devel] [PATCH v2 1.7] pc: get rid of builtin pvpanic for -M pc-1.5
This causes two slight backwards-incompatibilities between -M pc-1.5 and 1.5's -M pc: (1) a fw_cfg file is removed with this patch. This is only a problem if migration stops the virtual machine exactly during fw_cfg enumeration. (2) after migration, a VM created without an explicit -device pvpanic will stop reporting panics to management. The first problem only occurs if migration is done at a very, very early point (and I'm not sure it can happen in practice for reasonable-size VMs, since it will likely take more time to send the RAM to destination, than it will take for BIOS to scan fw_cfg). The second problem only occurs if the guest panics _and_ has a guest driver _and_ management knows to look at the crash event, so it is mostly theoretical at this point in time. Thus keep the code simple, and pretend it was never broken. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/i386/pc_piix.c| 7 --- hw/i386/pc_q35.c | 7 --- hw/misc/pvpanic.c| 5 - include/hw/i386/pc.h | 1 - 4 files changed, 20 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 4fdb7b6..b3d94bd 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -57,7 +57,6 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; -static bool has_pvpanic; static bool has_pci_info = true; static bool has_acpi_build = true; @@ -229,10 +228,6 @@ static void pc_init1(QEMUMachineInitArgs *args, if (pci_enabled) { pc_pci_device_init(pci_bus); } - -if (has_pvpanic) { -pvpanic_init(isa_bus); -} } static void pc_init_pci(QEMUMachineInitArgs *args) @@ -250,13 +245,11 @@ static void pc_compat_1_6(QEMUMachineInitArgs *args) static void pc_compat_1_5(QEMUMachineInitArgs *args) { pc_compat_1_6(args); -has_pvpanic = true; } static void pc_compat_1_4(QEMUMachineInitArgs *args) { pc_compat_1_5(args); -has_pvpanic = false; x86_cpu_compat_set_features(n270, FEAT_1_ECX, 0, CPUID_EXT_MOVBE); x86_cpu_compat_set_features(Westmere, FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ); } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 4c191d3..2e315f7 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -47,7 +47,6 @@ /* ICH9 AHCI has 6 ports */ #define MAX_SATA_PORTS 6 -static bool has_pvpanic; static bool has_pci_info = true; static bool has_acpi_build = true; @@ -216,10 +215,6 @@ static void pc_q35_init(QEMUMachineInitArgs *args) if (pci_enabled) { pc_pci_device_init(host_bus); } - -if (has_pvpanic) { -pvpanic_init(isa_bus); -} } static void pc_compat_1_6(QEMUMachineInitArgs *args) @@ -232,13 +227,11 @@ static void pc_compat_1_6(QEMUMachineInitArgs *args) static void pc_compat_1_5(QEMUMachineInitArgs *args) { pc_compat_1_6(args); -has_pvpanic = true; } static void pc_compat_1_4(QEMUMachineInitArgs *args) { pc_compat_1_5(args); -has_pvpanic = false; x86_cpu_compat_set_features(n270, FEAT_1_ECX, 0, CPUID_EXT_MOVBE); x86_cpu_compat_set_features(Westmere, FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ); } diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c index 226e298..5377fee 100644 --- a/hw/misc/pvpanic.c +++ b/hw/misc/pvpanic.c @@ -112,11 +112,6 @@ static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp) isa_register_ioport(d, s-io, s-ioport); } -void pvpanic_init(ISABus *bus) -{ -isa_create_simple(bus, TYPE_ISA_PVPANIC_DEVICE); -} - #define PVPANIC_IOPORT_PROP ioport uint16_t pvpanic_port(void) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 03cc0ba..1f39b27 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -235,7 +235,6 @@ void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw); /* pvpanic.c */ -void pvpanic_init(ISABus *bus); uint16_t pvpanic_port(void); /* e820 types */ -- 1.8.4.2
[Qemu-devel] [PATCH v6] .travis.yml: basic compile and check recipes
From: Alex Bennée a...@bennee.com This adds a build matrix definition for travis-ci.org continuous integration service. It is usable on any public repository hosted on GitHub. Once you have created an account signed into Travis you can enable it on selected projects via travis-ci.org/profile. Alternatively you can configure the service hooks on GitHub via the repository Settings tab,then Service Hooks and selecting Travis. Once setup Travis will automatically test every push as well as any pull requests submitted to that repository. The build matrix is currently split by target architecture (see TARGETS environment variable) because a full build of QEMU can take some time. This way you get quick feedback for any obvious errors. The additional environment variables exist to allow additional builds to tweak the environment. These are: EXTRA_CONFIG - extra terms passed to configure EXTRA_PKGS - extra dev packages to install TEST_CMD - default make check, can be overridden I've confined the additional stuff to x86/x86_64 for convenience. As Travis supports clang the main builds are done twice (once for gcc and once for clang). However clang is disabled for the debug/trace builds for the purposes of brevity. Other wrinkles: * The lttng user-space tracing back-end is disabled (it is currently horribly broken) * The ftrace back-end doesn't run make check (it requires a mounted debugfs to work) * There are two debug enabled build (with and without TCG interpreter) Signed-off-by: Alex Bennée a...@bennee.com Reviewed-by: Stefan Hajnoczi stefa...@redhat.com --- .travis.yml | 71 + 1 file changed, 71 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000..6e60d84 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,71 @@ +language: c +python: + - 2.4 +compiler: + - gcc + - clang +env: + global: +- TEST_CMD=make check +- EXTRA_CONFIG= +# Development packages, EXTRA_PKGS saved for additional builds +- CORE_PKGS=libusb-1.0-0-dev libiscsi-dev librados-dev libncurses5-dev +- NET_PKGS=libseccomp-dev libgnutls-dev libssh2-1-dev libspice-server-dev libspice-protocol-dev libnss3-dev +- GUI_PKGS=libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev +- EXTRA_PKGS= + matrix: + - TARGETS=alpha-softmmu,alpha-linux-user + - TARGETS=arm-softmmu,arm-linux-user + - TARGETS=cris-softmmu + - TARGETS=i386-softmmu,x86_64-softmmu + - TARGETS=lm32-softmmu + - TARGETS=m68k-softmmu + - TARGETS=microblaze-softmmu,microblazeel-softmmu + - TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu + - TARGETS=moxie-softmmu + - TARGETS=or32-softmmu, + - TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu + - TARGETS=s390x-softmmu + - TARGETS=sh4-softmmu,sh4eb-softmmu + - TARGETS=sparc-softmmu,sparc64-softmmu + - TARGETS=unicore32-softmmu + - TARGETS=xtensa-softmmu,xtensaeb-softmmu +before_install: + - git submodule update --init --recursive + - sudo apt-get update -qq + - sudo apt-get install -qq ${CORE_PKGS} ${NET_PKGS} ${GUI_PKGS} ${EXTRA_PKGS} +script: ./configure --target-list=${TARGETS} ${EXTRA_CONFIG} make ${TEST_CMD} +matrix: + # We manually include a number of additional build for non-standard bits + include: +# Debug related options +- env: TARGETS=i386-softmmu,x86_64-softmmu + EXTRA_CONFIG=--enable-debug + compiler: gcc +- env: TARGETS=i386-softmmu,x86_64-softmmu + EXTRA_CONFIG=--enable-debug --enable-tcg-interpreter + compiler: gcc +# Currently configure doesn't force --disable-pie +- env: TARGETS=i386-softmmu,x86_64-softmmu + EXTRA_CONFIG=--enable-gprof --enable-gcov --disable-pie + compiler: gcc +- env: TARGETS=i386-softmmu,x86_64-softmmu + EXTRA_PKGS=sparse + EXTRA_CONFIG=--enable-sparse + compiler: gcc +# All the trace backends (apart from dtrace) +- env: TARGETS=i386-softmmu,x86_64-softmmu + EXTRA_CONFIG=--enable-trace-backend=stderr + compiler: gcc +- env: TARGETS=i386-softmmu,x86_64-softmmu + EXTRA_CONFIG=--enable-trace-backend=simple + compiler: gcc +- env: TARGETS=i386-softmmu,x86_64-softmmu + EXTRA_CONFIG=--enable-trace-backend=ftrace + TEST_CMD= + compiler: gcc +# This disabled make check for the ftrace backend which needs more setting up +# Currently broken on 12.04 due to mis-packaged liburcu and changed API, will be pulled. +#- env: TARGETS=i386-softmmu,x86_64-softmmu +# EXTRA_PKGS=liblttng-ust-dev liburcu-dev +# EXTRA_CONFIG=--enable-trace-backend=ust -- 1.8.4.2
[Qemu-devel] [PATCH v6] Add .travis.yml metadata for CI
From: Alex Bennée a...@bennee.com Hi, I think this patch is ready to be merged via trivial. While I was testing it last night it caught yet another regression (register_subpage: Assertion, since fixed) so I think it proves it's worth with that alone. Since v5 - Forced the python to 2.4 (our current baseline python) Alex Bennée (1): .travis.yml: basic compile and check recipes .travis.yml | 71 + 1 file changed, 71 insertions(+) create mode 100644 .travis.yml -- 1.8.4.2
[Qemu-devel] [PATCH v6] net: Adding netmap network backend
This patch adds support for a network backend based on netmap. netmap is a framework for high speed packet I/O. You can use it to build extremely fast traffic generators, monitors, software switches or network middleboxes. Its companion software switch VALE lets you interconnect virtual machines. netmap and VALE are implemented as a non-intrusive kernel module, support NICs from multiple vendors, are part of standard FreeBSD distributions and available in source format for Linux too. To compile QEMU with netmap support, use the following configure options: ./configure [...] --enable-netmap --extra-cflags=-I/path/to/netmap/sys where /path/to/netmap contains the netmap source code, available at http://info.iet.unipi.it/~luigi/netmap/ The same webpage contains more information about the netmap project (together with papers and presentations). Signed-off-by: Vincenzo Maffione v.maffi...@gmail.com --- Changes: - Misspelling error (err -- errno) fixed. - Early return also in netmap_receive(). - Help/qapi-schema modified, since with netmap backend you can also directly connect to a netmap-supported host network interface, as well as to a VALE switch port. configure | 32 hmp-commands.hx | 4 +- net/Makefile.objs | 1 + net/clients.h | 5 + net/net.c | 6 + net/netmap.c | 435 ++ qapi-schema.json | 24 ++- qemu-options.hx | 9 ++ 8 files changed, 513 insertions(+), 3 deletions(-) create mode 100644 net/netmap.c diff --git a/configure b/configure index 91372f9..cfeef21 100755 --- a/configure +++ b/configure @@ -156,6 +156,7 @@ curl= curses= docs= fdt= +netmap=no pixman= sdl= virtfs= @@ -473,6 +474,7 @@ FreeBSD) audio_possible_drivers=oss sdl esd pa # needed for kinfo_getvmmap(3) in libutil.h LIBS=-lutil $LIBS + netmap= # enable netmap autodetect ;; DragonFly) bsd=yes @@ -780,6 +782,10 @@ for opt do ;; --enable-vde) vde=yes ;; + --disable-netmap) netmap=no + ;; + --enable-netmap) netmap=yes + ;; --disable-xen) xen=no ;; --enable-xen) xen=yes @@ -1161,6 +1167,8 @@ echo --disable-uuid disable uuid support echo --enable-uuidenable uuid support echo --disable-vdedisable support for vde network echo --enable-vde enable support for vde network +echo --disable-netmap disable support for netmap network +echo --enable-netmap enable support for netmap network echo --disable-linux-aio disable Linux AIO support echo --enable-linux-aio enable Linux AIO support echo --disable-cap-ng disable libcap-ng support @@ -2065,6 +2073,26 @@ EOF fi ## +# netmap headers probe +if test $netmap != no ; then + cat $TMPC EOF +#include inttypes.h +#include net/if.h +#include net/netmap.h +#include net/netmap_user.h +int main(void) { return 0; } +EOF + if compile_prog ; then +netmap=yes + else +if test $netmap = yes ; then + feature_not_found netmap +fi +netmap=no + fi +fi + +## # libcap-ng library probe if test $cap_ng != no ; then cap_libs=-lcap-ng @@ -3720,6 +3748,7 @@ echo uname -r $uname_release echo GUEST_BASE$guest_base echo PIE $pie echo vde support $vde +echo netmap support$netmap echo Linux AIO support $linux_aio echo ATTR/XATTR support $attr echo Install blobs $blobs @@ -3858,6 +3887,9 @@ fi if test $vde = yes ; then echo CONFIG_VDE=y $config_host_mak fi +if test $netmap = yes ; then + echo CONFIG_NETMAP=y $config_host_mak +fi if test $cap_ng = yes ; then echo CONFIG_LIBCAP=y $config_host_mak fi diff --git a/hmp-commands.hx b/hmp-commands.hx index caae5ad..ebe8e78 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1190,7 +1190,7 @@ ETEXI { .name = host_net_add, .args_type = device:s,opts:s?, -.params = tap|user|socket|vde|dump [options], +.params = tap|user|socket|vde|netmap|dump [options], .help = add host VLAN client, .mhandler.cmd = net_host_device_add, }, @@ -1218,7 +1218,7 @@ ETEXI { .name = netdev_add, .args_type = netdev:O, -.params = [user|tap|socket|hubport],id=str[,prop=value][,...], +.params = [user|tap|socket|hubport|netmap],id=str[,prop=value][,...], .help = add host network device, .mhandler.cmd = hmp_netdev_add, }, diff --git a/net/Makefile.objs b/net/Makefile.objs index 4854a14..c25fe69 100644 --- a/net/Makefile.objs +++ b/net/Makefile.objs @@ -11,3 +11,4 @@ common-obj-$(CONFIG_AIX) += tap-aix.o common-obj-$(CONFIG_HAIKU) += tap-haiku.o common-obj-$(CONFIG_SLIRP) += slirp.o common-obj-$(CONFIG_VDE) += vde.o +common-obj-$(CONFIG_NETMAP) += netmap.o diff --git a/net/clients.h b/net/clients.h index
Re: [Qemu-devel] [PATCH] ossaudio: do not enable by default
On 6 November 2013 09:18, Gerd Hoffmann kra...@redhat.com wrote: I think the audio backend handling needs a serious makeover. Detect sound libraries (pulse, esd, alsa, ...) via configure like any other library. Zap the whole can_be_default logic. Replace it by walking the list of backends, sorted by priority, take the first which initializes successfully. I agree on the need for a serious overhaul. I think the thing we're actually hitting at the moment is that none of the backends are quiet when they fail to initialize, which is bad since we already have loop through and take first which initializes logic. That is clearly 1.8 material though. I think for 1.7 we should simply leave things as-is. Do you mean as-is with Anthony's patch applied, or as it was before that patch was applied ? I would suggest the latter (ie revert this patch), because that's the safest choice this close to release. thanks -- PMM
Re: [Qemu-devel] TARGET_AARCH64
On 6 November 2013 10:25, Phi Debian phi.deb...@gmail.com wrote: Hi All, Browsing the qemu 'latest' src, I see some #define TARGET_AARCH64, does it mean we can boot a qemu-system-arm64 ? Nope. This is preliminary foundation code which we can use to add v8 user-mode emulation (coming soon) and v8 KVM control (also coming soon) and then eventually system emulation (coming, but not for a while yet). thanks -- PMM
Re: [Qemu-devel] [PATCH v5] net: Adding netmap network backend
Hi, I'm sorry, the v5 patch doesn't fix the strerror(err) bug because I saw your reply on v4 after I sent v5 to fix what was pointed out by Eric Blake. The v6 patch should hopefully fix also that. Thanks, Vincenzo 2013/11/6 Stefan Hajnoczi stefa...@gmail.com On Tue, Nov 05, 2013 at 05:42:06PM +0100, Vincenzo Maffione wrote: This patch adds support for a network backend based on netmap. netmap is a framework for high speed packet I/O. You can use it to build extremely fast traffic generators, monitors, software switches or network middleboxes. Its companion software switch VALE lets you interconnect virtual machines. netmap and VALE are implemented as a non-intrusive kernel module, support NICs from multiple vendors, are part of standard FreeBSD distributions and available in source format for Linux too. To compile QEMU with netmap support, use the following configure options: ./configure [...] --enable-netmap --extra-cflags=-I/path/to/netmap/sys where /path/to/netmap contains the netmap source code, available at http://info.iet.unipi.it/~luigi/netmap/ The same webpage contains more information about the netmap project (together with papers and presentations). Signed-off-by: Vincenzo Maffione v.maffi...@gmail.com --- In the future, please include a changelog after the --- line so reviewers know what to look for. I commented on v4, the strerror(error) code looks wrong, it should probably use the errno variable instead. Stefan -- Vincenzo Maffione
Re: [Qemu-devel] Multi-head support RFC
Hi, In QEMU 1.3, there was a DisplayState list. We used one DisplayState per monitor. The DisplayChangeListener has a new hw_add_display vector, so that when the UI requests a second monitor the new display gets attached to the emulated hardware. (patch: add_display_ptr) I don't think we want actually add/remove stuff here. On real hardware your gfx card has a fixed set of display connectors, and I think we are best of mimic that. Support for propagating connect/disconnect events and enabling/disabling displays needs to be added properly. Currently qxl/spice can handle this, but it uses a private side channel. A new vector, hw_store_edid, was added to DisplayState so that UIs could tell emulated hardware what the EDID for a given display should be. (patch: edid-vector) Note that multiple uis can be active at the same time. What happened with the edids then? VRAM size was made configurable, so that more could be allocated to handle multiple high-resolution displays. (patch: variable-vram-size) upstream stdvga has this meanwhile. I don't think it makes sense to have a QemuConsole per display. Why not? That is exactly my plan. Just have the virtual graphic card call graphic_console_init() multiple times, once for each display connector it has. Do you see fundamental issues with that approach? I can use a model similar to what qxl does, and put the framebuffer for each display inside a single DisplaySurface allocated to be a bounding rectangle around all framebuffers. This has the advantage of looking like something that already exists in the tree, but has several disadvantages. Indeed. I don't recommend that. It is that way for several historical reasons (one being that the code predates the qemu console cleanup in the 1.5 devel cycle). Are these features something that people would want to see in the tree? Sure. One of the reasons for the console cleanup was to allow proper multihead support. cheers, Gerd
Re: [Qemu-devel] Multi-head support RFC
Hi, It currently just adds multiple DisplaySurfaces to the QemuConsole, now Gerd said he thought I should be using multiple QemuConsoles but I really didn't think this was a good idea, Why? cheers, Gerd
Re: [Qemu-devel] USB Passthrough not working for Windows 7 guest
On Mi, 2013-11-06 at 10:36 +, Frederich, Jens wrote: I'm not sure which mode it has been. I've used the virt-manager to configure the device. A usb controller is already configured in mode 'default'. Flip that to usb 2.
Re: [Qemu-devel] TARGET_AARCH64
Exciting. Thanx Peter.
Re: [Qemu-devel] [PATCH] virtio-net: only delete bh that existed
On Wed, Nov 06, 2013 at 04:58:08PM +0800, Jason Wang wrote: We delete without check whether it existed during exit. This will lead NULL pointer deference since it was created conditionally depends on guest driver status and features. So add a check of existence before trying to delete it. Cc: qemu-sta...@nongnu.org Signed-off-by: Jason Wang jasow...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Looks like the bug was introduced by: commit 17ec5a8686143da66208273d355f2eeb09807614 Author: KONRAD Frederic fred.kon...@greensocs.com Date: Thu Apr 11 16:29:57 2013 +0200 virtio-net: add the virtio-net device. Before that we had a single bh and created/destroyed that unconditionally. Is this a correct analysis? --- hw/net/virtio-net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 22dbd05..ae51d96 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1601,7 +1601,7 @@ static int virtio_net_device_exit(DeviceState *qdev) if (q-tx_timer) { timer_del(q-tx_timer); timer_free(q-tx_timer); -} else { +} else if (q-tx_bh) { qemu_bh_delete(q-tx_bh); } } -- 1.8.3.2
Re: [Qemu-devel] [PATCH v2] spapr: make sure RMA is in first mode of first memory node
On Wed, 6 Nov 2013 18:54:11 +1100 Alexey Kardashevskiy a...@ozlabs.ru wrote: The SPAPR specification says that the RMA starts at the LPAR's logical address 0 and is the first logical memory block reported in the LPAR’s device tree. So SLOF only maps the first block and that block needs to span the full RMA. This makes sure that the RMA area is where SLOF expects it. Cc: Benjamin Herrenschmidt b...@kernel.crashing.org Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- I came up with v1 of the patch but the actual code came from Alexander Graf. Who should I put as author of this? --- hw/ppc/spapr.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 57b38cf..57473df 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1114,6 +1114,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); hwaddr rma_alloc_size; +hwaddr node0_size = (nb_numa_nodes 1) ? node_mem[0] : ram_size; uint32_t initrd_base = 0; long kernel_size = 0, initrd_size = 0; long load_limit, rtas_limit, fw_size; @@ -1138,7 +1139,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) if (rma_alloc_size (rma_alloc_size ram_size)) { spapr-rma_size = rma_alloc_size; } else { -spapr-rma_size = ram_size; +spapr-rma_size = node0_size; /* With KVM, we don't actually know whether KVM supports an * unbounded RMA (PR KVM) or is limited by the hash table size @@ -1155,6 +1156,12 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) } } +if (spapr-rma_size node0_size) { +fprintf(stderr, Error: Numa node 0 has to span the RMA (%#08HWADDR_PRIx)\n, +spapr-rma_size); +exit(1); +} + What about the if (spapr-rma_size node0_size) at the beginning of spapr_populate_memory()? Could/should that go away now? Thomas
Re: [Qemu-devel] [PATCH] ossaudio: do not enable by default
On Mi, 2013-11-06 at 10:48 +, Peter Maydell wrote: That is clearly 1.8 material though. I think for 1.7 we should simply leave things as-is. Do you mean as-is with Anthony's patch applied, or as it was before that patch was applied ? Oh, it is in? I would suggest the latter (ie revert this patch), because that's the safest choice this close to release. Agree. cheers, Gerd
Re: [Qemu-devel] USB Passthrough not working for Windows 7 guest
-Original Message- From: Gerd Hoffmann [mailto:kra...@redhat.com] Sent: Wednesday, November 06, 2013 12:09 PM To: Frederich, Jens Cc: Jan Kiszka; Jens Frederich; qemu-devel@nongnu.org Subject: Re: [Qemu-devel] USB Passthrough not working for Windows 7 guest On Mi, 2013-11-06 at 10:36 +, Frederich, Jens wrote: I'm not sure which mode it has been. I've used the virt-manager to configure the device. A usb controller is already configured in mode 'default'. Flip that to usb 2. Thanks, Gerd. Now I can see the usb controller on Win 7. But my device isn't there...
Re: [Qemu-devel] [PATCH v2] spapr: make sure RMA is in first mode of first memory node
On 06.11.2013, at 12:13, Thomas Huth th...@linux.vnet.ibm.com wrote: On Wed, 6 Nov 2013 18:54:11 +1100 Alexey Kardashevskiy a...@ozlabs.ru wrote: The SPAPR specification says that the RMA starts at the LPAR's logical address 0 and is the first logical memory block reported in the LPAR’s device tree. So SLOF only maps the first block and that block needs to span the full RMA. This makes sure that the RMA area is where SLOF expects it. Cc: Benjamin Herrenschmidt b...@kernel.crashing.org Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- I came up with v1 of the patch but the actual code came from Alexander Graf. Who should I put as author of this? --- hw/ppc/spapr.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 57b38cf..57473df 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1114,6 +1114,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); hwaddr rma_alloc_size; +hwaddr node0_size = (nb_numa_nodes 1) ? node_mem[0] : ram_size; uint32_t initrd_base = 0; long kernel_size = 0, initrd_size = 0; long load_limit, rtas_limit, fw_size; @@ -1138,7 +1139,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) if (rma_alloc_size (rma_alloc_size ram_size)) { spapr-rma_size = rma_alloc_size; } else { -spapr-rma_size = ram_size; +spapr-rma_size = node0_size; /* With KVM, we don't actually know whether KVM supports an * unbounded RMA (PR KVM) or is limited by the hash table size @@ -1155,6 +1156,12 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) } } +if (spapr-rma_size node0_size) { +fprintf(stderr, Error: Numa node 0 has to span the RMA (%#08HWADDR_PRIx)\n, +spapr-rma_size); +exit(1); +} + What about the if (spapr-rma_size node0_size) at the beginning of spapr_populate_memory()? Could/should that go away now? It should, yes. It was very wrong in that spot from the first place, as that helper really should only create the fdt entries, not modify global state. Alex
Re: [Qemu-devel] [PATCH v2] spapr: make sure RMA is in first mode of first memory node
On 06.11.2013, at 08:54, Alexey Kardashevskiy a...@ozlabs.ru wrote: The SPAPR specification says that the RMA starts at the LPAR's logical address 0 and is the first logical memory block reported in the LPAR’s device tree. So SLOF only maps the first block and that block needs to span the full RMA. This makes sure that the RMA area is where SLOF expects it. Cc: Benjamin Herrenschmidt b...@kernel.crashing.org Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- I came up with v1 of the patch but the actual code came from Alexander Graf. Who should I put as author of this? Just declare it as your own ;). Alex
Re: [Qemu-devel] USB Passthrough not working for Windows 7 guest
the device. A usb controller is already configured in mode 'default'. Flip that to usb 2. Thanks, Gerd. Now I can see the usb controller on Win 7. But my device isn't there... Anything in the logs (/var/log/libvirt/qemu/$guest.log)? cheers, Gerd
Re: [Qemu-devel] [PATCH] spapr: add compat machine option
On Tue, 05 Nov 2013 14:53:14 +0100 Andreas Färber afaer...@suse.de wrote: Am 05.11.2013 10:52, schrieb Paolo Bonzini: Il 05/11/2013 10:16, Alexander Graf ha scritto: On 05.11.2013, at 10:06, Paolo Bonzini pbonz...@redhat.com wrote: Il 30/09/2013 14:57, Alexey Kardashevskiy ha scritto: Why is the option under -machine instead of -cpu? Because it is still the same CPU and the guest will still read the real PVR from the hardware (which it may not support but this is why we need compatibility mode). How do you support migration from a newer to an older CPU then? I think the guest should never see anything about the hardware CPU model. POWER can't model that. It always leaks the host CPU information into the guest. It's the guest kernel's responsibility to not expose that change to user space. Yes, it's broken :). I'm not even sure there is any sensible way to do live migration between different CPU types. Still in my opinion it should be -cpu, not -machine. Even if it's just a virtual CPU model. PowerPC currently does not have -cpu option parsing. If you need to implement it, I would ask for a generic hook in CPUClass set by TYPE_POWERPC_CPU, so that the logic does not get hardcoded in cpu_init, and for the p=v parsing logic to be so generic as to just set property p to value v on the CPU instance. I.e. please make the compatibility settings a static property or dynamic property of the CPU. Seconded, that's what is on my to-do list for x86 once x86 properties series is applied. moreover, all hook has to do is to translate -cpu to a set of global options, adding [CPUtype.foo, val] pairs to global option list. Then options will be automatically applied to any new instance of CPUtype and there won't be any need for accessing/storing cpu_model string during cpu creation and hotplug. Maybe the parsing code could even live in generic qom/cpu.c, overridden by x86/sparc and reused for arm? Somewhere down my to-do list but patches appreciated... Andreas
[Qemu-devel] [PATCH] block: Round up total_sectors
Since b94a2610, bdrv_getlength() is omitted when probing image. VMDK monolithicFlat is broken by that because a file 512 bytes can't be read with its total_sectors truncated to 0. This patch round up the size to BDRV_SECTOR_SIZE, when a image size is not sector aligned. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block.c b/block.c index 58efb5b..f706634 100644 --- a/block.c +++ b/block.c @@ -640,7 +640,7 @@ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint) if (length 0) { return length; } -hint = length BDRV_SECTOR_BITS; +hint = DIV_ROUND_UP(length, BDRV_SECTOR_SIZE); } bs-total_sectors = hint; -- 1.8.3.1
Re: [Qemu-devel] i386: pc: align gpa-hpa on 1GB boundary (v3)
On Tue, 5 Nov 2013 23:55:43 -0200 Marcelo Tosatti mtosa...@redhat.com wrote: v2: condition enablement of new mapping to new machine types (Paolo) v3: fix changelog - Align guest physical address and host physical address beyond guest 4GB on a 1GB boundary. Otherwise 1GB TLBs cannot be cached for the range. Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0c313fe..534e067 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1116,7 +1116,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory, [...] +/* + * + * If 1GB hugepages are used to back guest RAM, map guest address + * space in the range [ramsize,ramsize+holesize] to the ram block + * range [holestart, 4GB] + * + * 0 h 4G [ramsize,ramsize+holesize] + * + * guest-addr-space [ ] [ ][xxx] + */--/ + * contiguous-ram-block [ ][xxx][ ] + * + * So that memory beyond 4GB is aligned on a 1GB boundary, + * at the host physical address space. + * + */ +if (guest_info-gb_align) { 'gb_align' is one shot usage, it would be better to just add it as an argument to pc_memory_init(). That would allow to avoid extending PcGuestInfo needlessly, since gb_align isn't reused. +unsigned long holesize = 0x1ULL - below_4g_mem_size; + +memory_region_init_alias(ram_above_4g, NULL, ram-above-4g, ram, +0x1ULL, +above_4g_mem_size - holesize); +memory_region_add_subregion(system_memory, 0x1ULL, ram_above_4g); [...] diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 6083839..00afe4a 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -20,6 +20,7 @@ typedef struct PcPciInfo { struct PcGuestInfo { bool has_pci_info; bool isapc_ram_fw; +bool gb_align; FWCfgState *fw_cfg; }; it doesn't apply anymore.
Re: [Qemu-devel] [PATCH v3] qemu-iotests: use blkdebug to make test deterministic
On Thu, Oct 31, 2013 at 10:18:08AM +0800, Fam Zheng wrote: This patch suspends the test image IO before starting block stream job so that it doesn't complete before we could check the status. Signed-off-by: Fam Zheng f...@redhat.com --- tests/qemu-iotests/030| 10 ++ tests/qemu-iotests/iotests.py | 5 - 2 files changed, 10 insertions(+), 5 deletions(-) ./check -qcow2 030 hangs with this patch applied. Can you reproduce it or am I missing something? Stefan
Re: [Qemu-devel] [PATCH] spapr: add compat machine option
On 06.11.2013, at 06:48, Paul Mackerras pau...@samba.org wrote: On Mon, Sep 30, 2013 at 01:25:32PM +0200, Alexander Graf wrote: On 27.09.2013, at 10:06, Alexey Kardashevskiy wrote: To be able to boot on newer hardware that the software support, PowerISA defines a logical PVR, one per every PowerISA specification version from 2.04. [snip] +case 205: +spapr-arch_compat = CPU_POWERPC_LOGICAL_2_05; +break; +case 206: +spapr-arch_compat = CPU_POWERPC_LOGICAL_2_06; Does it make sense to declare compat mode a number or would a string be easier for users? I can imagine that -machine compat=power6 is easier to understand for a user than -machine compat=205. That's probably true. I don't mind either way. Also, we need to handle failure. If the kernel can not set the CPU to 2.05 mode for example (IIRC POWER8 doesn't allow you to) we should bail out here. POWER8 does have 2.05 (POWER6) and 2.06 (POWER7) compatibility modes. +/* Architecture compatibility mode */ +uint32_t arch_compat; Do we really need to carry this in the vcpu struct? Or can we just fire-and-forget about it? If we want to preserve anything, it should be the PCR register. There are two relevant values here; the compatibility mode (if any) that the user has requested via the command line, and the mode that has been negotiated with the ibm,client-architecture-support (CAS) call. CAS should select the latest mode supported by the guest that is not later than the mode requested on the command line, and is supported by QEMU, and is not later than the architecture of the host. Both values should be sent across to the destination VM on migration AFAICS. So how does this work on pHyp? I thought the guest always comes up in full native compat mode and downgrades itself then? On reset/reboot, the compatibility mode should not change. The device tree that is supplied to the new SLOF instance should reflect the current compatibility mode. Ok, this should work if we just don't touch PCR across reset. Alex
Re: [Qemu-devel] i386: pc: align gpa-hpa on 1GB boundary (v3)
Il 06/11/2013 12:59, Igor Mammedov ha scritto: On Tue, 5 Nov 2013 23:55:43 -0200 Marcelo Tosatti mtosa...@redhat.com wrote: v2: condition enablement of new mapping to new machine types (Paolo) v3: fix changelog - Align guest physical address and host physical address beyond guest 4GB on a 1GB boundary. Otherwise 1GB TLBs cannot be cached for the range. Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0c313fe..534e067 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1116,7 +1116,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory, [...] +/* + * + * If 1GB hugepages are used to back guest RAM, map guest address + * space in the range [ramsize,ramsize+holesize] to the ram block + * range [holestart, 4GB] + * + * 0 h 4G [ramsize,ramsize+holesize] + * + * guest-addr-space [ ] [ ][xxx] + */--/ + * contiguous-ram-block [ ][xxx][ ] + * + * So that memory beyond 4GB is aligned on a 1GB boundary, + * at the host physical address space. + * + */ +if (guest_info-gb_align) { 'gb_align' is one shot usage, it would be better to just add it as an argument to pc_memory_init(). That would allow to avoid extending PcGuestInfo needlessly, since gb_align isn't reused. No, Marcelo's way is better. pc_memory_init already has too many arguments, moving them to PcGuestInfo (which ultimately might become properties of the /machine QOM object) is the right thing to do. Paolo +unsigned long holesize = 0x1ULL - below_4g_mem_size; + +memory_region_init_alias(ram_above_4g, NULL, ram-above-4g, ram, +0x1ULL, +above_4g_mem_size - holesize); +memory_region_add_subregion(system_memory, 0x1ULL, ram_above_4g); [...] diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 6083839..00afe4a 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -20,6 +20,7 @@ typedef struct PcPciInfo { struct PcGuestInfo { bool has_pci_info; bool isapc_ram_fw; +bool gb_align; FWCfgState *fw_cfg; }; it doesn't apply anymore.
Re: [Qemu-devel] [PATCH v3] qemu-iotests: use blkdebug to make test deterministic
Il 31/10/2013 03:18, Fam Zheng ha scritto: This patch suspends the test image IO before starting block stream job so that it doesn't complete before we could check the status. Signed-off-by: Fam Zheng f...@redhat.com --- tests/qemu-iotests/030| 10 ++ tests/qemu-iotests/iotests.py | 5 - 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index d0f96ea..bc66e6f 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -391,7 +391,7 @@ class TestStreamStop(iotests.QMPTestCase): qemu_io('-c', 'write -P 0x1 0 32M', backing_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) qemu_io('-c', 'write -P 0x1 32M 32M', test_img) -self.vm = iotests.VM().add_drive(test_img) +self.vm = iotests.VM().add_drive(blkdebug:: + test_img) self.vm.launch() def tearDown(self): @@ -402,6 +402,7 @@ class TestStreamStop(iotests.QMPTestCase): def test_stream_stop(self): self.assert_no_active_block_jobs() +self.vm.qmp('human-monitor-command', command_line='qemu-io drive0 break write_aio a') result = self.vm.qmp('block-stream', device='drive0') self.assert_qmp(result, 'return', {}) @@ -409,7 +410,7 @@ class TestStreamStop(iotests.QMPTestCase): events = self.vm.get_qmp_events(wait=False) self.assertEqual(events, [], 'unexpected QMP event: %s' % events) -self.cancel_and_wait() +self.cancel_and_wait(resume='a') class TestSetSpeed(iotests.QMPTestCase): image_len = 80 * 1024 * 1024 # MB @@ -419,7 +420,7 @@ class TestSetSpeed(iotests.QMPTestCase): qemu_io('-c', 'write -P 0x1 0 32M', backing_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) qemu_io('-c', 'write -P 0x1 32M 32M', test_img) -self.vm = iotests.VM().add_drive(test_img) +self.vm = iotests.VM().add_drive('blkdebug::' + test_img) self.vm.launch() def tearDown(self): @@ -453,6 +454,7 @@ class TestSetSpeed(iotests.QMPTestCase): def test_set_speed(self): self.assert_no_active_block_jobs() +self.vm.qmp('human-monitor-command', command_line='qemu-io drive0 break write_aio a') result = self.vm.qmp('block-stream', device='drive0') self.assert_qmp(result, 'return', {}) @@ -469,7 +471,7 @@ class TestSetSpeed(iotests.QMPTestCase): self.assert_qmp(result, 'return[0]/device', 'drive0') self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024) -self.cancel_and_wait() +self.cancel_and_wait(resume='a') # Check setting speed in block-stream works result = self.vm.qmp('block-stream', device='drive0', speed=4 * 1024 * 1024) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index fb10ff4..de45079 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -222,11 +222,14 @@ class QMPTestCase(unittest.TestCase): result = self.vm.qmp('query-block-jobs') self.assert_qmp(result, 'return', []) -def cancel_and_wait(self, drive='drive0', force=False): +def cancel_and_wait(self, drive='drive0', force=False, resume=): '''Cancel a block job and wait for it to finish, returning the event''' result = self.vm.qmp('block-job-cancel', device=drive, force=force) self.assert_qmp(result, 'return', {}) +if resume: +self.vm.qmp('human-monitor-command', command_line='qemu-io %s resume %s' % (drive, resume)) + cancelled = False result = None while not cancelled: Can you do the same for the mirror test too? Paolo
Re: [Qemu-devel] [PATCH v3] Fix pc migration from qemu = 1.5
On Tue, Nov 05, 2013 at 06:46:27PM -0500, Cole Robinson wrote: The following commit introduced a migration incompatibility: commit 568f0690fd9aa4d39d84b04c1a5dbb53a915c3fe Author: David Gibson da...@gibson.dropbear.id.au Date: Thu Jun 6 18:48:49 2013 +1000 pci: Replace pci_find_domain() with more general pci_root_bus_path() The issue is that i440fx savevm idstr went from :00:00.0/I440FX to :00.0/I440FX. Unfortunately we are stuck with the breakage for 1.6 machine types. Add a compat property to maintain the busted idstr for the 1.6 machine types, but revert to the old style format for 1.7+, and = 1.5. Tested with migration from qemu 1.5, qemu 1.6, and qemu.git. Cc: qemu-sta...@nongnu.org Signed-off-by: Cole Robinson crobi...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com BTW we really need unit tests for migration. --- v3: Don't regress -M pc-q35* hw/pci-host/piix.c| 9 - hw/pci-host/q35.c | 10 -- include/hw/i386/pc.h | 16 include/hw/pci-host/q35.h | 1 + 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index bad3953..edc974e 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -48,6 +48,7 @@ typedef struct I440FXState { PCIHostState parent_obj; PcPciInfo pci_info; uint64_t pci_hole64_size; +uint32_t short_root_bus; } I440FXState; #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ @@ -720,13 +721,19 @@ static const TypeInfo i440fx_info = { static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus) { +I440FXState *s = I440FX_PCI_HOST_BRIDGE(host_bridge); + /* For backwards compat with old device paths */ -return ; +if (s-short_root_bus) { +return ; +} +return :00; } static Property i440fx_props[] = { DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState, pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE), +DEFINE_PROP_UINT32(short_root_bus, I440FXState, short_root_bus, 0), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index b8feed1..c043998 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -61,8 +61,13 @@ static void q35_host_realize(DeviceState *dev, Error **errp) static const char *q35_host_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus) { -/* For backwards compat with old device paths */ -return ; +Q35PCIHost *s = Q35_HOST_DEVICE(host_bridge); + + /* For backwards compat with old device paths */ +if (s-mch.short_root_bus) { +return ; +} +return :00; } static void q35_host_get_pci_hole_start(Object *obj, Visitor *v, @@ -124,6 +129,7 @@ static Property mch_props[] = { MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT), DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost, mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE), +DEFINE_PROP_UINT32(short_root_bus, Q35PCIHost, mch.short_root_bus, 0), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 03cc0ba..57e8d16 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -260,6 +260,14 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); .driver = qemu32- TYPE_X86_CPU,\ .property = model,\ .value= stringify(3),\ +},{\ +.driver = i440FX-pcihost,\ +.property = short_root_bus,\ +.value= stringify(1),\ +},{\ +.driver = q35-pcihost,\ +.property = short_root_bus,\ +.value= stringify(1),\ } #define PC_COMPAT_1_5 \ @@ -296,6 +304,14 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); .driver = TYPE_X86_CPU,\ .property = pmu,\ .value = on,\ +},{\ +.driver = i440FX-pcihost,\ +.property = short_root_bus,\ +.value= stringify(0),\ +},{\ +.driver = q35-pcihost,\ +.property = short_root_bus,\ +.value= stringify(0),\ } #define PC_COMPAT_1_4 \ diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index aee91aa..309065f 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -61,6 +61,7 @@ typedef struct MCHPCIState { ram_addr_t above_4g_mem_size; uint64_t pci_hole64_size; PcGuestInfo *guest_info; +uint32_t short_root_bus; } MCHPCIState; typedef struct Q35PCIHost { -- 1.8.4.2
Re: [Qemu-devel] [PATCH] integrator/cp: add support for REFCNTregisterr
BTW, I just cooked very simple support for PL030 RTC chip, but I guess there is zero interest on it as it seems that PL030 is somehow simplified predecessor of well-known PL031, which in turn, is used on all devboards but Integrator. So, I'm sending it here only for reference. I need to note that I have no access to any PL030 documentation, so it was reverse work of corresponding rtc-pl030.c driver from Linux kernel 3.12 The only reason for having PL030 here is that Linux kernel's integrator_defconfig enables only PL030, so without current code, the kernel console says something like that: drivers/rtc/hctosys.c: unable to open rtc device (rtc0) Adding PL030 support to QEMU makes kernel start happy: rtc-pl030 mb:15: rtc core: registered pl030 as rtc0 rtc-pl030 mb:15: setting system clock to 2013-11-06 11:55:09 UTC (1383738909) BR. /Jan From cd7c6f0130392c0c81064867e346b8a4b218e2cd Mon Sep 17 00:00:00 2001 From: Jan Petrous jan.petr...@tieto.com Date: Wed, 6 Nov 2013 12:38:58 +0100 Subject: [PATCH] arm: add pl030 rtc support Devboard Integrator/CP features RTC PL030. To get supported default kernel config for Integrator (integrator_defconfig) the PL030 RTC IP is added. Signed-off-by: Jan Petrous jan.petr...@tieto.com --- default-configs/arm-softmmu.mak | 1 + hw/arm/integratorcp.c | 2 +- hw/timer/Makefile.objs | 1 + hw/timer/pl030.c| 245 4 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 hw/timer/pl030.c diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 7e69137..87b9852 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -43,6 +43,7 @@ CONFIG_ARM_TIMER=y CONFIG_ARM_MPTIMER=y CONFIG_PL011=y CONFIG_PL022=y +CONFIG_PL030=y CONFIG_PL031=y CONFIG_PL041=y CONFIG_PL050=y diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index a759689..0f703b2 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -510,7 +510,7 @@ static void integratorcp_init(QEMUMachineInitArgs *args) sysbus_create_simple(TYPE_INTEGRATOR_PIC, 0xca00, pic[26]); sysbus_create_varargs(integrator_pit, 0x1300, pic[5], pic[6], pic[7], NULL); -sysbus_create_simple(pl031, 0x1500, pic[8]); +sysbus_create_simple(pl030, 0x1500, pic[8]); sysbus_create_simple(pl011, 0x1600, pic[1]); sysbus_create_simple(pl011, 0x1700, pic[2]); icp_control_init(0xcb00); diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index eca5905..f4b4ea1 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -5,6 +5,7 @@ common-obj-$(CONFIG_DS1338) += ds1338.o common-obj-$(CONFIG_HPET) += hpet.o common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o common-obj-$(CONFIG_M48T59) += m48t59.o +common-obj-$(CONFIG_PL030) += pl030.o common-obj-$(CONFIG_PL031) += pl031.o common-obj-$(CONFIG_PUV3) += puv3_ost.o common-obj-$(CONFIG_TWL92230) += twl92230.o diff --git a/hw/timer/pl030.c b/hw/timer/pl030.c new file mode 100644 index 000..cee7a74 --- /dev/null +++ b/hw/timer/pl030.c @@ -0,0 +1,245 @@ +/* + * ARM AMBA PrimeCell PL030 RTC + * + * Tightly based on pl031.c QEMU sources (c) 2007 CodeSourcery + * Copyright (c) 2013 Tieto Corp., Jan Petrous + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + */ + +#include hw/sysbus.h +#include qemu/timer.h +#include sysemu/sysemu.h + +//#define DEBUG_PL030 + +#ifdef DEBUG_PL030 +#define DPRINTF(fmt, ...) \ +do { printf(pl030: fmt , ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) do {} while (0) +#endif + +#define RTC_DR 0x00/* Data read register */ +#define RTC_MR 0x04/* Match register */ +#define RTC_STAT0x08/* Masked interrupt status register */ +#define RTC_LR 0x0c/* Data load register */ +#define RTC_CR 0x10/* Control register */ + +#define TYPE_PL030 pl030 +#define PL030(obj) OBJECT_CHECK(PL030State, (obj), TYPE_PL030) + +typedef struct PL030State { +SysBusDevice parent_obj; + +MemoryRegion iomem; +QEMUTimer *timer; +qemu_irq irq; + +/* Needed to preserve the tick_count across migration, even if the + * absolute value of the rtc_clock is different on the source and + * destination. + */ +uint32_t tick_offset_vmstate; +uint32_t tick_offset; + +uint32_t mr; +uint32_t lr; +uint32_t cr; +uint32_t stat; +} PL030State; + +static const unsigned char pl030_id[] = { +0x30, 0x10, 0x04, 0x00, /* Device ID*/ +0x0d, 0xf0, 0x05, 0xb1 /* Cell ID */ +}; + +static void pl030_update(PL030State *s) +{ +qemu_set_irq(s-irq,
[Qemu-devel] [PATCH 00/80] COW: Speed up writes
Following on from Paolo's commits 26ae980 and 276cbc7, this patchset implements some changes he recommended earlier which I didn't previously have time to do while on GSoC. Patch 2 was written initially I was intending to use cow_co_is_allocated in Patch 3 and needed it to consider all sectors but in the end cow_find_streak was sufficient, so it may not strictly be necessary. Andreas Färber (49): mips_mipssim: Silence BIOS loading warning for qtest puv3: Turn puv3_load_kernel() into a no-op for qtest without -kernel mainstone: Don't enforce use of -pflash for qtest gumstix: Don't enforce use of -pflash for qtest z2: Don't enforce use of -pflash for qtest palm: Don't enforce loading ROM or kernel for qtest omap_sx1: Don't enforce use of kernel or flash for qtest exynos4_boards: Silence lack of -smp 2 warning for qtest armv7m: Don't enforce use of kernel for qtest axis_dev88: Don't enforce use of kernel for qtest mcf5208: Don't enforce use of kernel for qtest an5206: Don't enforce use of kernel for qtest milkymist: Suppress -kernel/-bios/-drive error for qtest shix: Drop debug output shix: Don't require firmware presence for qtest leon3: Don't enforce use of -bios with qtest qtest: Prepare QOM machine tests a9mpcore: Split off instance_init arm_gic: Extract headers hw/intc/arm_gic{,_common}.h a9mpcore: Embed GICState a9scu: QOM cleanups a9mpcore: Embed A9SCUState arm_mptimer: Convert to QOM realize a9mpcore: Embed ARMMPTimerState a9mpcore: Convert to QOM realize a9mpcore: Prepare for QOM embedding a15mpcore: Split off instance_init a15mpcore: Embed GICState a15mpcore: Convert to QOM realize a15mpcore: Prepare for QOM embedding a9scu: Build only once arm11mpcore: Fix typo in MemoryRegion name arm11mpcore: Drop unused fields arm11mpcore: Create container MemoryRegion in instance_init arm11mpcore: Split off SCU device arm11mpcore: Convert ARM11MPCorePriveState to QOM realize realview_gic: Convert to QOM realize realview_gic: Prepare for QOM embedding arm11mpcore: Convert mpcore_rirq_state to QOM realize arm11mpcore: Prepare for QOM embedding arm11mpcore: Split off RealView MPCore qdev-monitor: Clean up qdev_device_add() variable naming qdev-monitor: Avoid qdev as variable name qdev-monitor: Inline qdev_init() for device_add pxa: Fix typo dettach pcmcia: QOM'ify PCMCIACardState and MicroDriveState microdrive: Coding Style cleanups ide: Drop ide_init2_with_non_qdev_drives() pcmcia/pxa2xx: QOM'ify PXA2xxPCMCIAState Anthony Liguori (1): ossaudio: do not enable by default Antony Pavlov (1): milkymist-uart: Use Device::realize instead of SysBusDevice::init Charlie Shepherd (3): COW: Speed up writes COW: Extend checking allocated bits to beyond one sector COW: Skip setting already set bits Gerd Hoffmann (3): pc: add etc/e820 fw_cfg file pc: register e820 entries for ram qxl: replace pipe signaling with bottom half Igor Mammedov (1): qdev-monitor: Fix crash when device_add is called with abstract driver Jan Kiszka (1): rtc: remove dead SQW IRQ code Marc-André Lureau (1): vga: fix invalid read after free Michael S. Tsirkin (3): pc: disable acpi info for isapc and old pc machine exec: limit system memory size qom: Fix pointer to int property helpers' documentation Mike Frysinger (1): configure: detect endian via compile test Paolo Bonzini (1): vl: allow cont from panicked state Peter Maydell (10): bswap.h: Remove cpu_to_le16wu() bswap.h: Remove cpu_to_le32wu() bswap.h: Remove le16_to_cpupu() bswap.h: Remove le32_to_cpupu() bswap.h: Remove be32_to_cpupu() bswap.h: Remove cpu_to_be16wu() bswap.h: Remove cpu_to_be32wu() bswap.h: Remove cpu_to_be64wu() bswap.h: Remove cpu_to_32wu() docs/memory.txt: Clarify and expand priority/overlap documentation Stefan Hajnoczi (3): qdev-monitor: Unref device when device_add fails qdev: Drop misleading qdev_free() function tests: fix 64-bit int literals for 32-bit hosts Wenchao Xia (2): qapi: fix memleak by adding implict struct functions in dealloc visitor tests: fix memleak in error path test for input visitor
[Qemu-devel] [PATCH 01/80] pc: add etc/e820 fw_cfg file
From: Gerd Hoffmann kra...@redhat.com Unlike the existing FW_CFG_E820_TABLE entry which carries reservations only the new etc/e820 file also has entries for RAM. Format is simliar to the FW_CFG_E820_TABLE, it is a simple list of e820_entry structs. Unlike FW_CFG_E820_TABLE it has no count though as the number of entries can be figured from the file size. Cc: Andrea Arcangeli aarca...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- hw/i386/pc.c | 39 --- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index dee409d..a653ae4 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -90,7 +90,9 @@ struct e820_table { struct e820_entry entry[E820_NR_ENTRIES]; } QEMU_PACKED __attribute((__aligned__(4))); -static struct e820_table e820_table; +static struct e820_table e820_reserve; +static struct e820_entry *e820_table; +static unsigned e820_entries; struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; void gsi_handler(void *opaque, int n, int level) @@ -577,19 +579,32 @@ static void handle_a20_line_change(void *opaque, int irq, int level) int e820_add_entry(uint64_t address, uint64_t length, uint32_t type) { -int index = le32_to_cpu(e820_table.count); +int index = le32_to_cpu(e820_reserve.count); struct e820_entry *entry; -if (index = E820_NR_ENTRIES) -return -EBUSY; -entry = e820_table.entry[index++]; +if (type != E820_RAM) { +/* old FW_CFG_E820_TABLE entry -- reservations only */ +if (index = E820_NR_ENTRIES) { +return -EBUSY; +} +entry = e820_reserve.entry[index++]; + +entry-address = cpu_to_le64(address); +entry-length = cpu_to_le64(length); +entry-type = cpu_to_le32(type); + +e820_reserve.count = cpu_to_le32(index); +} -entry-address = cpu_to_le64(address); -entry-length = cpu_to_le64(length); -entry-type = cpu_to_le32(type); +/* new etc/e820 file -- include ram too */ +e820_table = g_realloc(e820_table, + sizeof(struct e820_entry) * (e820_entries+1)); +e820_table[e820_entries].address = cpu_to_le64(address); +e820_table[e820_entries].length = cpu_to_le64(length); +e820_table[e820_entries].type = cpu_to_le32(type); +e820_entries++; -e820_table.count = cpu_to_le32(index); -return index; +return e820_entries; } /* Calculates the limit to CPU APIC ID values @@ -640,7 +655,9 @@ static FWCfgState *bochs_bios_init(void) fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, smbios_table, smbios_len); fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, - e820_table, sizeof(e820_table)); + e820_reserve, sizeof(e820_reserve)); +fw_cfg_add_file(fw_cfg, etc/e820, e820_table, +sizeof(struct e820_entry) * e820_entries); fw_cfg_add_bytes(fw_cfg, FW_CFG_HPET, hpet_cfg, sizeof(hpet_cfg)); /* allocate memory for the NUMA channel: one (64bit) word for the number -- 1.8.4.rc3
[Qemu-devel] [PATCH 02/80] pc: register e820 entries for ram
From: Gerd Hoffmann kra...@redhat.com So RAM shows up in the new etc/e820 fw_cfg file. Cc: Andrea Arcangeli aarca...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- hw/i386/pc.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index a653ae4..12c436e 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1174,13 +1174,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory, memory_region_init_alias(ram_below_4g, NULL, ram-below-4g, ram, 0, below_4g_mem_size); memory_region_add_subregion(system_memory, 0, ram_below_4g); -if (0) { -/* - * Ideally we should do that too, but that would ruin the e820 - * reservations added by seabios before initializing fw_cfg. - */ -e820_add_entry(0, below_4g_mem_size, E820_RAM); -} +e820_add_entry(0, below_4g_mem_size, E820_RAM); if (above_4g_mem_size 0) { ram_above_4g = g_malloc(sizeof(*ram_above_4g)); memory_region_init_alias(ram_above_4g, NULL, ram-above-4g, ram, -- 1.8.4.rc3
Re: [Qemu-devel] [PATCH 01/80] pc: add etc/e820 fw_cfg file
Sorry all, some confusion using git-publish, apologies for the spam. Charlie
Re: [Qemu-devel] [PATCH] RFC: powerpc: add PVR compatibility check
On 06.11.2013, at 04:02, Paul Mackerras pau...@samba.org wrote: On Tue, Nov 05, 2013 at 05:16:33PM +0100, Andreas Färber wrote: Am 05.11.2013 07:05, schrieb Alexander Graf: Am 05.11.2013 um 05:00 schrieb Paul Mackerras pau...@samba.org: On Mon, Nov 04, 2013 at 10:05:58AM +0100, Alexander Graf wrote: Yeah, we really need to check that guest vpcu == host vcpu for HV KVM. In general I agree, but the one difficulty I see is that a check for exact equality will interact badly with qemu's habit of picking a specific processor version when the user specifies something general like POWER7. So if the user does -cpu POWER7 on a machine with (for example) a POWER7 v2.1 processor, but qemu arbitrarily picks the PVR for POWER7 v2.3, then it will fail, which will be completely puzzling to the user -- I asked for POWER7, and it is a POWER7, what's the problem??. Maybe if the user asks for a non-specific processor type, and the host's PVR matches the request, then qemu should take the host's PVR rather than just picking some arbitrary processor version. Yup. But then it's no longer generally reproducible: POWER7 won't be POWER7 on another machine. There aren't any observable differences between POWER7 versions that have been sold to customers, as far as I have been able to ascertain (other than the PVR value, of course). So this whole business of carefully distinguishing between POWER7 v2.2 and POWER7 v2.3 is largely a waste of time as far as I can see. I admit that in the past we (IBM) did a silly thing in releasing the POWER5+ v3.0 chip with some architecturally new features (64k pages and some other MMU changes). That was a mistake and I don't think we'll do it again. I think the default assumption should be that versions of a given IBM POWER chip (identified by the upper 16 bits of the PVR) are architecturally identical, and behaviourally identical at the level at which QEMU models the chip. Differences between chips would normally be limited to bug fixes and performance improvements. Then we just need a way to cope with POWER5+ v3.0. One thing I original did iirc was to hide the aliases from QMP. You can always do stupid things on the command line and then we can blame you, but if libvirt and upper layers don't offer POWER7 to the end user then we don't need to worry about the average user misinterpreting its semantics. Given that the only difference between POWER7 v2.2 and POWER7 v2.3 (say) will be which set of host systems you get an error on, there doesn't seem to me to be a lot of point. Given that for HV KVM the only possible cpu type that is ever guaranteed to work is -cpu host, why bother with a database that maintains compatibility flags between different versions? Just tell the user to use -cpu host and call it a day, no? Alex
Re: [Qemu-devel] i386: pc: align gpa-hpa on 1GB boundary (v3)
On Wed, 06 Nov 2013 13:07:26 +0100 Paolo Bonzini pbonz...@redhat.com wrote: Il 06/11/2013 12:59, Igor Mammedov ha scritto: On Tue, 5 Nov 2013 23:55:43 -0200 Marcelo Tosatti mtosa...@redhat.com wrote: v2: condition enablement of new mapping to new machine types (Paolo) v3: fix changelog - Align guest physical address and host physical address beyond guest 4GB on a 1GB boundary. Otherwise 1GB TLBs cannot be cached for the range. Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0c313fe..534e067 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1116,7 +1116,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory, [...] +/* + * + * If 1GB hugepages are used to back guest RAM, map guest address + * space in the range [ramsize,ramsize+holesize] to the ram block + * range [holestart, 4GB] + * + * 0 h 4G [ramsize,ramsize+holesize] + * + * guest-addr-space [ ] [ ][xxx] + */--/ + * contiguous-ram-block [ ][xxx][ ] + * + * So that memory beyond 4GB is aligned on a 1GB boundary, + * at the host physical address space. + * + */ +if (guest_info-gb_align) { 'gb_align' is one shot usage, it would be better to just add it as an argument to pc_memory_init(). That would allow to avoid extending PcGuestInfo needlessly, since gb_align isn't reused. No, Marcelo's way is better. pc_memory_init already has too many arguments, moving them to PcGuestInfo (which ultimately might become properties of the /machine QOM object) is the right thing to do. In general I agree. But unless there is plans to reuse gb_align in future, it doesn't really belong to PcGuestInfo (this change however looks like cannibalizing structure for argument passing only). Paolo +unsigned long holesize = 0x1ULL - below_4g_mem_size; + +memory_region_init_alias(ram_above_4g, NULL, ram-above-4g, ram, +0x1ULL, +above_4g_mem_size - holesize); +memory_region_add_subregion(system_memory, 0x1ULL, ram_above_4g); [...] diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 6083839..00afe4a 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -20,6 +20,7 @@ typedef struct PcPciInfo { struct PcGuestInfo { bool has_pci_info; bool isapc_ram_fw; +bool gb_align; FWCfgState *fw_cfg; }; it doesn't apply anymore.
[Qemu-devel] [PATCH 2/3] COW: Extend checking allocated bits to beyond one sector
cow_co_is_allocated() only checks one sector's worth of allocated bits before returning. This is allowed but (slightly) inefficient, so extend it to check all of the file's metadata sectors. Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- block/cow.c | 36 ++-- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/block/cow.c b/block/cow.c index 66f1478..4a081cb 100644 --- a/block/cow.c +++ b/block/cow.c @@ -152,18 +152,34 @@ static int coroutine_fn cow_co_is_allocated(BlockDriverState *bs, { int64_t bitnum = sector_num + sizeof(struct cow_header_v2) * 8; uint64_t offset = (bitnum / 8) -BDRV_SECTOR_SIZE; -uint8_t bitmap[BDRV_SECTOR_SIZE]; -int ret; -int changed; +bool first = true; +int changed, same = 0; -ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); -if (ret 0) { -return ret; -} +do { +int ret; +uint8_t bitmap[BDRV_SECTOR_SIZE]; + +bitnum = BITS_PER_BITMAP_SECTOR - 1; +int sector_bits = MIN(nb_sectors, BITS_PER_BITMAP_SECTOR - bitnum); + +ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); +if (ret 0) { +return ret; +} + +if (first) { +changed = cow_test_bit(bitnum, bitmap); +first = false; +} + +same += cow_find_streak(bitmap, changed, bitnum, nb_sectors); + +bitnum += sector_bits; +nb_sectors -= sector_bits; +offset += BDRV_SECTOR_SIZE; +} while (nb_sectors); -bitnum = BITS_PER_BITMAP_SECTOR - 1; -changed = cow_test_bit(bitnum, bitmap); -*num_same = cow_find_streak(bitmap, changed, bitnum, nb_sectors); +*num_same = same; return changed; } -- 1.8.4.rc3
[Qemu-devel] [PATCH 1/3] COW: Speed up writes
Process a whole sector's worth of COW bits by reading a sector, setting the bits, then writing it out again. Make sure we only flush once, before writing metadata. Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- block/cow.c | 79 - 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/block/cow.c b/block/cow.c index 909c3e7..66f1478 100644 --- a/block/cow.c +++ b/block/cow.c @@ -103,40 +103,18 @@ static int cow_open(BlockDriverState *bs, QDict *options, int flags, return ret; } -/* - * XXX(hch): right now these functions are extremely inefficient. - * We should just read the whole bitmap we'll need in one go instead. - */ -static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum, bool *first) +static inline void cow_set_bits(uint8_t *bitmap, int start, int64_t nb_sectors) { -uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8; -uint8_t bitmap; -int ret; - -ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); -if (ret 0) { - return ret; -} - -if (bitmap (1 (bitnum % 8))) { -return 0; -} - -if (*first) { -ret = bdrv_flush(bs-file); -if (ret 0) { -return ret; +int64_t bitnum = start, last = start + nb_sectors; +while (bitnum last) { +if ((bitnum 7) == 0) { +bitmap[bitnum / 8] = 0xFF; +bitnum += 8; +continue; } -*first = false; -} - -bitmap |= (1 (bitnum % 8)); - -ret = bdrv_pwrite(bs-file, offset, bitmap, sizeof(bitmap)); -if (ret 0) { - return ret; +bitmap[bitnum/8] |= (1 (bitnum % 8)); +bitnum++; } -return 0; } #define BITS_PER_BITMAP_SECTOR (512 * 8) @@ -204,18 +182,43 @@ static int64_t coroutine_fn cow_co_get_block_status(BlockDriverState *bs, static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { -int error = 0; -int i; +int64_t bitnum = sector_num + sizeof(struct cow_header_v2) * 8; +uint64_t offset = (bitnum / 8) -BDRV_SECTOR_SIZE; bool first = true; -for (i = 0; i nb_sectors; i++) { -error = cow_set_bit(bs, sector_num + i, first); -if (error) { -break; +while (nb_sectors) { +int ret; +uint8_t bitmap[BDRV_SECTOR_SIZE]; + +bitnum = BITS_PER_BITMAP_SECTOR - 1; +int sector_bits = MIN(nb_sectors, BITS_PER_BITMAP_SECTOR - bitnum); + +ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); +if (ret 0) { +return ret; } + +if (first) { +ret = bdrv_flush(bs-file); +if (ret 0) { +return ret; +} +first = false; +} + +cow_set_bits(bitmap, bitnum, sector_bits); + +ret = bdrv_pwrite(bs-file, offset, bitmap, sizeof(bitmap)); +if (ret 0) { +return ret; +} + +bitnum += sector_bits; +nb_sectors -= sector_bits; +offset += BDRV_SECTOR_SIZE; } -return error; +return 0; } static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num, -- 1.8.4.rc3
[Qemu-devel] [PATCH 0/3] COW: Speed up writes
Following on from Paolo's commits 26ae980 and 276cbc7, this patchset implements some changes he recommended earlier which I didn't previously have time to do while on GSoC. Patch 2 was written initially I was intending to use cow_co_is_allocated in Patch 3 and needed it to consider all sectors but in the end cow_find_streak was sufficient, so it may not strictly be necessary. Charlie Shepherd (3): COW: Speed up writes COW: Extend checking allocated bits to beyond one sector COW: Skip setting already set bits block/cow.c | 122 1 file changed, 74 insertions(+), 48 deletions(-) -- 1.8.4.rc3
[Qemu-devel] [PATCH 3/3] COW: Skip setting already set bits
Rather than unnecessarily setting bits that are already set, re-use cow_find_streak to find how many bits are already set for this sector, and only set unset bits. Do this before the flush to avoid it if no bits need to be set at all. Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- block/cow.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/block/cow.c b/block/cow.c index 4a081cb..d7d992b 100644 --- a/block/cow.c +++ b/block/cow.c @@ -203,7 +203,7 @@ static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, bool first = true; while (nb_sectors) { -int ret; +int ret, set; uint8_t bitmap[BDRV_SECTOR_SIZE]; bitnum = BITS_PER_BITMAP_SECTOR - 1; @@ -214,6 +214,13 @@ static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, return ret; } +/* Skip over any already set bits */ +set = cow_find_streak(bitmap, 1, bitnum, sector_bits); +if (set == sector_bits) { +continue; +} +bitnum += set; + if (first) { ret = bdrv_flush(bs-file); if (ret 0) { -- 1.8.4.rc3
Re: [Qemu-devel] i386: pc: align gpa-hpa on 1GB boundary (v3)
Il 06/11/2013 13:22, Igor Mammedov ha scritto: 'gb_align' is one shot usage, it would be better to just add it as an argument to pc_memory_init(). That would allow to avoid extending PcGuestInfo needlessly, since gb_align isn't reused. No, Marcelo's way is better. pc_memory_init already has too many arguments, moving them to PcGuestInfo (which ultimately might become properties of the /machine QOM object) is the right thing to do. In general I agree. But unless there is plans to reuse gb_align in future, The plan is to turn it (and also has_acpi_build etc.) into a global property that can be set using the usual compat-property machinery. it doesn't really belong to PcGuestInfo (this change however looks like cannibalizing structure for argument passing only). For now, it doesn't just look like that, it is like that. :) But it is still a step in the right direction. Paolo
Re: [Qemu-devel] [PATCH 1/3] COW: Speed up writes
Il 06/11/2013 13:23, Charlie Shepherd ha scritto: Process a whole sector's worth of COW bits by reading a sector, setting the bits, then writing it out again. Make sure we only flush once, before writing metadata. Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- block/cow.c | 79 - 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/block/cow.c b/block/cow.c index 909c3e7..66f1478 100644 --- a/block/cow.c +++ b/block/cow.c @@ -103,40 +103,18 @@ static int cow_open(BlockDriverState *bs, QDict *options, int flags, return ret; } -/* - * XXX(hch): right now these functions are extremely inefficient. - * We should just read the whole bitmap we'll need in one go instead. - */ -static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum, bool *first) +static inline void cow_set_bits(uint8_t *bitmap, int start, int64_t nb_sectors) { -uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8; -uint8_t bitmap; -int ret; - -ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); -if (ret 0) { - return ret; -} - -if (bitmap (1 (bitnum % 8))) { -return 0; -} - -if (*first) { -ret = bdrv_flush(bs-file); -if (ret 0) { -return ret; +int64_t bitnum = start, last = start + nb_sectors; +while (bitnum last) { +if ((bitnum 7) == 0) { I think this is missing bitnum + 8 = last in the condition. Otherwise looks good. Paolo +bitmap[bitnum / 8] = 0xFF; +bitnum += 8; +continue; } -*first = false; -} - -bitmap |= (1 (bitnum % 8)); - -ret = bdrv_pwrite(bs-file, offset, bitmap, sizeof(bitmap)); -if (ret 0) { - return ret; +bitmap[bitnum/8] |= (1 (bitnum % 8)); +bitnum++; } -return 0; } #define BITS_PER_BITMAP_SECTOR (512 * 8) @@ -204,18 +182,43 @@ static int64_t coroutine_fn cow_co_get_block_status(BlockDriverState *bs, static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { -int error = 0; -int i; +int64_t bitnum = sector_num + sizeof(struct cow_header_v2) * 8; +uint64_t offset = (bitnum / 8) -BDRV_SECTOR_SIZE; bool first = true; -for (i = 0; i nb_sectors; i++) { -error = cow_set_bit(bs, sector_num + i, first); -if (error) { -break; +while (nb_sectors) { +int ret; +uint8_t bitmap[BDRV_SECTOR_SIZE]; + +bitnum = BITS_PER_BITMAP_SECTOR - 1; +int sector_bits = MIN(nb_sectors, BITS_PER_BITMAP_SECTOR - bitnum); + +ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); +if (ret 0) { +return ret; } + +if (first) { +ret = bdrv_flush(bs-file); +if (ret 0) { +return ret; +} +first = false; +} + +cow_set_bits(bitmap, bitnum, sector_bits); + +ret = bdrv_pwrite(bs-file, offset, bitmap, sizeof(bitmap)); +if (ret 0) { +return ret; +} + +bitnum += sector_bits; +nb_sectors -= sector_bits; +offset += BDRV_SECTOR_SIZE; } -return error; +return 0; } static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num,
Re: [Qemu-devel] [PATCH 3/3] COW: Skip setting already set bits
Il 06/11/2013 13:23, Charlie Shepherd ha scritto: +set = cow_find_streak(bitmap, 1, bitnum, sector_bits); +if (set == sector_bits) { +continue; I think this shouldn't be a continue; these lines should be executed: bitnum += sector_bits; nb_sectors -= sector_bits; offset += BDRV_SECTOR_SIZE; +} +bitnum += set; Here you're adjusting bitnum but not nb_sectors and sector_bits. Paolo
Re: [Qemu-devel] [PATCH 2/3] COW: Extend checking allocated bits to beyond one sector
Il 06/11/2013 13:23, Charlie Shepherd ha scritto: cow_co_is_allocated() only checks one sector's worth of allocated bits before returning. This is allowed but (slightly) inefficient, so extend it to check all of the file's metadata sectors. Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- block/cow.c | 36 ++-- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/block/cow.c b/block/cow.c index 66f1478..4a081cb 100644 --- a/block/cow.c +++ b/block/cow.c @@ -152,18 +152,34 @@ static int coroutine_fn cow_co_is_allocated(BlockDriverState *bs, { int64_t bitnum = sector_num + sizeof(struct cow_header_v2) * 8; uint64_t offset = (bitnum / 8) -BDRV_SECTOR_SIZE; -uint8_t bitmap[BDRV_SECTOR_SIZE]; -int ret; -int changed; +bool first = true; +int changed, same = 0; -ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); -if (ret 0) { -return ret; -} +do { +int ret; +uint8_t bitmap[BDRV_SECTOR_SIZE]; + +bitnum = BITS_PER_BITMAP_SECTOR - 1; +int sector_bits = MIN(nb_sectors, BITS_PER_BITMAP_SECTOR - bitnum); + +ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); +if (ret 0) { +return ret; +} + +if (first) { +changed = cow_test_bit(bitnum, bitmap); +first = false; +} + +same += cow_find_streak(bitmap, changed, bitnum, nb_sectors); + +bitnum += sector_bits; +nb_sectors -= sector_bits; +offset += BDRV_SECTOR_SIZE; +} while (nb_sectors); -bitnum = BITS_PER_BITMAP_SECTOR - 1; -changed = cow_test_bit(bitnum, bitmap); -*num_same = cow_find_streak(bitmap, changed, bitnum, nb_sectors); +*num_same = same; return changed; } This one is good. Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Re: [Qemu-devel] [PATCH 3/3] COW: Skip setting already set bits
On 06/11/2013 12:29, Paolo Bonzini wrote: Il 06/11/2013 13:23, Charlie Shepherd ha scritto: +set = cow_find_streak(bitmap, 1, bitnum, sector_bits); +if (set == sector_bits) { +continue; I think this shouldn't be a continue; these lines should be executed: bitnum += sector_bits; nb_sectors -= sector_bits; offset += BDRV_SECTOR_SIZE; Good point, this is basically a poor man's for-loop. I'll turn it into a for loop then continue will make sense here. +} +bitnum += set; Here you're adjusting bitnum but not nb_sectors and sector_bits. Good catch. Charlie
Re: [Qemu-devel] [Qemu-trivial] [PATCH v6] .travis.yml: basic compile and check recipes
06.11.2013 14:43, alex.ben...@linaro.org wrote: From: Alex Bennée a...@bennee.com This adds a build matrix definition for travis-ci.org [] Thanks, applied to the trivial-patches queue. With one tiny fix -- removed trailing whitespace in the line - TARGETS=m68k-softmmu /mjt
Re: [Qemu-devel] [PATCH 0/3] COW: Speed up writes
Il 06/11/2013 13:23, Charlie Shepherd ha scritto: Patch 2 was written initially I was intending to use cow_co_is_allocated in Patch 3 and needed it to consider all sectors but in the end cow_find_streak was sufficient, so it may not strictly be necessary. Patch 2 can still speed up reads that cross a sector boundary from 4 I/O operations (2 for the bitmap, 2 for the data) to 3 (only 1 for the data). Paolo
Re: [Qemu-devel] [PATCH v2 5/6] xilinx_zynq: add pl353
Hi, I want to emulate PL35x SMC controller with Nand flash as a device. Though I got the patch from the following link. http://qemu.11.n7.nabble.com/Qemu-devel-PATCH-v1-0-7-QOMify-pflash-cfi0x-PL353-for-Xilinx-Zynq-td167995.html. I dont know how to test the nand flash with the SMC controller. Please can you guide me if it is possible. Thanks in advance Balaji. -- View this message in context: http://qemu.11.n7.nabble.com/Qemu-devel-PATCH-v2-0-6-QOMify-pflash-cfi0x-PL353-for-Xilinx-Zynq-tp168323p232520.html Sent from the Developer mailing list archive at Nabble.com.
Re: [Qemu-devel] [PATCH] block/vpc: fix virtual size for images created with disk2vhd
On Mon, Oct 21, 2013 at 04:00:18PM +0200, Peter Lieven wrote: Signed-off-by: Peter Lieven p...@kamp.de --- block/vpc.c |9 + 1 file changed, 9 insertions(+) Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan
[Qemu-devel] [PATCH for-1.7 v2] pc: disable pci-info
The BIOS that we ship in 1.7 does not use pci info from host and so far isn't going to use it. Taking in account problems it caused see 9604f70fdf and to avoid future incompatibility issues, it's safest to disable that interface by default for all machine types including 1.7 as it was never exposed/used by guest. And properly remove/cleanup it during 1.8 development cycle. Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Reviewed-by: Eduardo Habkost ehabk...@redhat.com --- v2: rebased after ACPI tables series merge caused conflicts --- hw/i386/pc_piix.c | 2 +- hw/i386/pc_q35.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 4fdb7b6..094c421 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -58,7 +58,7 @@ static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; static bool has_pvpanic; -static bool has_pci_info = true; +static bool has_pci_info; static bool has_acpi_build = true; /* PC hardware initialisation */ diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 4c191d3..1af8e2b 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -48,7 +48,7 @@ #define MAX_SATA_PORTS 6 static bool has_pvpanic; -static bool has_pci_info = true; +static bool has_pci_info; static bool has_acpi_build = true; /* PC hardware initialisation */ -- 1.8.3.1
[Qemu-devel] [PATCH v2 2/3] COW: Extend checking allocated bits to beyond one sector
cow_co_is_allocated() only checks one sector's worth of allocated bits before returning. This is allowed but (slightly) inefficient, so extend it to check all of the file's metadata sectors. Signed-off-by: Charlie Shepherd char...@ctshepherd.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com --- block/cow.c | 36 ++-- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/block/cow.c b/block/cow.c index 5dfffb0..41097d8 100644 --- a/block/cow.c +++ b/block/cow.c @@ -152,18 +152,34 @@ static int coroutine_fn cow_co_is_allocated(BlockDriverState *bs, { int64_t bitnum = sector_num + sizeof(struct cow_header_v2) * 8; uint64_t offset = (bitnum / 8) -BDRV_SECTOR_SIZE; -uint8_t bitmap[BDRV_SECTOR_SIZE]; -int ret; -int changed; +bool first = true; +int changed, same = 0; -ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); -if (ret 0) { -return ret; -} +do { +int ret; +uint8_t bitmap[BDRV_SECTOR_SIZE]; + +bitnum = BITS_PER_BITMAP_SECTOR - 1; +int sector_bits = MIN(nb_sectors, BITS_PER_BITMAP_SECTOR - bitnum); + +ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); +if (ret 0) { +return ret; +} + +if (first) { +changed = cow_test_bit(bitnum, bitmap); +first = false; +} + +same += cow_find_streak(bitmap, changed, bitnum, nb_sectors); + +bitnum += sector_bits; +nb_sectors -= sector_bits; +offset += BDRV_SECTOR_SIZE; +} while (nb_sectors); -bitnum = BITS_PER_BITMAP_SECTOR - 1; -changed = cow_test_bit(bitnum, bitmap); -*num_same = cow_find_streak(bitmap, changed, bitnum, nb_sectors); +*num_same = same; return changed; } -- 1.8.4.rc3
[Qemu-devel] [PATCH v2 3/3] COW: Skip setting already set bits
Rather than unnecessarily setting bits that are already set, re-use cow_find_streak to find how many bits are already set for this sector, and only set unset bits. Do this before the flush to avoid it if no bits need to be set at all. Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- block/cow.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/block/cow.c b/block/cow.c index 41097d8..93207eb 100644 --- a/block/cow.c +++ b/block/cow.c @@ -203,7 +203,7 @@ static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, bool first = true; while (nb_sectors) { -int ret; +int ret, set; uint8_t bitmap[BDRV_SECTOR_SIZE]; bitnum = BITS_PER_BITMAP_SECTOR - 1; @@ -214,6 +214,15 @@ static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, return ret; } +/* Skip over any already set bits */ +set = cow_find_streak(bitmap, 1, bitnum, sector_bits); +bitnum += set; +sector_bits -= set; +nb_sectors -= set; +if (set == sector_bits) { +continue; +} + if (first) { ret = bdrv_flush(bs-file); if (ret 0) { @@ -228,7 +237,6 @@ static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, if (ret 0) { return ret; } - bitnum += sector_bits; nb_sectors -= sector_bits; offset += BDRV_SECTOR_SIZE; -- 1.8.4.rc3
[Qemu-devel] [PATCH v2 1/3] COW: Speed up writes
Process a whole sector's worth of COW bits by reading a sector, setting the bits, then writing it out again. Make sure we only flush once, before writing metadata. Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- block/cow.c | 79 - 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/block/cow.c b/block/cow.c index 909c3e7..5dfffb0 100644 --- a/block/cow.c +++ b/block/cow.c @@ -103,40 +103,18 @@ static int cow_open(BlockDriverState *bs, QDict *options, int flags, return ret; } -/* - * XXX(hch): right now these functions are extremely inefficient. - * We should just read the whole bitmap we'll need in one go instead. - */ -static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum, bool *first) +static inline void cow_set_bits(uint8_t *bitmap, int start, int64_t nb_sectors) { -uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8; -uint8_t bitmap; -int ret; - -ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); -if (ret 0) { - return ret; -} - -if (bitmap (1 (bitnum % 8))) { -return 0; -} - -if (*first) { -ret = bdrv_flush(bs-file); -if (ret 0) { -return ret; +int64_t bitnum = start, last = start + nb_sectors; +while (bitnum last) { +if ((bitnum 7) == 0 bitnum + 8 = last) { +bitmap[bitnum / 8] = 0xFF; +bitnum += 8; +continue; } -*first = false; -} - -bitmap |= (1 (bitnum % 8)); - -ret = bdrv_pwrite(bs-file, offset, bitmap, sizeof(bitmap)); -if (ret 0) { - return ret; +bitmap[bitnum/8] |= (1 (bitnum % 8)); +bitnum++; } -return 0; } #define BITS_PER_BITMAP_SECTOR (512 * 8) @@ -204,18 +182,43 @@ static int64_t coroutine_fn cow_co_get_block_status(BlockDriverState *bs, static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { -int error = 0; -int i; +int64_t bitnum = sector_num + sizeof(struct cow_header_v2) * 8; +uint64_t offset = (bitnum / 8) -BDRV_SECTOR_SIZE; bool first = true; -for (i = 0; i nb_sectors; i++) { -error = cow_set_bit(bs, sector_num + i, first); -if (error) { -break; +while (nb_sectors) { +int ret; +uint8_t bitmap[BDRV_SECTOR_SIZE]; + +bitnum = BITS_PER_BITMAP_SECTOR - 1; +int sector_bits = MIN(nb_sectors, BITS_PER_BITMAP_SECTOR - bitnum); + +ret = bdrv_pread(bs-file, offset, bitmap, sizeof(bitmap)); +if (ret 0) { +return ret; } + +if (first) { +ret = bdrv_flush(bs-file); +if (ret 0) { +return ret; +} +first = false; +} + +cow_set_bits(bitmap, bitnum, sector_bits); + +ret = bdrv_pwrite(bs-file, offset, bitmap, sizeof(bitmap)); +if (ret 0) { +return ret; +} + +bitnum += sector_bits; +nb_sectors -= sector_bits; +offset += BDRV_SECTOR_SIZE; } -return error; +return 0; } static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num, -- 1.8.4.rc3
[Qemu-devel] [PATCH v2 0/3] COW: Speed up writes
v2: - Fix bit position calculations in cow_update_bitmap - Add necessary check in cow_set_bits Following on from Paolo's commits 26ae980 and 276cbc7, this patchset implements some changes he recommended earlier which I didn't previously have time to do while on GSoC. Charlie Shepherd (3): COW: Speed up writes COW: Extend checking allocated bits to beyond one sector COW: Skip setting already set bits block/cow.c | 123 1 file changed, 75 insertions(+), 48 deletions(-) -- 1.8.4.rc3
Re: [Qemu-devel] [PATCH v2 3/3] COW: Skip setting already set bits
Il 06/11/2013 13:56, Charlie Shepherd ha scritto: Rather than unnecessarily setting bits that are already set, re-use cow_find_streak to find how many bits are already set for this sector, and only set unset bits. Do this before the flush to avoid it if no bits need to be set at all. Signed-off-by: Charlie Shepherd char...@ctshepherd.com --- block/cow.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/block/cow.c b/block/cow.c index 41097d8..93207eb 100644 --- a/block/cow.c +++ b/block/cow.c @@ -203,7 +203,7 @@ static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, bool first = true; while (nb_sectors) { You still need to make this a for and put offset += BDRV_SECTOR_SIZE in the third clause. -int ret; +int ret, set; uint8_t bitmap[BDRV_SECTOR_SIZE]; bitnum = BITS_PER_BITMAP_SECTOR - 1; @@ -214,6 +214,15 @@ static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, return ret; } +/* Skip over any already set bits */ +set = cow_find_streak(bitmap, 1, bitnum, sector_bits); +bitnum += set; +sector_bits -= set; +nb_sectors -= set; +if (set == sector_bits) { +continue; +} This now has to be if (set == 0). With the change to the for above, that's correct. if (first) { ret = bdrv_flush(bs-file); if (ret 0) { @@ -228,7 +237,6 @@ static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num, if (ret 0) { return ret; } - bitnum += sector_bits; nb_sectors -= sector_bits; offset += BDRV_SECTOR_SIZE; I also noticed that patch 1 introduces a small regression, in that it will always flush data even if the metadata doesn't change. This patch fixes it, because the bdrv_flush is preceded by the check to skip over any already set bits. So I suggest that, together with the above fixes, you squash patches 1 and 3 together. Paolo
[Qemu-devel] [PATCH 08/39] exec: simplify notdirty_mem_write()
We don't need to make special things for CODE, just set the other two bits Signed-off-by: Juan Quintela quint...@redhat.com --- exec.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/exec.c b/exec.c index 36b0a66..27e4540 100644 --- a/exec.c +++ b/exec.c @@ -1374,12 +1374,8 @@ found: static void notdirty_mem_write(void *opaque, hwaddr ram_addr, uint64_t val, unsigned size) { - -int dirty_flags; -dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); if (!cpu_physical_memory_get_dirty_flag(ram_addr, CODE_DIRTY_FLAG)) { tb_invalidate_phys_page_fast(ram_addr, size); -dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); } switch (size) { case 1: @@ -1394,8 +1390,8 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr, default: abort(); } -dirty_flags |= (0xff ~CODE_DIRTY_FLAG); -cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags); +cpu_physical_memory_set_dirty_flag(ram_addr, MIGRATION_DIRTY_FLAG); +cpu_physical_memory_set_dirty_flag(ram_addr, VGA_DIRTY_FLAG); /* we remove the notdirty callback only if the code has been flushed */ if (cpu_physical_memory_is_dirty(ram_addr)) { -- 1.8.3.1
[Qemu-devel] [PATCH 06/39] exec: create function to get a single dirty bit
Signed-off-by: Juan Quintela quint...@redhat.com --- exec.c | 3 ++- include/exec/memory-internal.h | 6 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/exec.c b/exec.c index 7cf5634..36b0a66 100644 --- a/exec.c +++ b/exec.c @@ -1374,9 +1374,10 @@ found: static void notdirty_mem_write(void *opaque, hwaddr ram_addr, uint64_t val, unsigned size) { + int dirty_flags; dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); -if (!(dirty_flags CODE_DIRTY_FLAG)) { +if (!cpu_physical_memory_get_dirty_flag(ram_addr, CODE_DIRTY_FLAG)) { tb_invalidate_phys_page_fast(ram_addr, size); dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); } diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 4ebab80..9cd2f53 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -49,6 +49,12 @@ static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr) return ram_list.phys_dirty[addr TARGET_PAGE_BITS]; } +static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, + int dirty_flag) +{ +return ram_list.phys_dirty[addr TARGET_PAGE_BITS] dirty_flag; +} + /* read dirty bit (return 0 or 1) */ static inline int cpu_physical_memory_is_dirty(ram_addr_t addr) { -- 1.8.3.1
[Qemu-devel] [PATCH 02/39] memory: cpu_physical_memory_set_dirty_flags() result is never used
So return void. Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index d0e0633..c71a5e6 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -70,10 +70,10 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t start, return ret; } -static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr, +static inline void cpu_physical_memory_set_dirty_flags(ram_addr_t addr, int dirty_flags) { -return ram_list.phys_dirty[addr TARGET_PAGE_BITS] |= dirty_flags; +ram_list.phys_dirty[addr TARGET_PAGE_BITS] |= dirty_flags; } static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) -- 1.8.3.1
[Qemu-devel] [PATCH 05/39] memory: create function to set a single dirty bit
Signed-off-by: Juan Quintela quint...@redhat.com --- cputlb.c | 2 +- include/exec/memory-internal.h | 6 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cputlb.c b/cputlb.c index fff0afb..72452e5 100644 --- a/cputlb.c +++ b/cputlb.c @@ -137,7 +137,7 @@ void tlb_protect_code(ram_addr_t ram_addr) void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr, target_ulong vaddr) { -cpu_physical_memory_set_dirty_flags(ram_addr, CODE_DIRTY_FLAG); +cpu_physical_memory_set_dirty_flag(ram_addr, CODE_DIRTY_FLAG); } static bool tlb_is_dirty_ram(CPUTLBEntry *tlbe) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index c71a5e6..4ebab80 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -76,6 +76,12 @@ static inline void cpu_physical_memory_set_dirty_flags(ram_addr_t addr, ram_list.phys_dirty[addr TARGET_PAGE_BITS] |= dirty_flags; } +static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, + int dirty_flag) +{ +ram_list.phys_dirty[addr TARGET_PAGE_BITS] |= dirty_flag; +} + static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) { cpu_physical_memory_set_dirty_flags(addr, 0xff); -- 1.8.3.1
[Qemu-devel] [PATCH 04/39] exec: use accessor function to know if memory is dirty
Signed-off-by: Juan Quintela quint...@redhat.com --- exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exec.c b/exec.c index 79610ce..7cf5634 100644 --- a/exec.c +++ b/exec.c @@ -1397,7 +1397,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr, cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags); /* we remove the notdirty callback only if the code has been flushed */ -if (dirty_flags == 0xff) { +if (cpu_physical_memory_is_dirty(ram_addr)) { CPUArchState *env = current_cpu-env_ptr; tlb_set_dirty(env, env-mem_io_vaddr); } -- 1.8.3.1
[Qemu-devel] [PATCH 07/39] memory: make cpu_physical_memory_is_dirty return bool
Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-internal.h | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 9cd2f53..eefe501 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -56,9 +56,12 @@ static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, } /* read dirty bit (return 0 or 1) */ -static inline int cpu_physical_memory_is_dirty(ram_addr_t addr) +static inline bool cpu_physical_memory_is_dirty(ram_addr_t addr) { -return cpu_physical_memory_get_dirty_flags(addr) == 0xff; +bool vga = cpu_physical_memory_get_dirty_flag(addr, VGA_DIRTY_FLAG); +bool code = cpu_physical_memory_get_dirty_flag(addr, CODE_DIRTY_FLAG); +bool migration = cpu_physical_memory_get_dirty_flag(addr, MIGRATION_DIRTY_FLAG); +return vga code migration; } static inline int cpu_physical_memory_get_dirty(ram_addr_t start, -- 1.8.3.1
[Qemu-devel] [PATCH 12/39] memory: cpu_physical_memory_mask_dirty_range() always clear a single flag
Document it Signed-off-by: Juan Quintela quint...@redhat.com --- exec.c | 4 ++-- include/exec/memory-internal.h | 12 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/exec.c b/exec.c index 3fd7616..94076ae 100644 --- a/exec.c +++ b/exec.c @@ -662,7 +662,7 @@ static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t end, /* Note: start and end must be within the same ram block. */ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, - int dirty_flags) + int dirty_flag) { uintptr_t length; @@ -672,7 +672,7 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, length = end - start; if (length == 0) return; -cpu_physical_memory_mask_dirty_range(start, length, dirty_flags); +cpu_physical_memory_mask_dirty_range(start, length, dirty_flag); if (tcg_enabled()) { tlb_reset_dirty_range_all(start, end, length); diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index e3b5834..cfe1a24 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -87,10 +87,10 @@ static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) cpu_physical_memory_set_dirty_flag(addr, CODE_DIRTY_FLAG); } -static inline int cpu_physical_memory_clear_dirty_flags(ram_addr_t addr, -int dirty_flags) +static inline int cpu_physical_memory_clear_dirty_flag(ram_addr_t addr, + int dirty_flag) { -int mask = ~dirty_flags; +int mask = ~dirty_flag; return ram_list.phys_dirty[addr TARGET_PAGE_BITS] = mask; } @@ -110,19 +110,19 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, ram_addr_t length, -int dirty_flags) +int dirty_flag) { ram_addr_t addr, end; end = TARGET_PAGE_ALIGN(start + length); start = TARGET_PAGE_MASK; for (addr = start; addr end; addr += TARGET_PAGE_SIZE) { -cpu_physical_memory_clear_dirty_flags(addr, dirty_flags); +cpu_physical_memory_clear_dirty_flag(addr, dirty_flag); } } void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, - int dirty_flags); + int dirty_flag); #endif -- 1.8.3.1
[Qemu-devel] [PATCH 03/39] memory: cpu_physical_memory_set_dirty_range() return void
Signed-off-by: Juan Quintela quint...@redhat.com --- memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/memory.c b/memory.c index 28f6449..9722f23 100644 --- a/memory.c +++ b/memory.c @@ -1182,7 +1182,7 @@ void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size) { assert(mr-terminates); -return cpu_physical_memory_set_dirty_range(mr-ram_addr + addr, size, -1); +cpu_physical_memory_set_dirty_range(mr-ram_addr + addr, size, -1); } bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr, -- 1.8.3.1
[Qemu-devel] [PATCH 20/39] memory: unfold cpu_physical_memory_clear_dirty_flag() in its only user
Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-internal.h | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 71f198e..d6d3537 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -86,12 +86,6 @@ static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) cpu_physical_memory_set_dirty_flag(addr, DIRTY_MEMORY_CODE); } -static inline void cpu_physical_memory_clear_dirty_flag(ram_addr_t addr, - unsigned client) -{ -clear_bit(addr TARGET_PAGE_BITS, ram_list.dirty_memory[client]); -} - static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, ram_addr_t length) { @@ -114,7 +108,7 @@ static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, end = TARGET_PAGE_ALIGN(start + length); start = TARGET_PAGE_MASK; for (addr = start; addr end; addr += TARGET_PAGE_SIZE) { -cpu_physical_memory_clear_dirty_flag(addr, client); +clear_bit(addr TARGET_PAGE_BITS, ram_list.dirty_memory[client]); } } -- 1.8.3.1
[Qemu-devel] [PATCH 15/39] memory: make sure that client is always inside range
Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-internal.h | 4 1 file changed, 4 insertions(+) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 3947caa..e08ac42 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -43,6 +43,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr); static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, unsigned client) { +assert(client DIRTY_MEMORY_NUM); return ram_list.phys_dirty[addr TARGET_PAGE_BITS] (1 client); } @@ -73,6 +74,7 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t start, static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, unsigned client) { +assert(client DIRTY_MEMORY_NUM); ram_list.phys_dirty[addr TARGET_PAGE_BITS] |= (1 client); } @@ -88,6 +90,8 @@ static inline int cpu_physical_memory_clear_dirty_flag(ram_addr_t addr, { int mask = ~(1 client); +assert(client DIRTY_MEMORY_NUM); + return ram_list.phys_dirty[addr TARGET_PAGE_BITS] = mask; } -- 1.8.3.1
[Qemu-devel] [PATCH 13/39] memory: use DIRTY_MEMORY_* instead of *_DIRTY_FLAG
Instead of the bitmap, we use the bitmap number. Once this is done, we change all names from dirty_flag to memory regions naming of client. Signed-off-by: Juan Quintela quint...@redhat.com --- cputlb.c | 4 ++-- exec.c | 18 +- include/exec/memory-internal.h | 38 +- include/exec/memory.h | 3 --- memory.c | 10 -- 5 files changed, 32 insertions(+), 41 deletions(-) diff --git a/cputlb.c b/cputlb.c index 72452e5..dfd747a 100644 --- a/cputlb.c +++ b/cputlb.c @@ -129,7 +129,7 @@ void tlb_protect_code(ram_addr_t ram_addr) { cpu_physical_memory_reset_dirty(ram_addr, ram_addr + TARGET_PAGE_SIZE, -CODE_DIRTY_FLAG); +DIRTY_MEMORY_CODE); } /* update the TLB so that writes in physical page 'phys_addr' are no longer @@ -137,7 +137,7 @@ void tlb_protect_code(ram_addr_t ram_addr) void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr, target_ulong vaddr) { -cpu_physical_memory_set_dirty_flag(ram_addr, CODE_DIRTY_FLAG); +cpu_physical_memory_set_dirty_flag(ram_addr, DIRTY_MEMORY_CODE); } static bool tlb_is_dirty_ram(CPUTLBEntry *tlbe) diff --git a/exec.c b/exec.c index 94076ae..64a621f 100644 --- a/exec.c +++ b/exec.c @@ -662,7 +662,7 @@ static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t end, /* Note: start and end must be within the same ram block. */ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, - int dirty_flag) + unsigned client) { uintptr_t length; @@ -672,7 +672,7 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, length = end - start; if (length == 0) return; -cpu_physical_memory_mask_dirty_range(start, length, dirty_flag); +cpu_physical_memory_mask_dirty_range(start, length, client); if (tcg_enabled()) { tlb_reset_dirty_range_all(start, end, length); @@ -1374,7 +1374,7 @@ found: static void notdirty_mem_write(void *opaque, hwaddr ram_addr, uint64_t val, unsigned size) { -if (!cpu_physical_memory_get_dirty_flag(ram_addr, CODE_DIRTY_FLAG)) { +if (!cpu_physical_memory_get_dirty_flag(ram_addr, DIRTY_MEMORY_CODE)) { tb_invalidate_phys_page_fast(ram_addr, size); } switch (size) { @@ -1390,8 +1390,8 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr, default: abort(); } -cpu_physical_memory_set_dirty_flag(ram_addr, MIGRATION_DIRTY_FLAG); -cpu_physical_memory_set_dirty_flag(ram_addr, VGA_DIRTY_FLAG); +cpu_physical_memory_set_dirty_flag(ram_addr, DIRTY_MEMORY_MIGRATION); +cpu_physical_memory_set_dirty_flag(ram_addr, DIRTY_MEMORY_VGA); /* we remove the notdirty callback only if the code has been flushed */ if (cpu_physical_memory_is_dirty(ram_addr)) { @@ -1819,8 +1819,8 @@ static void invalidate_and_set_dirty(hwaddr addr, /* invalidate code */ tb_invalidate_phys_page_range(addr, addr + length, 0); /* set dirty bit */ -cpu_physical_memory_set_dirty_flag(addr, VGA_DIRTY_FLAG); -cpu_physical_memory_set_dirty_flag(addr, MIGRATION_DIRTY_FLAG); +cpu_physical_memory_set_dirty_flag(addr, DIRTY_MEMORY_VGA); +cpu_physical_memory_set_dirty_flag(addr, DIRTY_MEMORY_MIGRATION); } xen_modified_memory(addr, length); } @@ -2402,8 +2402,8 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val) /* invalidate code */ tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); /* set dirty bit */ -cpu_physical_memory_set_dirty_flag(addr1, MIGRATION_DIRTY_FLAG); -cpu_physical_memory_set_dirty_flag(addr1, VGA_DIRTY_FLAG); +cpu_physical_memory_set_dirty_flag(addr1, DIRTY_MEMORY_MIGRATION); +cpu_physical_memory_set_dirty_flag(addr1, DIRTY_MEMORY_VGA); } } } diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index cfe1a24..3947caa 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -40,28 +40,24 @@ void *qemu_get_ram_ptr(ram_addr_t addr); void qemu_ram_free(ram_addr_t addr); void qemu_ram_free_from_ptr(ram_addr_t addr); -#define VGA_DIRTY_FLAG 0x01 -#define CODE_DIRTY_FLAG 0x02 -#define MIGRATION_DIRTY_FLAG 0x08 - static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, - int dirty_flag) + unsigned client) { -return ram_list.phys_dirty[addr TARGET_PAGE_BITS] dirty_flag; +return ram_list.phys_dirty[addr TARGET_PAGE_BITS] (1
[Qemu-devel] [PATCH 11/39] memory: cpu_physical_memory_set_dirty_range() allways dirty all flags
So remove the flag argument and do it directly. After this change, there is nothing else using cpu_physical_memory_set_dirty_flags() so remove it. Signed-off-by: Juan Quintela quint...@redhat.com --- exec.c | 2 +- include/exec/memory-internal.h | 11 ++- memory.c | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/exec.c b/exec.c index 0cc7877..3fd7616 100644 --- a/exec.c +++ b/exec.c @@ -1164,7 +1164,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, last_ram_offset() TARGET_PAGE_BITS); memset(ram_list.phys_dirty + (new_block-offset TARGET_PAGE_BITS), 0, size TARGET_PAGE_BITS); -cpu_physical_memory_set_dirty_range(new_block-offset, size, 0xff); +cpu_physical_memory_set_dirty_range(new_block-offset, size); qemu_ram_setup_dump(new_block-host, size); qemu_madvise(new_block-host, size, QEMU_MADV_HUGEPAGE); diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index bfbfc48..e3b5834 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -74,12 +74,6 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t start, return ret; } -static inline void cpu_physical_memory_set_dirty_flags(ram_addr_t addr, - int dirty_flags) -{ -ram_list.phys_dirty[addr TARGET_PAGE_BITS] |= dirty_flags; -} - static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, int dirty_flag) { @@ -102,15 +96,14 @@ static inline int cpu_physical_memory_clear_dirty_flags(ram_addr_t addr, } static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, - ram_addr_t length, - int dirty_flags) + ram_addr_t length) { ram_addr_t addr, end; end = TARGET_PAGE_ALIGN(start + length); start = TARGET_PAGE_MASK; for (addr = start; addr end; addr += TARGET_PAGE_SIZE) { -cpu_physical_memory_set_dirty_flags(addr, dirty_flags); +cpu_physical_memory_set_dirty(addr); } xen_modified_memory(addr, length); } diff --git a/memory.c b/memory.c index 9722f23..08cd07e 100644 --- a/memory.c +++ b/memory.c @@ -1182,7 +1182,7 @@ void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size) { assert(mr-terminates); -cpu_physical_memory_set_dirty_range(mr-ram_addr + addr, size, -1); +cpu_physical_memory_set_dirty_range(mr-ram_addr + addr, size); } bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr, -- 1.8.3.1
[Qemu-devel] [PATCH 24/39] memory: cpu_physical_memory_get_dirty() is used as returning a bool
Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-internal.h | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index f66d2ce..de8f279 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -40,11 +40,10 @@ void *qemu_get_ram_ptr(ram_addr_t addr); void qemu_ram_free(ram_addr_t addr); void qemu_ram_free_from_ptr(ram_addr_t addr); -static inline int cpu_physical_memory_get_dirty(ram_addr_t start, -ram_addr_t length, -unsigned client) +static inline bool cpu_physical_memory_get_dirty(ram_addr_t start, + ram_addr_t length, + unsigned client) { -int ret = 0; ram_addr_t addr, end; assert(client DIRTY_MEMORY_NUM); @@ -52,9 +51,11 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t start, end = TARGET_PAGE_ALIGN(start + length); start = TARGET_PAGE_MASK; for (addr = start; addr end; addr += TARGET_PAGE_SIZE) { -ret |= test_bit(addr TARGET_PAGE_BITS, ram_list.dirty_memory[client]); +if (test_bit(addr TARGET_PAGE_BITS, ram_list.dirty_memory[client])) { +return true; +} } -return ret; +return false; } static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, -- 1.8.3.1
[Qemu-devel] [PATCH 18/39] bitmap: Add bitmap_zero_extend operation
Signed-off-by: Juan Quintela quint...@redhat.com --- include/qemu/bitmap.h | 9 + 1 file changed, 9 insertions(+) diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h index 308bbb7..53f5f1f 100644 --- a/include/qemu/bitmap.h +++ b/include/qemu/bitmap.h @@ -219,4 +219,13 @@ unsigned long bitmap_find_next_zero_area(unsigned long *map, unsigned int nr, unsigned long align_mask); +static inline unsigned long *bitmap_zero_extend(unsigned long *old, +int old_nbits, int new_nbits) +{ +int new_len = BITS_TO_LONGS(new_nbits) * sizeof(unsigned long); +unsigned long *new = g_realloc(old, new_len); +bitmap_clear(new, old_nbits, new_nbits - old_nbits); +return new; +} + #endif /* BITMAP_H */ -- 1.8.3.1
Re: [Qemu-devel] [PATCH] block: Round up total_sectors
Le Wednesday 06 Nov 2013 à 19:48:06 (+0800), Fam Zheng a écrit : Since b94a2610, bdrv_getlength() is omitted when probing image. VMDK monolithicFlat is broken by that because a file 512 bytes can't be read with its total_sectors truncated to 0. This patch round up the size to BDRV_SECTOR_SIZE, when a image size is not sector aligned. Signed-off-by: Fam Zheng f...@redhat.com --- block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block.c b/block.c index 58efb5b..f706634 100644 --- a/block.c +++ b/block.c @@ -640,7 +640,7 @@ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint) if (length 0) { return length; } -hint = length BDRV_SECTOR_BITS; +hint = DIV_ROUND_UP(length, BDRV_SECTOR_SIZE); } bs-total_sectors = hint; -- 1.8.3.1 Reviewed-by: Benoit Canet ben...@irqsave.net
[Qemu-devel] [PATCH 09/39] memory: all users of cpu_physical_memory_get_dirty used only one flag
So cpu_physical_memory_get_dirty_flags is not needed anymore Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-internal.h | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index eefe501..b72c14a 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -44,11 +44,6 @@ void qemu_ram_free_from_ptr(ram_addr_t addr); #define CODE_DIRTY_FLAG 0x02 #define MIGRATION_DIRTY_FLAG 0x08 -static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr) -{ -return ram_list.phys_dirty[addr TARGET_PAGE_BITS]; -} - static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, int dirty_flag) { @@ -66,7 +61,7 @@ static inline bool cpu_physical_memory_is_dirty(ram_addr_t addr) static inline int cpu_physical_memory_get_dirty(ram_addr_t start, ram_addr_t length, -int dirty_flags) +int dirty_flag) { int ret = 0; ram_addr_t addr, end; @@ -74,7 +69,7 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t start, end = TARGET_PAGE_ALIGN(start + length); start = TARGET_PAGE_MASK; for (addr = start; addr end; addr += TARGET_PAGE_SIZE) { -ret |= cpu_physical_memory_get_dirty_flags(addr) dirty_flags; +ret |= cpu_physical_memory_get_dirty_flag(addr, dirty_flag); } return ret; } -- 1.8.3.1
[Qemu-devel] [PATCH 25/39] memory: s/mask/clear/ cpu_physical_memory_mask_dirty_range
Now all functions use the same wording that bitops/bitmap operations Signed-off-by: Juan Quintela quint...@redhat.com --- exec.c | 2 +- include/exec/memory-internal.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exec.c b/exec.c index 98700d3..b95c584 100644 --- a/exec.c +++ b/exec.c @@ -672,7 +672,7 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, length = end - start; if (length == 0) return; -cpu_physical_memory_mask_dirty_range(start, length, client); +cpu_physical_memory_clear_dirty_range(start, length, client); if (tcg_enabled()) { tlb_reset_dirty_range_all(start, end, length); diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index de8f279..0c1dbfa 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -99,9 +99,9 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, xen_modified_memory(addr, length); } -static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, -ram_addr_t length, -unsigned client) +static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start, + ram_addr_t length, + unsigned client) { ram_addr_t addr, end; -- 1.8.3.1
[Qemu-devel] [PATCH 19/39] memory: split dirty bitmap into three
After all the previous patches, spliting the bitmap gets direct. ToDo: Why can't i include exec/memory.h into cpu-all.h? This is the reason that I have duplicated DIRTY_MEMORY_NUM. ToDo2: current bitmaps have one int as index, this limit us to 8TB RAM guest, Should we move to longs? Signed-off-by: Juan Quintela quint...@redhat.com --- exec.c | 9 ++--- include/exec/cpu-all.h | 4 +++- include/exec/memory-internal.h | 11 --- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/exec.c b/exec.c index 38b5c1c..98700d3 100644 --- a/exec.c +++ b/exec.c @@ -1166,9 +1166,12 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, new_ram_size = last_ram_offset() TARGET_PAGE_BITS; if (new_ram_size old_ram_size) { -ram_list.phys_dirty = g_realloc(ram_list.phys_dirty, new_ram_size); -memset(ram_list.phys_dirty + (new_block-offset TARGET_PAGE_BITS), - 0, size TARGET_PAGE_BITS); +int i; +for (i = 0; i DIRTY_MEMORY_NUM; i++) { +ram_list.dirty_memory[i] = +bitmap_zero_extend(ram_list.dirty_memory[i], + old_ram_size, new_ram_size); + } } cpu_physical_memory_set_dirty_range(new_block-offset, size); diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index b6998f0..019dc20 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -456,10 +456,12 @@ typedef struct RAMBlock { int fd; } RAMBlock; +#define DIRTY_MEMORY_NUM 3 + typedef struct RAMList { QemuMutex mutex; /* Protected by the iothread lock. */ -uint8_t *phys_dirty; +unsigned long *dirty_memory[DIRTY_MEMORY_NUM]; RAMBlock *mru_block; /* Protected by the ramlist lock. */ QTAILQ_HEAD(, RAMBlock) blocks; diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 3f885a6..71f198e 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -44,7 +44,7 @@ static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, unsigned client) { assert(client DIRTY_MEMORY_NUM); -return ram_list.phys_dirty[addr TARGET_PAGE_BITS] (1 client); +return test_bit(addr TARGET_PAGE_BITS, ram_list.dirty_memory[client]); } /* read dirty bit (return 0 or 1) */ @@ -75,7 +75,8 @@ static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, unsigned client) { assert(client DIRTY_MEMORY_NUM); -ram_list.phys_dirty[addr TARGET_PAGE_BITS] |= (1 client); + +set_bit(addr TARGET_PAGE_BITS, ram_list.dirty_memory[client]); } static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) @@ -88,11 +89,7 @@ static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) static inline void cpu_physical_memory_clear_dirty_flag(ram_addr_t addr, unsigned client) { -int mask = ~(1 client); - -assert(client DIRTY_MEMORY_NUM); - -ram_list.phys_dirty[addr TARGET_PAGE_BITS] = mask; +clear_bit(addr TARGET_PAGE_BITS, ram_list.dirty_memory[client]); } static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, -- 1.8.3.1
[Qemu-devel] [PATCH 16/39] memory: only resize dirty bitmap when memory size increases
Signed-off-by: Juan Quintela quint...@redhat.com --- exec.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/exec.c b/exec.c index 64a621f..38b5c1c 100644 --- a/exec.c +++ b/exec.c @@ -1100,6 +1100,9 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, MemoryRegion *mr) { RAMBlock *block, *new_block; +ram_addr_t old_ram_size, new_ram_size; + +old_ram_size = last_ram_offset() TARGET_PAGE_BITS; size = TARGET_PAGE_ALIGN(size); new_block = g_malloc0(sizeof(*new_block)); @@ -1160,10 +1163,13 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, ram_list.version++; qemu_mutex_unlock_ramlist(); -ram_list.phys_dirty = g_realloc(ram_list.phys_dirty, - last_ram_offset() TARGET_PAGE_BITS); -memset(ram_list.phys_dirty + (new_block-offset TARGET_PAGE_BITS), +new_ram_size = last_ram_offset() TARGET_PAGE_BITS; + +if (new_ram_size old_ram_size) { +ram_list.phys_dirty = g_realloc(ram_list.phys_dirty, new_ram_size); +memset(ram_list.phys_dirty + (new_block-offset TARGET_PAGE_BITS), 0, size TARGET_PAGE_BITS); +} cpu_physical_memory_set_dirty_range(new_block-offset, size); qemu_ram_setup_dump(new_block-host, size); -- 1.8.3.1
Re: [Qemu-devel] [PATCHv7 00/17] block: logical block provisioning enhancements
On Thu, Oct 24, 2013 at 12:06:49PM +0200, Peter Lieven wrote: this patch adds the ability for targets to stay sparse during block migration (if the zero_blocks capability is set) and qemu-img convert even if the target does not have has_zero_init = 1. the series was especially developed for iSCSI, but it should also work with other drivers with little or no adjustments. these adjustments should be limited to providing block provisioning information through get_block_info and/or honouring BDRV_REQ_MAY_UNMAP on writing zeroes. v6-v7: - switched position of iscsi: set limits in BlockDriverState and iscsi: simplify iscsi_co_discard. (Paolo) - fixed commit message of block/get_block_status: fix BDRV_BLOCK_ZERO for unallocated blocks. (Paolo) - moved block/raw: copy BlockLimits on raw_open right after block: add BlockLimits structure to BlockDriverState. (Paolo) - Reworded desciption for -S 0 in qemu-img: add support for fully allocated images as suggested by Paolo. - Reworded commit message of: qemu-img: conditionally zero out target on convert. regarding iscsi (Paolo) v5-v6: - protected iscsi_co_write_zeroes by the existence of the SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED macro. This is ugly but necessary because the semantic of iscsi_writesame16_task silently changed between libiscsi 1.8.0 and 1.9.0. The above macro was the first added after the change. I already contacted Ronnie to introduce an API version macro which has to be bumped on each new function that will be added. Changes to the parameters should not happen at all of course. v4-v5: - new patches 4-6 to move the block provisioning information to the BlockDriverInfo. - kept 2 wrappers to read the information from the BDI and renamed them to make more clear what they do: bdrv_has_discard_zeroes - bdrv_unallocated_blocks_are_zero bdrv_has_discard_write_zeroes - bdrv_can_write_zeroes_with_unmap - added additional information about the 2 flags in the BDI struct in block.h v3-v4: - changed BlockLimits struct to typedef (Stefan, Eric) - renamed bdrv_zeroize to bdrv_make_zero (Stefan) - added comment about the -S flag of qemu-img convert in qemu-img.texi (Eric) - used struct assignment for bs-bl in raw_open (Stefan, Eric) - dropped 3 get_block_status fixes that are independent of this series and already partly merged. v2-v3: - fix merge conflict in block/qcow2_cluster.c - changed return type of bdrv_has_discard_zeroes and bdrv_has_discard_write_zeroes to bool. - moved alignment and limits info to a BlockLimits struct (Paolo). - added magic constanst for default maximum in bdrv_co_do_write_zeroes and bdrv_co_discard (Eric). - bdrv_co_do_write_zeroes: allocating the bounce buffer only once (Eric), fixed bounce iov_len in the fall back path. - bdrv_zeroize: added inline docu (Eric) and do not mask flags passed to bdrv_write_zeroes (Eric). - qemu-img: changed the default hint for -S (min_sparse) in the usage help to 4k. not changing the default as it is unclear why this default was set. size suffixes are already supported (Eric). v1-v2: - moved block max_discard and max_write_zeroes to BlockDriverState - added discard_alignment and write_zeroes_alignment to BlockDriverState - added bdrv_has_discard_zeroes() and bdrv_has_discard_write_zeroes() - added logic to bdrv_co_discard and bdrv_co_do_write_zeroes to honour limit and alignment info. - added support for -S 0 in qemu-img convert. Peter Lieven (17): block: make BdrvRequestFlags public block: add flags to bdrv_*_write_zeroes block: introduce BDRV_REQ_MAY_UNMAP request flag block: add logical block provisioning info to BlockDriverInfo block: add wrappers for logical block provisioning information block/iscsi: add .bdrv_get_info block: add BlockLimits structure to BlockDriverState block/raw: copy BlockLimits on raw_open block: honour BlockLimits in bdrv_co_do_write_zeroes block: honour BlockLimits in bdrv_co_discard iscsi: set limits in BlockDriverState iscsi: simplify iscsi_co_discard iscsi: add bdrv_co_write_zeroes block: introduce bdrv_make_zero block/get_block_status: fix BDRV_BLOCK_ZERO for unallocated blocks qemu-img: add support for fully allocated images qemu-img: conditionally zero out target on convert block-migration.c |3 +- block.c | 200 + block/backup.c|3 +- block/iscsi.c | 150 +- block/qcow2-cluster.c |2 +- block/qcow2.c |2 +- block/qed.c |3 +- block/raw_bsd.c |6 +- block/vmdk.c |3 +- include/block/block.h | 35 +++- include/block/block_int.h | 19 - qemu-img.c| 20 -
[Qemu-devel] [PATCH 22/39] memory: unfold cpu_physical_memory_set_dirty_flag()
Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-internal.h | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 5fc4eb6..e56f43b 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -87,9 +87,12 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, end = TARGET_PAGE_ALIGN(start + length); start = TARGET_PAGE_MASK; for (addr = start; addr end; addr += TARGET_PAGE_SIZE) { -cpu_physical_memory_set_dirty_flag(addr, DIRTY_MEMORY_MIGRATION); -cpu_physical_memory_set_dirty_flag(addr, DIRTY_MEMORY_VGA); -cpu_physical_memory_set_dirty_flag(addr, DIRTY_MEMORY_CODE); +set_bit(addr TARGET_PAGE_BITS, +ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION]); +set_bit(addr TARGET_PAGE_BITS, +ram_list.dirty_memory[DIRTY_MEMORY_VGA]); +set_bit(addr TARGET_PAGE_BITS, +ram_list.dirty_memory[DIRTY_MEMORY_CODE]); } xen_modified_memory(addr, length); } -- 1.8.3.1
[Qemu-devel] [PATCH 26/39] memory: use find_next_bit() to find dirty bits
This operation is way faster than doing it bit by bit. Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-internal.h | 15 ++- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 0c1dbfa..5a5bc0d 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -44,18 +44,15 @@ static inline bool cpu_physical_memory_get_dirty(ram_addr_t start, ram_addr_t length, unsigned client) { -ram_addr_t addr, end; +unsigned long end, page, next; assert(client DIRTY_MEMORY_NUM); -end = TARGET_PAGE_ALIGN(start + length); -start = TARGET_PAGE_MASK; -for (addr = start; addr end; addr += TARGET_PAGE_SIZE) { -if (test_bit(addr TARGET_PAGE_BITS, ram_list.dirty_memory[client])) { -return true; -} -} -return false; +end = TARGET_PAGE_ALIGN(start + length) TARGET_PAGE_BITS; +page = start TARGET_PAGE_BITS; +next = find_next_bit(ram_list.dirty_memory[client], end, page); + +return next end; } static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, -- 1.8.3.1
[Qemu-devel] [PATCH 29/39] memory: s/dirty/clean/ in cpu_physical_memory_is_dirty()
All uses except one really want the other meaning. Signed-off-by: Juan Quintela quint...@redhat.com --- cputlb.c | 2 +- exec.c | 6 +++--- include/exec/memory-internal.h | 5 ++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cputlb.c b/cputlb.c index dfd747a..a3a957b 100644 --- a/cputlb.c +++ b/cputlb.c @@ -299,7 +299,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr, /* Write access calls the I/O callback. */ te-addr_write = address | TLB_MMIO; } else if (memory_region_is_ram(section-mr) -!cpu_physical_memory_is_dirty(section-mr-ram_addr + xlat)) { +cpu_physical_memory_is_clean(section-mr-ram_addr + xlat)) { te-addr_write = address | TLB_NOTDIRTY; } else { te-addr_write = address; diff --git a/exec.c b/exec.c index b95c584..a0d431a 100644 --- a/exec.c +++ b/exec.c @@ -1403,7 +1403,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr, cpu_physical_memory_set_dirty_flag(ram_addr, DIRTY_MEMORY_VGA); /* we remove the notdirty callback only if the code has been flushed */ -if (cpu_physical_memory_is_dirty(ram_addr)) { +if (!cpu_physical_memory_is_clean(ram_addr)) { CPUArchState *env = current_cpu-env_ptr; tlb_set_dirty(env, env-mem_io_vaddr); } @@ -1824,7 +1824,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, static void invalidate_and_set_dirty(hwaddr addr, hwaddr length) { -if (!cpu_physical_memory_is_dirty(addr)) { +if (cpu_physical_memory_is_clean(addr)) { /* invalidate code */ tb_invalidate_phys_page_range(addr, addr + length, 0); /* set dirty bit */ @@ -2407,7 +2407,7 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val) stl_p(ptr, val); if (unlikely(in_migration)) { -if (!cpu_physical_memory_is_dirty(addr1)) { +if (cpu_physical_memory_is_clean(addr1)) { /* invalidate code */ tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); /* set dirty bit */ diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index d46570e..4bca95f 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -61,13 +61,12 @@ static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, return cpu_physical_memory_get_dirty(addr, 1, client); } -/* read dirty bit (return 0 or 1) */ -static inline bool cpu_physical_memory_is_dirty(ram_addr_t addr) +static inline bool cpu_physical_memory_is_clean(ram_addr_t addr) { bool vga = cpu_physical_memory_get_dirty_flag(addr, DIRTY_MEMORY_VGA); bool code = cpu_physical_memory_get_dirty_flag(addr, DIRTY_MEMORY_CODE); bool migration = cpu_physical_memory_get_dirty_flag(addr, DIRTY_MEMORY_MIGRATION); -return vga code migration; +return !(vga code migration); } static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, -- 1.8.3.1
[Qemu-devel] [PATCH 30/39] memory: make cpu_physical_memory_reset_dirty() take a length parameter
We have an end parameter in all the callers, and this make it coherent with the rest of cpu_physical_memory_* functions, that also take a length parameter. Once here, move the start/end calculation to tlb_reset_dirty_range_all() as we don't need it here anymore. Signed-off-by: Juan Quintela quint...@redhat.com --- cputlb.c | 3 +-- exec.c | 19 --- include/exec/memory-internal.h | 2 +- memory.c | 8 ++-- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/cputlb.c b/cputlb.c index a3a957b..865430c 100644 --- a/cputlb.c +++ b/cputlb.c @@ -127,8 +127,7 @@ void tlb_flush_page(CPUArchState *env, target_ulong addr) can be detected */ void tlb_protect_code(ram_addr_t ram_addr) { -cpu_physical_memory_reset_dirty(ram_addr, -ram_addr + TARGET_PAGE_SIZE, +cpu_physical_memory_reset_dirty(ram_addr, TARGET_PAGE_SIZE, DIRTY_MEMORY_CODE); } diff --git a/exec.c b/exec.c index a0d431a..984b417 100644 --- a/exec.c +++ b/exec.c @@ -648,11 +648,14 @@ found: return block; } -static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t end, - uintptr_t length) +static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length) { -RAMBlock *block; ram_addr_t start1; +RAMBlock *block; +ram_addr_t end; + +end = TARGET_PAGE_ALIGN(start + length); +start = TARGET_PAGE_MASK; block = qemu_get_ram_block(start); assert(block == qemu_get_ram_block(end - 1)); @@ -661,21 +664,15 @@ static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t end, } /* Note: start and end must be within the same ram block. */ -void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, +void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t length, unsigned client) { -uintptr_t length; - -start = TARGET_PAGE_MASK; -end = TARGET_PAGE_ALIGN(end); - -length = end - start; if (length == 0) return; cpu_physical_memory_clear_dirty_range(start, length, client); if (tcg_enabled()) { -tlb_reset_dirty_range_all(start, end, length); +tlb_reset_dirty_range_all(start, length); } } diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 4bca95f..c790ab8 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -101,7 +101,7 @@ static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start, bitmap_clear(ram_list.dirty_memory[client], page, end - page); } -void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, +void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t length, unsigned client); #endif diff --git a/memory.c b/memory.c index f93c1e8..c58661b 100644 --- a/memory.c +++ b/memory.c @@ -1191,9 +1191,7 @@ bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr, assert(mr-terminates); ret = cpu_physical_memory_get_dirty(mr-ram_addr + addr, size, client); if (ret) { -cpu_physical_memory_reset_dirty(mr-ram_addr + addr, -mr-ram_addr + addr + size, -client); +cpu_physical_memory_reset_dirty(mr-ram_addr + addr, size, client); } return ret; } @@ -1239,9 +1237,7 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size, unsigned client) { assert(mr-terminates); -cpu_physical_memory_reset_dirty(mr-ram_addr + addr, -mr-ram_addr + addr + size, -client); +cpu_physical_memory_reset_dirty(mr-ram_addr + addr, size, client); } void *memory_region_get_ram_ptr(MemoryRegion *mr) -- 1.8.3.1
[Qemu-devel] [PATCH 27/39] memory: cpu_physical_memory_set_dirty_range() now uses bitmap operations
We were setting a range of bits, so use bitmap_set(). Note: xen has always been wrong, and should have used start instead of addr from the beggining. Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-internal.h | 19 +++ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 5a5bc0d..2f704e8 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -81,19 +81,14 @@ static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, ram_addr_t length) { -ram_addr_t addr, end; +unsigned long end, page; -end = TARGET_PAGE_ALIGN(start + length); -start = TARGET_PAGE_MASK; -for (addr = start; addr end; addr += TARGET_PAGE_SIZE) { -set_bit(addr TARGET_PAGE_BITS, -ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION]); -set_bit(addr TARGET_PAGE_BITS, -ram_list.dirty_memory[DIRTY_MEMORY_VGA]); -set_bit(addr TARGET_PAGE_BITS, -ram_list.dirty_memory[DIRTY_MEMORY_CODE]); -} -xen_modified_memory(addr, length); +end = TARGET_PAGE_ALIGN(start + length) TARGET_PAGE_BITS; +page = start TARGET_PAGE_BITS; +bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION], page, end - page); +bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_VGA], page, end - page); +bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_CODE], page, end - page); +xen_modified_memory(start, length); } static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start, -- 1.8.3.1
[Qemu-devel] [PATCH 34/39] kvm: use directly cpu_physical_memory_* api for tracking dirty pages
Performance is important in this function, and we want to optimize even further. Signed-off-by: Juan Quintela quint...@redhat.com --- kvm-all.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 4478969..963c2d1 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -31,6 +31,7 @@ #include sysemu/kvm.h #include qemu/bswap.h #include exec/memory.h +#include exec/memory-physical.h #include exec/address-spaces.h #include qemu/event_notifier.h #include trace.h @@ -381,6 +382,7 @@ static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section, unsigned int i, j; unsigned long page_number, c; hwaddr addr, addr1; +ram_addr_t ram_addr; unsigned int pages = int128_get64(section-size) / getpagesize(); unsigned int len = (pages + HOST_LONG_BITS - 1) / HOST_LONG_BITS; unsigned long hpratio = getpagesize() / TARGET_PAGE_SIZE; @@ -398,8 +400,9 @@ static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section, page_number = (i * HOST_LONG_BITS + j) * hpratio; addr1 = page_number * TARGET_PAGE_SIZE; addr = section-offset_within_region + addr1; -memory_region_set_dirty(section-mr, addr, -TARGET_PAGE_SIZE * hpratio); +ram_addr = section-mr-ram_addr + addr; +cpu_physical_memory_set_dirty_range(ram_addr, +TARGET_PAGE_SIZE * hpratio); } while (c != 0); } } -- 1.8.3.1
[Qemu-devel] [PATCH 32/39] memory: split cpu_physical_memory_* functions to its own include
So we know who is using the bitmap directly Signed-off-by: Juan Quintela quint...@redhat.com --- cputlb.c | 1 + exec.c | 1 + include/exec/memory-internal.h | 69 include/exec/memory-physical.h | 90 ++ memory.c | 1 + 5 files changed, 93 insertions(+), 69 deletions(-) create mode 100644 include/exec/memory-physical.h diff --git a/cputlb.c b/cputlb.c index 865430c..96aa143 100644 --- a/cputlb.c +++ b/cputlb.c @@ -26,6 +26,7 @@ #include exec/cputlb.h #include exec/memory-internal.h +#include exec/memory-physical.h //#define DEBUG_TLB //#define DEBUG_TLB_CHECK diff --git a/exec.c b/exec.c index 11b434b..04eb2b4 100644 --- a/exec.c +++ b/exec.c @@ -50,6 +50,7 @@ #include translate-all.h #include exec/memory-internal.h +#include exec/memory-physical.h //#define DEBUG_SUBPAGE diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index c790ab8..69a92cf 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -20,9 +20,6 @@ #define MEMORY_INTERNAL_H #ifndef CONFIG_USER_ONLY -#include hw/xen/xen.h - - typedef struct AddressSpaceDispatch AddressSpaceDispatch; void address_space_init_dispatch(AddressSpace *as); @@ -39,71 +36,5 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr); void *qemu_get_ram_ptr(ram_addr_t addr); void qemu_ram_free(ram_addr_t addr); void qemu_ram_free_from_ptr(ram_addr_t addr); - -static inline bool cpu_physical_memory_get_dirty(ram_addr_t start, - ram_addr_t length, - unsigned client) -{ -unsigned long end, page, next; - -assert(client DIRTY_MEMORY_NUM); - -end = TARGET_PAGE_ALIGN(start + length) TARGET_PAGE_BITS; -page = start TARGET_PAGE_BITS; -next = find_next_bit(ram_list.dirty_memory[client], end, page); - -return next end; -} - -static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr, - unsigned client) -{ -return cpu_physical_memory_get_dirty(addr, 1, client); -} - -static inline bool cpu_physical_memory_is_clean(ram_addr_t addr) -{ -bool vga = cpu_physical_memory_get_dirty_flag(addr, DIRTY_MEMORY_VGA); -bool code = cpu_physical_memory_get_dirty_flag(addr, DIRTY_MEMORY_CODE); -bool migration = cpu_physical_memory_get_dirty_flag(addr, DIRTY_MEMORY_MIGRATION); -return !(vga code migration); -} - -static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, - unsigned client) -{ -assert(client DIRTY_MEMORY_NUM); - -set_bit(addr TARGET_PAGE_BITS, ram_list.dirty_memory[client]); -} - -static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, - ram_addr_t length) -{ -unsigned long end, page; - -end = TARGET_PAGE_ALIGN(start + length) TARGET_PAGE_BITS; -page = start TARGET_PAGE_BITS; -bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION], page, end - page); -bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_VGA], page, end - page); -bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_CODE], page, end - page); -xen_modified_memory(start, length); -} - -static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start, - ram_addr_t length, - unsigned client) -{ -unsigned long end, page; - -end = TARGET_PAGE_ALIGN(start + length) TARGET_PAGE_BITS; -page = start TARGET_PAGE_BITS; -bitmap_clear(ram_list.dirty_memory[client], page, end - page); -} - -void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t length, - unsigned client); - #endif - #endif diff --git a/include/exec/memory-physical.h b/include/exec/memory-physical.h new file mode 100644 index 000..610c55f --- /dev/null +++ b/include/exec/memory-physical.h @@ -0,0 +1,90 @@ +/* + * Declarations for cpu physical memory functions + * + * Copyright 2011 Red Hat, Inc. and/or its affiliates + * + * Authors: + * Avi Kivity a...@redhat.com + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + * + */ + +/* + * This header is for use by exec.c and memory.c ONLY. Do not include it. + * The functions declared here will be removed soon. + */ + +#ifndef MEMORY_PHYSICAL_H +#define MEMORY_PHYSICAL_H + +#ifndef CONFIG_USER_ONLY +#include hw/xen/xen.h + +static inline bool cpu_physical_memory_get_dirty(ram_addr_t start, + ram_addr_t length, + unsigned client) +{ +unsigned long end, page,
[Qemu-devel] [PATCH 37/39] memory: syncronize kvm bitmap using bitmaps operations
If bitmaps are aligned properly, use bitmap operations. If they are not, just use old bit at a time code. Signed-off-by: Juan Quintela quint...@redhat.com --- include/exec/memory-physical.h | 54 +- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/include/exec/memory-physical.h b/include/exec/memory-physical.h index 72faf06..9057714 100644 --- a/include/exec/memory-physical.h +++ b/include/exec/memory-physical.h @@ -82,23 +82,45 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap, ram_addr_t ram_addr; unsigned int len = (pages + HOST_LONG_BITS - 1) / HOST_LONG_BITS; unsigned long hpratio = getpagesize() / TARGET_PAGE_SIZE; +unsigned long page = BIT_WORD(start TARGET_PAGE_BITS); -/* - * bitmap-traveling is faster than memory-traveling (for addr...) - * especially when most of the memory is not dirty. - */ -for (i = 0; i len; i++) { -if (bitmap[i] != 0) { -c = leul_to_cpu(bitmap[i]); -do { -j = ffsl(c) - 1; -c = ~(1ul j); -page_number = (i * HOST_LONG_BITS + j) * hpratio; -addr = page_number * TARGET_PAGE_SIZE; -ram_addr = start + addr; -cpu_physical_memory_set_dirty_range(ram_addr, -TARGET_PAGE_SIZE * hpratio); -} while (c != 0); +/* start address is aligned at the start of a word? */ +if (((page * BITS_PER_LONG) TARGET_PAGE_BITS) == start) { +int k; +int nr = BITS_TO_LONGS(pages); + +printf(XXX: aligned start %lx page %lx\n, start, page); +assert(start == ((start TARGET_PAGE_BITS) TARGET_PAGE_BITS)); + +for (k = 0; k nr; k++) { +if (bitmap[k]) { +unsigned long temp = leul_to_cpu(bitmap[k]); + +ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION][page + k] |= temp; +ram_list.dirty_memory[DIRTY_MEMORY_VGA][page + k] |= temp; +ram_list.dirty_memory[DIRTY_MEMORY_CODE][page + k] |= temp; +} +} +xen_modified_memory(start, pages); +} else { +printf(XXX: not aligned start %lx pages %lu\n, start, pages); +/* + * bitmap-traveling is faster than memory-traveling (for addr...) + * especially when most of the memory is not dirty. + */ +for (i = 0; i len; i++) { +if (bitmap[i] != 0) { +c = leul_to_cpu(bitmap[i]); +do { +j = ffsl(c) - 1; +c = ~(1ul j); +page_number = (i * HOST_LONG_BITS + j) * hpratio; +addr = page_number * TARGET_PAGE_SIZE; +ram_addr = start + addr; +cpu_physical_memory_set_dirty_range(ram_addr, +TARGET_PAGE_SIZE * hpratio); +} while (c != 0); +} } } } -- 1.8.3.1
[Qemu-devel] [PATCH 31/39] memory: cpu_physical_memory_set_dirty_tracking() should return void
Result was always 0, and not used anywhere. Once there, use bool type for the parameter. Signed-off-by: Juan Quintela quint...@redhat.com --- exec.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/exec.c b/exec.c index 984b417..11b434b 100644 --- a/exec.c +++ b/exec.c @@ -54,7 +54,7 @@ //#define DEBUG_SUBPAGE #if !defined(CONFIG_USER_ONLY) -static int in_migration; +static bool in_migration; RAMList ram_list = { .blocks = QTAILQ_HEAD_INITIALIZER(ram_list.blocks) }; @@ -676,11 +676,9 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t length, } } -static int cpu_physical_memory_set_dirty_tracking(int enable) +static void cpu_physical_memory_set_dirty_tracking(bool enable) { -int ret = 0; in_migration = enable; -return ret; } hwaddr memory_region_section_get_iotlb(CPUArchState *env, @@ -1699,12 +1697,12 @@ static void tcg_commit(MemoryListener *listener) static void core_log_global_start(MemoryListener *listener) { -cpu_physical_memory_set_dirty_tracking(1); +cpu_physical_memory_set_dirty_tracking(true); } static void core_log_global_stop(MemoryListener *listener) { -cpu_physical_memory_set_dirty_tracking(0); +cpu_physical_memory_set_dirty_tracking(false); } static MemoryListener core_memory_listener = { -- 1.8.3.1
[Qemu-devel] [PATCH 33/39] memory: unfold memory_region_test_and_clear()
We are going to update the bitmap directly Signed-off-by: Juan Quintela quint...@redhat.com --- arch_init.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch_init.c b/arch_init.c index 7545d96..72ef993 100644 --- a/arch_init.c +++ b/arch_init.c @@ -48,6 +48,7 @@ #include qmp-commands.h #include trace.h #include exec/cpu-all.h +#include exec/memory-physical.h #include hw/acpi/acpi.h #ifdef DEBUG_ARCH_INIT @@ -400,9 +401,12 @@ static void migration_bitmap_sync(void) QTAILQ_FOREACH(block, ram_list.blocks, next) { for (addr = 0; addr block-length; addr += TARGET_PAGE_SIZE) { -if (memory_region_test_and_clear_dirty(block-mr, - addr, TARGET_PAGE_SIZE, - DIRTY_MEMORY_MIGRATION)) { +if (cpu_physical_memory_get_dirty(block-mr-ram_addr + addr, + TARGET_PAGE_SIZE, + DIRTY_MEMORY_MIGRATION)) { +cpu_physical_memory_reset_dirty(block-mr-ram_addr + addr, +TARGET_PAGE_SIZE, +DIRTY_MEMORY_MIGRATION); migration_bitmap_set_dirty(block-mr, addr); } } -- 1.8.3.1
[Qemu-devel] [PATCH 39/39] migration: synchronize memory bitmap 64bits at a time
We use the old code if the bitmaps are not aligned Signed-off-by: Juan Quintela quint...@redhat.com --- arch_init.c | 43 ++- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/arch_init.c b/arch_init.c index fe88d64..0909531 100644 --- a/arch_init.c +++ b/arch_init.c @@ -50,6 +50,7 @@ #include exec/cpu-all.h #include exec/memory-physical.h #include hw/acpi/acpi.h +#include qemu/host-utils.h #ifdef DEBUG_ARCH_INIT #define DPRINTF(fmt, ...) \ @@ -376,15 +377,37 @@ static inline bool migration_bitmap_set_dirty(ram_addr_t addr) static void migration_bitmap_sync_range(ram_addr_t start, ram_addr_t length) { ram_addr_t addr; - -for (addr = 0; addr length; addr += TARGET_PAGE_SIZE) { -if (cpu_physical_memory_get_dirty(start + addr, - TARGET_PAGE_SIZE, - DIRTY_MEMORY_MIGRATION)) { -cpu_physical_memory_reset_dirty(start + addr, -TARGET_PAGE_SIZE, -DIRTY_MEMORY_MIGRATION); -migration_bitmap_set_dirty(start + addr); +unsigned long page = BIT_WORD(start TARGET_PAGE_BITS); + +/* start address is aligned at the start of a word? */ +if (((page * BITS_PER_LONG) TARGET_PAGE_BITS) == start) { +int k; +int nr = BITS_TO_LONGS(length TARGET_PAGE_BITS); +unsigned long *src = ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION]; + +printf(:optimized start %lx page %lx length %lu\n, start, page, length); + +for (k = page; k page + nr; k++) { +if (src[k]) { +unsigned long new_dirty; +new_dirty = ~migration_bitmap[k]; +migration_bitmap[k] |= src[k]; +new_dirty = src[k]; +migration_dirty_pages += ctpopl(new_dirty); +src[k] = 0; +} +} +} else { +printf(:not optimized start %lx length %lu\n, start, length); +for (addr = 0; addr length; addr += TARGET_PAGE_SIZE) { +if (cpu_physical_memory_get_dirty(start + addr, + TARGET_PAGE_SIZE, + DIRTY_MEMORY_MIGRATION)) { +cpu_physical_memory_reset_dirty(start + addr, +TARGET_PAGE_SIZE, +DIRTY_MEMORY_MIGRATION); +migration_bitmap_set_dirty(start + addr); +} } } } @@ -415,6 +438,8 @@ static void migration_bitmap_sync(void) address_space_sync_dirty_bitmap(address_space_memory); QTAILQ_FOREACH(block, ram_list.blocks, next) { +printf(: name %s addr %lx length %lu\n, + block-idstr, block-mr-ram_addr, block-length); migration_bitmap_sync_range(block-mr-ram_addr, block-length); } trace_migration_bitmap_sync_end(migration_dirty_pages -- 1.8.3.1