Compare commits

...

71 Commits

Author SHA1 Message Date
Michael Roth 0d83fccb4f Update version for 2.7.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-23 09:38:06 -06:00
Ashijeet Acharya 4dde694191 ide: Fix memory leak in ide_register_restart_cb()
Fix a memory leak in ide_register_restart_cb() in hw/ide/core.c and add
idebus_unrealize() in hw/ide/qdev.c to have calls to
qemu_del_vm_change_state_handler() to deal with the dangling change
state handler during hot-unplugging ide devices which might lead to a
crash.

Signed-off-by: Ashijeet Acharya <ashijeetacharya@gmail.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 1474995212-10580-1-git-send-email-ashijeetacharya@gmail.com
[Minor whitespace fix --js]
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit ca44141d5f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-21 10:49:48 -06:00
Marc-André Lureau 7d17d68971 portio: keep references on portio
The isa_register_portio_list() function allocates ioports
data/state. Let's keep the reference to this data on some owner.  This
isn't enough to fix leaks, but at least, ASAN stops complaining of
direct leaks. Further cleanup would require calling
portio_list_del/destroy().

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e305a16510)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-21 10:08:19 -06:00
John Snow 345f1cd9f6 block-backend: Always notify on blk_eject
blk_eject is only used by scsi-disk and atapi, and in both cases we
only attempt to invoke blk_eject if we have a bona-fide change in
tray state.

The "issue" here is that the tray state does not generate a QMP event
unless there is a medium/BDS attached to the device, so if libvirt et al
are waiting for a tray event to occur from an empty-but-closed drive,
software opening that drive will not emit an event and libvirt will
wait forever.

Change this by modifying blk_eject to always emit an event, instead of
conditionally on a "real" backend eject.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1373264

Reported-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 1478553214-497-2-git-send-email-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit c47ee043dc)

* dropped functional depedenecy on 2d76e724

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-21 09:59:57 -06:00
Mark Cave-Ayland 8d5f2a7570 dma-helpers: explicitly pass alignment into DMA helpers
The hard-coded default alignment is BDRV_SECTOR_SIZE, however this is not
necessarily the case for all platforms. Use this as the default alignment for
all current callers.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Eric Blake <eblake@redhat.com>
Acked-by: John Snow <jsnow@redhat.com>
Message-id: 1476445266-27503-2-git-send-email-mark.cave-ayland@ilande.co.uk
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 99868af3d0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-21 09:27:59 -06:00
John Snow 5f20161cf3 atapi: classify read_cd as conditionally returning data
For the purposes of byte_count_limit verification, add a new flag that
identifies read_cd as sometimes returning data, then check the BCL in
its command handler after we know that it will indeed return data.

Reported-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 1477970211-25754-2-git-send-email-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit e7bd708ec8)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-20 19:33:05 -06:00
Stefan Hajnoczi 05838b4688 ui/gtk: fix "Copy" menu item segfault
The "Copy" menu item copies VTE terminal text to the clipboard.  This
only works with VTE terminals, not with graphics consoles.

Disable the menu item when the current notebook page isn't a VTE
terminal.

This patch fixes a segfault.  Reproducer: Start QEMU and click the Copy
menu item when the guest display is visible.

Reported-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20161214142518.10504-1-stefanha@redhat.com
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit a08156321a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-20 19:31:47 -06:00
Thorsten Kohfeldt 223d1a2da1 vfio/pci: Fix vfio_rtl8168_quirk_data_read address offset
Introductory comment for rtl8168 VFIO MSI-X quirk states:
At BAR2 offset 0x70 there is a dword data register,
         offset 0x74 is a dword address register.
vfio: vfio_bar_read(0000:05:00.0:BAR2+0x70, 4) = 0xfee00398 // read data

Thus, correct offset for data read is 0x70,
but function vfio_rtl8168_quirk_data_read() wrongfully uses offset 0x74.

Signed-off-by: Thorsten Kohfeldt <thorsten.kohfeldt@gmx.de>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
(cherry picked from commit 31e6a7b17b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-14 16:34:09 -06:00
Lin Ma 7f7ac2141e msmouse: Fix segfault caused by free the chr before chardev cleanup.
Segfault happens when leaving qemu with msmouse backend:

 #0  0x00007fa8526ac975 in raise () at /lib64/libc.so.6
 #1  0x00007fa8526add8a in abort () at /lib64/libc.so.6
 #2  0x0000558be78846ab in error_exit (err=16, msg=0x558be799da10 ...
 #3  0x0000558be7884717 in qemu_mutex_destroy (mutex=0x558be93be750) at ...
 #4  0x0000558be7549951 in qemu_chr_free_common (chr=0x558be93be750) at ...
 #5  0x0000558be754999c in qemu_chr_free (chr=0x558be93be750) at ...
 #6  0x0000558be7549a20 in qemu_chr_delete (chr=0x558be93be750) at ...
 #7  0x0000558be754a8ef in qemu_chr_cleanup () at qemu-char.c:4643
 #8  0x0000558be755843e in main (argc=5, argv=0x7ffe925d7118, ...

The chr was freed by msmouse close callback before chardev cleanup,
Then qemu_mutex_destroy triggered raise().

Because freeing chr is handled by qemu_chr_free_common, Remove the free from
msmouse_chr_close to avoid double free.

Fixes: c1111a24a3
Cc: qemu-stable@nongnu.org
Signed-off-by: Lin Ma <lma@suse.com>
Message-Id: <20160915143158.4796-1-lma@suse.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 9e14037f05)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-14 16:34:09 -06:00
Paolo Bonzini db1604cd60 Revert "megasas: remove useless check for cmd->frame"
This reverts commit 8cc46787b5.
It turns out that cmd->frame can be NULL and thus the commit
can cause a SIGSEGV

Reported-by: Holger Schranz <holger@fam-schranz.de>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 421cc3e7e8)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 18:15:33 -06:00
Eduardo Habkost cc1fd25295 vl: Delay initialization of memory backends
Initialization of memory backends may take a while when
prealloc=yes is used, depending on their size. Initializing
memory backends before chardevs may delay the creation of monitor
sockets, and trigger timeouts on management software that waits
until the monitor socket is created by QEMU. See, for example,
the bug report at:
https://bugzilla.redhat.com/show_bug.cgi?id=1371211

In addition to that, allocating memory before calling
configure_accelerator() breaks the tcg_enabled() checks at
memory_region_init_*().

This patch fixes those problems by adding "memory-backend-*"
classes to the delayed-initialization list.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 6546d0dba6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 18:13:21 -06:00
Eduardo Habkost ee99e42be4 vhost-user-test: Use libqos instead of pxe-virtio.rom
vhost-user-test relies on iPXE just to initialize the virtio-net
device, and doesn't do any actual packet tx/rx testing.

In addition to that, the test relies on TCG, which is
imcompatible with vhost. The test only worked by accident: a bug
the memory backend initialization made memory regions not have
the DIRTY_MEMORY_CODE bit set in dirty_log_mask.

This changes vhost-user-test to initialize the virtio-net device
using libqos, and not use TCG nor pxe-virtio.rom.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit cdafe92961)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 18:13:02 -06:00
Peter Xu 0ef167c907 intel_iommu: fix incorrect device invalidate
"mask" needs to be inverted before use.

Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 6cb99acc28)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 18:06:43 -06:00
Adrian Bunk 248a780fd3 rules.mak: Use -r instead of -Wl, -r to fix building when PIE is default
Building qemu fails in distributions where gcc enables PIE by default
(e.g. Debian unstable) with:

/usr/bin/ld: -r and -pie may not be used together

Use -r instead of -Wl,-r to avoid gcc passing -pie to the linker
when PIE is enabled and a relocatable object is passed.

Signed-off-by: Adrian Bunk <bunk@stusta.de>
Message-Id: <20161127162817.15144-1-bunk@stusta.de>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c96f0ee6a6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 18:05:55 -06:00
Peter Xu 80f630be21 pci-assign: sync MSI/MSI-X cap and table with PCIDevice
Since commit e1d4fb2d ("kvm-irqchip: x86: add msi route notify fn"),
kvm_irqchip_add_msi_route() starts to use pci_get_msi_message() to fetch
MSI info. This requires that we setup MSI related fields in PCIDevice.
For most devices, that won't be a problem, as long as we are using
general interfaces like msi_init()/msix_init().

However, for pci-assign devices, MSI/MSI-X is treated differently - PCI
assign devices are maintaining its own MSI table and cap information in
AssignedDevice struct. however that's not synced up with PCIDevice's
fields. That will leads to pci_get_msi_message() failed to find correct
MSI capability, even with an NULL msix_table.

A quick fix is to sync up the two places: both the capability bits and
table address for MSI/MSI-X.

Reported-by: Changlimin <changlimin@h3c.com>
Tested-by: Changlimin <changlimin@h3c.com>
Cc: qemu-stable@nongnu.org
Fixes: e1d4fb2d ("kvm-irqchip: x86: add msi route notify fn")
Signed-off-by: Peter Xu <peterx@redhat.com>

Message-Id: <1480042522-16551-1-git-send-email-peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 64e184e260)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 18:04:19 -06:00
Zhuang Yanying 353801cde4 ivshmem: Fix 64 bit memory bar configuration
Device ivshmem property use64=0 is designed to make the device
expose a 32 bit shared memory BAR instead of 64 bit one.  The
default is a 64 bit BAR, except pc-1.2 and older retain a 32 bit
BAR.  A 32 bit BAR can support only up to 1 GiB of shared memory.

This worked as designed until commit 5400c02 accidentally flipped
its sense: since then, we misinterpret use64=0 as use64=1 and vice
versa.  Worse, the default got flipped as well.  Devices
ivshmem-plain and ivshmem-doorbell are not affected.

Fix by restoring the test of IVShmemState member not_legacy_32bit
that got messed up in commit 5400c02.  Also update its
initialization for devices ivhsmem-plain and ivshmem-doorbell.
Without that, they'd regress to 32 bit BARs.

Cc: qemu-stable@nongnu.org
Signed-off-by: Zhuang Yanying <ann.zhuangyanying@huawei.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit be4e0d7375)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:49:41 -06:00
Greg Kurz c8a3159df4 vhost: drop legacy vring layout bits
The legacy vring layout is not used anymore as we use the separate
mappings even for legacy devices.
This patch simply removes it.

This also fixes a bug with virtio 1 devices when the vring descriptor table
is mapped at a higher address than the used vring because the following
function may return an insanely great value:

hwaddr virtio_queue_get_ring_size(VirtIODevice *vdev, int n)
{
    return vdev->vq[n].vring.used - vdev->vq[n].vring.desc +
           virtio_queue_get_used_size(vdev, n);
}

and the mapping fails.

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 1cdce7c54d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:49:41 -06:00
Max Reitz 48fdfebab6 block/curl: Do not wait for data beyond EOF
libcurl will only give us as much data as there is, not more. The block
layer will deny requests beyond the end of file for us; but since this
block driver is still using a sector-based interface, we can still get
in trouble if the file size is not a multiple of 512.

While we have already made sure not to attempt transfers beyond the end
of the file, we are currently still trying to receive data from there if
the original request exceeds the file size. This patch fixes this issue
and invokes qemu_iovec_memset() on the iovec's tail.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20161025025431.24714-5-mreitz@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit 4e504535c1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:48:44 -06:00
Max Reitz 6eb194ddd7 block/curl: Remember all sockets
For some connection types (like FTP, generally), more than one socket
may be used (in FTP's case: control vs. data stream). As of commit
838ef60249 ("curl: Eliminate unnecessary
use of curl_multi_socket_all"), we have to remember all of the sockets
used by libcurl, but in fact we only did that for a single one. Since
one libcurl connection may use multiple sockets, however, we have to
remember them all.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20161025025431.24714-4-mreitz@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit ff5ca1664a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:48:44 -06:00
Max Reitz 7e278ef797 block/curl: Fix return value from curl_read_cb
While commit 38bbc0a580 is correct in that
the callback is supposed to return the number of bytes handled; what it
does not mention is that libcurl will throw an error if the callback did
not "handle" all of the data passed to it.

Therefore, if the callback receives some data that it cannot handle
(either because the receive buffer has not been set up yet or because it
would not fit into the receive buffer) and we have to ignore it, we
still have to report that the data has been handled.

Obviously, this should not happen normally. But it does happen at least
for FTP connections where some data (that we do not expect) may be
generated when the connection is established.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20161025025431.24714-3-mreitz@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit 4e7676571b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:48:44 -06:00
Max Reitz 6a5ea68e9e block/curl: Use BDRV_SECTOR_SIZE
Currently, curl defines its own constant SECTOR_SIZE. There is no
advantage over using the global BDRV_SECTOR_SIZE, so drop it.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20161025025431.24714-2-mreitz@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit 9054d9f6b0)

Conflicts:
	block/curl.c

* drop context dep on fffb6e1 / aio_bh_schedule_oneshot

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:48:44 -06:00
Eric Blake 31454ebde5 block: Pass unaligned discard requests to drivers
Discard is advisory, so rounding the requests to alignment
boundaries is never semantically wrong from the data that
the guest sees.  But at least the Dell Equallogic iSCSI SANs
has an interesting property that its advertised discard
alignment is 15M, yet documents that discarding a sequence
of 1M slices will eventually result in the 15M page being
marked as discarded, and it is possible to observe which
pages have been discarded.

Between commits 9f1963b and b8d0a980, we converted the block
layer to a byte-based interface that ultimately ignores any
unaligned head or tail based on the driver's advertised
discard granularity, which means that qemu 2.7 refuses to
pass any discard request smaller than 15M down to the Dell
Equallogic hardware.  This is a slight regression in behavior
compared to earlier qemu, where a guest executing discards
in power-of-2 chunks used to be able to get every page
discarded, but is now left with various pages still allocated
because the guest requests did not align with the hardware's
15M pages.

Since the SCSI specification says nothing about a minimum
discard granularity, and only documents the preferred
alignment, it is best if the block layer gives the driver
every bit of information about discard requests, rather than
rounding it to alignment boundaries early.

Rework the block layer discard algorithm to mirror the write
zero algorithm: always peel off any unaligned head or tail
and manage that in isolation, then do the bulk of the request
on an aligned boundary.  The fallback when the driver returns
-ENOTSUP for an unaligned request is to silently ignore that
portion of the discard request; but for devices that can pass
the partial request all the way down to hardware, this can
result in the hardware coalescing requests and discarding
aligned pages after all.

Reported by: Peter Lieven <pl@kamp.de>
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>

(cherry picked from commit 3482b9bc41)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:48:44 -06:00
Eric Blake 5e4eb851dd block: Return -ENOTSUP rather than assert on unaligned discards
Right now, the block layer rounds discard requests, so that
individual drivers are able to assert that discard requests
will never be unaligned.  But there are some ISCSI devices
that track and coalesce multiple unaligned requests, turning it
into an actual discard if the requests eventually cover an
entire page, which implies that it is better to always pass
discard requests as low down the stack as possible.

In isolation, this patch has no semantic effect, since the
block layer currently never passes an unaligned request through.
But the block layer already has code that silently ignores
drivers that return -ENOTSUP for a discard request that cannot
be honored (as well as drivers that return 0 even when nothing
was done).  But the next patch will update the block layer to
fragment discard requests, so that clients are guaranteed that
they are either dealing with an unaligned head or tail, or an
aligned core, making it similar to the block layer semantics of
write zero fragmentation.

CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 49228d1e95)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:48:43 -06:00
Eric Blake dd11d33deb block: Let write zeroes fallback work even with small max_transfer
Commit 443668ca rewrote the write_zeroes logic to guarantee that
an unaligned request never crosses a cluster boundary.  But
in the rewrite, the new code assumed that at most one iteration
would be needed to get to an alignment boundary.

However, it is easy to trigger an assertion failure: the Linux
kernel limits loopback devices to advertise a max_transfer of
only 64k.  Any operation that requires falling back to writes
rather than more efficient zeroing must obey max_transfer during
that fallback, which means an unaligned head may require multiple
iterations of the write fallbacks before reaching the aligned
boundaries, when layering a format with clusters larger than 64k
atop the protocol of file access to a loopback device.

Test case:

$ qemu-img create -f qcow2 -o cluster_size=1M file 10M
$ losetup /dev/loop2 /path/to/file
$ qemu-io -f qcow2 /dev/loop2
qemu-io> w 7m 1k
qemu-io> w -z 8003584 2093056

In fairness to Denis (as the original listed author of the culprit
commit), the faulty logic for at most one iteration is probably all
my fault in reworking his idea.  But the solution is to restore what
was in place prior to that commit: when dealing with an unaligned
head or tail, iterate as many times as necessary while fragmenting
the operation at max_transfer boundaries.

Reported-by: Ed Swierk <eswierk@skyportsystems.com>
CC: qemu-stable@nongnu.org
CC: Denis V. Lunev <den@openvz.org>
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b2f95feec5)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:48:30 -06:00
Eric Blake c4bf37e0b0 qcow2: Inform block layer about discard boundaries
At the qcow2 layer, discard is only possible on a per-cluster
basis; at the moment, qcow2 silently rounds any unaligned
requests to this granularity.  However, an upcoming patch will
fix a regression in the block layer ignoring too much of an
unaligned discard request, by changing the block layer to
break up a discard request at alignment boundaries; for that
to work, the block layer must know about our limits.

However, we can't go one step further by changing
qcow2_discard_clusters() to assert that requests are always
aligned, since that helper function is reached on paths
outside of the block layer.

CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit ecdbead659)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-12 17:48:19 -06:00
Samuel Thibault e9dbd28e2a slirp: Fix access to freed memory
if_start() goes through the slirp->if_fastq and slirp->if_batchq
list of pending messages, and accesses ifm->ifq_so->so_nqueued of its
elements if ifm->ifq_so != NULL.  When freeing a socket, we thus need
to make sure that any pending message for this socket does not refer
to the socket any more.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Tested-by: Brian Candler <b.candler@pobox.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit ea64d5f088)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-08 13:56:26 -06:00
Greg Kurz 92230a5963 vhost: adapt vhost_verify_ring_mappings() to virtio 1 ring layout
With virtio 1, the vring layout is split in 3 separate regions of
contiguous memory for the descriptor table, the available ring and the
used ring, as opposed with legacy virtio which uses a single region.

In case of memory re-mapping, the code ensures it doesn't affect the
vring mapping. This is done in vhost_verify_ring_mappings() which assumes
the device is legacy.

This patch changes vhost_verify_ring_mappings() to check the mappings of
each part of the vring separately.

This works for legacy mappings as well.

Cc: qemu-stable@nongnu.org
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit f1f9e6c596)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-08 13:53:11 -06:00
Kevin Wolf 48b3aa20ae block: Don't mark node clean after failed flush
Commit 3ff2f67a changed bdrv_co_flush() so that no flush is issues if
the image hasn't been dirtied since the last flush. This is not quite
correct: The condition should be that the image hasn't been dirtied
since the last _successful_ flush. This patch changes the logic
accordingly.

Without this fix, subsequent bdrv_co_flush() calls would return success
without actually doing anything even though the image is still dirty.
The difference is visible in some blkdebug test cases where error
messages incorrectly disappeared after commit 3ff2f67a.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 1478300595-10090-1-git-send-email-kwolf@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit e6af1e0854)

Conflicts:
	block/io.c

* remove context dep on 9972354

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-08 13:50:54 -06:00
Michael S. Tsirkin f1372d6e14 virtio-net: mark VIRTIO_NET_F_GSO as legacy
virtio 1.0 spec says this is a legacy feature bit,
hide it from guests in modern mode.

Note: for cross-version migration compatibility,
we keep the bit set in host_features.
The result will be that a guest migrating cross-version
will see host features change under it.
As guests only seem to read it once, this should
not be an issue. Meanwhile, will work to fix guests to
ignore this bit in virtio1 mode, too.

Cc: qemu-stable@nongnu.org
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit 2a083ffd2e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-08 13:50:54 -06:00
Michael S. Tsirkin 63087cd74b virtio: allow per-device-class legacy features
Legacy features are those that transitional devices only
expose on the legacy interface.
Allow different ones per device class.

Cc: qemu-stable@nongnu.org # dependency for the next patch
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit 9b706dbbbb)

Conflicts:
	hw/virtio/virtio.c

* drop context dep on ff4c07df
* resolv func dep on ff4c07df creating vdc variable in
  virtio_device_class_init()

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-08 13:50:54 -06:00
David Gibson 9df69dcd14 target-ppc: Fix CPU migration from qemu-2.6 <-> later versions
When migration for target-ppc was converted to vmstate, several
VMSTATE_EQUAL() checks were foolishly included of things that really
should be internal state.  Specifically we verified equality of the
insns_flags and insns_flags2 fields, which are used within TCG to
determine which groups of instructions are available on this cpu
model.  Between qemu-2.6 and qemu-2.7 we made some changes to these
classes which broke migration.

This path fixes migration both forwards and backwards.  On migration
from 2.6 to later versions we import the fields into teporary
variables, which we then ignore.  In migration backwards, we populate
the temporary fields from the runtime fields, but mask out the bits
which were added after qemu-2.6, allowing the VMSTATE_EQUAL in
qemu-2.6 to accept the stream.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit 16a2497bd4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-12-02 09:38:26 -06:00
Daniel P. Berrange 95a0638043 net: fix sending of data with -net socket, listen backend
The use of -net socket,listen was broken in the following
commit

  commit 16a3df403b
  Author: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
  Date:   Fri May 13 15:35:19 2016 +0800

    net/net: Add SocketReadState for reuse codes

    This function is from net/socket.c, move it to net.c and net.h.
    Add SocketReadState to make others reuse net_fill_rstate().
    suggestion from jason.

This refactored the state out of NetSocketState into a
separate SocketReadState. This refactoring requires
that a callback is provided to be triggered upon
completion of a packet receive from the guest.

The patch only registered this callback in the codepaths
hit by -net socket,connect, not -net socket,listen. So
as a result packets sent by the guest in the latter case
get dropped on the floor.

This bug is hidden because net_fill_rstate() silently
does nothing if the callback is not set.

This patch adds in the middle callback registration
and also adds an assert so that QEMU aborts if there
are any other codepaths hit which are missing the
callback.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit e79cd40680)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-18 19:06:19 -06:00
Corey Minyard 1790a9d77d acpi/ipmi: Initialize the fwinfo before fetching it
The initialization was missed before, resulting in some
bad data in the smbus case.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 698ae42b91)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-18 19:05:21 -06:00
Alex Williamson 1b16ded6a5 memory: Don't use memcpy for ram_device regions
With a vfio assigned device we lay down a base MemoryRegion registered
as an IO region, giving us read & write accessors.  If the region
supports mmap, we lay down a higher priority sub-region MemoryRegion
on top of the base layer initialized as a RAM device pointer to the
mmap.  Finally, if we have any quirks for the device (ie. address
ranges that need additional virtualization support), we put another IO
sub-region on top of the mmap MemoryRegion.  When this is flattened,
we now potentially have sub-page mmap MemoryRegions exposed which
cannot be directly mapped through KVM.

This is as expected, but a subtle detail of this is that we end up
with two different access mechanisms through QEMU.  If we disable the
mmap MemoryRegion, we make use of the IO MemoryRegion and service
accesses using pread and pwrite to the vfio device file descriptor.
If the mmap MemoryRegion is enabled and results in one of these
sub-page gaps, QEMU handles the access as RAM, using memcpy to the
mmap.  Using either pread/pwrite or the mmap directly should be
correct, but using memcpy causes us problems.  I expect that not only
does memcpy not necessarily honor the original width and alignment in
performing a copy, but it potentially also uses processor instructions
not intended for MMIO spaces.  It turns out that this has been a
problem for Realtek NIC assignment, which has such a quirk that
creates a sub-page mmap MemoryRegion access.

To resolve this, we disable memory_access_is_direct() for ram_device
regions since QEMU assumes that it can use memcpy for those regions.
Instead we access through MemoryRegionOps, which replaces the memcpy
with simple de-references of standard sizes to the host memory.

With this patch we attempt to provide unrestricted access to the RAM
device, allowing byte through qword access as well as unaligned
access.  The assumption here is that accesses initiated by the VM are
driven by a device specific driver, which knows the device
capabilities.  If unaligned accesses are not supported by the device,
we don't want them to work in a VM by performing multiple aligned
accesses to compose the unaligned access.  A down-side of this
philosophy is that the xp command from the monitor attempts to use
the largest available access weidth, unaware of the underlying
device.  Using memcpy had this same restriction, but at least now an
operator can dump individual registers, even if blocks of device
memory may result in access widths beyond the capabilities of a
given device (RTL NICs only support up to dword).

Reported-by: Thorsten Kohfeldt <thorsten.kohfeldt@gmx.de>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 4a2e242bbb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 18:19:01 -05:00
Alex Williamson ca83f87a66 memory: Replace skip_dump flag with "ram_device"
Setting skip_dump on a MemoryRegion allows us to modify one specific
code path, but the restriction we're trying to address encompasses
more than that.  If we have a RAM MemoryRegion backed by a physical
device, it not only restricts our ability to dump that region, but
also affects how we should manipulate it.  Here we recognize that
MemoryRegions do not change to sometimes allow dumps and other times
not, so we replace setting the skip_dump flag with a new initializer
so that we know exactly the type of region to which we're applying
this behavior.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 21e00fa55f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 18:19:01 -05:00
Prasad J Pandit 2817466c55 net: rtl8139: limit processing of ring descriptors
RTL8139 ethernet controller in C+ mode supports multiple
descriptor rings, each with maximum of 64 descriptors. While
processing transmit descriptor ring in 'rtl8139_cplus_transmit',
it does not limit the descriptor count and runs forever. Add
check to avoid it.

Reported-by: Andrew Henderson <hendersa@icculus.org>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit c7c3591669)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 18:19:01 -05:00
Alberto Garcia e389e44a35 qemu-iotests: Test I/O in a single drive from a throttling group
iotest 093 contains a test that creates a throttling group with
several drives and performs I/O in all of them. This patch adds a new
test that creates a similar setup but only performs I/O in one of the
drives at the same time.

This is useful to test that the round robin algorithm is behaving
properly in these scenarios, and is specifically written using the
regression introduced in 27ccdd5259 as an example.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit a26ddb4396)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 18:19:00 -05:00
Alberto Garcia b1fdc94193 throttle: Correct access to wrong BlockBackendPublic structures
In 27ccdd5259 the throttling fields were
moved from BlockDriverState to BlockBackend. However in a few cases
the code started using throttling fields from the active BlockBackend
instead of the round-robin token, making the algorithm behave
incorrectly.

This can cause starvation if there's a throttling group with several
drives but only one of them has I/O.

Cc: qemu-stable@nongnu.org
Reported-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 6bf77e1c2d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 18:19:00 -05:00
Thomas Huth 61781984db ppc/kvm: Mark 64kB page size support as disabled if not available
QEMU currently refuses to start with KVM-PR and only prints out

	qemu: fatal: Unknown MMU model 851972

when being started there. This is because commit 4322e8ced5
("ppc: Fix 64K pages support in full emulation") introduced a new
POWERPC_MMU_64K bit to indicate support for this page size, but
it never gets cleared on KVM-PR if the host kernel does not support
this. Thus we've got to turn off this bit in the mmu_model for KVM-PR.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 0d594f5565)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 18:19:00 -05:00
Paolo Bonzini 857efecf91 rbd: shift byte count as a 64-bit value
Otherwise, reads of more than 2GB fail.  Until commit
7bbca9e290, reads of 2^41
bytes succeeded at least theoretically.

In fact, pdiscard ought to receive a 64-bit integer as the
count for the same reason.

Reported by Coverity.

Fixes: 7bbca9e290
Cc: qemu-stable@nongnu.org
Cc: kwolf@redhat.com
Cc: eblake@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e948f663e9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 18:19:00 -05:00
Markus Armbruster 99837b0d36 tests/test-qmp-input-strict: Cover missing struct members
These tests would have caught the bug fixed by the previous commit.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1475594630-24758-1-git-send-email-armbru@redhat.com>
(cherry picked from commit bce3035a44)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 18:19:00 -05:00
Marc-André Lureau b34c7bd463 qapi: Fix crash when 'any' or 'null' parameter is missing
Unlike the other visit methods, visit_type_any() and visit_type_null()
neglect to check whether qmp_input_get_object() succeeded.  They crash
when it fails.  Reproducer:

{ "execute": "qom-set",
  "arguments": { "path": "/machine", "property": "rtc-time" } }

Will crash with:

qapi/qapi-visit-core.c:277: visit_type_any: Assertion `!err != !*obj'
failed

Broken in commit 5c678ee.  Fix by adding the missing error checks.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20160922203927.28241-3-marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Commit message rephrased]
Signed-off-by: Markus Armbruster <armbru@redhat.com>

(cherry picked from commit c489780203)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 18:18:54 -05:00
Marc-André Lureau f3467f56c1 qmp: fix object-add assert() without props
Since commit ad739706bb, user_creatable_add_type() expects to be
given a qdict. However, if object-add is called without props, you reach
the assert: "qemu/qom/object_interfaces.c:115: user_creatable_add_type:
Assertion `qdict' failed.", because the qdict isn't created in this
case (it's optional).

Furthermore, qmp_input_visitor_new() is not meant to be called without a
dict, and a further commit will assert in this situation.

If none given, create an empty qdict in qmp to avoid the
user_creatable_add_type() assert(qdict).

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20160922203927.28241-2-marcandre.lureau@redhat.com>
Tested-by: Xiao Long Jiang <zxiaol@linux.vnet.ibm.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit e64c75a975)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 17:24:25 -05:00
Daniel P. Berrange 5be5335661 char: fix missing return in error path for chardev TLS init
If the qio_channel_tls_new_(server|client) methods fail,
we disconnect the client. Unfortunately a missing return
means we then go on to try and run the TLS handshake on
a NULL I/O channel. This gives predictably segfaulty
results.

The main way to trigger this is to request a bogus TLS
priority string for the TLS credentials. e.g.

  -object tls-creds-x509,id=tls0,priority=wibble,...

Most other ways appear impossible to trigger except
perhaps if OOM conditions cause gnutls initialization
to fail.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 660a2d83e0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 17:16:58 -05:00
Emilio G. Cota af29bd3193 qht: fix unlock-after-free segfault upon resizing
The old map's bucket locks are being unlocked *after*
that same old map has been passed to RCU for destruction.
This is a bug that can cause a segfault, since there's
no guarantee that the deletion will be deferred (e.g.
there may be no concurrent readers).

The segfault is easily triggered in RHEL6/CentOS6 with qht-test,
particularly on a single-core system or by pinning qht-test
to a single core.

Fix it by unlocking the map's bucket locks right after having
published the new map, and (crucially) before marking the map
for deletion via call_rcu().

While at it, expand qht_do_resize() to atomically do (1) a reset,
(2) a resize, or (3) a reset+resize. This simplifies the calling
code, since the new function (qht_do_resize_reset()) acquires
and releases the buckets' locks.

Note that no qht_do_reset inline is provided, since it would have
no users--qht_reset() already performs a reset without taking
ht->lock.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Reported-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Emilio G. Cota <cota@braap.org>
Message-Id: <1475706880-10667-3-git-send-email-cota@braap.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 76b553b308)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 17:15:30 -05:00
Emilio G. Cota f72ca1ac6f qht: simplify qht_reset_size
Sometimes gcc doesn't pick up the fact that 'new' is properly
set if 'resize == true', which may generate an unnecessary
build warning.

Fix it by removing 'resize' and directly checking that 'new'
is non-NULL.

Signed-off-by: Emilio G. Cota <cota@braap.org>
Message-Id: <1475706880-10667-2-git-send-email-cota@braap.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit f555a9d0b3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 17:14:57 -05:00
Eric Blake 4d45fe11d1 migrate: Fix cpu-throttle-increment regression in HMP
Commit 69ef1f3 accidentally broke migrate_set_parameter's ability
to set the cpu-throttle-increment to anything other than the
default, because it forgot to parse the user's string into an
integer.

CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit bb2b777cf9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 17:10:51 -05:00
John Snow 4a25ab2a04 block-backend: remove blk_flush_all
We can teach Xen to drain and flush each device as it needs to, instead
of trying to flush ALL devices. This removes the last user of
blk_flush_all.

The function is therefore removed under the premise that any new uses
of blk_flush_all would be the wrong paradigm: either flush the single
device that requires flushing, or use an appropriate flush_all mechanism
from outside of the BlkBackend layer.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Acked-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 49137bf684)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 17:06:27 -05:00
John Snow 95200ebb50 qemu: use bdrv_flush_all for vm_stop et al
Reimplement bdrv_flush_all for vm_stop. In contrast to blk_flush_all,
bdrv_flush_all does not have device model restrictions. This allows
us to flush and halt unconditionally without error.

This allows us to do things like migrate when we have a device with
an open tray, but has a node that may need to be flushed, or nodes
that aren't currently attached to any device and need to be flushed.

Specifically, this allows us to migrate when we have a CDROM with
an open tray.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Acked-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 22af08eacf)
Conflicts:
	cpus.c

* drop context dependancy on 6d0ceb80

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 17:04:56 -05:00
John Snow 8e94512568 block: reintroduce bdrv_flush_all
Commit fe1a9cbc moved the flush_all routine from the bdrv layer to the
block-backend layer. In doing so, however, the semantics of the routine
changed slightly such that flush_all now used blk_flush instead of
bdrv_flush.

blk_flush can fail if the attached device model reports that it is not
"available," (i.e. the tray is open.) This changed the semantics of
flush_all such that it can now fail for e.g. open CDROM drives.

Reintroduce bdrv_flush_all to regain the old semantics without having to
alter the behavior of blk_flush or blk_flush_all, which are already
'doing the right thing.'

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Acked-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 4085f5c7a2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 17:01:44 -05:00
Eric Blake d40d148feb iscsi: Fix divide-by-zero regression on raw SG devices
When qemu uses iscsi devices in sg mode, iscsilun->block_size
is left at 0.  Prior to commits cf081fca and similar, when
block limits were tracked in sectors, this did not matter:
various block limits were just left at 0.  But when we started
scaling by block size, this caused SIGFPE.

Then, in a later patch, commit a5b8dd2c added an assertion to
bdrv_open_common() that request_alignment is always non-zero;
which was not true for SG mode.  Rather than relax that assertion,
we can just provide a sane value (we don't know of any SG device
with a block size smaller than qemu's default sizing of 512 bytes).

One possible solution for SG mode is to just blindly skip ALL
of iscsi_refresh_limits(), since we already short circuit so
many other things in sg mode.  But this patch takes a slightly
more conservative approach, and merely guarantees that scaling
will succeed, while still using multiples of the original size
where possible.  Resulting limits may still be zero in SG mode
(that is, we mostly only fix block_size used as a denominator
or which affect assertions, not all uses).

Reported-by: Holger Schranz <holger@fam-schranz.de>
Signed-off-by: Eric Blake <eblake@redhat.com>
CC: qemu-stable@nongnu.org

Message-Id: <1473283640-15756-1-git-send-email-eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 95eaa78537)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:53:21 -05:00
Daniel P. Berrange f9856029d5 qcow2: fix encryption during cow of sectors
Broken in previous commit:

  commit aaa4d20b49
  Author: Kevin Wolf <kwolf@redhat.com>
  Date:   Wed Jun 1 15:21:05 2016 +0200

      qcow2: Make copy_sectors() byte based

The copy_sectors() code was originally using the 'sector'
parameter for encryption, which was passed in by the caller
from the QCowL2Meta.offset field (aka the guest logical
offset).

After the change, the code is using 'cluster_offset' which
was passed in from QCow2L2Meta.alloc_offset field (aka the
host physical offset).

This would cause the data to be encrypted using an incorrect
initialization vector which will in turn cause later reads
to return garbage.

Although current qcow2 built-in encryption is blocked from
usage in the emulator, one could still hit this if writing
to the file via qemu-{img,io,nbd} commands.

Cc: qemu-stable@nongnu.org
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit bb9f8dd0e1)
Conflicts:
	tests/qemu-iotests/group

* drop context dependancy on non-2.7 iotest groups

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:51:20 -05:00
David Gibson a3a254550b vfio/pci: Fix regression in MSI routing configuration
d1f6af6 "kvm-irqchip: simplify kvm_irqchip_add_msi_route" was a cleanup
of kvmchip routing configuration, that was mostly intended for x86.
However, it also contains a subtle change in behaviour which breaks EEH[1]
error recovery on certain VFIO passthrough devices on spapr guests.  So far
it's only been seen on a BCM5719 NIC on a POWER8 server, but there may be
other hardware with the same problem.  It's also possible there could be
circumstances where it causes a bug on x86 as well, though I don't know of
any obvious candidates.

Prior to d1f6af6, both vfio_msix_vector_do_use() and
vfio_add_kvm_msi_virq() used msg == NULL as a special flag to mark this
as the "dummy" vector used to make the host hardware state sync with the
guest expected hardware state in terms of MSI configuration.

Specifically that flag caused vfio_add_kvm_msi_virq() to become a no-op,
meaning the dummy irq would always be delivered via qemu. d1f6af6 changed
vfio_add_kvm_msi_virq() so it takes a vector number instead of the msg
parameter, and determines the correct message itself.  The test for !msg
was removed, and not replaced with anything there or in the caller.

With an spapr guest which has a VFIO device, if an EEH error occurs on the
host hardware, then the device will be isolated then reset.  This is a
combination of host and guest action, mediated by some EEH related
hypercalls.  I haven't fully traced the mechanics, but somehow installing
the kvm irqchip route for the dummy irq on the BCM5719 means that after EEH
reset and recovery, at least some irqs are no longer delivered to the
guest.

In particular, the guest never gets the link up event, and so the NIC is
effectively dead.

[1] EEH (Enhanced Error Handling) is an IBM POWER server specific PCI-*
    error reporting and recovery mechanism.  The concept is somewhat
    similar to PCI-E AER, but the details are different.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1373802

Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Gavin Shan <gwshan@au1.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Cc: qemu-stable@nongnu.org
Fixes: d1f6af6a17 ("kvm-irqchip: simplify kvm_irqchip_add_msi_route")
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
(cherry picked from commit 6d17a018d0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:47:51 -05:00
Cornelia Huck 533dedf059 s390x/css: handle cssid 255 correctly
The cssid 255 is reserved but still valid from an architectural
point of view. However, feeding a bogus schid of 0xffffffff into
the virtio hypercall will lead to a crash:

Stack trace of thread 138363:
        #0  0x00000000100d168c css_find_subch (qemu-system-s390x)
        #1  0x00000000100d3290 virtio_ccw_hcall_notify
        #2  0x00000000100cbf60 s390_virtio_hypercall
        #3  0x000000001010ff7a handle_hypercall
        #4  0x0000000010079ed4 kvm_cpu_exec (qemu-system-s390x)
        #5  0x00000000100609b4 qemu_kvm_cpu_thread_fn
        #6  0x000003ff8b887bb4 start_thread (libpthread.so.0)
        #7  0x000003ff8b78df0a thread_start (libc.so.6)

This is because the css array was only allocated for 0..254
instead of 0..255.

Let's fix this by bumping MAX_CSSID to 255 and fencing off the
reserved cssid of 255 during css image allocation.

Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit 882b3b9769)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:36 -05:00
John Snow 54c26b7340 ahci: clear aiocb in ncq_cb
Similar to existing fixes for IDE (87ac25fd) and ATAPI (7f951b2d), the
AIOCB must be cleared in the callback. Otherwise, we may accidentally
try to reset a dangling pointer in bdrv_aio_cancel() from a port reset.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1474575040-32079-2-git-send-email-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit df403bc588)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:36 -05:00
Fam Zheng f5436d1dab virtio-scsi: Don't abort when media is ejected
With an ejected block backend, blk_get_aio_context() would return
qemu_aio_context. In this case don't assert.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <1473848224-24809-3-git-send-email-famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2a2d69f490)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:35 -05:00
Fam Zheng 3550eeafcd scsi-disk: Cleaning up around tray open state
Even if tray is not open, it can be empty (blk_is_inserted() == false).
Handle both cases correctly by replacing the s->tray_open checks with
blk_is_available(), which is an AND of the two.

Also simplify successive checks of them into blk_is_available(), in a
couple cases.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <1473848224-24809-2-git-send-email-famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit cd723b8560)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:35 -05:00
Fam Zheng 316c2c9448 iothread: Stop threads before main() quits
Right after main_loop ends, we release various things but keep iothread
alive. The latter is not prepared to the sudden change of resources.

Specifically, after bdrv_close_all(), virtio-scsi dataplane get a
surprise at the empty BlockBackend:

(gdb) bt
    at /usr/src/debug/qemu-2.6.0/hw/scsi/virtio-scsi.c:543
    at /usr/src/debug/qemu-2.6.0/hw/scsi/virtio-scsi.c:577

It is because the d->conf.blk->root is set to NULL, then
blk_get_aio_context() returns qemu_aio_context, whereas s->ctx is still
pointing to the iothread:

    hw/scsi/virtio-scsi.c:543:

    if (s->dataplane_started) {
        assert(blk_get_aio_context(d->conf.blk) == s->ctx);
    }

To fix this, let's stop iothreads before doing bdrv_close_all().

Cc: qemu-stable@nongnu.org
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1473326931-9699-1-git-send-email-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit dce8921b2b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:35 -05:00
Daniel P. Berrange 98b4465f7d crypto: ensure XTS is only used with ciphers with 16 byte blocks
The XTS cipher mode needs to be used with a cipher which has
a block size of 16 bytes. If a mis-matching block size is used,
the code will either corrupt memory beyond the IV array, or
not fully encrypt/decrypt the IV.

This fixes a memory corruption crash when attempting to use
cast5-128 with xts, since the former has an 8 byte block size.

A test case is added to ensure the cipher creation fails with
such an invalid combination.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit a5d2f44d0d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:35 -05:00
Paolo Bonzini 8342e1240b scsi: mptconfig: fix misuse of MPTSAS_CONFIG_PACK
These issues cause respectively a QEMU crash and a leak of 2 bytes of
stack.  They were discovered by VictorV of 360 Marvel Team.

Reported-by: Tom Victor <i-tangtianwen@360.cm>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 65a8e1f641)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:35 -05:00
Prasad J Pandit 0b6ab25367 scsi: mptconfig: fix an assert expression
When LSI SAS1068 Host Bus emulator builds configuration page
headers, mptsas_config_pack() should assert that the size
fits in a byte.  However, the size is expressed in 32-bit
units, so up to 1020 bytes fit.  The assertion was only
allowing replies up to 252 bytes, so fix it.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1472645167-30765-2-git-send-email-ppandit@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit cf2bce203a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:35 -05:00
Prasad J Pandit 742886578d vmw_pvscsi: check page count while initialising descriptor rings
Vmware Paravirtual SCSI emulation uses command descriptors to
process SCSI commands. These descriptors come with their ring
buffers. A guest could set the page count for these rings to
an arbitrary value, leading to infinite loop or OOB access.
Add check to avoid it.

Reported-by: Tom Victor <vv474172261@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1472626169-12989-1-git-send-email-ppandit@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7f61f4690d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:34 -05:00
Rony Weng 2f8e8c7396 scsi-disk: change disk serial length from 20 to 36
Openstack Cinder assigns volume a 36 characters uuid as serial.
QEMU will shrinks the uuid to 20 characters, which does not match
the original uuid.

Note that there is no limit to the length of the serial number in
the SCSI spec.  20 was copy-pasted from virtio-blk which in turn was
copy-pasted from ATA; 36 is even more arbitrary.  However, bumping it
up too much might cause issues (e.g. 252 seems to make sense because
then the maximum amount of returned data is 256; but who knows there's
no off-by-one somewhere for such a nicely rounded number).

Signed-off-by: Rony Weng <ronyweng@synology.com>
Message-Id: <1472457138-23386-1-git-send-email-ronyweng@synology.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 48b6206305)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:34 -05:00
Lin Ma 069e885d83 qemu-char: avoid segfault if user lacks of permisson of a given logfile
Function qemu_chr_alloc returns NULL if it failed to open logfile by any reason,
says no write permission. For backends tty, stdio and msmouse, They need to
check this return value to avoid segfault in this case.

Signed-off-by: Lin Ma <lma@suse.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Message-Id: <20160914062250.22226-1-lma@suse.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 71200fb966)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:34 -05:00
Prasad J Pandit bfb15f77bb scsi: pvscsi: limit process IO loop to ring size
Vmware Paravirtual SCSI emulator while processing IO requests
could run into an infinite loop if 'pvscsi_ring_pop_req_descr'
always returned positive value. Limit IO loop to the ring size.

Cc: qemu-stable@nongnu.org
Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1473845952-30785-1-git-send-email-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit d251157ac1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:34 -05:00
Li Qiang c6a7b922f8 scsi: mptsas: use g_new0 to allocate MPTSASRequest object
When processing IO request in mptsas, it uses g_new to allocate
a 'req' object. If an error occurs before 'req->sreq' is
allocated, It could lead to an OOB write in mptsas_free_request
function. Use g_new0 to avoid it.

Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1473684251-17476-1-git-send-email-ppandit@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 670e56d3ed)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:34 -05:00
Greg Kurz d06c61f310 9pfs: fix potential segfault during walk
If the call to fid_to_qid() returns an error, we will call v9fs_path_free()
on uninitialized paths.

It is a regression introduced by the following commit:

56f101ecce 9pfs: handle walk of ".." in the root directory

Let's fix this by initializing dpath and path before calling fid_to_qid().

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
[groug: updated the changelog to indicate this is regression and to provide
        the offending commit SHA1]
Signed-off-by: Greg Kurz <groug@kaod.org>

(cherry picked from commit 13fd08e631)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:34 -05:00
Gonglei 91a2f46297 vnc: fix qemu crash because of SIGSEGV
The backtrace is:

0x00007f0b75cdf880 in pixman_image_get_stride () from /lib64/libpixman-1.so.0
0x00007f0b77bcb3cf in vnc_server_fb_stride (vd=0x7f0b7a1a2bb0) at ui/vnc.c:680
vnc_dpy_copy (dcl=0x7f0b7a1a2c00, src_x=224, src_y=263, dst_x=319, dst_y=363, w=1, h=1) at ui/vnc.c:915
0x00007f0b77bbcc35 in dpy_gfx_copy (con=0x7f0b7a146210, src_x=src_x@entry=224, src_y=src_y@entry=263, dst_x=dst_x@entry=319,
dst_y=dst_y@entry=363, w=1, h=1) at ui/console.c:1575
0x00007f0b77bbda4e in qemu_console_copy (con=<optimized out>, src_x=src_x@entry=224, src_y=src_y@entry=263, dst_x=dst_x@entry=319,
dst_y=dst_y@entry=363, w=<optimized out>, h=<optimized out>) at ui/console.c:2111
0x00007f0b77ac0980 in cirrus_do_copy (h=<optimized out>, w=<optimized out>, src=<optimized out>, dst=<optimized out>, s=0x7f0b7b086090) at hw/display/cirrus_vga.c:774
cirrus_bitblt_videotovideo_copy (s=0x7f0b7b086090) at hw/display/cirrus_vga.c:793
cirrus_bitblt_videotovideo (s=0x7f0b7b086090) at hw/display/cirrus_vga.c:915
cirrus_bitblt_start (s=0x7f0b7b086090) at hw/display/cirrus_vga.c:1056
0x00007f0b77965cfb in memory_region_write_accessor (mr=0x7f0b7b096e40, addr=320, value=<optimized out>, size=1, shift=<optimized out>,mask=<optimized out>, attrs=...) at /root/rpmbuild/BUILD/master/qemu/memory.c:525
0x00007f0b77963f59 in access_with_adjusted_size (addr=addr@entry=320, value=value@entry=0x7f0b69a268d8, size=size@entry=4,
access_size_min=<optimized out>, access_size_max=<optimized out>, access=access@entry=0x7f0b77965c80 <memory_region_write_accessor>,
mr=mr@entry=0x7f0b7b096e40, attrs=attrs@entry=...) at /root/rpmbuild/BUILD/master/qemu/memory.c:591
0x00007f0b77968315 in memory_region_dispatch_write (mr=mr@entry=0x7f0b7b096e40, addr=addr@entry=320, data=18446744073709551362,
size=size@entry=4, attrs=attrs@entry=...) at /root/rpmbuild/BUILD/master/qemu/memory.c:1262
0x00007f0b779256a9 in address_space_write_continue (mr=0x7f0b7b096e40, l=4, addr1=320, len=4, buf=0x7f0b77713028 "\002\377\377\377",
attrs=..., addr=4273930560, as=0x7f0b7827d280 <address_space_memory>) at /root/rpmbuild/BUILD/master/qemu/exec.c:2544
address_space_write (as=<optimized out>, addr=<optimized out>, attrs=..., buf=<optimized out>, len=<optimized out>) at /root/rpmbuild/BUILD/master/qemu/exec.c:2601
0x00007f0b77925c1d in address_space_rw (as=<optimized out>, addr=<optimized out>, attrs=..., attrs@entry=...,
buf=buf@entry=0x7f0b77713028 "\002\377\377\377", len=<optimized out>, is_write=<optimized out>) at /root/rpmbuild/BUILD/master/qemu/exec.c:2703
0x00007f0b77962f53 in kvm_cpu_exec (cpu=cpu@entry=0x7f0b79fcc2d0) at /root/rpmbuild/BUILD/master/qemu/kvm-all.c:1965
0x00007f0b77950cc6 in qemu_kvm_cpu_thread_fn (arg=0x7f0b79fcc2d0) at /root/rpmbuild/BUILD/master/qemu/cpus.c:1078
0x00007f0b744b3dc5 in start_thread (arg=0x7f0b69a27700) at pthread_create.c:308
0x00007f0b70d3d66d in clone () from /lib64/libc.so.6

The code path while meeting segfault:
 vnc_dpy_copy
   vnc_update_client
     vnc_disconnect_finish [while vnc_disconnect_start() is invoked because somethins wrong]
       vnc_update_server_surface
         vd->server = NULL;
   vnc_server_fb_stride
     pixman_image_get_stride(vd->server)

Let's add a non-NULL check before calling vnc_server_fb_stride() to avoid segmentation fault.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Daniel P. Berrange <berrange@redhat.com>
Reported-by: Yanying Zhuang <ann.zhuangyanying@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 1472788698-120964-1-git-send-email-arei.gonglei@huawei.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 3e10c3ecfc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:33 -05:00
Ladi Prosek 520d4b288f virtio-balloon: discard virtqueue element on reset
The one pending element is being freed but not discarded on device
reset, which causes svq->inuse to creep up, eventually hitting the
"Virtqueue size exceeded" error.

Properly discarding the element on device reset makes sure that its
buffers are unmapped and the inuse counter stays balanced.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Roman Kagan <rkagan@virtuozzo.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 104e70cae7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:33 -05:00
Stefan Hajnoczi 4b6542dd17 virtio: zero vq->inuse in virtio_reset()
vq->inuse must be zeroed upon device reset like most other virtqueue
fields.

In theory, virtio_reset() just needs assert(vq->inuse == 0) since
devices must clean up in-flight requests during reset (requests cannot
not be leaked!).

In practice, it is difficult to achieve vq->inuse == 0 across reset
because balloon, blk, 9p, etc implement various different strategies for
cleaning up requests.  Most devices call g_free(elem) directly without
telling virtio.c that the VirtQueueElement is cleaned up.  Therefore
vq->inuse is not decremented during reset.

This patch zeroes vq->inuse and trusts that devices are not leaking
VirtQueueElements across reset.

I will send a follow-up series that refactors request life-cycle across
all devices and converts vq->inuse = 0 into assert(vq->inuse == 0) but
this more invasive approach is not appropriate for stable trees.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Cc: qemu-stable <qemu-stable@nongnu.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Ladi Prosek <lprosek@redhat.com>
(cherry picked from commit 4b7f91ed02)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2016-11-02 16:41:33 -05:00
Michael Roth c1a77fd6fa [stable] ppc-for-2.7 queue
-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCAAGBQJX/xWpAAoJEGw4ysog2bOSpP0P/jHSBZULGdT+l1CIPU72YH1F
 BneMVVjTkYLyOByngrxRDKwwwLXJT3eMgVXUZsENqDmPCWqglRljxYbk9GF4ZrAA
 h2/1RGHHRSE49RaulFSJYHWW+NHQiXNOMowlP4hlUfgSTVzRgY1ZFqc8F/EKOxOV
 9CLpHq1YqeCZ5+FyWRpG4Ydm51uFFdtGniqQVjSmuGHuMmhWlMmGcbmucA63dLPZ
 mRfShnYeC6/6mWyudEh7kx00Xf8QqyTEOz7s+Ct8bMl2FpHWw3fiXSLvW8YVIrks
 SrqFliJbONJZsbBwKFrgt2Ih1cnuPBXu7cVnoG2EEOAxLKbsPKrQImTtS7aeRCpx
 HpBCs+Qlsx0xRb9XS+Bjdy/l+R91T2MLCGpeCWmD3g7742zcVh8hD8yNm0AWhcO+
 UE2niXGX7PV/Kb6dqbKFY3ue0m93dDx1uvYZU0Fr1w3JZ2rFTvjp6JPpYqv2Vvbp
 4Sj+CoFYt3ow+mQpfMRmheM7G6Nc0pjRxshYL0mIVQH+1G7QHfgVVlw4Cnvfmj6s
 wvZzSapDdBEmCm27jczOhZA10oCu25x5FH3biL4FdOQKN0jA6NcoY+fvRHouAcpm
 66jNs7zpp6rtouI/PCmXyAm0FjhiEVooQZe3xnFrb8/k1RHFJLQwWKQkBB2/PQo4
 uhGnDs9EcmKo5D/Xg+Tt
 =sJlf
 -----END PGP SIGNATURE-----

Merge tag 'ppc-for-2.7-20161013' into stable-2.7-staging

qemu-2.7 (stable): ppc patch queue 2016-10-13

TCG for ppc does not properly implement hardware transactional memory.
It has a stub implementation in which transactions always fail.
Unfortunately in v2.7.0, HTM is advertised as being available to
guests, which means guests may incorrectly attempt to use it and hang.

This has been the case for a while, but has become more urgent with
recent (guest) Linux kernel versions which attempt to lazily enable
TM.  Under TCG that now triggers the problem regularly, instead of
just when running a TM aware userspace program.

The problem is already fixed in the 2.8/master branch, by correctly
advertising HTM as not being available with TCG.  This series
backports the relevant patches to the qemu-2.7 stable branch to fix
the problem there.

* tag 'ppc-for-2.7-20161013':
  ppc: Check the availability of transactional memory
  hw/ppc/spapr: Fix the selection of the processor features
  hw/ppc/spapr: Move code related to "ibm,pa-features" to a separate function
  linux-headers: update
2016-11-02 16:40:01 -05:00
94 changed files with 1069 additions and 314 deletions

View File

@ -1 +1 @@
2.7.0
2.7.1

View File

@ -139,7 +139,6 @@ static void msmouse_chr_close (struct CharDriverState *chr)
qemu_input_handler_unregister(mouse->hs);
g_free(mouse);
g_free(chr);
}
static QemuInputHandler msmouse_handler = {
@ -159,6 +158,9 @@ static CharDriverState *qemu_chr_open_msmouse(const char *id,
CharDriverState *chr;
chr = qemu_chr_alloc(common, errp);
if (!chr) {
return NULL;
}
chr->chr_write = msmouse_chr_write;
chr->chr_close = msmouse_chr_close;
chr->chr_accept_input = msmouse_chr_accept_input;

View File

@ -1296,6 +1296,11 @@ void blk_eject(BlockBackend *blk, bool eject_flag)
if (bs) {
bdrv_eject(bs, eject_flag);
}
/* Whether or not we ejected on the backend,
* the frontend experienced a tray event. */
qapi_event_send_device_tray_moved(blk_name(blk),
eject_flag, &error_abort);
}
int blk_get_flags(BlockBackend *blk)
@ -1624,28 +1629,6 @@ int blk_commit_all(void)
return 0;
}
int blk_flush_all(void)
{
BlockBackend *blk = NULL;
int result = 0;
while ((blk = blk_all_next(blk)) != NULL) {
AioContext *aio_context = blk_get_aio_context(blk);
int ret;
aio_context_acquire(aio_context);
if (blk_is_inserted(blk)) {
ret = blk_flush(blk);
if (ret < 0 && !result) {
result = ret;
}
}
aio_context_release(aio_context);
}
return result;
}
/* throttling disk I/O limits */
void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)

View File

@ -73,7 +73,6 @@ static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
#define CURL_NUM_STATES 8
#define CURL_NUM_ACB 8
#define SECTOR_SIZE 512
#define READ_AHEAD_DEFAULT (256 * 1024)
#define CURL_TIMEOUT_DEFAULT 5
#define CURL_TIMEOUT_MAX 10000
@ -106,12 +105,17 @@ typedef struct CURLAIOCB {
size_t end;
} CURLAIOCB;
typedef struct CURLSocket {
int fd;
QLIST_ENTRY(CURLSocket) next;
} CURLSocket;
typedef struct CURLState
{
struct BDRVCURLState *s;
CURLAIOCB *acb[CURL_NUM_ACB];
CURL *curl;
curl_socket_t sock_fd;
QLIST_HEAD(, CURLSocket) sockets;
char *orig_buf;
size_t buf_start;
size_t buf_off;
@ -165,10 +169,27 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
{
BDRVCURLState *s;
CURLState *state = NULL;
CURLSocket *socket;
curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
state->sock_fd = fd;
s = state->s;
QLIST_FOREACH(socket, &state->sockets, next) {
if (socket->fd == fd) {
if (action == CURL_POLL_REMOVE) {
QLIST_REMOVE(socket, next);
g_free(socket);
}
break;
}
}
if (!socket) {
socket = g_new0(CURLSocket, 1);
socket->fd = fd;
QLIST_INSERT_HEAD(&state->sockets, socket, next);
}
socket = NULL;
DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, (int)fd);
switch (action) {
case CURL_POLL_IN:
@ -214,12 +235,13 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
DPRINTF("CURL: Just reading %zd bytes\n", realsize);
if (!s || !s->orig_buf)
return 0;
if (!s || !s->orig_buf) {
goto read_end;
}
if (s->buf_off >= s->buf_len) {
/* buffer full, read nothing */
return 0;
goto read_end;
}
realsize = MIN(realsize, s->buf_len - s->buf_off);
memcpy(s->orig_buf + s->buf_off, ptr, realsize);
@ -232,15 +254,26 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
continue;
if ((s->buf_off >= acb->end)) {
size_t request_length = acb->nb_sectors * BDRV_SECTOR_SIZE;
qemu_iovec_from_buf(acb->qiov, 0, s->orig_buf + acb->start,
acb->end - acb->start);
if (acb->end - acb->start < request_length) {
size_t offset = acb->end - acb->start;
qemu_iovec_memset(acb->qiov, offset, 0,
request_length - offset);
}
acb->common.cb(acb->common.opaque, 0);
qemu_aio_unref(acb);
s->acb[i] = NULL;
}
}
return realsize;
read_end:
/* curl will error out if we do not return this value */
return size * nmemb;
}
static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
@ -248,6 +281,8 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
{
int i;
size_t end = start + len;
size_t clamped_end = MIN(end, s->len);
size_t clamped_len = clamped_end - start;
for (i=0; i<CURL_NUM_STATES; i++) {
CURLState *state = &s->states[i];
@ -262,12 +297,15 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
// Does the existing buffer cover our section?
if ((start >= state->buf_start) &&
(start <= buf_end) &&
(end >= state->buf_start) &&
(end <= buf_end))
(clamped_end >= state->buf_start) &&
(clamped_end <= buf_end))
{
char *buf = state->orig_buf + (start - state->buf_start);
qemu_iovec_from_buf(acb->qiov, 0, buf, len);
qemu_iovec_from_buf(acb->qiov, 0, buf, clamped_len);
if (clamped_len < len) {
qemu_iovec_memset(acb->qiov, clamped_len, 0, len - clamped_len);
}
acb->common.cb(acb->common.opaque, 0);
return FIND_RET_OK;
@ -277,13 +315,13 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
if (state->in_use &&
(start >= state->buf_start) &&
(start <= buf_fend) &&
(end >= state->buf_start) &&
(end <= buf_fend))
(clamped_end >= state->buf_start) &&
(clamped_end <= buf_fend))
{
int j;
acb->start = start - state->buf_start;
acb->end = acb->start + len;
acb->end = acb->start + clamped_len;
for (j=0; j<CURL_NUM_ACB; j++) {
if (!state->acb[j]) {
@ -353,6 +391,7 @@ static void curl_multi_check_completion(BDRVCURLState *s)
static void curl_multi_do(void *arg)
{
CURLState *s = (CURLState *)arg;
CURLSocket *socket, *next_socket;
int running;
int r;
@ -360,10 +399,13 @@ static void curl_multi_do(void *arg)
return;
}
do {
r = curl_multi_socket_action(s->s->multi, s->sock_fd, 0, &running);
} while(r == CURLM_CALL_MULTI_PERFORM);
/* Need to use _SAFE because curl_multi_socket_action() may trigger
* curl_sock_cb() which might modify this list */
QLIST_FOREACH_SAFE(socket, &s->sockets, next, next_socket) {
do {
r = curl_multi_socket_action(s->s->multi, socket->fd, 0, &running);
} while (r == CURLM_CALL_MULTI_PERFORM);
}
}
static void curl_multi_read(void *arg)
@ -467,6 +509,7 @@ static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)
#endif
}
QLIST_INIT(&state->sockets);
state->s = s;
return state;
@ -476,6 +519,14 @@ static void curl_clean_state(CURLState *s)
{
if (s->s->multi)
curl_multi_remove_handle(s->s->multi, s->curl);
while (!QLIST_EMPTY(&s->sockets)) {
CURLSocket *socket = QLIST_FIRST(&s->sockets);
QLIST_REMOVE(socket, next);
g_free(socket);
}
s->in_use = 0;
}
@ -725,12 +776,12 @@ static void curl_readv_bh_cb(void *p)
qemu_bh_delete(acb->bh);
acb->bh = NULL;
size_t start = acb->sector_num * SECTOR_SIZE;
size_t start = acb->sector_num * BDRV_SECTOR_SIZE;
size_t end;
// In case we have the requested data already (e.g. read-ahead),
// we can just call the callback and be done.
switch (curl_find_buf(s, start, acb->nb_sectors * SECTOR_SIZE, acb)) {
switch (curl_find_buf(s, start, acb->nb_sectors * BDRV_SECTOR_SIZE, acb)) {
case FIND_RET_OK:
qemu_aio_unref(acb);
// fall through
@ -749,13 +800,13 @@ static void curl_readv_bh_cb(void *p)
}
acb->start = 0;
acb->end = (acb->nb_sectors * SECTOR_SIZE);
acb->end = MIN(acb->nb_sectors * BDRV_SECTOR_SIZE, s->len - start);
state->buf_off = 0;
g_free(state->orig_buf);
state->buf_start = start;
state->buf_len = acb->end + s->readahead_size;
end = MIN(start + state->buf_len, s->len) - 1;
state->buf_len = MIN(acb->end + s->readahead_size, s->len - start);
end = start + state->buf_len - 1;
state->orig_buf = g_try_malloc(state->buf_len);
if (state->buf_len && state->orig_buf == NULL) {
curl_clean_state(state);
@ -766,8 +817,8 @@ static void curl_readv_bh_cb(void *p)
state->acb[0] = acb;
snprintf(state->range, 127, "%zd-%zd", start, end);
DPRINTF("CURL (AIO): Reading %d at %zd (%s)\n",
(acb->nb_sectors * SECTOR_SIZE), start, state->range);
DPRINTF("CURL (AIO): Reading %llu at %zd (%s)\n",
(acb->nb_sectors * BDRV_SECTOR_SIZE), start, state->range);
curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
curl_multi_add_handle(s->multi, state->curl);

View File

@ -1179,6 +1179,8 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX);
int alignment = MAX(bs->bl.pwrite_zeroes_alignment,
bs->bl.request_alignment);
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
MAX_WRITE_ZEROES_BOUNCE_BUFFER);
assert(alignment % bs->bl.request_alignment == 0);
head = offset % alignment;
@ -1194,9 +1196,12 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
* boundaries.
*/
if (head) {
/* Make a small request up to the first aligned sector. */
num = MIN(count, alignment - head);
head = 0;
/* Make a small request up to the first aligned sector. For
* convenience, limit this request to max_transfer even if
* we don't need to fall back to writes. */
num = MIN(MIN(count, max_transfer), alignment - head);
head = (head + num) % alignment;
assert(num < max_write_zeroes);
} else if (tail && num > alignment) {
/* Shorten the request to the last aligned sector. */
num -= tail;
@ -1222,8 +1227,6 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
if (ret == -ENOTSUP) {
/* Fall back to bounce buffer if write zeroes is unsupported */
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,
MAX_WRITE_ZEROES_BOUNCE_BUFFER);
BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;
if ((flags & BDRV_REQ_FUA) &&
@ -1615,6 +1618,31 @@ int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
BDRV_REQ_ZERO_WRITE | flags);
}
/*
* Flush ALL BDSes regardless of if they are reachable via a BlkBackend or not.
*/
int bdrv_flush_all(void)
{
BdrvNextIterator it;
BlockDriverState *bs = NULL;
int result = 0;
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
AioContext *aio_context = bdrv_get_aio_context(bs);
int ret;
aio_context_acquire(aio_context);
ret = bdrv_flush(bs);
if (ret < 0 && !result) {
result = ret;
}
aio_context_release(aio_context);
}
return result;
}
typedef struct BdrvCoGetBlockStatusData {
BlockDriverState *bs;
BlockDriverState *base;
@ -2356,7 +2384,9 @@ flush_parent:
ret = bs->file ? bdrv_co_flush(bs->file->bs) : 0;
out:
/* Notify any pending flushes that we have completed */
bs->flushed_gen = current_gen;
if (ret == 0) {
bs->flushed_gen = current_gen;
}
bs->active_flush_req = NULL;
/* Return value is ignored - it's ok if wait queue is empty */
qemu_co_queue_next(&bs->flush_queue);
@ -2407,7 +2437,7 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
{
BdrvTrackedRequest req;
int max_pdiscard, ret;
int head, align;
int head, tail, align;
if (!bs->drv) {
return -ENOMEDIUM;
@ -2430,19 +2460,15 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
return 0;
}
/* Discard is advisory, so ignore any unaligned head or tail */
/* Discard is advisory, but some devices track and coalesce
* unaligned requests, so we must pass everything down rather than
* round here. Still, most devices will just silently ignore
* unaligned requests (by returning -ENOTSUP), so we must fragment
* the request accordingly. */
align = MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment);
assert(align % bs->bl.request_alignment == 0);
head = offset % align;
if (head) {
head = MIN(count, align - head);
count -= head;
offset += head;
}
count = QEMU_ALIGN_DOWN(count, align);
if (!count) {
return 0;
}
tail = (offset + count) % align;
tracked_request_begin(&req, bs, offset, count, BDRV_TRACKED_DISCARD);
@ -2453,11 +2479,34 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, int64_t offset,
max_pdiscard = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pdiscard, INT_MAX),
align);
assert(max_pdiscard);
assert(max_pdiscard >= bs->bl.request_alignment);
while (count > 0) {
int ret;
int num = MIN(count, max_pdiscard);
int num = count;
if (head) {
/* Make small requests to get to alignment boundaries. */
num = MIN(count, align - head);
if (!QEMU_IS_ALIGNED(num, bs->bl.request_alignment)) {
num %= bs->bl.request_alignment;
}
head = (head + num) % align;
assert(num < max_pdiscard);
} else if (tail) {
if (num > align) {
/* Shorten the request to the last aligned cluster. */
num -= tail;
} else if (!QEMU_IS_ALIGNED(tail, bs->bl.request_alignment) &&
tail > bs->bl.request_alignment) {
tail %= bs->bl.request_alignment;
num -= tail;
}
}
/* limit request size */
if (num > max_pdiscard) {
num = max_pdiscard;
}
if (bs->drv->bdrv_co_pdiscard) {
ret = bs->drv->bdrv_co_pdiscard(bs, offset, num);

View File

@ -1048,7 +1048,9 @@ coroutine_fn iscsi_co_pdiscard(BlockDriverState *bs, int64_t offset, int count)
struct IscsiTask iTask;
struct unmap_list list;
assert(is_byte_request_lun_aligned(offset, count, iscsilun));
if (!is_byte_request_lun_aligned(offset, count, iscsilun)) {
return -ENOTSUP;
}
if (!iscsilun->lbp.lbpu) {
/* UNMAP is not supported by the target */
@ -1813,19 +1815,22 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
IscsiLun *iscsilun = bs->opaque;
uint64_t max_xfer_len = iscsilun->use_16_for_rw ? 0xffffffff : 0xffff;
unsigned int block_size = MAX(BDRV_SECTOR_SIZE, iscsilun->block_size);
bs->bl.request_alignment = iscsilun->block_size;
assert(iscsilun->block_size >= BDRV_SECTOR_SIZE || bs->sg);
bs->bl.request_alignment = block_size;
if (iscsilun->bl.max_xfer_len) {
max_xfer_len = MIN(max_xfer_len, iscsilun->bl.max_xfer_len);
}
if (max_xfer_len * iscsilun->block_size < INT_MAX) {
if (max_xfer_len * block_size < INT_MAX) {
bs->bl.max_transfer = max_xfer_len * iscsilun->block_size;
}
if (iscsilun->lbp.lbpu) {
if (iscsilun->bl.max_unmap < 0xffffffff / iscsilun->block_size) {
if (iscsilun->bl.max_unmap < 0xffffffff / block_size) {
bs->bl.max_pdiscard =
iscsilun->bl.max_unmap * iscsilun->block_size;
}
@ -1835,7 +1840,7 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.pdiscard_alignment = iscsilun->block_size;
}
if (iscsilun->bl.max_ws_len < 0xffffffff / iscsilun->block_size) {
if (iscsilun->bl.max_ws_len < 0xffffffff / block_size) {
bs->bl.max_pwrite_zeroes =
iscsilun->bl.max_ws_len * iscsilun->block_size;
}
@ -1846,7 +1851,7 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.pwrite_zeroes_alignment = iscsilun->block_size;
}
if (iscsilun->bl.opt_xfer_len &&
iscsilun->bl.opt_xfer_len < INT_MAX / iscsilun->block_size) {
iscsilun->bl.opt_xfer_len < INT_MAX / block_size) {
bs->bl.opt_transfer = pow2floor(iscsilun->bl.opt_xfer_len *
iscsilun->block_size);
}

View File

@ -427,7 +427,7 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
if (bs->encrypted) {
Error *err = NULL;
int64_t sector = (cluster_offset + offset_in_cluster)
int64_t sector = (src_cluster_offset + offset_in_cluster)
>> BDRV_SECTOR_BITS;
assert(s->cipher);
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);

View File

@ -1204,6 +1204,7 @@ static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.request_alignment = BDRV_SECTOR_SIZE;
}
bs->bl.pwrite_zeroes_alignment = s->cluster_size;
bs->bl.pdiscard_alignment = s->cluster_size;
}
static int qcow2_set_key(BlockDriverState *bs, const char *key)
@ -2485,6 +2486,11 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
int ret;
BDRVQcow2State *s = bs->opaque;
if (!QEMU_IS_ALIGNED(offset | count, s->cluster_size)) {
assert(count < s->cluster_size);
return -ENOTSUP;
}
qemu_co_mutex_lock(&s->lock);
ret = qcow2_discard_clusters(bs, offset, count >> BDRV_SECTOR_BITS,
QCOW2_DISCARD_REQUEST, false);

View File

@ -737,7 +737,7 @@ static BlockAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs,
void *opaque)
{
return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
(int64_t) nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
RBD_AIO_READ);
}
@ -749,7 +749,7 @@ static BlockAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
void *opaque)
{
return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
(int64_t) nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
RBD_AIO_WRITE);
}

View File

@ -2820,8 +2820,9 @@ static coroutine_fn int sd_co_pdiscard(BlockDriverState *bs, int64_t offset,
iov.iov_len = sizeof(zero);
discard_iov.iov = &iov;
discard_iov.niov = 1;
assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
assert((count & (BDRV_SECTOR_SIZE - 1)) == 0);
if (!QEMU_IS_ALIGNED(offset | count, BDRV_SECTOR_SIZE)) {
return -ENOTSUP;
}
acb = sd_aio_setup(bs, &discard_iov, offset >> BDRV_SECTOR_BITS,
count >> BDRV_SECTOR_BITS);
acb->aiocb_type = AIOCB_DISCARD_OBJ;

View File

@ -168,6 +168,22 @@ static BlockBackend *throttle_group_next_blk(BlockBackend *blk)
return blk_by_public(next);
}
/*
* Return whether a BlockBackend has pending requests.
*
* This assumes that tg->lock is held.
*
* @blk: the BlockBackend
* @is_write: the type of operation (read/write)
* @ret: whether the BlockBackend has pending requests.
*/
static inline bool blk_has_pending_reqs(BlockBackend *blk,
bool is_write)
{
const BlockBackendPublic *blkp = blk_get_public(blk);
return blkp->pending_reqs[is_write];
}
/* Return the next BlockBackend in the round-robin sequence with pending I/O
* requests.
*
@ -188,7 +204,7 @@ static BlockBackend *next_throttle_token(BlockBackend *blk, bool is_write)
/* get next bs round in round robin style */
token = throttle_group_next_blk(token);
while (token != start && !blkp->pending_reqs[is_write]) {
while (token != start && !blk_has_pending_reqs(token, is_write)) {
token = throttle_group_next_blk(token);
}
@ -196,10 +212,13 @@ static BlockBackend *next_throttle_token(BlockBackend *blk, bool is_write)
* then decide the token is the current bs because chances are
* the current bs get the current request queued.
*/
if (token == start && !blkp->pending_reqs[is_write]) {
if (token == start && !blk_has_pending_reqs(token, is_write)) {
token = blk;
}
/* Either we return the original BB, or one with pending requests */
assert(token == blk || blk_has_pending_reqs(token, is_write));
return token;
}
@ -257,7 +276,7 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
/* Check if there's any pending request to schedule next */
token = next_throttle_token(blk, is_write);
if (!blkp->pending_reqs[is_write]) {
if (!blk_has_pending_reqs(token, is_write)) {
return;
}
@ -271,7 +290,7 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
qemu_co_queue_next(&blkp->throttled_reqs[is_write])) {
token = blk;
} else {
ThrottleTimers *tt = &blkp->throttle_timers;
ThrottleTimers *tt = &blk_get_public(token)->throttle_timers;
int64_t now = qemu_clock_get_ns(tt->clock_type);
timer_mod(tt->timers[is_write], now + 1);
tg->any_timer_armed[is_write] = true;

4
cpus.c
View File

@ -745,7 +745,7 @@ static int do_vm_stop(RunState state)
}
bdrv_drain_all();
ret = blk_flush_all();
ret = bdrv_flush_all();
return ret;
}
@ -1488,7 +1488,7 @@ int vm_stop_force_state(RunState state)
bdrv_drain_all();
/* Make sure to return an error if the flush in a previous vm_stop()
* failed. */
return blk_flush_all();
return bdrv_flush_all();
}
}

View File

@ -192,6 +192,12 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
}
if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
if (ctx->blocksize != XTS_BLOCK_SIZE) {
error_setg(errp,
"Cipher block size %zu must equal XTS block size %d",
ctx->blocksize, XTS_BLOCK_SIZE);
goto error;
}
ctx->iv = g_new0(uint8_t, ctx->blocksize);
}

View File

@ -361,6 +361,13 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
goto error;
}
if (mode == QCRYPTO_CIPHER_MODE_XTS &&
ctx->blocksize != XTS_BLOCK_SIZE) {
error_setg(errp, "Cipher block size %zu must equal XTS block size %d",
ctx->blocksize, XTS_BLOCK_SIZE);
goto error;
}
ctx->iv = g_new0(uint8_t, ctx->blocksize);
cipher->opaque = ctx;
@ -456,11 +463,6 @@ int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
break;
case QCRYPTO_CIPHER_MODE_XTS:
if (ctx->blocksize != XTS_BLOCK_SIZE) {
error_setg(errp, "Block size must be %d not %zu",
XTS_BLOCK_SIZE, ctx->blocksize);
return -1;
}
xts_decrypt(ctx->ctx, ctx->ctx_tweak,
ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper,
ctx->iv, len, out, in);

View File

@ -73,6 +73,7 @@ typedef struct {
AioContext *ctx;
BlockAIOCB *acb;
QEMUSGList *sg;
uint32_t align;
uint64_t offset;
DMADirection dir;
int sg_cur_index;
@ -160,8 +161,9 @@ static void dma_blk_cb(void *opaque, int ret)
return;
}
if (dbs->iov.size & ~BDRV_SECTOR_MASK) {
qemu_iovec_discard_back(&dbs->iov, dbs->iov.size & ~BDRV_SECTOR_MASK);
if (!QEMU_IS_ALIGNED(dbs->iov.size, dbs->align)) {
qemu_iovec_discard_back(&dbs->iov,
QEMU_ALIGN_DOWN(dbs->iov.size, dbs->align));
}
dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
@ -199,7 +201,7 @@ static const AIOCBInfo dma_aiocb_info = {
};
BlockAIOCB *dma_blk_io(AioContext *ctx,
QEMUSGList *sg, uint64_t offset,
QEMUSGList *sg, uint64_t offset, uint32_t align,
DMAIOFunc *io_func, void *io_func_opaque,
BlockCompletionFunc *cb,
void *opaque, DMADirection dir)
@ -212,6 +214,7 @@ BlockAIOCB *dma_blk_io(AioContext *ctx,
dbs->sg = sg;
dbs->ctx = ctx;
dbs->offset = offset;
dbs->align = align;
dbs->sg_cur_index = 0;
dbs->sg_cur_byte = 0;
dbs->dir = dir;
@ -234,11 +237,11 @@ BlockAIOCB *dma_blk_read_io_func(int64_t offset, QEMUIOVector *iov,
}
BlockAIOCB *dma_blk_read(BlockBackend *blk,
QEMUSGList *sg, uint64_t offset,
QEMUSGList *sg, uint64_t offset, uint32_t align,
void (*cb)(void *opaque, int ret), void *opaque)
{
return dma_blk_io(blk_get_aio_context(blk),
sg, offset, dma_blk_read_io_func, blk, cb, opaque,
return dma_blk_io(blk_get_aio_context(blk), sg, offset, align,
dma_blk_read_io_func, blk, cb, opaque,
DMA_DIRECTION_FROM_DEVICE);
}
@ -252,11 +255,11 @@ BlockAIOCB *dma_blk_write_io_func(int64_t offset, QEMUIOVector *iov,
}
BlockAIOCB *dma_blk_write(BlockBackend *blk,
QEMUSGList *sg, uint64_t offset,
QEMUSGList *sg, uint64_t offset, uint32_t align,
void (*cb)(void *opaque, int ret), void *opaque)
{
return dma_blk_io(blk_get_aio_context(blk),
sg, offset, dma_blk_write_io_func, blk, cb, opaque,
return dma_blk_io(blk_get_aio_context(blk), sg, offset, align,
dma_blk_write_io_func, blk, cb, opaque,
DMA_DIRECTION_TO_DEVICE);
}

1
hmp.c
View File

@ -1284,6 +1284,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
break;
case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT:
has_cpu_throttle_increment = true;
use_int_value = true;
break;
case MIGRATION_PARAMETER_TLS_CREDS:
has_tls_creds = true;

View File

@ -1320,13 +1320,14 @@ static void v9fs_walk(void *opaque)
goto out_nofid;
}
v9fs_path_init(&dpath);
v9fs_path_init(&path);
err = fid_to_qid(pdu, fidp, &qid);
if (err < 0) {
goto out;
}
v9fs_path_init(&dpath);
v9fs_path_init(&path);
/*
* Both dpath and path initially poin to fidp.
* Needed to handle request with nwnames == 0

View File

@ -99,6 +99,7 @@ void build_acpi_ipmi_devices(Aml *scope, BusState *bus)
ii = IPMI_INTERFACE(obj);
iic = IPMI_INTERFACE_GET_CLASS(obj);
memset(&info, 0, sizeof(info));
iic->get_fwinfo(ii, &info);
aml_append(scope, aml_ipmi_device(&info));
}

View File

@ -60,6 +60,8 @@ typedef struct GUSState {
int64_t last_ticks;
qemu_irq pic;
IsaDma *isa_dma;
PortioList portio_list1;
PortioList portio_list2;
} GUSState;
static uint32_t gus_readb(void *opaque, uint32_t nport)
@ -265,9 +267,10 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;
s->mixbuf = g_malloc0 (s->samples << s->shift);
isa_register_portio_list (d, s->port, gus_portio_list1, s, "gus");
isa_register_portio_list (d, (s->port + 0x100) & 0xf00,
gus_portio_list2, s, "gus");
isa_register_portio_list(d, &s->portio_list1, s->port,
gus_portio_list1, s, "gus");
isa_register_portio_list(d, &s->portio_list2, (s->port + 0x100) & 0xf00,
gus_portio_list2, s, "gus");
s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->emu.gusdma);
k = ISADMA_GET_CLASS(s->isa_dma);

View File

@ -106,6 +106,7 @@ typedef struct SB16State {
/* mixer state */
int mixer_nreg;
uint8_t mixer_regs[256];
PortioList portio_list;
} SB16State;
static void SB_audio_callback (void *opaque, int free);
@ -1378,7 +1379,8 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
dolog ("warning: Could not create auxiliary timer\n");
}
isa_register_portio_list (isadev, s->port, sb16_ioport_list, s, "sb16");
isa_register_portio_list(isadev, &s->portio_list, s->port,
sb16_ioport_list, s, "sb16");
s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
k = ISADMA_GET_CLASS(s->isa_hdma);

View File

@ -692,6 +692,7 @@ struct FDCtrl {
/* Timers state */
uint8_t timer0;
uint8_t timer1;
PortioList portio_list;
};
static FloppyDriveType get_fallback_drive_type(FDrive *drv)
@ -2495,7 +2496,8 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
FDCtrl *fdctrl = &isa->state;
Error *err = NULL;
isa_register_portio_list(isadev, isa->iobase, fdc_portio_list, fdctrl,
isa_register_portio_list(isadev, &fdctrl->portio_list,
isa->iobase, fdc_portio_list, fdctrl,
"fdc");
isa_init_irq(isadev, &fdctrl->irq, isa->irq);

View File

@ -258,8 +258,10 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
req->has_sg = true;
dma_acct_start(n->conf.blk, &req->acct, &req->qsg, acct);
req->aiocb = is_write ?
dma_blk_write(n->conf.blk, &req->qsg, data_offset, nvme_rw_cb, req) :
dma_blk_read(n->conf.blk, &req->qsg, data_offset, nvme_rw_cb, req);
dma_blk_write(n->conf.blk, &req->qsg, data_offset, BDRV_SECTOR_SIZE,
nvme_rw_cb, req) :
dma_blk_read(n->conf.blk, &req->qsg, data_offset, BDRV_SECTOR_SIZE,
nvme_rw_cb, req);
return NVME_NO_COMPLETE;
}

View File

@ -80,6 +80,7 @@ typedef struct ParallelState {
uint32_t last_read_offset; /* For debugging */
/* Memory-mapped interface */
int it_shift;
PortioList portio_list;
} ParallelState;
#define TYPE_ISA_PARALLEL "isa-parallel"
@ -532,7 +533,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
s->status = dummy;
}
isa_register_portio_list(isadev, base,
isa_register_portio_list(isadev, &s->portio_list, base,
(s->hw_driver
? &isa_parallel_portio_hw_list[0]
: &isa_parallel_portio_sw_list[0]),

View File

@ -39,6 +39,8 @@ typedef struct ISAVGAState {
ISADevice parent_obj;
struct VGACommonState state;
PortioList portio_vga;
PortioList portio_vbe;
} ISAVGAState;
static void vga_isa_reset(DeviceState *dev)
@ -60,9 +62,11 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)
vga_common_init(s, OBJECT(dev), true);
s->legacy_address_space = isa_address_space(isadev);
vga_io_memory = vga_init_io(s, OBJECT(dev), &vga_ports, &vbe_ports);
isa_register_portio_list(isadev, 0x3b0, vga_ports, s, "vga");
isa_register_portio_list(isadev, &d->portio_vga,
0x3b0, vga_ports, s, "vga");
if (vbe_ports) {
isa_register_portio_list(isadev, 0x1ce, vbe_ports, s, "vbe");
isa_register_portio_list(isadev, &d->portio_vbe,
0x1ce, vbe_ports, s, "vbe");
}
memory_region_add_subregion_overlap(isa_address_space(isadev),
0x000a0000,

View File

@ -553,10 +553,12 @@ static void i8257_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(isa_address_space_io(isa),
d->base, &d->channel_io);
isa_register_portio_list(isa, d->page_base, page_portio_list, d,
isa_register_portio_list(isa, &d->portio_page,
d->page_base, page_portio_list, d,
"dma-page");
if (d->pageh_base >= 0) {
isa_register_portio_list(isa, d->pageh_base, pageh_portio_list, d,
isa_register_portio_list(isa, &d->portio_pageh,
d->pageh_base, pageh_portio_list, d,
"dma-pageh");
}

View File

@ -985,6 +985,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
mask = 7; /* Mask bit 2:0 in the SID field */
break;
}
mask = ~mask;
VTD_DPRINTF(INV, "device-selective invalidation source 0x%"PRIx16
" mask %"PRIu16, source_id, mask);
vtd_bus = vtd_find_as_from_bus_num(s, VTD_SID_TO_BUS(source_id));

View File

@ -1251,6 +1251,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
error_propagate(errp, local_err);
return -ENOTSUP;
}
dev->dev.cap_present |= QEMU_PCI_CAP_MSI;
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;
/* Only 32-bit/no-mask currently supported */
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSI, pos, 10,
@ -1285,6 +1286,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
error_propagate(errp, local_err);
return -ENOTSUP;
}
dev->dev.cap_present |= QEMU_PCI_CAP_MSIX;
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX;
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSIX, pos, 12,
&local_err);
@ -1648,6 +1650,7 @@ static void assigned_dev_register_msix_mmio(AssignedDevice *dev, Error **errp)
dev->msix_table = NULL;
return;
}
dev->dev.msix_table = (uint8_t *)dev->msix_table;
assigned_dev_msix_reset(dev);
@ -1665,6 +1668,7 @@ static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev)
error_report("error unmapping msix_table! %s", strerror(errno));
}
dev->msix_table = NULL;
dev->dev.msix_table = NULL;
}
static const VMStateDescription vmstate_assigned_device = {

View File

@ -134,8 +134,6 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
devices, and bit 2 the non-primary-master IDE devices. */
if (val & UNPLUG_ALL_IDE_DISKS) {
DPRINTF("unplug disks\n");
blk_drain_all();
blk_flush_all();
pci_unplug_disks(pci_dev->bus);
}
if (val & UNPLUG_ALL_NICS) {

View File

@ -948,6 +948,7 @@ static void ncq_cb(void *opaque, int ret)
NCQTransferState *ncq_tfs = (NCQTransferState *)opaque;
IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];
ncq_tfs->aiocb = NULL;
if (ret == -ECANCELED) {
return;
}
@ -1008,6 +1009,7 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
&ncq_tfs->sglist, BLOCK_ACCT_READ);
ncq_tfs->aiocb = dma_blk_read(ide_state->blk, &ncq_tfs->sglist,
ncq_tfs->lba << BDRV_SECTOR_BITS,
BDRV_SECTOR_SIZE,
ncq_cb, ncq_tfs);
break;
case WRITE_FPDMA_QUEUED:
@ -1021,6 +1023,7 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
&ncq_tfs->sglist, BLOCK_ACCT_WRITE);
ncq_tfs->aiocb = dma_blk_write(ide_state->blk, &ncq_tfs->sglist,
ncq_tfs->lba << BDRV_SECTOR_BITS,
BDRV_SECTOR_SIZE,
ncq_cb, ncq_tfs);
break;
default:

View File

@ -637,6 +637,23 @@ static unsigned int event_status_media(IDEState *s,
return 8; /* We wrote to 4 extra bytes from the header */
}
/*
* Before transferring data or otherwise signalling acceptance of a command
* marked CONDDATA, we must check the validity of the byte_count_limit.
*/
static bool validate_bcl(IDEState *s)
{
/* TODO: Check IDENTIFY data word 125 for defacult BCL (currently 0) */
if (s->atapi_dma || atapi_byte_count_limit(s)) {
return true;
}
/* TODO: Move abort back into core.c and introduce proper error flow between
* ATAPI layer and IDE core layer */
ide_abort_command(s);
return false;
}
static void cmd_get_event_status_notification(IDEState *s,
uint8_t *buf)
{
@ -1028,12 +1045,19 @@ static void cmd_read_cd(IDEState *s, uint8_t* buf)
return;
}
transfer_request = buf[9];
switch(transfer_request & 0xf8) {
case 0x00:
transfer_request = buf[9] & 0xf8;
if (transfer_request == 0x00) {
/* nothing */
ide_atapi_cmd_ok(s);
break;
return;
}
/* Check validity of BCL before transferring data */
if (!validate_bcl(s)) {
return;
}
switch (transfer_request) {
case 0x10:
/* normal read */
ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
@ -1266,6 +1290,14 @@ enum {
* See ATA8-ACS3 "7.21.5 Byte Count Limit"
*/
NONDATA = 0x04,
/*
* CONDDATA implies a command that transfers data only conditionally based
* on the presence of suboptions. It should be exempt from the BCL check at
* command validation time, but it needs to be checked at the command
* handler level instead.
*/
CONDDATA = 0x08,
};
static const struct AtapiCmd {
@ -1289,7 +1321,7 @@ static const struct AtapiCmd {
[ 0xad ] = { cmd_read_dvd_structure, CHECK_READY },
[ 0xbb ] = { cmd_set_speed, NONDATA },
[ 0xbd ] = { cmd_mechanism_status, 0 },
[ 0xbe ] = { cmd_read_cd, CHECK_READY },
[ 0xbe ] = { cmd_read_cd, CHECK_READY | CONDDATA },
/* [1] handler detects and reports not ready condition itself */
};
@ -1348,15 +1380,12 @@ void ide_atapi_cmd(IDEState *s)
return;
}
/* Nondata commands permit the byte_count_limit to be 0.
/* Commands that don't transfer DATA permit the byte_count_limit to be 0.
* If this is a data-transferring PIO command and BCL is 0,
* we abort at the /ATA/ level, not the ATAPI level.
* See ATA8 ACS3 section 7.17.6.49 and 7.21.5 */
if (cmd->handler && !(cmd->flags & NONDATA)) {
/* TODO: Check IDENTIFY data word 125 for default BCL (currently 0) */
if (!(atapi_byte_count_limit(s) || s->atapi_dma)) {
/* TODO: Move abort back into core.c and make static inline again */
ide_abort_command(s);
if (cmd->handler && !(cmd->flags & (NONDATA | CONDDATA))) {
if (!validate_bcl(s)) {
return;
}
}

View File

@ -882,15 +882,15 @@ static void ide_dma_cb(void *opaque, int ret)
switch (s->dma_cmd) {
case IDE_DMA_READ:
s->bus->dma->aiocb = dma_blk_read(s->blk, &s->sg, offset,
ide_dma_cb, s);
BDRV_SECTOR_SIZE, ide_dma_cb, s);
break;
case IDE_DMA_WRITE:
s->bus->dma->aiocb = dma_blk_write(s->blk, &s->sg, offset,
ide_dma_cb, s);
BDRV_SECTOR_SIZE, ide_dma_cb, s);
break;
case IDE_DMA_TRIM:
s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk),
&s->sg, offset,
&s->sg, offset, BDRV_SECTOR_SIZE,
ide_issue_trim, s->blk, ide_dma_cb, s,
DMA_DIRECTION_TO_DEVICE);
break;
@ -2582,7 +2582,7 @@ static void ide_restart_cb(void *opaque, int running, RunState state)
void ide_register_restart_cb(IDEBus *bus)
{
if (bus->dma->ops->restart_dma) {
qemu_add_vm_change_state_handler(ide_restart_cb, bus);
bus->vmstate = qemu_add_vm_change_state_handler(ide_restart_cb, bus);
}
}
@ -2619,10 +2619,12 @@ void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2)
{
/* ??? Assume only ISA and PCI configurations, and that the PCI-ISA
bridge has been setup properly to always register with ISA. */
isa_register_portio_list(dev, iobase, ide_portio_list, bus, "ide");
isa_register_portio_list(dev, &bus->portio_list,
iobase, ide_portio_list, bus, "ide");
if (iobase2) {
isa_register_portio_list(dev, iobase2, ide_portio2_list, bus, "ide");
isa_register_portio_list(dev, &bus->portio2_list,
iobase2, ide_portio2_list, bus, "ide");
}
}

View File

@ -179,6 +179,10 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
if (di != NULL && !di->media_cd) {
BlockBackend *blk = blk_by_legacy_dinfo(di);
DeviceState *ds = blk_get_attached_dev(blk);
blk_drain(blk);
blk_flush(blk);
if (ds) {
blk_detach_dev(blk, ds);
}

View File

@ -31,6 +31,7 @@
/* --------------------------------- */
static char *idebus_get_fw_dev_path(DeviceState *dev);
static void idebus_unrealize(DeviceState *qdev, Error **errp);
static Property ide_props[] = {
DEFINE_PROP_UINT32("unit", IDEDevice, unit, -1),
@ -44,6 +45,15 @@ static void ide_bus_class_init(ObjectClass *klass, void *data)
k->get_fw_dev_path = idebus_get_fw_dev_path;
}
static void idebus_unrealize(DeviceState *qdev, Error **errp)
{
IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);
if (bus->vmstate) {
qemu_del_vm_change_state_handler(bus->vmstate);
}
}
static const TypeInfo ide_bus_info = {
.name = TYPE_IDE_BUS,
.parent = TYPE_BUS,
@ -345,6 +355,7 @@ static void ide_device_class_init(ObjectClass *klass, void *data)
k->init = ide_qdev_init;
set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
k->bus_type = TYPE_IDE_BUS;
k->unrealize = idebus_unrealize;
k->props = ide_props;
}

View File

@ -131,24 +131,20 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
isa_init_ioport(dev, start);
}
void isa_register_portio_list(ISADevice *dev, uint16_t start,
void isa_register_portio_list(ISADevice *dev,
PortioList *piolist, uint16_t start,
const MemoryRegionPortio *pio_start,
void *opaque, const char *name)
{
PortioList piolist;
assert(piolist && !piolist->owner);
/* START is how we should treat DEV, regardless of the actual
contents of the portio array. This is how the old code
actually handled e.g. the FDC device. */
isa_init_ioport(dev, start);
/* FIXME: the device should store created PortioList in its state. Note
that DEV can be NULL here and that single device can register several
portio lists. Current implementation is leaking memory allocated
in portio_list_init. The leak is not critical because it happens only
at initialization time. */
portio_list_init(&piolist, OBJECT(dev), pio_start, opaque, name);
portio_list_add(&piolist, isabus->address_space_io, start);
portio_list_init(piolist, OBJECT(dev), pio_start, opaque, name);
portio_list_add(piolist, isabus->address_space_io, start);
}
static void isa_device_init(Object *obj)

View File

@ -859,7 +859,7 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
&s->ivshmem_mmio);
if (!s->not_legacy_32bit) {
if (s->not_legacy_32bit) {
attr |= PCI_BASE_ADDRESS_MEM_TYPE_64;
}
@ -1045,6 +1045,7 @@ static void ivshmem_plain_init(Object *obj)
ivshmem_check_memdev_is_busy,
OBJ_PROP_LINK_UNREF_ON_RELEASE,
&error_abort);
s->not_legacy_32bit = 1;
}
static void ivshmem_plain_realize(PCIDevice *dev, Error **errp)
@ -1116,6 +1117,7 @@ static void ivshmem_doorbell_init(Object *obj)
s->features |= (1 << IVSHMEM_MSI);
s->legacy_size = SIZE_MAX; /* whatever the server sends */
s->not_legacy_32bit = 1;
}
static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp)

View File

@ -2350,7 +2350,7 @@ static void rtl8139_cplus_transmit(RTL8139State *s)
{
int txcount = 0;
while (rtl8139_cplus_transmit_one(s))
while (txcount < 64 && rtl8139_cplus_transmit_one(s))
{
++txcount;
}

View File

@ -1904,6 +1904,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
vdc->guest_notifier_pending = virtio_net_guest_notifier_pending;
vdc->load = virtio_net_load_device;
vdc->save = virtio_net_save_device;
vdc->legacy_features |= (0x1 << VIRTIO_NET_F_GSO);
}
static const TypeInfo virtio_net_info = {

View File

@ -141,7 +141,8 @@ out_err:
int css_create_css_image(uint8_t cssid, bool default_image)
{
trace_css_new_image(cssid, default_image ? "(default)" : "");
if (cssid > MAX_CSSID) {
/* 255 is reserved */
if (cssid == 255) {
return -EINVAL;
}
if (channel_subsys.css[cssid]) {
@ -1267,7 +1268,7 @@ bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)
uint8_t real_cssid;
real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;
if (real_cssid > MAX_CSSID || ssid > MAX_SSID ||
if (ssid > MAX_SSID ||
!channel_subsys.css[real_cssid] ||
!channel_subsys.css[real_cssid]->sch_set[ssid]) {
return true;
@ -1282,9 +1283,6 @@ static int css_add_virtual_chpid(uint8_t cssid, uint8_t chpid, uint8_t type)
CssImage *css;
trace_css_chpid_add(cssid, chpid, type);
if (cssid > MAX_CSSID) {
return -EINVAL;
}
css = channel_subsys.css[cssid];
if (!css) {
return -EINVAL;

View File

@ -330,6 +330,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
if (!ccw.cda) {
ret = -EFAULT;
} else {
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
features.index = address_space_ldub(&address_space_memory,
ccw.cda
+ sizeof(features.features),
@ -339,7 +341,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
if (dev->revision >= 1) {
/* Don't offer legacy features for modern devices. */
features.features = (uint32_t)
(vdev->host_features & ~VIRTIO_LEGACY_FEATURES);
(vdev->host_features & ~vdc->legacy_features);
} else {
features.features = (uint32_t)vdev->host_features;
}

View File

@ -1981,7 +1981,11 @@ static void megasas_handle_frame(MegasasState *s, uint64_t frame_addr,
break;
}
if (frame_status != MFI_STAT_INVALID_STATUS) {
cmd->frame->header.cmd_status = frame_status;
if (cmd->frame) {
cmd->frame->header.cmd_status = frame_status;
} else {
megasas_frame_set_cmd_status(s, frame_addr, frame_status);
}
megasas_unmap_frame(s, cmd);
megasas_complete_frame(s, cmd->context);
}

View File

@ -158,7 +158,7 @@ static size_t mptsas_config_pack(uint8_t **data, const char *fmt, ...)
va_end(ap);
if (data) {
assert(ret < 256 && (ret % 4) == 0);
assert(ret / 4 < 256 && (ret % 4) == 0);
stb_p(*data + 1, ret / 4);
}
return ret;
@ -203,7 +203,7 @@ size_t mptsas_config_manufacturing_1(MPTSASState *s, uint8_t **data, int address
{
/* VPD - all zeros */
return MPTSAS_CONFIG_PACK(1, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
"s256");
"*s256");
}
static
@ -328,7 +328,7 @@ size_t mptsas_config_ioc_0(MPTSASState *s, uint8_t **data, int address)
return MPTSAS_CONFIG_PACK(0, MPI_CONFIG_PAGETYPE_IOC, 0x01,
"*l*lwwb*b*b*blww",
pcic->vendor_id, pcic->device_id, pcic->revision,
pcic->subsystem_vendor_id,
pcic->class_id, pcic->subsystem_vendor_id,
pcic->subsystem_id);
}

View File

@ -304,7 +304,7 @@ static int mptsas_process_scsi_io_request(MPTSASState *s,
goto bad;
}
req = g_new(MPTSASRequest, 1);
req = g_new0(MPTSASRequest, 1);
QTAILQ_INSERT_TAIL(&s->pending, req, next);
req->scsi_io = *scsi_io;
req->dev = s;

View File

@ -341,6 +341,7 @@ static void scsi_do_read(SCSIDiskReq *r, int ret)
r->req.resid -= r->req.sg->size;
r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
r->req.sg, r->sector << BDRV_SECTOR_BITS,
BDRV_SECTOR_SIZE,
sdc->dma_readv, r, scsi_dma_complete, r,
DMA_DIRECTION_FROM_DEVICE);
} else {
@ -396,7 +397,7 @@ static void scsi_read_data(SCSIRequest *req)
return;
}
if (s->tray_open) {
if (!blk_is_available(req->dev->conf.blk)) {
scsi_read_complete(r, -ENOMEDIUM);
return;
}
@ -519,7 +520,7 @@ static void scsi_write_data(SCSIRequest *req)
scsi_write_complete_noio(r, 0);
return;
}
if (s->tray_open) {
if (!blk_is_available(req->dev->conf.blk)) {
scsi_write_complete_noio(r, -ENOMEDIUM);
return;
}
@ -539,6 +540,7 @@ static void scsi_write_data(SCSIRequest *req)
r->req.resid -= r->req.sg->size;
r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
r->req.sg, r->sector << BDRV_SECTOR_BITS,
BDRV_SECTOR_SIZE,
sdc->dma_writev, r, scsi_dma_complete, r,
DMA_DIRECTION_TO_DEVICE);
} else {
@ -599,8 +601,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
}
l = strlen(s->serial);
if (l > 20) {
l = 20;
if (l > 36) {
l = 36;
}
DPRINTF("Inquiry EVPD[Serial number] "
@ -792,10 +794,7 @@ static inline bool media_is_dvd(SCSIDiskState *s)
if (s->qdev.type != TYPE_ROM) {
return false;
}
if (!blk_is_inserted(s->qdev.conf.blk)) {
return false;
}
if (s->tray_open) {
if (!blk_is_available(s->qdev.conf.blk)) {
return false;
}
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
@ -808,10 +807,7 @@ static inline bool media_is_cd(SCSIDiskState *s)
if (s->qdev.type != TYPE_ROM) {
return false;
}
if (!blk_is_inserted(s->qdev.conf.blk)) {
return false;
}
if (s->tray_open) {
if (!blk_is_available(s->qdev.conf.blk)) {
return false;
}
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
@ -875,7 +871,7 @@ static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
}
if (format != 0xff) {
if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
if (!blk_is_available(s->qdev.conf.blk)) {
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
return -1;
}
@ -1857,7 +1853,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
break;
default:
if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
if (!blk_is_available(s->qdev.conf.blk)) {
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
return 0;
}
@ -1886,7 +1882,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
memset(outbuf, 0, r->buflen);
switch (req->cmd.buf[0]) {
case TEST_UNIT_READY:
assert(!s->tray_open && blk_is_inserted(s->qdev.conf.blk));
assert(blk_is_available(s->qdev.conf.blk));
break;
case INQUIRY:
buflen = scsi_disk_emulate_inquiry(req, outbuf);
@ -2126,7 +2122,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
command = buf[0];
if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
if (!blk_is_available(s->qdev.conf.blk)) {
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
return 0;
}

View File

@ -236,6 +236,13 @@ static void virtio_scsi_cancel_notify(Notifier *notifier, void *data)
g_free(n);
}
static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d)
{
if (s->dataplane_started && d && blk_is_available(d->conf.blk)) {
assert(blk_get_aio_context(d->conf.blk) == s->ctx);
}
}
/* Return 0 if the request is ready to be completed and return to guest;
* -EINPROGRESS if the request is submitted and will be completed later, in the
* case of async cancellation. */
@ -247,9 +254,7 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
int target;
int ret = 0;
if (s->dataplane_started && d) {
assert(blk_get_aio_context(d->conf.blk) == s->ctx);
}
virtio_scsi_ctx_check(s, d);
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
req->resp.tmf.response = VIRTIO_SCSI_S_OK;
@ -539,9 +544,7 @@ static bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req
virtio_scsi_complete_cmd_req(req);
return false;
}
if (s->dataplane_started) {
assert(blk_get_aio_context(d->conf.blk) == s->ctx);
}
virtio_scsi_ctx_check(s, d);
req->sreq = scsi_req_new(d, req->req.cmd.tag,
virtio_scsi_get_lun(req->req.cmd.lun),
req->req.cmd.cdb, req);

View File

@ -152,7 +152,7 @@ pvscsi_log2(uint32_t input)
return log;
}
static int
static void
pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
{
int i;
@ -160,10 +160,6 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
uint32_t req_ring_size, cmp_ring_size;
m->rs_pa = ri->ringsStatePPN << VMW_PAGE_SHIFT;
if ((ri->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)
|| (ri->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)) {
return -1;
}
req_ring_size = ri->reqRingNumPages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
cmp_ring_size = ri->cmpRingNumPages * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE;
txr_len_log2 = pvscsi_log2(req_ring_size - 1);
@ -195,8 +191,6 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
/* Flush ring state page changes */
smp_wmb();
return 0;
}
static int
@ -251,8 +245,11 @@ static hwaddr
pvscsi_ring_pop_req_descr(PVSCSIRingInfo *mgr)
{
uint32_t ready_ptr = RS_GET_FIELD(mgr, reqProdIdx);
uint32_t ring_size = PVSCSI_MAX_NUM_PAGES_REQ_RING
* PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
if (ready_ptr != mgr->consumed_ptr) {
if (ready_ptr != mgr->consumed_ptr
&& ready_ptr - mgr->consumed_ptr < ring_size) {
uint32_t next_ready_ptr =
mgr->consumed_ptr++ & mgr->txr_len_mask;
uint32_t next_ready_page =
@ -746,7 +743,7 @@ pvscsi_dbg_dump_tx_rings_config(PVSCSICmdDescSetupRings *rc)
trace_pvscsi_tx_rings_num_pages("Confirm Ring", rc->cmpRingNumPages);
for (i = 0; i < rc->cmpRingNumPages; i++) {
trace_pvscsi_tx_rings_ppn("Confirm Ring", rc->reqRingPPNs[i]);
trace_pvscsi_tx_rings_ppn("Confirm Ring", rc->cmpRingPPNs[i]);
}
}
@ -779,11 +776,16 @@ pvscsi_on_cmd_setup_rings(PVSCSIState *s)
trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_RINGS");
pvscsi_dbg_dump_tx_rings_config(rc);
if (pvscsi_ring_init_data(&s->rings, rc) < 0) {
if (!rc->reqRingNumPages
|| rc->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
|| !rc->cmpRingNumPages
|| rc->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES) {
return PVSCSI_COMMAND_PROCESSING_FAILED;
}
pvscsi_dbg_dump_tx_rings_config(rc);
pvscsi_ring_init_data(&s->rings, rc);
s->rings_info_valid = TRUE;
return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
}

View File

@ -723,12 +723,11 @@ int vfio_region_mmap(VFIORegion *region)
name = g_strdup_printf("%s mmaps[%d]",
memory_region_name(region->mem), i);
memory_region_init_ram_ptr(&region->mmaps[i].mem,
memory_region_owner(region->mem),
name, region->mmaps[i].size,
region->mmaps[i].mmap);
memory_region_init_ram_device_ptr(&region->mmaps[i].mem,
memory_region_owner(region->mem),
name, region->mmaps[i].size,
region->mmaps[i].mmap);
g_free(name);
memory_region_set_skip_dump(&region->mmaps[i].mem);
memory_region_add_subregion(region->mem, region->mmaps[i].offset,
&region->mmaps[i].mem);

View File

@ -898,7 +898,7 @@ static uint64_t vfio_rtl8168_quirk_data_read(void *opaque,
{
VFIOrtl8168Quirk *rtl = opaque;
VFIOPCIDevice *vdev = rtl->vdev;
uint64_t data = vfio_region_read(&vdev->bars[2].region, addr + 0x74, size);
uint64_t data = vfio_region_read(&vdev->bars[2].region, addr + 0x70, size);
if (rtl->enabled && (vdev->pdev.cap_present & QEMU_PCI_CAP_MSIX)) {
hwaddr offset = rtl->addr & 0xfff;

View File

@ -496,7 +496,9 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
vfio_update_kvm_msi_virq(vector, *msg, pdev);
}
} else {
vfio_add_kvm_msi_virq(vdev, vector, nr, true);
if (msg) {
vfio_add_kvm_msi_virq(vdev, vector, nr, true);
}
}
/*

View File

@ -25,7 +25,7 @@ static bool vfio_prereg_listener_skipped_section(MemoryRegionSection *section)
}
return !memory_region_is_ram(section->mr) ||
memory_region_is_skip_dump(section->mr);
memory_region_is_ram_device(section->mr);
}
static void *vfio_prereg_gpa_to_vaddr(MemoryRegionSection *section, hwaddr gpa)

View File

@ -421,32 +421,73 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
dev->log_size = size;
}
static int vhost_verify_ring_part_mapping(void *part,
uint64_t part_addr,
uint64_t part_size,
uint64_t start_addr,
uint64_t size)
{
hwaddr l;
void *p;
int r = 0;
if (!ranges_overlap(start_addr, size, part_addr, part_size)) {
return 0;
}
l = part_size;
p = cpu_physical_memory_map(part_addr, &l, 1);
if (!p || l != part_size) {
r = -ENOMEM;
}
if (p != part) {
r = -EBUSY;
}
cpu_physical_memory_unmap(p, l, 0, 0);
return r;
}
static int vhost_verify_ring_mappings(struct vhost_dev *dev,
uint64_t start_addr,
uint64_t size)
{
int i;
int i, j;
int r = 0;
const char *part_name[] = {
"descriptor table",
"available ring",
"used ring"
};
for (i = 0; !r && i < dev->nvqs; ++i) {
for (i = 0; i < dev->nvqs; ++i) {
struct vhost_virtqueue *vq = dev->vqs + i;
hwaddr l;
void *p;
if (!ranges_overlap(start_addr, size, vq->ring_phys, vq->ring_size)) {
continue;
j = 0;
r = vhost_verify_ring_part_mapping(vq->desc, vq->desc_phys,
vq->desc_size, start_addr, size);
if (!r) {
break;
}
l = vq->ring_size;
p = cpu_physical_memory_map(vq->ring_phys, &l, 1);
if (!p || l != vq->ring_size) {
error_report("Unable to map ring buffer for ring %d", i);
r = -ENOMEM;
j++;
r = vhost_verify_ring_part_mapping(vq->avail, vq->avail_phys,
vq->avail_size, start_addr, size);
if (!r) {
break;
}
if (p != vq->ring) {
error_report("Ring buffer relocated for ring %d", i);
r = -EBUSY;
j++;
r = vhost_verify_ring_part_mapping(vq->used, vq->used_phys,
vq->used_size, start_addr, size);
if (!r) {
break;
}
cpu_physical_memory_unmap(p, l, 0, 0);
}
if (r == -ENOMEM) {
error_report("Unable to map %s for ring %d", part_name[j], i);
} else if (r == -EBUSY) {
error_report("%s relocated for ring %d", part_name[j], i);
}
return r;
}
@ -857,15 +898,15 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
}
}
s = l = virtio_queue_get_desc_size(vdev, idx);
a = virtio_queue_get_desc_addr(vdev, idx);
vq->desc_size = s = l = virtio_queue_get_desc_size(vdev, idx);
vq->desc_phys = a = virtio_queue_get_desc_addr(vdev, idx);
vq->desc = cpu_physical_memory_map(a, &l, 0);
if (!vq->desc || l != s) {
r = -ENOMEM;
goto fail_alloc_desc;
}
s = l = virtio_queue_get_avail_size(vdev, idx);
a = virtio_queue_get_avail_addr(vdev, idx);
vq->avail_size = s = l = virtio_queue_get_avail_size(vdev, idx);
vq->avail_phys = a = virtio_queue_get_avail_addr(vdev, idx);
vq->avail = cpu_physical_memory_map(a, &l, 0);
if (!vq->avail || l != s) {
r = -ENOMEM;
@ -879,14 +920,6 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
goto fail_alloc_used;
}
vq->ring_size = s = l = virtio_queue_get_ring_size(vdev, idx);
vq->ring_phys = a = virtio_queue_get_ring_addr(vdev, idx);
vq->ring = cpu_physical_memory_map(a, &l, 1);
if (!vq->ring || l != s) {
r = -ENOMEM;
goto fail_alloc_ring;
}
r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled);
if (r < 0) {
r = -errno;
@ -916,9 +949,6 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
fail_kick:
fail_alloc:
cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
0, 0);
fail_alloc_ring:
cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
0, 0);
fail_alloc_used:
@ -959,8 +989,6 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
vhost_vq_index);
}
cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
0, virtio_queue_get_ring_size(vdev, idx));
cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
1, virtio_queue_get_used_size(vdev, idx));
cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),

View File

@ -463,6 +463,7 @@ static void virtio_balloon_device_reset(VirtIODevice *vdev)
VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
if (s->stats_vq_elem != NULL) {
virtqueue_discard(s->svq, s->stats_vq_elem, 0);
g_free(s->stats_vq_elem);
s->stats_vq_elem = NULL;
}

View File

@ -1192,7 +1192,9 @@ static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
break;
case VIRTIO_PCI_COMMON_DF:
if (proxy->dfselect <= 1) {
val = (vdev->host_features & ~VIRTIO_LEGACY_FEATURES) >>
VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
val = (vdev->host_features & ~vdc->legacy_features) >>
(32 * proxy->dfselect);
}
break;

View File

@ -822,6 +822,7 @@ void virtio_reset(void *opaque)
vdev->vq[i].signalled_used_valid = false;
vdev->vq[i].notification = true;
vdev->vq[i].vring.num = vdev->vq[i].vring.num_default;
vdev->vq[i].inuse = 0;
}
}
@ -1965,12 +1966,15 @@ static Property virtio_properties[] = {
static void virtio_device_class_init(ObjectClass *klass, void *data)
{
/* Set the default value here. */
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = virtio_device_realize;
dc->unrealize = virtio_device_unrealize;
dc->bus_type = TYPE_VIRTIO_BUS;
dc->props = virtio_properties;
vdc->legacy_features |= VIRTIO_LEGACY_FEATURES;
}
static const TypeInfo virtio_device_info = {

View File

@ -336,6 +336,7 @@ int bdrv_inactivate_all(void);
/* Ensure contents are flushed to disk. */
int bdrv_flush(BlockDriverState *bs);
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
int bdrv_flush_all(void);
void bdrv_close_all(void);
void bdrv_drain(BlockDriverState *bs);
void coroutine_fn bdrv_co_drain(BlockDriverState *bs);

View File

@ -188,7 +188,7 @@ struct MemoryRegion {
void (*destructor)(MemoryRegion *mr);
uint64_t align;
bool terminates;
bool skip_dump;
bool ram_device;
bool enabled;
bool warning_printed; /* For reservations */
uint8_t vga_logging_count;
@ -425,6 +425,30 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
uint64_t size,
void *ptr);
/**
* memory_region_init_ram_device_ptr: Initialize RAM device memory region from
* a user-provided pointer.
*
* A RAM device represents a mapping to a physical device, such as to a PCI
* MMIO BAR of an vfio-pci assigned device. The memory region may be mapped
* into the VM address space and access to the region will modify memory
* directly. However, the memory region should not be included in a memory
* dump (device may not be enabled/mapped at the time of the dump), and
* operations incompatible with manipulating MMIO should be avoided. Replaces
* skip_dump flag.
*
* @mr: the #MemoryRegion to be initialized.
* @owner: the object that tracks the region's reference count
* @name: the name of the region.
* @size: size of the region.
* @ptr: memory to be mapped; must contain at least @size bytes.
*/
void memory_region_init_ram_device_ptr(MemoryRegion *mr,
struct Object *owner,
const char *name,
uint64_t size,
void *ptr);
/**
* memory_region_init_alias: Initialize a memory region that aliases all or a
* part of another memory region.
@ -551,22 +575,13 @@ static inline bool memory_region_is_ram(MemoryRegion *mr)
}
/**
* memory_region_is_skip_dump: check whether a memory region should not be
* dumped
* memory_region_is_ram_device: check whether a memory region is a ram device
*
* Returns %true is a memory region should not be dumped(e.g. VFIO BAR MMAP).
* Returns %true is a memory region is a device backed ram region
*
* @mr: the memory region being queried
*/
bool memory_region_is_skip_dump(MemoryRegion *mr);
/**
* memory_region_set_skip_dump: Set skip_dump flag, dump will ignore this memory
* region
*
* @mr: the memory region being queried
*/
void memory_region_set_skip_dump(MemoryRegion *mr);
bool memory_region_is_ram_device(MemoryRegion *mr);
/**
* memory_region_is_romd: check whether a memory region is in ROMD mode
@ -1431,9 +1446,11 @@ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
if (is_write) {
return memory_region_is_ram(mr) && !mr->readonly;
return memory_region_is_ram(mr) &&
!mr->readonly && !memory_region_is_ram_device(mr);
} else {
return memory_region_is_ram(mr) || memory_region_is_romd(mr);
return (memory_region_is_ram(mr) && !memory_region_is_ram_device(mr)) ||
memory_region_is_romd(mr);
}
}

View File

@ -480,6 +480,9 @@ struct IDEBus {
uint8_t retry_unit;
int64_t retry_sector_num;
uint32_t retry_nsector;
PortioList portio_list;
PortioList portio2_list;
VMChangeStateEntry *vmstate;
};
#define TYPE_IDE_DEVICE "ide-device"

View File

@ -36,6 +36,8 @@ typedef struct I8257State {
QEMUBH *dma_bh;
bool dma_bh_scheduled;
int running;
PortioList portio_page;
PortioList portio_pageh;
} I8257State;
#endif

View File

@ -134,12 +134,15 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start);
* device and use the legacy portio routines.
*
* @dev: the ISADevice against which these are registered; may be NULL.
* @piolist: the PortioList associated with the io ports
* @start: the base I/O port against which the portio->offset is applied.
* @portio: the ports, sorted by offset.
* @opaque: passed into the portio callbacks.
* @name: passed into memory_region_init_io.
*/
void isa_register_portio_list(ISADevice *dev, uint16_t start,
void isa_register_portio_list(ISADevice *dev,
PortioList *piolist,
uint16_t start,
const MemoryRegionPortio *portio,
void *opaque, const char *name);

View File

@ -20,7 +20,7 @@
#define MAX_DEVNO 65535
#define MAX_SCHID 65535
#define MAX_SSID 3
#define MAX_CSSID 254 /* 255 is reserved */
#define MAX_CSSID 255
#define MAX_CHPID 255
#define MAX_CIWS 62

View File

@ -14,11 +14,12 @@ struct vhost_virtqueue {
void *avail;
void *used;
int num;
unsigned long long desc_phys;
unsigned desc_size;
unsigned long long avail_phys;
unsigned avail_size;
unsigned long long used_phys;
unsigned used_size;
void *ring;
unsigned long long ring_phys;
unsigned ring_size;
EventNotifier masked_notifier;
};

View File

@ -112,6 +112,11 @@ typedef struct VirtioDeviceClass {
void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
void (*reset)(VirtIODevice *vdev);
void (*set_status)(VirtIODevice *vdev, uint8_t val);
/* For transitional devices, this is a bitmap of features
* that are only exposed on the legacy interface but not
* the modern one.
*/
uint64_t legacy_features;
/* Test and clear event pending status.
* Should be called after unmask to avoid losing events.
* If backend does not support masking,

View File

@ -149,7 +149,6 @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int count);
int blk_co_flush(BlockBackend *blk);
int blk_flush(BlockBackend *blk);
int blk_flush_all(void);
int blk_commit_all(void);
void blk_drain(BlockBackend *blk);
void blk_drain_all(void);

View File

@ -199,14 +199,14 @@ typedef BlockAIOCB *DMAIOFunc(int64_t offset, QEMUIOVector *iov,
void *opaque);
BlockAIOCB *dma_blk_io(AioContext *ctx,
QEMUSGList *sg, uint64_t offset,
QEMUSGList *sg, uint64_t offset, uint32_t align,
DMAIOFunc *io_func, void *io_func_opaque,
BlockCompletionFunc *cb, void *opaque, DMADirection dir);
BlockAIOCB *dma_blk_read(BlockBackend *blk,
QEMUSGList *sg, uint64_t offset,
QEMUSGList *sg, uint64_t offset, uint32_t align,
BlockCompletionFunc *cb, void *opaque);
BlockAIOCB *dma_blk_write(BlockBackend *blk,
QEMUSGList *sg, uint64_t offset,
QEMUSGList *sg, uint64_t offset, uint32_t align,
BlockCompletionFunc *cb, void *opaque);
uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);

View File

@ -35,5 +35,6 @@ typedef struct {
char *iothread_get_id(IOThread *iothread);
AioContext *iothread_get_aio_context(IOThread *iothread);
void iothread_stop_all(void);
#endif /* IOTHREAD_H */

View File

@ -54,16 +54,25 @@ static void *iothread_run(void *opaque)
return NULL;
}
static void iothread_instance_finalize(Object *obj)
static int iothread_stop(Object *object, void *opaque)
{
IOThread *iothread = IOTHREAD(obj);
IOThread *iothread;
if (!iothread->ctx) {
return;
iothread = (IOThread *)object_dynamic_cast(object, TYPE_IOTHREAD);
if (!iothread || !iothread->ctx) {
return 0;
}
iothread->stopping = true;
aio_notify(iothread->ctx);
qemu_thread_join(&iothread->thread);
return 0;
}
static void iothread_instance_finalize(Object *obj)
{
IOThread *iothread = IOTHREAD(obj);
iothread_stop(obj, NULL);
qemu_cond_destroy(&iothread->init_done_cond);
qemu_mutex_destroy(&iothread->init_done_lock);
aio_context_unref(iothread->ctx);
@ -174,3 +183,10 @@ IOThreadInfoList *qmp_query_iothreads(Error **errp)
object_child_foreach(container, query_one_iothread, &prev);
return head;
}
void iothread_stop_all(void)
{
Object *container = object_get_objects_root();
object_child_foreach(container, iothread_stop, NULL);
}

View File

@ -1132,6 +1132,71 @@ const MemoryRegionOps unassigned_mem_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
static uint64_t memory_region_ram_device_read(void *opaque,
hwaddr addr, unsigned size)
{
MemoryRegion *mr = opaque;
uint64_t data = (uint64_t)~0;
switch (size) {
case 1:
data = *(uint8_t *)(mr->ram_block->host + addr);
break;
case 2:
data = *(uint16_t *)(mr->ram_block->host + addr);
break;
case 4:
data = *(uint32_t *)(mr->ram_block->host + addr);
break;
case 8:
data = *(uint64_t *)(mr->ram_block->host + addr);
break;
}
trace_memory_region_ram_device_read(get_cpu_index(), mr, addr, data, size);
return data;
}
static void memory_region_ram_device_write(void *opaque, hwaddr addr,
uint64_t data, unsigned size)
{
MemoryRegion *mr = opaque;
trace_memory_region_ram_device_write(get_cpu_index(), mr, addr, data, size);
switch (size) {
case 1:
*(uint8_t *)(mr->ram_block->host + addr) = (uint8_t)data;
break;
case 2:
*(uint16_t *)(mr->ram_block->host + addr) = (uint16_t)data;
break;
case 4:
*(uint32_t *)(mr->ram_block->host + addr) = (uint32_t)data;
break;
case 8:
*(uint64_t *)(mr->ram_block->host + addr) = data;
break;
}
}
static const MemoryRegionOps ram_device_mem_ops = {
.read = memory_region_ram_device_read,
.write = memory_region_ram_device_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 1,
.max_access_size = 8,
.unaligned = true,
},
.impl = {
.min_access_size = 1,
.max_access_size = 8,
.unaligned = true,
},
};
bool memory_region_access_valid(MemoryRegion *mr,
hwaddr addr,
unsigned size,
@ -1359,9 +1424,16 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_fatal);
}
void memory_region_set_skip_dump(MemoryRegion *mr)
void memory_region_init_ram_device_ptr(MemoryRegion *mr,
Object *owner,
const char *name,
uint64_t size,
void *ptr)
{
mr->skip_dump = true;
memory_region_init_ram_ptr(mr, owner, name, size, ptr);
mr->ram_device = true;
mr->ops = &ram_device_mem_ops;
mr->opaque = mr;
}
void memory_region_init_alias(MemoryRegion *mr,
@ -1494,9 +1566,9 @@ const char *memory_region_name(const MemoryRegion *mr)
return mr->name;
}
bool memory_region_is_skip_dump(MemoryRegion *mr)
bool memory_region_is_ram_device(MemoryRegion *mr)
{
return mr->skip_dump;
return mr->ram_device;
}
uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr)

View File

@ -206,7 +206,7 @@ static void guest_phys_blocks_region_add(MemoryListener *listener,
/* we only care about RAM */
if (!memory_region_is_ram(section->mr) ||
memory_region_is_skip_dump(section->mr)) {
memory_region_is_ram_device(section->mr)) {
return;
}

View File

@ -1648,9 +1648,8 @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
if (rs->index >= rs->packet_len) {
rs->index = 0;
rs->state = 0;
if (rs->finalize) {
rs->finalize(rs);
}
assert(rs->finalize);
rs->finalize(rs);
}
break;
}

View File

@ -522,6 +522,7 @@ static int net_socket_listen_init(NetClientState *peer,
s->fd = -1;
s->listen_fd = fd;
s->nc.link_down = true;
net_socket_rs_init(&s->rs, net_socket_rs_finalize);
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
return 0;

View File

@ -338,6 +338,12 @@ static void qmp_input_type_any(Visitor *v, const char *name, QObject **obj,
QmpInputVisitor *qiv = to_qiv(v);
QObject *qobj = qmp_input_get_object(qiv, name, true);
if (!qobj) {
error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
*obj = NULL;
return;
}
qobject_incref(qobj);
*obj = qobj;
}
@ -347,6 +353,11 @@ static void qmp_input_type_null(Visitor *v, const char *name, Error **errp)
QmpInputVisitor *qiv = to_qiv(v);
QObject *qobj = qmp_input_get_object(qiv, name, true);
if (!qobj) {
error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
return;
}
if (qobject_type(qobj) != QTYPE_QNULL) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
"null");

View File

@ -1223,6 +1223,9 @@ static CharDriverState *qemu_chr_open_stdio(const char *id,
sigaction(SIGCONT, &act, NULL);
chr = qemu_chr_open_fd(0, 1, common, errp);
if (!chr) {
return NULL;
}
chr->chr_close = qemu_chr_close_stdio;
chr->chr_set_echo = qemu_chr_set_echo_stdio;
if (opts->has_signal) {
@ -1679,6 +1682,9 @@ static CharDriverState *qemu_chr_open_tty_fd(int fd,
tty_serial_init(fd, 115200, 'N', 8, 1);
chr = qemu_chr_open_fd(fd, fd, backend, errp);
if (!chr) {
return NULL;
}
chr->chr_ioctl = tty_serial_ioctl;
chr->chr_close = qemu_chr_close_tty;
return chr;
@ -3090,6 +3096,7 @@ static void tcp_chr_tls_init(CharDriverState *chr)
if (tioc == NULL) {
error_free(err);
tcp_chr_disconnect(chr);
return;
}
object_unref(OBJECT(s->ioc));
s->ioc = QIO_CHANNEL(tioc);

8
qmp.c
View File

@ -654,7 +654,7 @@ void qmp_add_client(const char *protocol, const char *fdname,
void qmp_object_add(const char *type, const char *id,
bool has_props, QObject *props, Error **errp)
{
const QDict *pdict = NULL;
QDict *pdict;
Visitor *v;
Object *obj;
@ -664,14 +664,18 @@ void qmp_object_add(const char *type, const char *id,
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
return;
}
QINCREF(pdict);
} else {
pdict = qdict_new();
}
v = qmp_input_visitor_new(props, true);
v = qmp_input_visitor_new(QOBJECT(pdict), true);
obj = user_creatable_add_type(type, id, pdict, v, errp);
visit_free(v);
if (obj) {
object_unref(obj);
}
QDECREF(pdict);
}
void qmp_object_del(const char *id, Error **errp)

View File

@ -92,7 +92,7 @@ module-common.o: CFLAGS += $(DSO_OBJ_CFLAGS)
$(if $(findstring /,$@),$(call quiet-command,cp $@ $(subst /,-,$@), " CP $(subst /,-,$@)"))
LD_REL := $(CC) -nostdlib -Wl,-r $(LD_REL_FLAGS)
LD_REL := $(CC) -nostdlib -r $(LD_REL_FLAGS)
%.mo:
$(call quiet-command,$(LD_REL) -o $@ $^," LD -r $(TARGET_DIR)$@")

View File

@ -66,6 +66,23 @@ void
sofree(struct socket *so)
{
Slirp *slirp = so->slirp;
struct mbuf *ifm;
for (ifm = (struct mbuf *) slirp->if_fastq.qh_link;
(struct quehead *) ifm != &slirp->if_fastq;
ifm = ifm->ifq_next) {
if (ifm->ifq_so == so) {
ifm->ifq_so = NULL;
}
}
for (ifm = (struct mbuf *) slirp->if_batchq.qh_link;
(struct quehead *) ifm != &slirp->if_batchq;
ifm = ifm->ifq_next) {
if (ifm->ifq_so == so) {
ifm->ifq_so = NULL;
}
}
if (so->so_emu==EMU_RSH && so->extra) {
sofree(so->extra);

View File

@ -1164,6 +1164,12 @@ struct PowerPCCPU {
int cpu_dt_id;
uint32_t max_compat;
uint32_t cpu_version;
/* fields used only during migration for compatibility hacks */
target_ulong mig_msr_mask;
uint64_t mig_insns_flags;
uint64_t mig_insns_flags2;
uint32_t mig_nb_BATs;
};
static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)

View File

@ -429,6 +429,7 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
CPUPPCState *env = &cpu->env;
long rampagesize;
int iq, ik, jq, jk;
bool has_64k_pages = false;
/* We only handle page sizes for 64-bit server guests for now */
if (!(env->mmu_model & POWERPC_MMU_64)) {
@ -472,6 +473,9 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
ksps->enc[jk].page_shift)) {
continue;
}
if (ksps->enc[jk].page_shift == 16) {
has_64k_pages = true;
}
qsps->enc[jq].page_shift = ksps->enc[jk].page_shift;
qsps->enc[jq].pte_enc = ksps->enc[jk].pte_enc;
if (++jq >= PPC_PAGE_SIZES_MAX_SZ) {
@ -486,6 +490,9 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
if (!(smmu_info.flags & KVM_PPC_1T_SEGMENTS)) {
env->mmu_model &= ~POWERPC_MMU_1TSEG;
}
if (!has_64k_pages) {
env->mmu_model &= ~POWERPC_MMU_64K;
}
}
#else /* defined (TARGET_PPC64) */

View File

@ -141,6 +141,21 @@ static void cpu_pre_save(void *opaque)
PowerPCCPU *cpu = opaque;
CPUPPCState *env = &cpu->env;
int i;
uint64_t insns_compat_mask =
PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB
| PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES
| PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES
| PPC_FLOAT_STFIWX | PPC_FLOAT_EXT
| PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ
| PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC
| PPC_64B | PPC_64BX | PPC_ALTIVEC
| PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD;
uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX
| PPC2_PERM_ISA206 | PPC2_DIVE_ISA206
| PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206
| PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207
| PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207
| PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM;
env->spr[SPR_LR] = env->lr;
env->spr[SPR_CTR] = env->ctr;
@ -162,6 +177,12 @@ static void cpu_pre_save(void *opaque)
env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4];
env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4];
}
/* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */
cpu->mig_msr_mask = env->msr_mask;
cpu->mig_insns_flags = env->insns_flags & insns_compat_mask;
cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2;
cpu->mig_nb_BATs = env->nb_BATs;
}
static int cpu_post_load(void *opaque, int version_id)
@ -562,10 +583,10 @@ const VMStateDescription vmstate_ppc_cpu = {
/* FIXME: access_type? */
/* Sanity checking */
VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
VMSTATE_UINTTL(mig_msr_mask, PowerPCCPU),
VMSTATE_UINT64(mig_insns_flags, PowerPCCPU),
VMSTATE_UINT64(mig_insns_flags2, PowerPCCPU),
VMSTATE_UINT32(mig_nb_BATs, PowerPCCPU),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {

View File

@ -622,7 +622,7 @@ tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y)
tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o
tests/postcopy-test$(EXESUF): tests/postcopy-test.o
tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y) $(test-io-obj-y)
tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y) $(test-io-obj-y) $(libqos-virtio-obj-y)
tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y)

View File

@ -14,6 +14,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
@ -22,6 +23,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
@ -40,6 +42,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -48,6 +51,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -286,12 +290,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
@ -308,12 +314,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
@ -330,12 +338,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
@ -352,12 +362,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
@ -374,12 +386,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
@ -396,12 +410,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
@ -513,6 +529,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -521,6 +538,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -539,6 +557,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -547,6 +566,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -611,6 +631,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_write_table; errno: 5; imm: off; once: off
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
@ -622,6 +643,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_write_table; errno: 28; imm: off; once: off
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.

View File

@ -14,6 +14,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
@ -22,6 +23,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
@ -40,6 +42,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -48,6 +51,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -294,12 +298,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
@ -316,12 +322,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
@ -338,12 +346,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
@ -360,12 +370,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
@ -382,12 +394,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
@ -404,12 +418,14 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.
@ -521,6 +537,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -529,6 +546,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -547,6 +565,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -555,6 +574,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
@ -619,6 +639,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_write_table; errno: 5; imm: off; once: off
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error
No errors were found on the image.
@ -630,6 +651,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_write_table; errno: 28; imm: off; once: off
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device
No errors were found on the image.

View File

@ -86,5 +86,7 @@ read failed: Input/output error
{"return": ""}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
QEMU_PROG: Failed to flush the L2 table cache: Input/output error
QEMU_PROG: Failed to flush the refcount block cache: Input/output error
*** done

View File

@ -53,7 +53,7 @@ class ThrottleTestCase(iotests.QMPTestCase):
result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **params)
self.assert_qmp(result, 'return', {})
def do_test_throttle(self, ndrives, seconds, params):
def do_test_throttle(self, ndrives, seconds, params, first_drive = 0):
def check_limit(limit, num):
# IO throttling algorithm is discrete, allow 10% error so the test
# is more robust
@ -85,12 +85,14 @@ class ThrottleTestCase(iotests.QMPTestCase):
# Send I/O requests to all drives
for i in range(rd_nr):
for drive in range(0, ndrives):
self.vm.hmp_qemu_io("drive%d" % drive, "aio_read %d %d" %
idx = first_drive + drive
self.vm.hmp_qemu_io("drive%d" % idx, "aio_read %d %d" %
(i * rq_size, rq_size))
for i in range(wr_nr):
for drive in range(0, ndrives):
self.vm.hmp_qemu_io("drive%d" % drive, "aio_write %d %d" %
idx = first_drive + drive
self.vm.hmp_qemu_io("drive%d" % idx, "aio_write %d %d" %
(i * rq_size, rq_size))
# We'll store the I/O stats for each drive in these arrays
@ -105,15 +107,17 @@ class ThrottleTestCase(iotests.QMPTestCase):
# Read the stats before advancing the clock
for i in range(0, ndrives):
idx = first_drive + i
start_rd_bytes[i], start_rd_iops[i], start_wr_bytes[i], \
start_wr_iops[i] = self.blockstats('drive%d' % i)
start_wr_iops[i] = self.blockstats('drive%d' % idx)
self.vm.qtest("clock_step %d" % ns)
# Read the stats after advancing the clock
for i in range(0, ndrives):
idx = first_drive + i
end_rd_bytes[i], end_rd_iops[i], end_wr_bytes[i], \
end_wr_iops[i] = self.blockstats('drive%d' % i)
end_wr_iops[i] = self.blockstats('drive%d' % idx)
# Check that the I/O is within the limits and evenly distributed
for i in range(0, ndrives):
@ -129,6 +133,7 @@ class ThrottleTestCase(iotests.QMPTestCase):
self.assertTrue(check_limit(params['iops_rd'], rd_iops))
self.assertTrue(check_limit(params['iops_wr'], wr_iops))
# Connect N drives to a VM and test I/O in all of them
def test_all(self):
params = {"bps": 4096,
"bps_rd": 4096,
@ -146,6 +151,24 @@ class ThrottleTestCase(iotests.QMPTestCase):
self.configure_throttle(ndrives, limits)
self.do_test_throttle(ndrives, 5, limits)
# Connect N drives to a VM and test I/O in just one of them a time
def test_one(self):
params = {"bps": 4096,
"bps_rd": 4096,
"bps_wr": 4096,
"iops": 10,
"iops_rd": 10,
"iops_wr": 10,
}
# Repeat the test for each one of the drives
for drive in range(0, self.max_drives):
# Pick each out of all possible params and test
for tk in params:
limits = dict([(k, 0) for k in params])
limits[tk] = params[tk] * self.max_drives
self.configure_throttle(self.max_drives, limits)
self.do_test_throttle(1, 5, limits, drive)
def test_burst(self):
params = {"bps": 4096,
"bps_rd": 4096,

View File

@ -1,5 +1,5 @@
.....
.......
----------------------------------------------------------------------
Ran 5 tests
Ran 7 tests
OK

View File

@ -0,0 +1,80 @@
#!/bin/bash
#
# Test encrypted read/write using backing files
#
# Copyright (C) 2015 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=berrange@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt qcow2
_supported_proto generic
_supported_os Linux
size=128M
TEST_IMG_BASE=$TEST_IMG.base
TEST_IMG_SAVE=$TEST_IMG
TEST_IMG=$TEST_IMG_BASE
echo "== create base =="
IMGOPTS="encryption=on" _make_test_img $size
TEST_IMG=$TEST_IMG_SAVE
echo
echo "== writing whole image =="
echo "astrochicken" | $QEMU_IO -c "write -P 0xa 0 $size" "$TEST_IMG_BASE" | _filter_qemu_io | _filter_testdir
echo
echo "== verify pattern =="
echo "astrochicken" | $QEMU_IO -c "read -P 0xa 0 $size" "$TEST_IMG_BASE" | _filter_qemu_io | _filter_testdir
echo "== create overlay =="
IMGOPTS="encryption=on" _make_test_img -b "$TEST_IMG_BASE" $size
echo
echo "== writing part of a cluster =="
echo "astrochicken" | $QEMU_IO -c "write -P 0xe 0 1024" "$TEST_IMG" | _filter_qemu_io | _filter_testdir
echo
echo "== verify pattern =="
echo "astrochicken" | $QEMU_IO -c "read -P 0xe 0 1024" "$TEST_IMG" | _filter_qemu_io | _filter_testdir
echo
echo "== verify pattern =="
echo "astrochicken" | $QEMU_IO -c "read -P 0xa 1024 64512" "$TEST_IMG" | _filter_qemu_io | _filter_testdir
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View File

@ -0,0 +1,36 @@
QA output created by 158
== create base ==
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 encryption=on
== writing whole image ==
Disk image 'TEST_DIR/t.qcow2.base' is encrypted.
password:
wrote 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== verify pattern ==
Disk image 'TEST_DIR/t.qcow2.base' is encrypted.
password:
read 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== create overlay ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base encryption=on
== writing part of a cluster ==
Disk image 'TEST_DIR/t.qcow2' is encrypted.
password:
wrote 1024/1024 bytes at offset 0
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== verify pattern ==
Disk image 'TEST_DIR/t.qcow2' is encrypted.
password:
read 1024/1024 bytes at offset 0
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== verify pattern ==
Disk image 'TEST_DIR/t.qcow2' is encrypted.
password:
read 64512/64512 bytes at offset 1024
63 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done

View File

@ -157,4 +157,5 @@
155 rw auto
156 rw auto quick
157 auto
158 rw auto quick
162 auto quick

View File

@ -370,6 +370,17 @@ static QCryptoCipherTestData test_data[] = {
"eb4a427d1923ce3ff262735779a418f2"
"0a282df920147beabe421ee5319d0568",
},
{
/* Bad config - cast5-128 has 8 byte block size
* which is incompatible with XTS
*/
.path = "/crypto/cipher/cast5-xts-128",
.alg = QCRYPTO_CIPHER_ALG_CAST5_128,
.mode = QCRYPTO_CIPHER_MODE_XTS,
.key =
"27182818284590452353602874713526"
"31415926535897932384626433832795",
}
};
@ -432,15 +443,23 @@ static void test_cipher(const void *opaque)
const QCryptoCipherTestData *data = opaque;
QCryptoCipher *cipher;
uint8_t *key, *iv, *ciphertext, *plaintext, *outtext;
size_t nkey, niv, nciphertext, nplaintext;
char *outtexthex;
uint8_t *key, *iv = NULL, *ciphertext = NULL,
*plaintext = NULL, *outtext = NULL;
size_t nkey, niv = 0, nciphertext = 0, nplaintext = 0;
char *outtexthex = NULL;
size_t ivsize, keysize, blocksize;
Error *err = NULL;
nkey = unhex_string(data->key, &key);
niv = unhex_string(data->iv, &iv);
nciphertext = unhex_string(data->ciphertext, &ciphertext);
nplaintext = unhex_string(data->plaintext, &plaintext);
if (data->iv) {
niv = unhex_string(data->iv, &iv);
}
if (data->ciphertext) {
nciphertext = unhex_string(data->ciphertext, &ciphertext);
}
if (data->plaintext) {
nplaintext = unhex_string(data->plaintext, &plaintext);
}
g_assert(nciphertext == nplaintext);
@ -449,8 +468,15 @@ static void test_cipher(const void *opaque)
cipher = qcrypto_cipher_new(
data->alg, data->mode,
key, nkey,
&error_abort);
g_assert(cipher != NULL);
&err);
if (data->plaintext) {
g_assert(err == NULL);
g_assert(cipher != NULL);
} else {
error_free_or_abort(&err);
g_assert(cipher == NULL);
goto cleanup;
}
keysize = qcrypto_cipher_get_key_len(data->alg);
blocksize = qcrypto_cipher_get_block_len(data->alg);
@ -498,6 +524,7 @@ static void test_cipher(const void *opaque)
g_assert_cmpstr(outtexthex, ==, data->plaintext);
cleanup:
g_free(outtext);
g_free(outtexthex);
g_free(key);

View File

@ -193,6 +193,50 @@ static void test_validate_fail_struct_nested(TestInputVisitorData *data,
g_assert(!udp);
}
static void test_validate_fail_struct_missing(TestInputVisitorData *data,
const void *unused)
{
Error *err = NULL;
Visitor *v;
QObject *any;
GenericAlternate *alt;
bool present;
int en;
int64_t i64;
uint32_t u32;
int8_t i8;
char *str;
double dbl;
v = validate_test_init(data, "{}");
visit_start_struct(v, NULL, NULL, 0, &error_abort);
visit_start_struct(v, "struct", NULL, 0, &err);
error_free_or_abort(&err);
visit_start_list(v, "list", NULL, 0, &err);
error_free_or_abort(&err);
visit_start_alternate(v, "alternate", &alt, sizeof(*alt), false, &err);
error_free_or_abort(&err);
visit_optional(v, "optional", &present);
g_assert(!present);
visit_type_enum(v, "enum", &en, EnumOne_lookup, &err);
error_free_or_abort(&err);
visit_type_int(v, "i64", &i64, &err);
error_free_or_abort(&err);
visit_type_uint32(v, "u32", &u32, &err);
error_free_or_abort(&err);
visit_type_int8(v, "i8", &i8, &err);
error_free_or_abort(&err);
visit_type_str(v, "i8", &str, &err);
error_free_or_abort(&err);
visit_type_number(v, "dbl", &dbl, &err);
error_free_or_abort(&err);
visit_type_any(v, "any", &any, &err);
error_free_or_abort(&err);
visit_type_null(v, "null", &err);
error_free_or_abort(&err);
visit_end_struct(v, NULL);
}
static void test_validate_fail_list(TestInputVisitorData *data,
const void *unused)
{
@ -316,6 +360,8 @@ int main(int argc, char **argv)
&testdata, test_validate_fail_struct);
validate_test_add("/visitor/input-strict/fail/struct-nested",
&testdata, test_validate_fail_struct_nested);
validate_test_add("/visitor/input-strict/fail/struct-missing",
&testdata, test_validate_fail_struct_missing);
validate_test_add("/visitor/input-strict/fail/list",
&testdata, test_validate_fail_list);
validate_test_add("/visitor/input-strict/fail/union-flat",

View File

@ -16,8 +16,13 @@
#include "qemu/sockets.h"
#include "sysemu/char.h"
#include "sysemu/sysemu.h"
#include "libqos/libqos.h"
#include "libqos/pci-pc.h"
#include "libqos/virtio-pci.h"
#include <linux/vhost.h>
#include <linux/virtio_ids.h>
#include <linux/virtio_net.h>
#include <sys/vfs.h>
/* GLIB version compatibility flags */
@ -29,14 +34,13 @@
#define HAVE_MONOTONIC_TIME
#endif
#define QEMU_CMD_ACCEL " -machine accel=tcg"
#define QEMU_CMD_MEM " -m %d -object memory-backend-file,id=mem,size=%dM,"\
"mem-path=%s,share=on -numa node,memdev=mem"
#define QEMU_CMD_CHR " -chardev socket,id=%s,path=%s%s"
#define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=%s,vhostforce"
#define QEMU_CMD_NET " -device virtio-net-pci,netdev=net0,romfile=./pc-bios/pxe-virtio.rom"
#define QEMU_CMD_NET " -device virtio-net-pci,netdev=net0"
#define QEMU_CMD QEMU_CMD_ACCEL QEMU_CMD_MEM QEMU_CMD_CHR \
#define QEMU_CMD QEMU_CMD_MEM QEMU_CMD_CHR \
QEMU_CMD_NETDEV QEMU_CMD_NET
#define HUGETLBFS_MAGIC 0x958458f6
@ -136,6 +140,30 @@ typedef struct TestServer {
static const char *tmpfs;
static const char *root;
static void init_virtio_dev(TestServer *s)
{
QPCIBus *bus;
QVirtioPCIDevice *dev;
uint32_t features;
bus = qpci_init_pc();
g_assert_nonnull(bus);
dev = qvirtio_pci_device_find(bus, VIRTIO_ID_NET);
g_assert_nonnull(dev);
qvirtio_pci_device_enable(dev);
qvirtio_reset(&qvirtio_pci, &dev->vdev);
qvirtio_set_acknowledge(&qvirtio_pci, &dev->vdev);
qvirtio_set_driver(&qvirtio_pci, &dev->vdev);
features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
features = features & VIRTIO_NET_F_MAC;
qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
}
static void wait_for_fds(TestServer *s)
{
gint64 end_time;
@ -548,6 +576,7 @@ static void test_migrate(void)
from = qtest_start(cmd);
g_free(cmd);
init_virtio_dev(s);
wait_for_fds(s);
size = get_log_size(s);
g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
@ -662,6 +691,7 @@ static void test_reconnect_subprocess(void)
qtest_start(cmd);
g_free(cmd);
init_virtio_dev(s);
wait_for_fds(s);
wait_for_rings_started(s, 2);
@ -728,6 +758,7 @@ int main(int argc, char **argv)
s = qtest_start(qemu_cmd);
g_free(qemu_cmd);
init_virtio_dev(server);
qtest_add_data_func("/vhost-user/read-guest-mem", server, read_guest_mem);
qtest_add_func("/vhost-user/migrate", test_migrate);

View File

@ -139,6 +139,8 @@ memory_region_subpage_read(int cpu_index, void *mr, uint64_t offset, uint64_t va
memory_region_subpage_write(int cpu_index, void *mr, uint64_t offset, uint64_t value, unsigned size) "cpu %d mr %p offset %#"PRIx64" value %#"PRIx64" size %u"
memory_region_tb_read(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr %#"PRIx64" value %#"PRIx64" size %u"
memory_region_tb_write(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr %#"PRIx64" value %#"PRIx64" size %u"
memory_region_ram_device_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr %#"PRIx64" value %#"PRIx64" size %u"
memory_region_ram_device_write(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr %#"PRIx64" value %#"PRIx64" size %u"
### Guest events, keep at bottom

View File

@ -1559,6 +1559,9 @@ static void gd_change_page(GtkNotebook *nb, gpointer arg1, guint arg2,
TRUE);
}
gtk_widget_set_sensitive(s->grab_item, on_vga);
#ifdef CONFIG_VTE
gtk_widget_set_sensitive(s->copy_item, vc->type == GD_VC_VTE);
#endif
gd_update_windowsize(vc);
gd_update_cursor(vc);
@ -2230,6 +2233,11 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
}
#endif
#ifdef CONFIG_VTE
gtk_widget_set_sensitive(s->copy_item,
gd_vc_find_current(s)->type == GD_VC_VTE);
#endif
if (full_screen) {
gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
}

View File

@ -911,6 +911,10 @@ static void vnc_dpy_copy(DisplayChangeListener *dcl,
}
}
if (!vd->server) {
/* no client connected */
return;
}
/* do bitblit op on the local surface too */
pitch = vnc_server_fb_stride(vd);
src_row = vnc_server_fb_ptr(vd, src_x, src_y);

View File

@ -133,7 +133,8 @@ struct qht_map {
/* trigger a resize when n_added_buckets > n_buckets / div */
#define QHT_NR_ADDED_BUCKETS_THRESHOLD_DIV 8
static void qht_do_resize(struct qht *ht, struct qht_map *new);
static void qht_do_resize_reset(struct qht *ht, struct qht_map *new,
bool reset);
static void qht_grow_maybe(struct qht *ht);
#ifdef QHT_DEBUG
@ -408,12 +409,21 @@ void qht_reset(struct qht *ht)
qht_map_unlock_buckets(map);
}
static inline void qht_do_resize(struct qht *ht, struct qht_map *new)
{
qht_do_resize_reset(ht, new, false);
}
static inline void qht_do_resize_and_reset(struct qht *ht, struct qht_map *new)
{
qht_do_resize_reset(ht, new, true);
}
bool qht_reset_size(struct qht *ht, size_t n_elems)
{
struct qht_map *new;
struct qht_map *new = NULL;
struct qht_map *map;
size_t n_buckets;
bool resize = false;
n_buckets = qht_elems_to_buckets(n_elems);
@ -421,18 +431,11 @@ bool qht_reset_size(struct qht *ht, size_t n_elems)
map = ht->map;
if (n_buckets != map->n_buckets) {
new = qht_map_create(n_buckets);
resize = true;
}
qht_map_lock_buckets(map);
qht_map_reset__all_locked(map);
if (resize) {
qht_do_resize(ht, new);
}
qht_map_unlock_buckets(map);
qht_do_resize_and_reset(ht, new);
qemu_mutex_unlock(&ht->lock);
return resize;
return !!new;
}
static inline
@ -561,9 +564,7 @@ static __attribute__((noinline)) void qht_grow_maybe(struct qht *ht)
if (qht_map_needs_resize(map)) {
struct qht_map *new = qht_map_create(map->n_buckets * 2);
qht_map_lock_buckets(map);
qht_do_resize(ht, new);
qht_map_unlock_buckets(map);
}
qemu_mutex_unlock(&ht->lock);
}
@ -739,24 +740,31 @@ static void qht_map_copy(struct qht *ht, void *p, uint32_t hash, void *userp)
}
/*
* Call with ht->lock and all bucket locks held.
*
* Creating the @new map here would add unnecessary delay while all the locks
* are held--holding up the bucket locks is particularly bad, since no writes
* can occur while these are held. Thus, we let callers create the new map,
* hopefully without the bucket locks held.
* Atomically perform a resize and/or reset.
* Call with ht->lock held.
*/
static void qht_do_resize(struct qht *ht, struct qht_map *new)
static void qht_do_resize_reset(struct qht *ht, struct qht_map *new, bool reset)
{
struct qht_map *old;
old = ht->map;
g_assert_cmpuint(new->n_buckets, !=, old->n_buckets);
qht_map_lock_buckets(old);
if (reset) {
qht_map_reset__all_locked(old);
}
if (new == NULL) {
qht_map_unlock_buckets(old);
return;
}
g_assert_cmpuint(new->n_buckets, !=, old->n_buckets);
qht_map_iter__all_locked(ht, old, qht_map_copy, new);
qht_map_debug__all_locked(new);
atomic_rcu_set(&ht->map, new);
qht_map_unlock_buckets(old);
call_rcu(old, qht_map_destroy, rcu);
}
@ -768,12 +776,9 @@ bool qht_resize(struct qht *ht, size_t n_elems)
qemu_mutex_lock(&ht->lock);
if (n_buckets != ht->map->n_buckets) {
struct qht_map *new;
struct qht_map *old = ht->map;
new = qht_map_create(n_buckets);
qht_map_lock_buckets(old);
qht_do_resize(ht, new);
qht_map_unlock_buckets(old);
ret = true;
}
qemu_mutex_unlock(&ht->lock);

15
vl.c
View File

@ -121,6 +121,7 @@ int main(int argc, char **argv)
#include "crypto/init.h"
#include "sysemu/replay.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/iothread.h"
#define MAX_VIRTIO_CONSOLES 1
#define MAX_SCLP_CONSOLES 1
@ -2810,6 +2811,19 @@ static bool object_create_initial(const char *type)
return false;
}
/* Memory allocation by backends needs to be done
* after configure_accelerator() (due to the tcg_enabled()
* checks at memory_region_init_*()).
*
* Also, allocation of large amounts of memory may delay
* chardev initialization for too long, and trigger timeouts
* on software that waits for a monitor socket to be created
* (e.g. libvirt).
*/
if (g_str_has_prefix(type, "memory-backend-")) {
return false;
}
return true;
}
@ -4603,6 +4617,7 @@ int main(int argc, char **argv, char **envp)
trace_init_vcpu_events();
main_loop();
replay_disable_events();
iothread_stop_all();
bdrv_close_all();
pause_all_vcpus();