Compare commits

...
87 Commits
Author SHA1 Message Date
Peter Maydell 32a1a94dd3 Update version for v3.1.0 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-11 17:18:37 +00:00
Peter Maydell 4f818e7b7f Update version for v3.1.0-rc5 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-06 17:07:12 +00:00
Prasad J Pandit f2609ffdf3 i2c: pm_smbus: check smb_index before block transfer write
While performing block transfer write in smb_ioport_writeb(),
'smb_index' is incremented and used to index smb_data[] array.
Check 'smb_index' value to avoid OOB access.

Note that this bug is exploitable by a guest to escape
from the virtual machine. However the commit which
introduced the bug was only made after the 3.0 release,
and so it is not present in any released QEMU versions.

Fixes: 38ad4fae43 i2c: pm_smbus: Add block transfer capability
Reported-by: Michael Hanselmann <public@hansmi.ch>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Michael Hanselmann <public@hansmi.ch>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-id: 20181206121830.6177-1-ppandit@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-06 15:51:57 +00:00
Peter Maydell 80422b0019 Update version for v3.1.0-rc4 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-04 18:31:50 +00:00
Jason Wang 118cafff25 virtio-net-test: add large tx buffer test
This test tries to build a packet whose size is greater than INT_MAX
which tries to trigger integer overflow in qemu_net_queue_append_iov()
which may result OOB.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-id: 20181204035347.6148-6-jasowang@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-04 11:06:15 +00:00
Jason Wang 432a82d727 virtio-net-test: remove unused macro
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Message-id: 20181204035347.6148-5-jasowang@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-04 11:06:15 +00:00
Jason Wang ae4c445c6f virtio-net-test: accept variable length argument in pci_test_start()
This allows flexibility to be reused for all kinds of command line
used by other tests.

Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Message-id: 20181204035347.6148-4-jasowang@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-04 11:06:15 +00:00
Jason Wang 56512e1dc1 net: hub: suppress warnings of no host network for qtest
If we want to qtest through hub, it would be much more simpler and
safer to configure the hub without host network. So silent this
warnings for qtest.

Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-id: 20181204035347.6148-3-jasowang@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-04 11:06:15 +00:00
Jason Wang 25c01bd19d net: drop too large packet early
We try to detect and drop too large packet (>INT_MAX) in 1592a99470
("net: ignore packet size greater than INT_MAX") during packet
delivering. Unfortunately, this is not sufficient as we may hit
another integer overflow when trying to queue such large packet in
qemu_net_queue_append_iov():

- size of the allocation may overflow on 32bit
- packet->size is integer which may overflow even on 64bit

Fixing this by moving the check to qemu_sendv_packet_async() which is
the entrance of all networking codes and reduce the limit to
NET_BUFSIZE to be more conservative. This works since:

- For the callers that call qemu_sendv_packet_async() directly, they
  only care about if zero is returned to determine whether to prevent
  the source from producing more packets. A callback will be triggered
  if peer can accept more then source could be enabled. This is
  usually used by high speed networking implementation like virtio-net
  or netmap.
- For the callers that call qemu_sendv_packet() that calls
  qemu_sendv_packet_async() indirectly, they often ignore the return
  value. In this case qemu will just the drop packets if peer can't
  receive.

Qemu will copy the packet if it was queued. So it was safe for both
kinds of the callers to assume the packet was sent.

Since we move the check from qemu_deliver_packet_iov() to
qemu_sendv_packet_async(), it would be safer to make
qemu_deliver_packet_iov() static to prevent any external user in the
future.

This is a revised patch of CVE-2018-17963.

Cc: qemu-stable@nongnu.org
Cc: Li Qiang <liq3ea@163.com>
Fixes: 1592a99470 ("net: ignore packet size greater than INT_MAX")
Reported-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-id: 20181204035347.6148-2-jasowang@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-04 11:06:15 +00:00
Peter Maydell 933cc4bb34 Merge remote-tracking branch 'remotes/kraxel/tags/fixes-31-20181203-pull-request' into staging
usb: mtp fixes.

# gpg: Signature made Mon 03 Dec 2018 19:50:26 GMT
# gpg:                using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/fixes-31-20181203-pull-request:
  usb-mtp: outlaw slashes in filenames
  usb-mtp: fix utf16_to_str

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-03 19:57:59 +00:00
Gerd Hoffmann c52d46e041 usb-mtp: outlaw slashes in filenames
Slash is unix directory separator, so they are not allowed in filenames.
Note this also stops the classic escape via "../".

Fixes: CVE-2018-16867
Reported-by: Michael Hanselmann <public@hansmi.ch>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20181203101045.27976-3-kraxel@redhat.com
2018-12-03 19:40:17 +01:00
Gerd Hoffmann 6de02a1323 usb-mtp: fix utf16_to_str
Make utf16_to_str return an allocated string.  Remove the assumtion that
the number of string bytes equals the number of utf16 chars (which is
only true for ascii chars).  Instead call wcstombs twice, once to figure
the storage size and once for the actual conversion (as suggested by the
wcstombs manpage).

FIXME: surrogate pairs are not working correctly.  Pre-existing bug,
fixing that is left for another day.

Reported-by: Michael Hanselmann <public@hansmi.ch>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-id: 20181203101045.27976-2-kraxel@redhat.com
2018-12-03 19:39:04 +01:00
Peter Maydell 9225cd127d Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-12-03' into staging
nbd patches for 2018-12-03

Improve x-dirty-bitmap handling for experimenting with pull mode
incremental backups.

- Eric Blake: 0/3 NBD dirty bitmap cleanups

# gpg: Signature made Mon 03 Dec 2018 15:56:23 GMT
# gpg:                using RSA key A7A16B4A2527436A
# gpg: Good signature from "Eric Blake <eblake@redhat.com>"
# gpg:                 aka "Eric Blake (Free Software Programmer) <ebb9@byu.net>"
# gpg:                 aka "[jpeg image of size 6874]"
# Primary key fingerprint: 71C2 CC22 B1C4 6029 27D2  F3AA A7A1 6B4A 2527 436A

* remotes/ericb/tags/pull-nbd-2018-12-03:
  nbd/client: Send NBD_CMD_DISC if open fails after connect
  nbd/client: Make x-dirty-bitmap more reliable
  nbd/server: Advertise all contexts in response to bare LIST

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-03 17:43:20 +00:00
Peter Maydell 3af8c4be90 Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches:

- mirror: Fix deadlock

# gpg: Signature made Mon 03 Dec 2018 16:57:33 GMT
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream:
  iotests: simple mirror test with kvm on 1G image
  mirror: fix dead-lock

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-03 17:12:48 +00:00
Vladimir Sementsov-Ogievskiy db5e8210ad iotests: simple mirror test with kvm on 1G image
This test is broken without previous commit fixing dead-lock in mirror.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Acked-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-12-03 16:51:53 +01:00
Vladimir Sementsov-Ogievskiy d12ade5732 mirror: fix dead-lock
Let start from the beginning:

Commit b9e413dd37 (in 2.9)
"block: explicitly acquire aiocontext in aio callbacks that need it"
added pairs of aio_context_acquire/release to mirror_write_complete and
mirror_read_complete, when they were aio callbacks for blk_aio_* calls.

Then, commit 2e1990b26e (in 3.0) "block/mirror: Convert to coroutines"
dropped these blk_aio_* calls, than mirror_write_complete and
mirror_read_complete are not callbacks more, and don't need additional
aiocontext acquiring. Furthermore, mirror_read_complete calls
blk_co_pwritev inside these pair of aio_context_acquire/release, which
leads to the following dead-lock with mirror:

 (gdb) info thr
   Id   Target Id         Frame
   3    Thread (LWP 145412) "qemu-system-x86" syscall ()
   2    Thread (LWP 145416) "qemu-system-x86" __lll_lock_wait ()
 * 1    Thread (LWP 145411) "qemu-system-x86" __lll_lock_wait ()

 (gdb) bt
 #0  __lll_lock_wait ()
 #1  _L_lock_812 ()
 #2  __GI___pthread_mutex_lock
 #3  qemu_mutex_lock_impl (mutex=0x561032dce420 <qemu_global_mutex>,
     file=0x5610327d8654 "util/main-loop.c", line=236) at
     util/qemu-thread-posix.c:66
 #4  qemu_mutex_lock_iothread_impl
 #5  os_host_main_loop_wait (timeout=480116000) at util/main-loop.c:236
 #6  main_loop_wait (nonblocking=0) at util/main-loop.c:497
 #7  main_loop () at vl.c:1892
 #8  main

Printing contents of qemu_global_mutex, I see that "__owner = 145416",
so, thr1 is main loop, and now it wants BQL, which is owned by thr2.

 (gdb) thr 2
 (gdb) bt
 #0  __lll_lock_wait ()
 #1  _L_lock_870 ()
 #2  __GI___pthread_mutex_lock
 #3  qemu_mutex_lock_impl (mutex=0x561034d25dc0, ...
 #4  aio_context_acquire (ctx=0x561034d25d60)
 #5  dma_blk_cb
 #6  dma_blk_io
 #7  dma_blk_read
 #8  ide_dma_cb
 #9  bmdma_cmd_writeb
 #10 bmdma_write
 #11 memory_region_write_accessor
 #12 access_with_adjusted_size
 #15 flatview_write
 #16 address_space_write
 #17 address_space_rw
 #18 kvm_handle_io
 #19 kvm_cpu_exec
 #20 qemu_kvm_cpu_thread_fn
 #21 qemu_thread_start
 #22 start_thread
 #23 clone ()

Printing mutex in fr 2, I see "__owner = 145411", so thr2 wants aio
context mutex, which is owned by thr1. Classic dead-lock.

Then, let's check that aio context is hold by mirror coroutine: just
print coroutine stack of first tracked request in mirror job target:

 (gdb) [...]
 (gdb) qemu coroutine 0x561035dd0860
 #0  qemu_coroutine_switch
 #1  qemu_coroutine_yield
 #2  qemu_co_mutex_lock_slowpath
 #3  qemu_co_mutex_lock
 #4  qcow2_co_pwritev
 #5  bdrv_driver_pwritev
 #6  bdrv_aligned_pwritev
 #7  bdrv_co_pwritev
 #8  blk_co_pwritev
 #9  mirror_read_complete () at block/mirror.c:232
 #10 mirror_co_read () at block/mirror.c:370
 #11 coroutine_trampoline
 #12 __start_context

Yes it is mirror_read_complete calling blk_co_pwritev after acquiring
aio context.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-12-03 16:50:58 +01:00
Roman Bolshakov 83ea23cd20 i386: hvf: Fix overrun of _decode_tbl1
Single opcode instructions in ff group were incorrectly processed
because an overrun of _decode_tbl1[0xff] resulted in access of
_decode_tbl2[0x0]. Thus, decode_sldtgroup was called instead of
decode_ffgroup:
  7d71: decode_sldtgroup: 1
  Unimplemented handler (7d71) for 108 (ff 0)

While at it correct maximum length for _decode_tbl2 and _decode_tbl3.

Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-03 15:09:55 +00:00
Corey Minyard 629457a130 i2c: Add a length check to the SMBus write handling
Avoid an overflow.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: QEMU Stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-12-03 13:00:38 +00:00
Eric Blake c688e6ca7b nbd/client: Send NBD_CMD_DISC if open fails after connect
If nbd_client_init() fails after we are already connected,
then the server will spam logs with:

Disconnect client, due to: Unexpected end-of-file before all bytes were read

unless we gracefully disconnect before closing the connection.

Ways to trigger this:

$ opts=driver=nbd,export=foo,server.type=inet,server.host=localhost,server.port=10809
$  qemu-img map --output=json --image-opts $opts,read-only=off
$  qemu-img map --output=json --image-opts $opts,x-dirty-bitmap=nosuch:

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20181130023232.3079982-4-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2018-11-30 14:13:37 -06:00
Eric Blake 47829c4079 nbd/client: Make x-dirty-bitmap more reliable
The implementation of x-dirty-bitmap in qemu 3.0 (commit 216ee365)
silently falls back to treating the server as not supporting
NBD_CMD_BLOCK_STATUS if a requested meta_context name was not
negotiated, which in turn means treating the _entire_ image as
data. Since our hack relied on using 'qemu-img map' to view
which portions of the image were dirty by seeing what the
redirected bdrv_block_status() treats as holes, this means
that our fallback treats the entire image as clean.  Better
would have been to treat the entire image as dirty, or to fail
to connect because the user's request for a specific context
could not be honored. This patch goes with the latter.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20181130023232.3079982-3-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2018-11-30 14:11:20 -06:00
Eric Blake e31d802479 nbd/server: Advertise all contexts in response to bare LIST
The NBD spec, and even our code comment, says that if the client
asks for NBD_OPT_LIST_META_CONTEXT with 0 queries, then we should
reply with (a possibly-compressed representation of) ALL contexts
that we are willing to let them try.  But commit 3d068aff forgot
to advertise qemu:dirty-bitmap:FOO.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20181130023232.3079982-2-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2018-11-30 13:55:18 -06:00
Peter Maydell 4750e1a888 Update version for v3.1.0-rc3 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-28 17:37:34 +00:00
Thomas Huth 3f2f3b33db target/arm/sve_helper: Fix compilation with clang 3.4
Clang 3.4 does not know the "flatten" attribute yet. We've already
introduced the QEMU_FLATTEN macro for this in commit 97ff87c0ed,
so use this macro now here, too, to fix this issue.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-id: 1543399094-2260-1-git-send-email-thuth@redhat.com
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-28 15:31:15 +00:00
Thomas Huth ea066d39ac hw/arm/aspeed: Fix build issue with clang 3.4
When using clang 3.4.2, compilation of QEMU fails like this:

  CC      aarch64-softmmu/hw/arm/aspeed.o
hw/arm/aspeed.c:36:3: error: redefinition of typedef 'AspeedBoardState' is a C11
      feature [-Werror,-Wtypedef-redefinition]
} AspeedBoardState;
  ^
include/hw/arm/aspeed.h:14:33: note: previous definition is here
typedef struct AspeedBoardState AspeedBoardState;
                                ^
1 error generated.
make[1]: *** [hw/arm/aspeed.o] Error 1
make: *** [subdir-aarch64-softmmu] Error 2

Remove the duplicated typedef to fix this issue.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Message-id: 1543397736-8198-1-git-send-email-thuth@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-28 13:51:41 +00:00
Peter Maydell c56606684a Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* lsi HBA reselection fix (George)
* Small cleanups (Li Qiang)
* bugfixes for vhost-user-bridge and hostmem (Marc-André)
* single-thread TCG fix (me)
* VMX migration blocker (me)
* target/i386 fix for LOCK (Richard)
* MAINTAINERS update (Philippe, Thomas)

# gpg: Signature made Wed 28 Nov 2018 10:51:36 GMT
# gpg:                using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  hostmem: no need to check for host_memory_backend_mr_inited() in alloc()
  hostmem-memfd: honour share=on/off property
  MAINTAINERS: Add an entry for the Firmware Configuration (fw_cfg) device
  MAINTAINERS: Add some missing entries related to accelerators
  target/i386: Generate #UD when applying LOCK to a register destination
  checkpatch: g_test_message does not need a trailing newline
  vl.c: remove outdated comment
  vhost-user-bridge: fix recvmsg iovlen
  vl: Improve error message when we can't load fw_cfg from file
  vmstate: constify VMStateField
  migration: savevm: consult migration blockers
  lsi: Reselection needed to remove pending commands from queue
  cpus: run work items for all vCPUs if single-threaded
  target/i386: kvm: add VMX migration blocker

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-28 11:32:33 +00:00
Marc-André Lureau 86100290cb hostmem: no need to check for host_memory_backend_mr_inited() in alloc()
memfd_backend_memory_alloc/file_backend_memory_alloc both needlessly
are are calling host_memory_backend_mr_inited() which creates an
illusion that alloc could be called multiple times but it isn't, it's
called once from UserCreatable complete().

Suggested-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-28 11:51:24 +01:00
John Snow 039d4e3df0 scsi: Address spurious clang warning
Some versions of Clang prior to 6.0 (and some builds of clang after,
such as 6.0.1-2.fc28) fail to recognize { 0 } as a valid initializer
for a struct with subobjects when -Wmissing-braces is enabled.

https://bugs.llvm.org/show_bug.cgi?id=21689 and
https://reviews.llvm.org/rL314499 suggests this should be fixed in 6.0,
but it might not be the case for older versions or downstream versions.

For now, follow the precedent of ebf2a499 and replace the standard { 0 }
with the accepted { } to silence this warning and allow the build to
work under clang 6.0.1-2.fc28, and builds prior to 6.0.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20181127184929.20065-1-jsnow@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-27 23:56:12 +00:00
Markus Armbruster 549b50a31d vfio-helpers: Fix qemu_vfio_open_pci() crash
qemu_vfio_open_common() initializes s->lock only after passing s to
qemu_vfio_dma_map() via qemu_vfio_init_ramblock().
qemu_vfio_dma_map() tries to lock the uninitialized lock and crashes.

Fix by initializing s->lock first.

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1645840
Fixes: 418026ca43
Cc: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20181127084143.1113-1-armbru@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-27 18:39:32 +00:00
Marc-André Lureau 36ea397956 hostmem-memfd: honour share=on/off property
The share=on/off property is used to modified mmap() MAP_SHARED
setting. Make it on by default for convenience and compatibility
reasons.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 19:36:22 +01:00
Philippe Mathieu-Daudé 15ffb43cbf MAINTAINERS: Add an entry for the Firmware Configuration (fw_cfg) device
Step in to maintain it, with Laszlo (EDK2) and Gerd (SeaBIOS)
as designated reviewers.

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20181122021139.1486-1-philmd@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:35:19 +01:00
Thomas Huth 9681ad3e2b MAINTAINERS: Add some missing entries related to accelerators
Add some files from accel/stubs/, include/hw/kvm/ and scripts/kvm/
to the MAINTAINERS file.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1542891438-13329-1-git-send-email-thuth@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:35:19 +01:00
Richard Henderson e84fcd7f66 target/i386: Generate #UD when applying LOCK to a register destination
Fixes a TCG crash due to attempting the atomic operation without
having set up the address first.  This does not attempt to fix
all of the other missing checks for LOCK.

Fixes: a7cee522f3
Fixes: https://bugs.launchpad.net/qemu/+bug/1803160
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20181113193510.24862-1-richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:35:19 +01:00
Paolo Bonzini f1e35acf78 checkpatch: g_test_message does not need a trailing newline
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:35:19 +01:00
Li Qiang d4c7e7e7e0 vl.c: remove outdated comment
Cc: qemu-trivial@nongnu.org

Signed-off-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1542276385-7638-1-git-send-email-liq3ea@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:35:19 +01:00
Marc-André Lureau 8f1d22d970 vhost-user-bridge: fix recvmsg iovlen
After iov_discard_front(), the iov may be smaller than its initial
size. Fixes the heap-buffer-overflow spotted by ASAN:

==9036==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000001e0 at pc 0x7fe632eca3f0 bp 0x7ffddc4a05a0 sp 0x7ffddc49fd48
WRITE of size 32 at 0x6060000001e0 thread T0
    #0 0x7fe632eca3ef  (/lib64/libasan.so.5+0x773ef)
    #1 0x7fe632ecad23 in __interceptor_recvmsg (/lib64/libasan.so.5+0x77d23)
    #2 0x561e7491936b in vubr_backend_recv_cb /home/elmarco/src/qemu/tests/vhost-user-bridge.c:333
    #3 0x561e74917711 in dispatcher_wait /home/elmarco/src/qemu/tests/vhost-user-bridge.c:160
    #4 0x561e7491c3b5 in vubr_run /home/elmarco/src/qemu/tests/vhost-user-bridge.c:725
    #5 0x561e7491c85c in main /home/elmarco/src/qemu/tests/vhost-user-bridge.c:806
    #6 0x7fe631a6c412 in __libc_start_main (/lib64/libc.so.6+0x24412)
    #7 0x561e7491667d in _start (/home/elmarco/src/qemu/build/tests/vhost-user-bridge+0x3967d)

0x6060000001e0 is located 0 bytes to the right of 64-byte region [0x6060000001a0,0x6060000001e0)
allocated by thread T0 here:
    #0 0x7fe632f42848 in __interceptor_malloc (/lib64/libasan.so.5+0xef848)
    #1 0x561e7493acd8 in virtqueue_alloc_element /home/elmarco/src/qemu/contrib/libvhost-user/libvhost-user.c:1848
    #2 0x561e7493c2a8 in vu_queue_pop /home/elmarco/src/qemu/contrib/libvhost-user/libvhost-user.c:1954
    #3 0x561e749189bf in vubr_backend_recv_cb /home/elmarco/src/qemu/tests/vhost-user-bridge.c:297
    #4 0x561e74917711 in dispatcher_wait /home/elmarco/src/qemu/tests/vhost-user-bridge.c:160
    #5 0x561e7491c3b5 in vubr_run /home/elmarco/src/qemu/tests/vhost-user-bridge.c:725
    #6 0x561e7491c85c in main /home/elmarco/src/qemu/tests/vhost-user-bridge.c:806
    #7 0x7fe631a6c412 in __libc_start_main (/lib64/libc.so.6+0x24412)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/lib64/libasan.so.5+0x773ef)
Shadow bytes around the buggy address:
  0x0c0c7fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0c7fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0c7fff8000: fa fa fa fa 00 00 00 00 00 00 05 fa fa fa fa fa
  0x0c0c7fff8010: 00 00 00 00 00 00 00 00 fa fa fa fa fd fd fd fd
  0x0c0c7fff8020: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
=>0x0c0c7fff8030: fa fa fa fa 00 00 00 00 00 00 00 00[fa]fa fa fa
  0x0c0c7fff8040: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
  0x0c0c7fff8050: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0c7fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20181109173028.3372-1-marcandre.lureau@redhat.com>
Signed-off-by: Paolo BOnzini <pbonzini@redhat.com>
2018-11-27 15:35:18 +01:00
Li Qiang 353c7d58b9 vl: Improve error message when we can't load fw_cfg from file
parse_fw_cfg() reports "can't load" without further details.  Get
the details from g_file_get_contents(), and include them in the
error message.

Signed-off-by: Li Qiang <liq3ea@gmail.com>
Message-Id: <1541051971-28584-1-git-send-email-liq3ea@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:35:18 +01:00
Marc-André Lureau 03fee66fde vmstate: constify VMStateField
Because they are supposed to remain const.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20181114132931.22624-1-marcandre.lureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:35:15 +01:00
Peter Maydell 59ed3fe8d3 Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches:

- block: Fix crash on migration with explicit child nodes
- nvme: Fix spurious interrupts

# gpg: Signature made Tue 27 Nov 2018 11:59:40 GMT
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream:
  nvme: Fix spurious interrupts
  iotests: Test migration with -blockdev
  block: Don't inactivate children before parents

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-27 14:35:11 +00:00
Paolo Bonzini 5aaac46793 migration: savevm: consult migration blockers
There is really no difference between live migration and savevm, except
that savevm does not require bdrv_invalidate_cache to be implemented
by all disks.  However, it is unlikely that savevm is used with anything
except qcow2 disks, so the penalty is small and worth the improvement
in catching bad usage of savevm.

Only one place was taking care of savevm when adding a migration blocker,
and it can be removed.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:06:14 +01:00
George Kennedy 56333e69ee lsi: Reselection needed to remove pending commands from queue
Under heavy IO (e.g. fio) the queue is not checked frequently enough for
pending commands. As a result some pending commands are timed out by the
linux sym53c8xx driver, which sends SCSI Abort messages for the timed out
commands. The SCSI Abort messages result in linux errors, which show up
on the console and in /var/log/messages.

e.g.
sd 0:0:3:0: [sdd] tag#33 ABORT operation started
scsi target0:0:3: control msgout:
80 20 47 d
sd 0:0:3:0: ABORT operation complete.
scsi target0:0:4: message d sent on bad reselection

Now following a WAIT DISCONNECT Script instruction, and if there is no
current command, check for a pending command on the queue and if one
exists call lsi_reselect().

Signed-off-by: George Kennedy <george.kennedy@oracle.com>
Message-Id: <1541776692-12271-1-git-send-email-george.kennedy@oracle.com>
[For safety, add a s->current check in lsi_update_irq - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:06:14 +01:00
Paolo Bonzini a8efa60633 cpus: run work items for all vCPUs if single-threaded
This avoids the following I/O thread deadlock:

1) the I/O thread calls run_on_cpu for CPU 3 from a timer.  single_tcg_halt_cond
is signaled

2) CPU 1 is running and exits.  It finds no work item and enters CPU 2

3) because the I/O thread is stuck in run_on_cpu, the round-robin kick
timer never triggers, and CPU 3 never runs the work item

4) run_on_cpu never completes

Reviewed-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:06:14 +01:00
Paolo Bonzini d98f26073b target/i386: kvm: add VMX migration blocker
Nested VMX does not support live migration yet.  Add a blocker
until that is worked out.

Nested SVM only does not support it, but unfortunately it is
enabled by default for -cpu host so we cannot really disable it.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2018-11-27 15:06:14 +01:00
ZhiPeng Lu 2264faa55f hw/virt/arm: Add support for Cortex-A72 in virt
Signed-off-by: ZhiPeng Lu <luzhipeng@uniudc.com>
Message-id: 1543316565-1101590-1-git-send-email-luzhipeng@uniudc.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-27 14:03:06 +00:00
Keith Busch 6da021815e nvme: Fix spurious interrupts
The code had asserted an interrupt every time it was requested to check
for new completion queue entries.This can result in spurious interrupts
seen by the guest OS.

Fix this by asserting an interrupt only if there are un-acknowledged
completion queue entries available.

Reported-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Keith Busch <keith.busch@intel.com>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-27 12:59:00 +01:00
Kevin Wolf 330ca111ea iotests: Test migration with -blockdev
Check that block node activation and inactivation works with a block
graph that is built with individually created nodes.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2018-11-27 12:59:00 +01:00
Kevin Wolf 9e37271f50 block: Don't inactivate children before parents
bdrv_child_cb_inactivate() asserts that parents are already inactive
when children get inactivated. This precondition is necessary because
parents could still issue requests in their inactivation code.

When block nodes are created individually with -blockdev, all of them
are monitor owned and will be returned by bdrv_next() in an undefined
order (in practice, in the order of their creation, which is usually
children before parents), which obviously fails the assertion:

qemu: block.c:899: bdrv_child_cb_inactivate: Assertion `bs->open_flags & BDRV_O_INACTIVE' failed.

This patch fixes the ordering by skipping nodes with still active
parents in bdrv_inactivate_recurse() because we know that they will be
covered by recursion when the last active parent becomes inactive.

With the correct parents-before-children ordering, we also got rid of
the reason why commit aad0b7a0bf introduced two passes, so we can go
back to a single-pass recursion. This is necessary so we can rely on the
BDRV_O_INACTIVE flag to skip nodes with active parents (the flag used
to be set only in pass 2, so we would always skip non-root nodes in
pass 1 because all parents would still be considered active; setting the
flag in pass 1 would mean, that we never skip anything in pass 2 because
all parents are already considered inactive).

Because of the change to single pass, this patch is best reviewed with
whitespace changes ignored.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
2018-11-27 12:59:00 +01:00
Peter Maydell 4822f1ee9e Merge remote-tracking branch 'remotes/kraxel/tags/fixes-31-20181127-pull-request' into staging
various bugfixes for 3.1: fmops, ps2, cirrus, hda, usb-host, qapi

# gpg: Signature made Tue 27 Nov 2018 06:49:13 GMT
# gpg:                using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/fixes-31-20181127-pull-request:
  qapi: add query-display-options command
  usb-host: set ifs.detached as true if kernel driver is not active
  audio/hda: fix guest triggerable assert
  cirrus_vga/migration: update the bank offset before use
  ps2kbd: default to scan enabled after reset
  fmops: fix off-by-one in AR_TABLE and DR_TABLE array size

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-27 11:21:38 +00:00
Peter Maydell d5d31c9a8a Merge remote-tracking branch 'remotes/ehabkost/tags/x86-for-3.1-pull-request' into staging
x86 fixes for -rc3

* Fix SynIC crash
* Fix x86 crash on MSR code on AMD hosts

# gpg: Signature made Mon 26 Nov 2018 20:58:34 GMT
# gpg:                using RSA key 2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/x86-for-3.1-pull-request:
  hw/hyperv: fix NULL dereference with pure-kvm SynIC
  kvm: Use KVM_GET_MSR_INDEX_LIST for MSR_IA32_ARCH_CAPABILITIES support

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-27 09:55:05 +00:00
Gerd Hoffmann e1ca8f7e19 qapi: add query-display-options command
Add query-display-options command, which allows querying the qemu
display configuration.  This isn't particularly useful, except it
exposes QAPI type DisplayOptions in query-qmp-schema, so that libvirt
can discover recently added -display parameter rendernode (commit
d4dc4ab133).  Works around lack of sufficiently powerful command line
introspection.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Eric Blake <eblake@redhat.com>
Tested-by: Erik Skultety <eskultet@redhat.com>
Message-id: 20181122071613.2889-1-kraxel@redhat.com

[ kraxel: reworded commit message as suggested by armbru ]
2018-11-27 07:47:57 +01:00
linzhecheng 933d2d4bf2 usb-host: set ifs.detached as true if kernel driver is not active
If no kernel driver is active, we can already claim and perform I/O on
it without detaching it.

Signed-off-by: linzhecheng <linzhecheng@huawei.com>
Message-id: 20181120083419.17716-1-linzhecheng@huawei.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2018-11-27 07:47:57 +01:00
Gerd Hoffmann 7ec9106759 audio/hda: fix guest triggerable assert
Guest writes to a readonly register trigger the assert in
intel_hda_reg_write().  Add a check and just ignore them.

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1628433
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20181123063957.9515-1-kraxel@redhat.com
2018-11-27 07:47:57 +01:00
Wang Xin b7ee9e4970 cirrus_vga/migration: update the bank offset before use
The cirrus bank0/1 offset should be updated before we update the vram's alias
offset.

Signed-off-by: Wang Xin <wangxinxin.wang@huawei.com>
Message-id: 20181123064646.23036-1-linzhecheng@huawei.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2018-11-27 07:47:57 +01:00
Hervé Poussineau d2e550a828 ps2kbd: default to scan enabled after reset
A check for scan_enabled has been added to ps2_keyboard_event in commit
143c04c7e0 to prevent stream corruption.
This works well as long as operating system is resetting keyboard, or enabling it.

This fixes IBM 40p firmware, which doesn't bother sending KBD_CMD_RESET,
KBD_CMD_ENABLE or KBD_CMD_RESET_ENABLE before trying to use the keyboard.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20181021190721.2148-1-hpoussin@reactos.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2018-11-27 07:47:50 +01:00
Roman Kagan 30a759b61a hw/hyperv: fix NULL dereference with pure-kvm SynIC
When started in compat configuration of SynIC, e.g.

qemu-system-x86_64 -machine pc-i440fx-2.10,accel=kvm \
 -cpu host,-vmx,hv-relaxed,hv_spinlocks=0x1fff,hv-vpindex,hv-synic

or explicitly

qemu-system-x86_64 -enable-kvm -cpu host,hv-synic,x-hv-synic-kvm-only=on

QEMU crashes in hyperv_synic_reset() trying to access the non-present
qobject for SynIC.

Add the missing check for NULL.

Reported-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Reported-by: Igor Mammedov <imammedo@redhat.com>
Fixes: 9b4cf107b0
Fixes: 4a93722f9c
Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
Message-Id: <20181126152836.25379-1-rkagan@virtuozzo.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2018-11-26 14:14:38 -02:00
Bandan Das aec5e9c3a9 kvm: Use KVM_GET_MSR_INDEX_LIST for MSR_IA32_ARCH_CAPABILITIES support
When writing to guest's MSR_IA32_ARCH_CAPABILITIES, check whether it's
supported in the guest using the KVM_GET_MSR_INDEX_LIST ioctl.

Fixes: d86f963694
Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
Tested-by: balducci@units.it
Signed-off-by: Bandan Das <bsd@redhat.com>
Message-Id: <jpg4lc4iiav.fsf_-_@linux.bootlegged.copy>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2018-11-26 13:00:38 -02:00
Peter Maydell d522fba244 Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20181126' into staging
target-arm queue:
 * some updates to MAINTAINERS file entries
 * cadence_gem: Remove an incorrect assert()

# gpg: Signature made Mon 26 Nov 2018 13:57:34 GMT
# gpg:                using RSA key 3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20181126:
  net: cadence_gem: Remove incorrect assert()
  MAINTAINERS: Add an ARM SMMU section
  MAINTAINERS: Assign some more files in the hw/arm/ directory

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-26 13:58:46 +00:00
Edgar E. Iglesias 58102ce7fb net: cadence_gem: Remove incorrect assert()
Don't assert on RX descriptor settings when the receiver is
disabled. This fixes an issue with incoming packets on an
unused GEM.

Reported-by: mbilal <muhammad_bilal@mentor.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20181123135450.24829-2-edgar.iglesias@gmail.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-26 13:41:42 +00:00
Eric Auger 49154ea0bf MAINTAINERS: Add an ARM SMMU section
Add a new ARM SMMU section and set Eric Auger as the maintainer
for ARM SMMU emulation sources.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Message-id: 20181122180143.14237-1-eric.auger@redhat.com
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-26 13:40:48 +00:00
Thomas Huth 123a069ae6 MAINTAINERS: Assign some more files in the hw/arm/ directory
I apparently missed some more files and even a complete machine (the
"imx25-pdk") in my previous patch... but now we should hopefully have
a completely coverage for all available ARM boards.

Fixes: 95a5db3ae5
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 1542782568-20059-1-git-send-email-thuth@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-26 13:39:23 +00:00
Peter Maydell 72138f9bf5 Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging
Fixes a QEMU crash triggerable by guest userspace (CVE-2018-19489).

# gpg: Signature made Mon 26 Nov 2018 07:25:01 GMT
# gpg:                using RSA key 71D4D5E5822F73D6
# gpg: Good signature from "Greg Kurz <groug@kaod.org>"
# gpg:                 aka "Gregory Kurz <gregory.kurz@free.fr>"
# gpg:                 aka "[jpeg image of size 3330]"
# Primary key fingerprint: B482 8BAF 9431 40CE F2A3  4910 71D4 D5E5 822F 73D6

* remotes/gkurz/tags/for-upstream:
  9p: fix QEMU crash when renaming files

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-26 11:46:04 +00:00
Peter Maydell b05730a876 Merge remote-tracking branch 'remotes/xtensa/tags/20181125-xtensa' into staging
xtensa fixes for 3.1:

- fix register counting logic for linux-user gdbserver;
- provide default memory sizes for XTFPGA boards;
- add missing xtensa patterns to MAINTAINTERS.

# gpg: Signature made Sun 25 Nov 2018 23:07:54 GMT
# gpg:                using RSA key 51F9CC91F83FA044
# gpg: Good signature from "Max Filippov <filippov@cadence.com>"
# gpg:                 aka "Max Filippov <max.filippov@cogentembedded.com>"
# gpg:                 aka "Max Filippov <jcmvbkbc@gmail.com>"
# Primary key fingerprint: 2B67 854B 98E5 327D CDEB  17D8 51F9 CC91 F83F A044

* remotes/xtensa/tags/20181125-xtensa:
  MAINTAINERS: add missing xtensa patterns
  target/xtensa: xtfpga: provide default memory sizes
  target/xtensa: drop num_[core_]regs from dc232b/dc233c configs
  target/xtensa: gdbstub fix register counting

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-26 11:07:35 +00:00
Gerd Hoffmann 57ac4a7a28 fmops: fix off-by-one in AR_TABLE and DR_TABLE array size
Cc: P J P <ppandit@redhat.com>
Reported-by: Wangjunqing <wangjunqing@huawei.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20181030082340.17170-1-kraxel@redhat.com
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2018-11-26 11:15:32 +01:00
Greg Kurz 1d20398694 9p: fix QEMU crash when renaming files
When using the 9P2000.u version of the protocol, the following shell
command line in the guest can cause QEMU to crash:

    while true; do rm -rf aa; mkdir -p a/b & touch a/b/c & mv a aa; done

With 9P2000.u, file renaming is handled by the WSTAT command. The
v9fs_wstat() function calls v9fs_complete_rename(), which calls
v9fs_fix_path() for every fid whose path is affected by the change.
The involved calls to v9fs_path_copy() may race with any other access
to the fid path performed by some worker thread, causing a crash like
shown below:

Thread 12 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
0x0000555555a25da2 in local_open_nofollow (fs_ctx=0x555557d958b8, path=0x0,
 flags=65536, mode=0) at hw/9pfs/9p-local.c:59
59          while (*path && fd != -1) {
(gdb) bt
#0  0x0000555555a25da2 in local_open_nofollow (fs_ctx=0x555557d958b8,
 path=0x0, flags=65536, mode=0) at hw/9pfs/9p-local.c:59
#1  0x0000555555a25e0c in local_opendir_nofollow (fs_ctx=0x555557d958b8,
 path=0x0) at hw/9pfs/9p-local.c:92
#2  0x0000555555a261b8 in local_lstat (fs_ctx=0x555557d958b8,
 fs_path=0x555556b56858, stbuf=0x7fff84830ef0) at hw/9pfs/9p-local.c:185
#3  0x0000555555a2b367 in v9fs_co_lstat (pdu=0x555557d97498,
 path=0x555556b56858, stbuf=0x7fff84830ef0) at hw/9pfs/cofile.c:53
#4  0x0000555555a1e9e2 in v9fs_stat (opaque=0x555557d97498)
 at hw/9pfs/9p.c:1083
#5  0x0000555555e060a2 in coroutine_trampoline (i0=-669165424, i1=32767)
 at util/coroutine-ucontext.c:116
#6  0x00007fffef4f5600 in __start_context () at /lib64/libc.so.6
#7  0x0000000000000000 in  ()
(gdb)

The fix is to take the path write lock when calling v9fs_complete_rename(),
like in v9fs_rename().

Impact:  DoS triggered by unprivileged guest users.

Fixes: CVE-2018-19489
Cc: P J P <ppandit@redhat.com>
Reported-by: zhibin hu <noirfate@gmail.com>
Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Greg Kurz <groug@kaod.org>
2018-11-23 13:28:03 +01:00
Peter Maydell 5298f4d67a Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches:

- block: Fix update of BDRV_O_AUTO_RDONLY in update_flags_from_options()
- block: Fix option inheritance after stream/commit job graph changes
- qemu-img: Fix memory leak and typo in error message
- nvme: Fixes for lockups and crashes
- scsi-disk: Fix crash if underlying host file or disk returns error
- Several qemu-iotests fixes and improvements

# gpg: Signature made Thu 22 Nov 2018 18:38:30 GMT
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream:
  block: Update BlockDriverState.inherits_from on bdrv_drop_intermediate()
  block: Update BlockDriverState.inherits_from on bdrv_set_backing_hd()
  iotests: Enhance 223 to cover multiple bitmap granularities
  nvme: fix bug with PCI IRQ pins on teardown
  nvme: fix CMB endianness confusion
  Revert "nvme: fix oob access issue(CVE-2018-16847)"
  nvme: fix out-of-bounds access to the CMB
  nvme: call blk_drain in NVMe reset code to avoid lockups
  iotests: fix nbd test 233 to work correctly with raw images
  block: Fix update of BDRV_O_AUTO_RDONLY in update_flags_from_options()
  scsi-disk: Fix crash if underlying host file or disk returns error
  qemu-img: Fix leak
  qemu-img: Fix typo
  iotests: Skip 233 if certtool not installed
  iotests: Replace assertEquals() with assertEqual()
  iotests: Replace time.clock() with Timeout

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-23 08:54:52 +00:00
Max Filippov 895e4897e2 MAINTAINERS: add missing xtensa patterns
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2018-11-22 21:16:43 -08:00
Alberto Garcia 6bd858b311 block: Update BlockDriverState.inherits_from on bdrv_drop_intermediate()
The previous patch fixed the inherits_from pointer after block-stream,
and this one does the same for block-commit.

When block-commit finishes and the 'top' node is not the topmost one
from the backing chain then all nodes above 'base' up to and including
'top' are removed from the chain.

The bdrv_drop_intermediate() call converts a chain like this one:

    base <- intermediate <- top <- active

into this one:

    base <- active

In a simple scenario each backing file from the first chain has the
inherits_from attribute pointing to its parent. This means that
reopening 'active' will recursively reopen all its children, whose
options can be changed in the process.

However after the 'block-commit' call base.inherits_from is NULL and
the chain is broken, so 'base' does not inherit from 'active' and will
not be reopened automatically:

   $ qemu-img create -f qcow2 hd0.qcow2 1M
   $ qemu-img create -f qcow2 -b hd0.qcow2 hd1.qcow2
   $ qemu-img create -f qcow2 -b hd1.qcow2 hd2.qcow2
   $ $QEMU -drive if=none,file=hd2.qcow2

   { 'execute': 'block-commit',
     'arguments': {
       'device': 'none0',
       'top': 'hd1.qcow2' } }

   { 'execute': 'human-monitor-command',
     'arguments': {
        'command-line':
          'qemu-io none0 "reopen -o backing.l2-cache-size=2M"' } }

   { "return": "Cannot change the option 'backing.l2-cache-size'\r\n"}

This patch updates base.inherits_from in this scenario, and adds a
test case.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 19:37:31 +01:00
Alberto Garcia 0065c455f9 block: Update BlockDriverState.inherits_from on bdrv_set_backing_hd()
When a BlockDriverState's child is opened (be it a backing file, the
protocol layer, or any other) inherits_from is set to point to the
parent node. Children opened separately and then attached to a parent
don't have this pointer set.

bdrv_reopen_queue_child() uses this to determine whether a node's
children must also be reopened inheriting the options from the parent
or not. If inherits_from points to the parent then the child is
reopened and its options can be changed, like in this example:

   $ qemu-img create -f qcow2 hd0.qcow2 1M
   $ qemu-img create -f qcow2 hd1.qcow2 1M
   $ $QEMU -drive if=none,node-name=hd0,file=hd0.qcow2,\
                  backing.driver=qcow2,backing.file.filename=hd1.qcow2
   (qemu) qemu-io hd0 "reopen -o backing.l2-cache-size=2M"

If the child does not inherit from the parent then it does not get
reopened and its options cannot be changed:

   $ $QEMU -drive if=none,node-name=hd1,file=hd1.qcow2
           -drive if=none,node-name=hd0,file=hd0.qcow2,backing=hd1
   (qemu) qemu-io hd0 "reopen -o backing.l2-cache-size=2M"
   Cannot change the option 'backing.l2-cache-size'

If a disk image has a chain of backing files then all of them are also
connected through their inherits_from pointers (i.e. it's possible to
walk the chain in reverse order from base to top).

However this is broken if the intermediate nodes are removed using
e.g. block-stream because the inherits_from pointer from the base node
becomes NULL:

   $ qemu-img create -f qcow2 hd0.qcow2 1M
   $ qemu-img create -f qcow2 -b hd0.qcow2 hd1.qcow2
   $ qemu-img create -f qcow2 -b hd1.qcow2 hd2.qcow2
   $ $QEMU -drive if=none,file=hd2.qcow2
   (qemu) qemu-io none0 "reopen -o backing.l2-cache-size=2M"
   (qemu) block_stream none0 0 hd0.qcow2
   (qemu) qemu-io none0 "reopen -o backing.l2-cache-size=2M"
   Cannot change the option 'backing.l2-cache-size'

This patch updates the inherits_from pointer if the intermediate nodes
of a backing chain are removed using bdrv_set_backing_hd(), and adds a
test case for this scenario.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 19:37:31 +01:00
Eric Blake a237dea330 iotests: Enhance 223 to cover multiple bitmap granularities
Testing granularity at the same size as the cluster isn't quite
as fun as what happens when it is larger or smaller.  This
enhancement also shows that qemu's nbd server can serve the
same disk over multiple exports simultaneously.

Signed-off-by: Eric Blake <eblake@redhat.com>
Tested-by: John Snow <jsnow@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 19:37:31 +01:00
Logan Gunthorpe ad3a7e4555 nvme: fix bug with PCI IRQ pins on teardown
When the submission and completion queues are being torn down
the IRQ will be asserted for the completion queue when the
submsission queue is deleted. Then when the completion queue
is deleted it stays asserted. Thus, on systems that do
not use MSI, no further interrupts can be triggered on the host.

Linux sees this as a long delay when unbinding the nvme device.
Eventually the interrupt timeout occurs and it continues.

To fix this we ensure we deassert the IRQ for a CQ when it is
deleted.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 19:37:31 +01:00
Paolo Bonzini 71a86ddece nvme: fix CMB endianness confusion
The CMB is marked as DEVICE_LITTLE_ENDIAN, so the data must be
read/written as if it was little-endian output (in the case of
big endian, we get two swaps, one in the memory core and one
in nvme.c).

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 19:37:31 +01:00
Kevin Wolf 2067d39e5e Revert "nvme: fix oob access issue(CVE-2018-16847)"
This reverts commit 5e3c0220d7.
We have a better fix commited for this now.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 16:43:52 +01:00
Paolo Bonzini 87ad860c62 nvme: fix out-of-bounds access to the CMB
Because the CMB BAR has a min_access_size of 2, if you read the last
byte it will try to memcpy *2* bytes from n->cmbuf, causing an off-by-one
error.  This is CVE-2018-16847.

Another way to fix this might be to register the CMB as a RAM memory
region, which would also be more efficient.  However, that might be a
change for big-endian machines; I didn't think this through and I don't
know how real hardware works.  Add a basic testcase for the CMB in case
somebody does this change later on.

Cc: Keith Busch <keith.busch@intel.com>
Cc: qemu-block@nongnu.org
Reported-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Tested-by: Li Qiang <liq3ea@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 16:43:52 +01:00
Igor Druzhinin 6bf7463615 nvme: call blk_drain in NVMe reset code to avoid lockups
When blk_flush called in NVMe reset path S/C queues are already freed
which means that re-entering AIO handling loop having some IO requests
unfinished will lockup or crash as their SG structures being potentially
reused. Call blk_drain before freeing the queues to avoid this nasty
scenario.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 16:43:52 +01:00
Daniel P. Berrangé e4c8f2925d iotests: fix nbd test 233 to work correctly with raw images
The first qemu-io command must honour the $IMGFMT that is set rather
than hardcoding qcow2. The qemu-nbd commands should also set $IMGFMT
to avoid the insecure format probe warning.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 16:43:52 +01:00
Alberto Garcia 2a3d4331fa block: Fix update of BDRV_O_AUTO_RDONLY in update_flags_from_options()
Commit e35bdc123a added the auto-read-only option and the
code to update its corresponding flag in update_flags_from_options(),
but forgot to clear the flag if auto-read-only is false.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reported-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 16:43:52 +01:00
Richard W.M. Jones 1c7f618f68 scsi-disk: Fix crash if underlying host file or disk returns error
Commit 40dce4ee6 "scsi-disk: fix rerror/werror=ignore" introduced a
bug which causes qemu to crash with the assertion error below if the
host file or disk returns an error:

  qemu-system-x86_64: hw/scsi/scsi-bus.c:1374: scsi_req_complete:
  Assertion `req->status == -1' failed.

Kevin Wolf suggested this fix:

  < kwolf> Hm, should the final return false; in that patch
           actually be a return true?
  < kwolf> Because I think he didn't intend to change anything
           except BLOCK_ERROR_ACTION_IGNORE

Buglink: https://bugs.launchpad.net/qemu/+bug/1804323
Fixes: 40dce4ee61
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-22 16:43:48 +01:00
Peter Maydell ebfd6216ec Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20181121a' into staging
Migration fixes 2018-11-21

Notably the fix for building with --disable-replication

# gpg: Signature made Wed 21 Nov 2018 13:03:20 GMT
# gpg:                using RSA key 0516331EBC5BFDE7
# gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>"
# Primary key fingerprint: 45F5 C71B 4A0C B7FB 977A  9FA9 0516 331E BC5B FDE7

* remotes/dgilbert/tags/pull-migration-20181121a:
  migration/migration.c: Add COLO dependency checks
  migration/colo.c: Fix compilation issue when disable replication

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2018-11-22 13:45:06 +00:00
Max Filippov 59b5e9bbea target/xtensa: xtfpga: provide default memory sizes
Provide default RAM sizes for all XTFPGA boards, so that when started
without -m option they do the right thing.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2018-11-21 10:53:21 -08:00
Max Reitz 3ecd5a4f19 qemu-img: Fix leak
create_opts was leaked here.  This is not too bad since the process is
about to exit anyway, but relying on that does not make the code nicer
to read.

Fixes: d402b6a21a
Reported-by: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-21 15:17:46 +01:00
Max Reitz f0998879e0 qemu-img: Fix typo
Fixes: d402b6a21a
Reported-by: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-21 15:17:46 +01:00
Eric Blake 155af09d44 iotests: Skip 233 if certtool not installed
The use of TLS while building qemu is optional. While the
'certtool' binary should be available on every platform that
supports building against TLS, that does not imply that the
developer has installed it.  Make the test gracefully skip
in that case.

Reported-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2018-11-21 15:17:37 +01:00
Zhang Chen 7e934f5b27 migration/migration.c: Add COLO dependency checks
Current COLO mode(independent disk mode) need replication module work
together. Suggested by Dr. David Alan Gilbert <dgilbert@redhat.com>.

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
Message-Id: <20181114190912.7242-1-chen.zhang@intel.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2018-11-21 11:38:12 +00:00
Zhang Chen 3ebb9c4f52 migration/colo.c: Fix compilation issue when disable replication
This compilation issue will occur when user use --disable-replication
to config Qemu.

Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Zhang Chen <zhangckid@gmail.com>
Message-Id: <20181101021226.6353-1-zhangckid@gmail.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
2018-11-21 11:20:14 +00:00
Kevin Wolf fa1cfb4026 iotests: Replace assertEquals() with assertEqual()
TestCase.assertEquals() is deprecated since Python 2.7. Recent Python
versions print a warning when the function is called, which makes test
cases fail.

Replace it with the preferred spelling assertEqual().

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2018-11-21 10:30:05 +01:00
Kevin Wolf d8336c6b28 iotests: Replace time.clock() with Timeout
time.clock() is deprecated since Python 3.3. Current Python versions
warn that the function will be removed in Python 3.8, and those warnings
make the test case 118 fail.

Replace it with the Timeout mechanism that is compatible with both
Python 2 and 3, and makes the code even a little nicer.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2018-11-21 10:30:05 +01:00
Max Filippov 7da9111e77 target/xtensa: drop num_[core_]regs from dc232b/dc233c configs
Now that xtensa_count_regs does the right thing, remove manual
initialization of these fields from the affected configurations and let
xtensa_finalize_config initialize them. Add XTREG_END to terminate
register lists.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2018-11-20 12:20:41 -08:00
Max Filippov 4614f0f8bd target/xtensa: gdbstub fix register counting
In order to communicate correctly with gdb xtensa gdbstub must provide
expected number of registers in 'g' packet response. xtensa-elf-gdb
expects both nonprivileged and privileged registers. xtensa-linux-gdb
only expects nonprivileged registers. gdb only counts one contiguous
stretch of registers, do the same for the core registers in the
xtensa_count_regs.

With this change qemu-system-xtensa is able to communicate with all
xtensa-elf-gdb versions (versions prior to 8.2 require overlay fixup),
and qemu-xtensa is able to communicate with all xtensa-linux-gdb
versions, except 8.2.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
2018-11-20 12:20:41 -08:00
87 changed files with 1215 additions and 372 deletions

No files matched your search

+43
View File
@@ -117,6 +117,7 @@ S: Maintained
F: cpus.c
F: exec.c
F: accel/tcg/
F: accel/stubs/tcg-stub.c
F: include/exec/cpu*.h
F: include/exec/exec-all.h
F: include/exec/helper*.h
@@ -151,6 +152,13 @@ F: disas/arm.c
F: disas/arm-a64.cc
F: disas/libvixl/
ARM SMMU
M: Eric Auger <eric.auger@redhat.com>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/arm/smmu*
F: include/hw/arm/smmu*
CRIS
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained
@@ -311,6 +319,8 @@ F: target/xtensa/
F: hw/xtensa/
F: tests/tcg/xtensa/
F: disas/xtensa.c
F: include/hw/xtensa/xtensa-isa.h
F: default-configs/xtensa*.mak
TriCore
M: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
@@ -332,7 +342,10 @@ L: kvm@vger.kernel.org
S: Supported
F: */kvm.*
F: accel/kvm/
F: accel/stubs/kvm-stub.c
F: include/hw/kvm/
F: include/sysemu/kvm*.h
F: scripts/kvm/kvm_flightrecorder
ARM
M: Peter Maydell <peter.maydell@linaro.org>
@@ -375,6 +388,7 @@ M: Marcelo Tosatti <mtosatti@redhat.com>
L: kvm@vger.kernel.org
S: Supported
F: target/i386/kvm.c
F: scripts/kvm/vmxcap
Guest CPU Cores (Xen):
----------------------
@@ -533,6 +547,17 @@ L: qemu-arm@nongnu.org
S: Odd Fixes
F: hw/arm/gumstix.c
i.MX25 PDK
M: Peter Maydell <peter.maydell@linaro.org>
R: Jean-Christophe Dubois <jcd@tribudubois.net>
L: qemu-arm@nongnu.org
S: Odd Fixes
F: hw/arm/fsl-imx25.c
F: hw/arm/imx25_pdk.c
F: hw/misc/imx25_ccm.c
F: include/hw/arm/fsl-imx25.h
F: include/hw/misc/imx25_ccm.h
i.MX31 (kzm)
M: Peter Chubb <peter.chubb@nicta.com.au>
M: Peter Maydell <peter.maydell@linaro.org>
@@ -615,6 +640,7 @@ R: Andrew Baumann <Andrew.Baumann@microsoft.com>
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
L: qemu-arm@nongnu.org
S: Odd Fixes
F: hw/arm/raspi.c
F: hw/arm/raspi_platform.h
F: hw/*/bcm283*
F: include/hw/arm/raspi*
@@ -639,8 +665,12 @@ F: hw/arm/spitz.c
F: hw/arm/tosa.c
F: hw/arm/z2.c
F: hw/*/pxa2xx*
F: hw/display/tc6393xb.c
F: hw/gpio/max7310.c
F: hw/gpio/zaurus.c
F: hw/misc/mst_fpga.c
F: include/hw/arm/pxa.h
F: include/hw/arm/sharpsl.h
SABRELITE / i.MX6
M: Peter Maydell <peter.maydell@linaro.org>
@@ -1534,6 +1564,19 @@ F: hw/display/edid*
F: include/hw/display/edid.h
F: qemu-edid.c
Firmware configuration (fw_cfg)
M: Philippe Mathieu-Daudé <philmd@redhat.com>
R: Laszlo Ersek <lersek@redhat.com>
R: Gerd Hoffmann <kraxel@redhat.com>
S: Supported
F: docs/specs/fw_cfg.txt
F: hw/nvram/fw_cfg.c
F: include/hw/nvram/fw_cfg.h
F: include/standard-headers/linux/qemu_fw_cfg.h
F: tests/libqos/fw_cfg.c
F: tests/fw_cfg-test.c
T: git https://github.com/philmd/qemu.git fw_cfg-next
Subsystems
----------
Audio
+1 -1
View File
@@ -1 +1 @@
3.0.92
3.1.0
+12 -12
View File
@@ -42,6 +42,9 @@ static void
file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
{
HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
#ifdef CONFIG_POSIX
gchar *path;
#endif
if (!backend->size) {
error_setg(errp, "can't create backend with size 0");
@@ -54,18 +57,15 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
#ifndef CONFIG_POSIX
error_setg(errp, "-mem-path not supported on this host");
#else
if (!host_memory_backend_mr_inited(backend)) {
gchar *path;
backend->force_prealloc = mem_prealloc;
path = object_get_canonical_path(OBJECT(backend));
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
path,
backend->size, fb->align,
(backend->share ? RAM_SHARED : 0) |
(fb->is_pmem ? RAM_PMEM : 0),
fb->mem_path, errp);
g_free(path);
}
backend->force_prealloc = mem_prealloc;
path = object_get_canonical_path(OBJECT(backend));
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
path,
backend->size, fb->align,
(backend->share ? RAM_SHARED : 0) |
(fb->is_pmem ? RAM_PMEM : 0),
fb->mem_path, errp);
g_free(path);
#endif
}
+3 -5
View File
@@ -44,10 +44,6 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
return;
}
if (host_memory_backend_mr_inited(backend)) {
return;
}
backend->force_prealloc = mem_prealloc;
fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
m->hugetlb, m->hugetlbsize, m->seal ?
@@ -59,7 +55,8 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
name = object_get_canonical_path(OBJECT(backend));
memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
name, backend->size, true, fd, errp);
name, backend->size,
backend->share, fd, errp);
g_free(name);
}
@@ -131,6 +128,7 @@ memfd_backend_instance_init(Object *obj)
/* default to sealed file */
m->seal = true;
MEMORY_BACKEND(m)->share = true;
}
static void
+92 -35
View File
@@ -1137,7 +1137,7 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
static void update_flags_from_options(int *flags, QemuOpts *opts)
{
*flags &= ~BDRV_O_CACHE_MASK;
*flags &= ~(BDRV_O_CACHE_MASK | BDRV_O_RDWR | BDRV_O_AUTO_RDONLY);
assert(qemu_opt_find(opts, BDRV_OPT_CACHE_NO_FLUSH));
if (qemu_opt_get_bool_del(opts, BDRV_OPT_CACHE_NO_FLUSH, false)) {
@@ -1149,8 +1149,6 @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
*flags |= BDRV_O_NOCACHE;
}
*flags &= ~BDRV_O_RDWR;
assert(qemu_opt_find(opts, BDRV_OPT_READ_ONLY));
if (!qemu_opt_get_bool_del(opts, BDRV_OPT_READ_ONLY, false)) {
*flags |= BDRV_O_RDWR;
@@ -2262,6 +2260,18 @@ static void bdrv_parent_cb_change_media(BlockDriverState *bs, bool load)
}
}
/* Return true if you can reach parent going through child->inherits_from
* recursively. If parent or child are NULL, return false */
static bool bdrv_inherits_from_recursive(BlockDriverState *child,
BlockDriverState *parent)
{
while (child && child != parent) {
child = child->inherits_from;
}
return child != NULL;
}
/*
* Sets the backing file link of a BDS. A new reference is created; callers
* which don't need their own reference any more must call bdrv_unref().
@@ -2269,6 +2279,9 @@ static void bdrv_parent_cb_change_media(BlockDriverState *bs, bool load)
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
Error **errp)
{
bool update_inherits_from = bdrv_chain_contains(bs, backing_hd) &&
bdrv_inherits_from_recursive(backing_hd, bs);
if (backing_hd) {
bdrv_ref(backing_hd);
}
@@ -2284,6 +2297,12 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_backing,
errp);
/* If backing_hd was already part of bs's backing chain, and
* inherits_from pointed recursively to bs then let's update it to
* point directly to bs (else it will become NULL). */
if (update_inherits_from) {
backing_hd->inherits_from = bs;
}
if (!bs->backing) {
bdrv_unref(backing_hd);
}
@@ -3836,6 +3855,8 @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs)
int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
const char *backing_file_str)
{
BlockDriverState *explicit_top = top;
bool update_inherits_from;
BdrvChild *c, *next;
Error *local_err = NULL;
int ret = -EIO;
@@ -3851,6 +3872,16 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
goto exit;
}
/* If 'base' recursively inherits from 'top' then we should set
* base->inherits_from to top->inherits_from after 'top' and all
* other intermediate nodes have been dropped.
* If 'top' is an implicit node (e.g. "commit_top") we should skip
* it because no one inherits from it. We use explicit_top for that. */
while (explicit_top && explicit_top->implicit) {
explicit_top = backing_bs(explicit_top);
}
update_inherits_from = bdrv_inherits_from_recursive(base, explicit_top);
/* success - we can delete the intermediate states, and link top->base */
/* TODO Check graph modification op blockers (BLK_PERM_GRAPH_MOD) once
* we've figured out how they should work. */
@@ -3886,6 +3917,10 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
bdrv_unref(top);
}
if (update_inherits_from) {
base->inherits_from = explicit_top->inherits_from;
}
ret = 0;
exit:
bdrv_unref(top);
@@ -4577,45 +4612,68 @@ void bdrv_invalidate_cache_all(Error **errp)
}
}
static int bdrv_inactivate_recurse(BlockDriverState *bs,
bool setting_flag)
static bool bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
{
BdrvChild *parent;
QLIST_FOREACH(parent, &bs->parents, next_parent) {
if (parent->role->parent_is_bds) {
BlockDriverState *parent_bs = parent->opaque;
if (!only_active || !(parent_bs->open_flags & BDRV_O_INACTIVE)) {
return true;
}
}
}
return false;
}
static int bdrv_inactivate_recurse(BlockDriverState *bs)
{
BdrvChild *child, *parent;
uint64_t perm, shared_perm;
int ret;
if (!bs->drv) {
return -ENOMEDIUM;
}
if (!setting_flag && bs->drv->bdrv_inactivate) {
/* Make sure that we don't inactivate a child before its parent.
* It will be covered by recursion from the yet active parent. */
if (bdrv_has_bds_parent(bs, true)) {
return 0;
}
assert(!(bs->open_flags & BDRV_O_INACTIVE));
/* Inactivate this node */
if (bs->drv->bdrv_inactivate) {
ret = bs->drv->bdrv_inactivate(bs);
if (ret < 0) {
return ret;
}
}
if (setting_flag && !(bs->open_flags & BDRV_O_INACTIVE)) {
uint64_t perm, shared_perm;
QLIST_FOREACH(parent, &bs->parents, next_parent) {
if (parent->role->inactivate) {
ret = parent->role->inactivate(parent);
if (ret < 0) {
return ret;
}
QLIST_FOREACH(parent, &bs->parents, next_parent) {
if (parent->role->inactivate) {
ret = parent->role->inactivate(parent);
if (ret < 0) {
return ret;
}
}
bs->open_flags |= BDRV_O_INACTIVE;
/* Update permissions, they may differ for inactive nodes */
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &error_abort);
bdrv_set_perm(bs, perm, shared_perm);
}
bs->open_flags |= BDRV_O_INACTIVE;
/* Update permissions, they may differ for inactive nodes */
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &error_abort);
bdrv_set_perm(bs, perm, shared_perm);
/* Recursively inactivate children */
QLIST_FOREACH(child, &bs->children, next) {
ret = bdrv_inactivate_recurse(child->bs, setting_flag);
ret = bdrv_inactivate_recurse(child->bs);
if (ret < 0) {
return ret;
}
@@ -4629,7 +4687,6 @@ int bdrv_inactivate_all(void)
BlockDriverState *bs = NULL;
BdrvNextIterator it;
int ret = 0;
int pass;
GSList *aio_ctxs = NULL, *ctx;
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
@@ -4641,17 +4698,17 @@ int bdrv_inactivate_all(void)
}
}
/* We do two passes of inactivation. The first pass calls to drivers'
* .bdrv_inactivate callbacks recursively so all cache is flushed to disk;
* the second pass sets the BDRV_O_INACTIVE flag so that no further write
* is allowed. */
for (pass = 0; pass < 2; pass++) {
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
ret = bdrv_inactivate_recurse(bs, pass);
if (ret < 0) {
bdrv_next_cleanup(&it);
goto out;
}
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
/* Nodes with BDS parents are covered by recursion from the last
* parent that gets inactivated. Don't inactivate them a second
* time if that has already happened. */
if (bdrv_has_bds_parent(bs, false)) {
continue;
}
ret = bdrv_inactivate_recurse(bs);
if (ret < 0) {
bdrv_next_cleanup(&it);
goto out;
}
}
+5 -8
View File
@@ -199,7 +199,6 @@ static void coroutine_fn mirror_write_complete(MirrorOp *op, int ret)
{
MirrorBlockJob *s = op->s;
aio_context_acquire(blk_get_aio_context(s->common.blk));
if (ret < 0) {
BlockErrorAction action;
@@ -209,15 +208,14 @@ static void coroutine_fn mirror_write_complete(MirrorOp *op, int ret)
s->ret = ret;
}
}
mirror_iteration_done(op, ret);
aio_context_release(blk_get_aio_context(s->common.blk));
}
static void coroutine_fn mirror_read_complete(MirrorOp *op, int ret)
{
MirrorBlockJob *s = op->s;
aio_context_acquire(blk_get_aio_context(s->common.blk));
if (ret < 0) {
BlockErrorAction action;
@@ -228,12 +226,11 @@ static void coroutine_fn mirror_read_complete(MirrorOp *op, int ret)
}
mirror_iteration_done(op, ret);
} else {
ret = blk_co_pwritev(s->target, op->offset,
op->qiov.size, &op->qiov, 0);
mirror_write_complete(op, ret);
return;
}
aio_context_release(blk_get_aio_context(s->common.blk));
ret = blk_co_pwritev(s->target, op->offset, op->qiov.size, &op->qiov, 0);
mirror_write_complete(op, ret);
}
/* Clip bytes relative to offset to not exceed end-of-file */
+20 -1
View File
@@ -992,10 +992,16 @@ int nbd_client_init(BlockDriverState *bs,
logout("Failed to negotiate with the NBD server\n");
return ret;
}
if (x_dirty_bitmap && !client->info.base_allocation) {
error_setg(errp, "requested x-dirty-bitmap %s not found",
x_dirty_bitmap);
ret = -EINVAL;
goto fail;
}
if (client->info.flags & NBD_FLAG_READ_ONLY) {
ret = bdrv_apply_auto_read_only(bs, "NBD export is read-only", errp);
if (ret < 0) {
return ret;
goto fail;
}
}
if (client->info.flags & NBD_FLAG_SEND_FUA) {
@@ -1024,4 +1030,17 @@ int nbd_client_init(BlockDriverState *bs,
logout("Established connection with NBD server\n");
return 0;
fail:
/*
* We have connected, but must fail for other reasons. The
* connection is still blocking; send NBD_CMD_DISC as a courtesy
* to the server.
*/
{
NBDRequest request = { .type = NBD_CMD_DISC };
nbd_send_request(client->ioc ?: QIO_CHANNEL(sioc), &request);
return ret;
}
}
+8 -4
View File
@@ -1220,16 +1220,20 @@ static void qemu_wait_io_event_common(CPUState *cpu)
process_queued_cpu_work(cpu);
}
static void qemu_tcg_rr_wait_io_event(CPUState *cpu)
static void qemu_tcg_rr_wait_io_event(void)
{
CPUState *cpu;
while (all_cpu_threads_idle()) {
stop_tcg_kick_timer();
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
qemu_cond_wait(first_cpu->halt_cond, &qemu_global_mutex);
}
start_tcg_kick_timer();
qemu_wait_io_event_common(cpu);
CPU_FOREACH(cpu) {
qemu_wait_io_event_common(cpu);
}
}
static void qemu_wait_io_event(CPUState *cpu)
@@ -1562,7 +1566,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
qemu_notify_event();
}
qemu_tcg_rr_wait_io_event(cpu ? cpu : first_cpu);
qemu_tcg_rr_wait_io_event();
deal_with_unplugged_cpus();
}
+3
View File
@@ -2855,6 +2855,7 @@ static void coroutine_fn v9fs_wstat(void *opaque)
struct stat stbuf;
V9fsFidState *fidp;
V9fsPDU *pdu = opaque;
V9fsState *s = pdu->s;
v9fs_stat_init(&v9stat);
err = pdu_unmarshal(pdu, offset, "dwS", &fid, &unused, &v9stat);
@@ -2920,7 +2921,9 @@ static void coroutine_fn v9fs_wstat(void *opaque)
}
}
if (v9stat.name.size != 0) {
v9fs_path_write_lock(s);
err = v9fs_complete_rename(pdu, fidp, -1, &v9stat.name);
v9fs_path_unlock(s);
if (err < 0) {
goto out;
}
+2 -2
View File
@@ -29,11 +29,11 @@ static struct arm_boot_info aspeed_board_binfo = {
.nb_cpus = 1,
};
typedef struct AspeedBoardState {
struct AspeedBoardState {
AspeedSoCState soc;
MemoryRegion ram;
MemoryRegion max_ram;
} AspeedBoardState;
};
/* Palmetto hardware value: 0x120CE416 */
#define PALMETTO_BMC_HW_STRAP1 ( \
+1
View File
@@ -174,6 +174,7 @@ static const char *valid_cpus[] = {
ARM_CPU_TYPE_NAME("cortex-a15"),
ARM_CPU_TYPE_NAME("cortex-a53"),
ARM_CPU_TYPE_NAME("cortex-a57"),
ARM_CPU_TYPE_NAME("cortex-a72"),
ARM_CPU_TYPE_NAME("host"),
ARM_CPU_TYPE_NAME("max"),
};
+2 -2
View File
@@ -72,8 +72,8 @@ typedef struct fm_opl_f {
/* Rhythm sention */
uint8_t rhythm; /* Rhythm mode , key flag */
/* time tables */
int32_t AR_TABLE[75]; /* atttack rate tables */
int32_t DR_TABLE[75]; /* decay rate tables */
int32_t AR_TABLE[76]; /* attack rate tables */
int32_t DR_TABLE[76]; /* decay rate tables */
uint32_t FN_TABLE[1024]; /* fnumber -> increment counter */
/* LFO */
int32_t *ams_table;
+6
View File
@@ -23,6 +23,7 @@
#include "hw/pci/msi.h"
#include "qemu/timer.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
#include "hw/audio/soundhw.h"
#include "intel-hda.h"
#include "intel-hda-defs.h"
@@ -929,6 +930,11 @@ static void intel_hda_reg_write(IntelHDAState *d, const IntelHDAReg *reg, uint32
if (!reg) {
return;
}
if (!reg->wmask) {
qemu_log_mask(LOG_GUEST_ERROR, "intel-hda: write to r/o reg %s\n",
reg->name);
return;
}
if (d->debug) {
time_t now = time(NULL);
+9 -14
View File
@@ -272,7 +272,9 @@ static void nvme_post_cqes(void *opaque)
sizeof(req->cqe));
QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);
}
nvme_irq_assert(n, cq);
if (cq->tail != cq->head) {
nvme_irq_assert(n, cq);
}
}
static void nvme_enqueue_req_completion(NvmeCQueue *cq, NvmeRequest *req)
@@ -554,6 +556,7 @@ static uint16_t nvme_del_cq(NvmeCtrl *n, NvmeCmd *cmd)
trace_nvme_err_invalid_del_cq_notempty(qid);
return NVME_INVALID_QUEUE_DEL;
}
nvme_irq_deassert(n, cq);
trace_nvme_del_cq(qid);
nvme_free_cq(cq, n);
return NVME_SUCCESS;
@@ -797,6 +800,8 @@ static void nvme_clear_ctrl(NvmeCtrl *n)
{
int i;
blk_drain(n->conf.blk);
for (i = 0; i < n->num_queues; i++) {
if (n->sq[i] != NULL) {
nvme_free_sq(n->sq[i], n);
@@ -1175,23 +1180,13 @@ static void nvme_cmb_write(void *opaque, hwaddr addr, uint64_t data,
unsigned size)
{
NvmeCtrl *n = (NvmeCtrl *)opaque;
if (addr + size > NVME_CMBSZ_GETSIZE(n->bar.cmbsz)) {
return;
}
memcpy(&n->cmbuf[addr], &data, size);
stn_le_p(&n->cmbuf[addr], size, data);
}
static uint64_t nvme_cmb_read(void *opaque, hwaddr addr, unsigned size)
{
uint64_t val;
NvmeCtrl *n = (NvmeCtrl *)opaque;
if (addr + size > NVME_CMBSZ_GETSIZE(n->bar.cmbsz)) {
return 0;
}
memcpy(&val, &n->cmbuf[addr], size);
return val;
return ldn_le_p(&n->cmbuf[addr], size);
}
static const MemoryRegionOps nvme_cmb_ops = {
@@ -1199,7 +1194,7 @@ static const MemoryRegionOps nvme_cmb_ops = {
.write = nvme_cmb_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
.min_access_size = 2,
.min_access_size = 1,
.max_access_size = 8,
},
};
+3 -2
View File
@@ -2746,11 +2746,12 @@ static int cirrus_post_load(void *opaque, int version_id)
s->vga.gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
s->vga.gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
cirrus_update_bank_ptr(s, 0);
cirrus_update_bank_ptr(s, 1);
cirrus_update_memory_access(s);
/* force refresh */
s->vga.graphic_mode = -1;
cirrus_update_bank_ptr(s, 0);
cirrus_update_bank_ptr(s, 1);
return 0;
}
+2 -2
View File
@@ -1073,7 +1073,7 @@ static const VMStateDescription vmstate_virtio_gpu_scanouts = {
};
static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
VirtIOGPU *g = opaque;
struct virtio_gpu_simple_resource *res;
@@ -1101,7 +1101,7 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,
}
static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
VMStateField *field)
const VMStateField *field)
{
VirtIOGPU *g = opaque;
struct virtio_gpu_simple_resource *res;
+5 -1
View File
@@ -136,7 +136,11 @@ void hyperv_synic_add(CPUState *cs)
void hyperv_synic_reset(CPUState *cs)
{
device_reset(DEVICE(get_synic(cs)));
SynICState *synic = get_synic(cs);
if (synic) {
device_reset(DEVICE(synic));
}
}
static const TypeInfo synic_type_info = {
+3
View File
@@ -240,6 +240,9 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
uint8_t read = s->smb_addr & 0x01;
s->smb_index++;
if (s->smb_index >= PM_SMBUS_MAX_MSG_SIZE) {
s->smb_index = 0;
}
if (!read && s->smb_index == s->smb_data0) {
uint8_t prot = (s->smb_ctl >> 2) & 0x07;
uint8_t cmd = s->smb_cmd;
+5 -1
View File
@@ -193,7 +193,11 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data)
switch (dev->mode) {
case SMBUS_WRITE_DATA:
DPRINTF("Write data %02x\n", data);
dev->data_buf[dev->data_len++] = data;
if (dev->data_len >= sizeof(dev->data_buf)) {
BADF("Too many bytes sent\n");
} else {
dev->data_buf[dev->data_len++] = data;
}
break;
default:
BADF("Unexpected write in state %d\n", dev->mode);
+1 -1
View File
@@ -942,7 +942,7 @@ static void ps2_kbd_reset(void *opaque)
trace_ps2_kbd_reset(opaque);
ps2_common_reset(&s->common);
s->scan_enabled = 0;
s->scan_enabled = 1;
s->translate = 0;
s->scancode_set = 2;
s->modifiers = 0;
+2 -2
View File
@@ -376,7 +376,7 @@ static void kvm_s390_release_adapter_routes(S390FLICState *fs,
* reached
*/
static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
KVMS390FLICState *flic = opaque;
int len = FLIC_SAVE_INITIAL_SIZE;
@@ -426,7 +426,7 @@ static int kvm_flic_save(QEMUFile *f, void *opaque, size_t size,
* in QEMUFile
*/
static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size,
VMStateField *field)
const VMStateField *field)
{
uint64_t len = 0;
uint64_t count = 0;
-1
View File
@@ -979,7 +979,6 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
/* Do nothing if receive is not enabled. */
if (!gem_can_receive(nc)) {
assert(!first_desc);
return -1;
}
+3 -3
View File
@@ -95,15 +95,15 @@ struct _eeprom_t {
*/
static int get_uint16_from_uint8(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
uint16_t *v = pv;
*v = qemu_get_ubyte(f);
return 0;
}
static int put_unused(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_unused(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
fprintf(stderr, "uint16_from_uint8 is used only for backwards compatibility.\n");
fprintf(stderr, "Never should be used to write a new state.\n");
+3 -3
View File
@@ -520,15 +520,15 @@ static void fw_cfg_reset(DeviceState *d)
*/
static int get_uint32_as_uint16(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
uint32_t *v = pv;
*v = qemu_get_be16(f);
return 0;
}
static int put_unused(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_unused(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
fprintf(stderr, "uint32_as_uint16 is only used for backward compatibility.\n");
fprintf(stderr, "This functions shouldn't be called.\n");
+2 -2
View File
@@ -625,7 +625,7 @@ void msix_unset_vector_notifiers(PCIDevice *dev)
}
static int put_msix_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
msix_save(pv, f);
@@ -633,7 +633,7 @@ static int put_msix_state(QEMUFile *f, void *pv, size_t size,
}
static int get_msix_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
msix_load(pv, f);
return 0;
+4 -4
View File
@@ -450,7 +450,7 @@ int pci_bus_numa_node(PCIBus *bus)
}
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
PCIDevice *s = container_of(pv, PCIDevice, config);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(s);
@@ -490,7 +490,7 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,
/* just put buffer */
static int put_pci_config_device(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
const uint8_t **v = pv;
assert(size == pci_config_size(container_of(pv, PCIDevice, config)));
@@ -506,7 +506,7 @@ static VMStateInfo vmstate_info_pci_config = {
};
static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
PCIDevice *s = container_of(pv, PCIDevice, irq_state);
uint32_t irq_state[PCI_NUM_PINS];
@@ -528,7 +528,7 @@ static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size,
}
static int put_pci_irq_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
int i;
PCIDevice *s = container_of(pv, PCIDevice, irq_state);
+4 -3
View File
@@ -688,8 +688,8 @@ void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
shpc_cap_update_dword(d);
}
static int shpc_save(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int shpc_save(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
PCIDevice *d = container_of(pv, PCIDevice, shpc);
qemu_put_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
@@ -697,7 +697,8 @@ static int shpc_save(QEMUFile *f, void *pv, size_t size, VMStateField *field,
return 0;
}
static int shpc_load(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int shpc_load(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
PCIDevice *d = container_of(pv, PCIDevice, shpc);
int ret = qemu_get_buffer(f, d->shpc->config, SHPC_SIZEOF(d));
+36 -12
View File
@@ -298,6 +298,18 @@ static inline int lsi_irq_on_rsl(LSIState *s)
return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE);
}
static lsi_request *get_pending_req(LSIState *s)
{
lsi_request *p;
QTAILQ_FOREACH(p, &s->queue, next) {
if (p->pending) {
return p;
}
}
return NULL;
}
static void lsi_soft_reset(LSIState *s)
{
trace_lsi_reset();
@@ -446,7 +458,6 @@ static void lsi_update_irq(LSIState *s)
{
int level;
static int last_level;
lsi_request *p;
/* It's unclear whether the DIP/SIP bits should be cleared when the
Interrupt Status Registers are cleared or when istat0 is read.
@@ -476,13 +487,13 @@ static void lsi_update_irq(LSIState *s)
}
lsi_set_irq(s, level);
if (!level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) {
if (!s->current && !level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) {
lsi_request *p;
trace_lsi_update_irq_disconnected();
QTAILQ_FOREACH(p, &s->queue, next) {
if (p->pending) {
lsi_reselect(s, p);
break;
}
p = get_pending_req(s);
if (p) {
lsi_reselect(s, p);
}
}
}
@@ -1065,11 +1076,12 @@ static void lsi_wait_reselect(LSIState *s)
trace_lsi_wait_reselect();
QTAILQ_FOREACH(p, &s->queue, next) {
if (p->pending) {
lsi_reselect(s, p);
break;
}
if (s->current) {
return;
}
p = get_pending_req(s);
if (p) {
lsi_reselect(s, p);
}
if (s->current == NULL) {
s->waiting = 1;
@@ -1259,6 +1271,18 @@ again:
case 1: /* Disconnect */
trace_lsi_execute_script_io_disconnect();
s->scntl1 &= ~LSI_SCNTL1_CON;
/* FIXME: this is not entirely correct; the target need not ask
* for reselection until it has to send data, while here we force a
* reselection as soon as the bus is free. The correct flow would
* reselect before lsi_transfer_data and disconnect as soon as
* DMA ends.
*/
if (!s->current) {
lsi_request *p = get_pending_req(s);
if (p) {
lsi_reselect(s, p);
}
}
break;
case 2: /* Wait Reselect */
if (!lsi_irq_on_rsl(s)) {
+2 -2
View File
@@ -1571,7 +1571,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
/* SCSI request list. For simplicity, pv points to the whole device */
static int put_scsi_requests(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
SCSIDevice *s = pv;
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
@@ -1599,7 +1599,7 @@ static int put_scsi_requests(QEMUFile *f, void *pv, size_t size,
}
static int get_scsi_requests(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
SCSIDevice *s = pv;
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus);
+1 -1
View File
@@ -482,7 +482,7 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed)
if (action == BLOCK_ERROR_ACTION_STOP) {
scsi_req_retry(&r->req);
}
return false;
return true;
}
static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
+2 -2
View File
@@ -750,7 +750,7 @@ static int menelaus_rx(I2CSlave *i2c)
*/
static int get_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
int *v = pv;
*v = qemu_get_be16(f);
@@ -758,7 +758,7 @@ static int get_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
}
static int put_int32_as_uint16(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
int *v = pv;
qemu_put_be16(f, *v);
+18 -6
View File
@@ -1593,17 +1593,23 @@ static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p)
fprintf(stderr, "%s\n", __func__);
}
static void utf16_to_str(uint8_t len, uint16_t *arr, char *name)
static char *utf16_to_str(uint8_t len, uint16_t *arr)
{
int count;
wchar_t *wstr = g_new0(wchar_t, len);
wchar_t *wstr = g_new0(wchar_t, len + 1);
int count, dlen;
char *dest;
for (count = 0; count < len; count++) {
/* FIXME: not working for surrogate pairs */
wstr[count] = (wchar_t)arr[count];
}
wstr[count] = 0;
wcstombs(name, wstr, len);
dlen = wcstombs(NULL, wstr, 0) + 1;
dest = g_malloc(dlen);
wcstombs(dest, wstr, dlen);
g_free(wstr);
return dest;
}
/* Wrapper around write, returns 0 on failure */
@@ -1703,7 +1709,7 @@ static void usb_mtp_write_metadata(MTPState *s)
{
MTPData *d = s->data_out;
ObjectInfo *dataset = (ObjectInfo *)d->data;
char *filename = g_new0(char, dataset->length);
char *filename;
MTPObject *o;
MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle);
uint32_t next_handle = s->next_handle;
@@ -1711,7 +1717,13 @@ static void usb_mtp_write_metadata(MTPState *s)
assert(!s->write_pending);
assert(p != NULL);
utf16_to_str(dataset->length, dataset->filename, filename);
filename = utf16_to_str(dataset->length, dataset->filename);
if (strchr(filename, '/')) {
usb_mtp_queue_result(s, RES_PARAMETER_NOT_SUPPORTED, d->trans,
0, 0, 0, 0);
return;
}
o = usb_mtp_object_lookup_name(p, filename, dataset->length);
if (o != NULL) {
+3
View File
@@ -1120,6 +1120,9 @@ static void usb_host_detach_kernel(USBHostDevice *s)
rc = libusb_kernel_driver_active(s->dh, i);
usb_host_libusb_error("libusb_kernel_driver_active", rc);
if (rc != 1) {
if (rc == 0) {
s->ifs[i].detached = true;
}
continue;
}
trace_usb_host_detach_kernel(s->bus_num, s->addr, i);
+6 -6
View File
@@ -2155,7 +2155,7 @@ static int usbredir_post_load(void *priv, int version_id)
/* For usbredirparser migration */
static int usbredir_put_parser(QEMUFile *f, void *priv, size_t unused,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
USBRedirDevice *dev = priv;
uint8_t *data;
@@ -2178,7 +2178,7 @@ static int usbredir_put_parser(QEMUFile *f, void *priv, size_t unused,
}
static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused,
VMStateField *field)
const VMStateField *field)
{
USBRedirDevice *dev = priv;
uint8_t *data;
@@ -2222,7 +2222,7 @@ static const VMStateInfo usbredir_parser_vmstate_info = {
/* For buffered packets (iso/irq) queue migration */
static int usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
struct endp_data *endp = priv;
USBRedirDevice *dev = endp->dev;
@@ -2245,7 +2245,7 @@ static int usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused,
}
static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused,
VMStateField *field)
const VMStateField *field)
{
struct endp_data *endp = priv;
USBRedirDevice *dev = endp->dev;
@@ -2349,7 +2349,7 @@ static const VMStateDescription usbredir_ep_vmstate = {
/* For PacketIdQueue migration */
static int usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
struct PacketIdQueue *q = priv;
USBRedirDevice *dev = q->dev;
@@ -2368,7 +2368,7 @@ static int usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused,
}
static int usbredir_get_packet_id_q(QEMUFile *f, void *priv, size_t unused,
VMStateField *field)
const VMStateField *field)
{
struct PacketIdQueue *q = priv;
USBRedirDevice *dev = q->dev;
+4 -4
View File
@@ -1816,7 +1816,7 @@ static const VMStateDescription vmstate_virtio_ringsize = {
};
static int get_extra_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
VirtIODevice *vdev = pv;
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@@ -1830,7 +1830,7 @@ static int get_extra_state(QEMUFile *f, void *pv, size_t size,
}
static int put_extra_state(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
VirtIODevice *vdev = pv;
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@@ -1979,14 +1979,14 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f)
/* A wrapper for use as a VMState .put function */
static int virtio_device_put(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
return virtio_save(VIRTIO_DEVICE(opaque), f);
}
/* A wrapper for use as a VMState .get function */
static int virtio_device_get(QEMUFile *f, void *opaque, size_t size,
VMStateField *field)
const VMStateField *field)
{
VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
DeviceClass *dc = DEVICE_CLASS(VIRTIO_DEVICE_GET_CLASS(vdev));
+10
View File
@@ -446,6 +446,8 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
}
}
#define XTFPGA_MMU_RESERVED_MEMORY_SIZE (128 * MiB)
static const hwaddr xtfpga_mmu_io[2] = {
0xf0000000,
};
@@ -568,6 +570,7 @@ static void xtfpga_lx60_class_init(ObjectClass *oc, void *data)
mc->init = xtfpga_lx60_init;
mc->max_cpus = 4;
mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE;
mc->default_ram_size = 64 * MiB;
}
static const TypeInfo xtfpga_lx60_type = {
@@ -584,6 +587,7 @@ static void xtfpga_lx60_nommu_class_init(ObjectClass *oc, void *data)
mc->init = xtfpga_lx60_nommu_init;
mc->max_cpus = 4;
mc->default_cpu_type = XTENSA_DEFAULT_CPU_NOMMU_TYPE;
mc->default_ram_size = 64 * MiB;
}
static const TypeInfo xtfpga_lx60_nommu_type = {
@@ -600,6 +604,7 @@ static void xtfpga_lx200_class_init(ObjectClass *oc, void *data)
mc->init = xtfpga_lx200_init;
mc->max_cpus = 4;
mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE;
mc->default_ram_size = 96 * MiB;
}
static const TypeInfo xtfpga_lx200_type = {
@@ -616,6 +621,7 @@ static void xtfpga_lx200_nommu_class_init(ObjectClass *oc, void *data)
mc->init = xtfpga_lx200_nommu_init;
mc->max_cpus = 4;
mc->default_cpu_type = XTENSA_DEFAULT_CPU_NOMMU_TYPE;
mc->default_ram_size = 96 * MiB;
}
static const TypeInfo xtfpga_lx200_nommu_type = {
@@ -632,6 +638,7 @@ static void xtfpga_ml605_class_init(ObjectClass *oc, void *data)
mc->init = xtfpga_ml605_init;
mc->max_cpus = 4;
mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE;
mc->default_ram_size = 512 * MiB - XTFPGA_MMU_RESERVED_MEMORY_SIZE;
}
static const TypeInfo xtfpga_ml605_type = {
@@ -648,6 +655,7 @@ static void xtfpga_ml605_nommu_class_init(ObjectClass *oc, void *data)
mc->init = xtfpga_ml605_nommu_init;
mc->max_cpus = 4;
mc->default_cpu_type = XTENSA_DEFAULT_CPU_NOMMU_TYPE;
mc->default_ram_size = 256 * MiB;
}
static const TypeInfo xtfpga_ml605_nommu_type = {
@@ -664,6 +672,7 @@ static void xtfpga_kc705_class_init(ObjectClass *oc, void *data)
mc->init = xtfpga_kc705_init;
mc->max_cpus = 4;
mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE;
mc->default_ram_size = 1 * GiB - XTFPGA_MMU_RESERVED_MEMORY_SIZE;
}
static const TypeInfo xtfpga_kc705_type = {
@@ -680,6 +689,7 @@ static void xtfpga_kc705_nommu_class_init(ObjectClass *oc, void *data)
mc->init = xtfpga_kc705_nommu_init;
mc->max_cpus = 4;
mc->default_cpu_type = XTENSA_DEFAULT_CPU_NOMMU_TYPE;
mc->default_ram_size = 256 * MiB;
}
static const TypeInfo xtfpga_kc705_nommu_type = {
+3 -3
View File
@@ -40,8 +40,8 @@ typedef struct VMStateField VMStateField;
*/
struct VMStateInfo {
const char *name;
int (*get)(QEMUFile *f, void *pv, size_t size, VMStateField *field);
int (*put)(QEMUFile *f, void *pv, size_t size, VMStateField *field,
int (*get)(QEMUFile *f, void *pv, size_t size, const VMStateField *field);
int (*put)(QEMUFile *f, void *pv, size_t size, const VMStateField *field,
QJSON *vmdesc);
};
@@ -186,7 +186,7 @@ struct VMStateDescription {
int (*post_load)(void *opaque, int version_id);
int (*pre_save)(void *opaque);
bool (*needed)(void *opaque);
VMStateField *fields;
const VMStateField *fields;
const VMStateDescription **subsections;
};
-6
View File
@@ -169,12 +169,6 @@ void qemu_check_nic_model(NICInfo *nd, const char *model);
int qemu_find_nic_model(NICInfo *nd, const char * const *models,
const char *default_model);
ssize_t qemu_deliver_packet_iov(NetClientState *sender,
unsigned flags,
const struct iovec *iov,
int iovcnt,
void *opaque);
void print_net_client(Monitor *mon, NetClientState *nc);
void hmp_info_network(Monitor *mon, const QDict *qdict);
void net_socket_rs_init(SocketReadState *rs,
+27 -1
View File
@@ -59,6 +59,8 @@ static bool colo_runstate_is_stopped(void)
static void secondary_vm_do_failover(void)
{
/* COLO needs enable block-replication */
#ifdef CONFIG_REPLICATION
int old_state;
MigrationIncomingState *mis = migration_incoming_get_current();
Error *local_err = NULL;
@@ -121,10 +123,14 @@ static void secondary_vm_do_failover(void)
if (mis->migration_incoming_co) {
qemu_coroutine_enter(mis->migration_incoming_co);
}
#else
abort();
#endif
}
static void primary_vm_do_failover(void)
{
#ifdef CONFIG_REPLICATION
MigrationState *s = migrate_get_current();
int old_state;
Error *local_err = NULL;
@@ -165,6 +171,9 @@ static void primary_vm_do_failover(void)
/* Notify COLO thread that failover work is finished */
qemu_sem_post(&s->colo_exit_sem);
#else
abort();
#endif
}
COLOMode get_colo_mode(void)
@@ -415,11 +424,16 @@ static int colo_do_checkpoint_transaction(MigrationState *s,
/* Disable block migration */
migrate_set_block_enabled(false, &local_err);
qemu_mutex_lock_iothread();
#ifdef CONFIG_REPLICATION
replication_do_checkpoint_all(&local_err);
if (local_err) {
qemu_mutex_unlock_iothread();
goto out;
}
#else
abort();
#endif
colo_send_message(s->to_dst_file, COLO_MESSAGE_VMSTATE_SEND, &local_err);
if (local_err) {
@@ -523,11 +537,15 @@ static void colo_process_checkpoint(MigrationState *s)
object_unref(OBJECT(bioc));
qemu_mutex_lock_iothread();
#ifdef CONFIG_REPLICATION
replication_start_all(REPLICATION_MODE_PRIMARY, &local_err);
if (local_err) {
qemu_mutex_unlock_iothread();
goto out;
}
#else
abort();
#endif
vm_start();
qemu_mutex_unlock_iothread();
@@ -690,11 +708,15 @@ void *colo_process_incoming_thread(void *opaque)
object_unref(OBJECT(bioc));
qemu_mutex_lock_iothread();
#ifdef CONFIG_REPLICATION
replication_start_all(REPLICATION_MODE_SECONDARY, &local_err);
if (local_err) {
qemu_mutex_unlock_iothread();
goto out;
}
#else
abort();
#endif
vm_start();
trace_colo_vm_state_change("stop", "run");
qemu_mutex_unlock_iothread();
@@ -785,18 +807,22 @@ void *colo_process_incoming_thread(void *opaque)
goto out;
}
#ifdef CONFIG_REPLICATION
replication_get_error_all(&local_err);
if (local_err) {
qemu_mutex_unlock_iothread();
goto out;
}
/* discard colo disk buffer */
replication_do_checkpoint_all(&local_err);
if (local_err) {
qemu_mutex_unlock_iothread();
goto out;
}
#else
abort();
#endif
/* Notify all filters of all NIC to do checkpoint */
colo_notify_filters_event(COLO_EVENT_CHECKPOINT, &local_err);
+9
View File
@@ -918,6 +918,15 @@ static bool migrate_caps_check(bool *cap_list,
}
#endif
#ifndef CONFIG_REPLICATION
if (cap_list[MIGRATION_CAPABILITY_X_COLO]) {
error_setg(errp, "QEMU compiled without replication module"
" can't enable COLO");
error_append_hint(errp, "Please enable replication before COLO.\n");
return false;
}
#endif
if (cap_list[MIGRATION_CAPABILITY_POSTCOPY_RAM]) {
if (cap_list[MIGRATION_CAPABILITY_COMPRESS]) {
/* The decompression threads asynchronously write into RAM
+8 -3
View File
@@ -263,15 +263,16 @@ void timer_get(QEMUFile *f, QEMUTimer *ts)
* Not in vmstate.c to not add qemu-timer.c as dependency to vmstate.c
*/
static int get_timer(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_timer(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
QEMUTimer *v = pv;
timer_get(f, v);
return 0;
}
static int put_timer(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_timer(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
QEMUTimer *v = pv;
timer_put(f, v);
@@ -2455,6 +2456,10 @@ int save_snapshot(const char *name, Error **errp)
struct tm tm;
AioContext *aio_context;
if (migration_is_blocked(errp)) {
return false;
}
if (!replay_can_snapshot()) {
error_setg(errp, "Record/replay does not allow making snapshot "
"right now. Try once more later.");
+66 -53
View File
@@ -22,15 +22,16 @@
/* bool */
static int get_bool(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_bool(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
bool *v = pv;
*v = qemu_get_byte(f);
return 0;
}
static int put_bool(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_bool(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
bool *v = pv;
qemu_put_byte(f, *v);
@@ -45,15 +46,16 @@ const VMStateInfo vmstate_info_bool = {
/* 8 bit int */
static int get_int8(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_int8(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
int8_t *v = pv;
qemu_get_s8s(f, v);
return 0;
}
static int put_int8(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_int8(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
int8_t *v = pv;
qemu_put_s8s(f, v);
@@ -68,15 +70,16 @@ const VMStateInfo vmstate_info_int8 = {
/* 16 bit int */
static int get_int16(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_int16(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
int16_t *v = pv;
qemu_get_sbe16s(f, v);
return 0;
}
static int put_int16(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_int16(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
int16_t *v = pv;
qemu_put_sbe16s(f, v);
@@ -91,15 +94,16 @@ const VMStateInfo vmstate_info_int16 = {
/* 32 bit int */
static int get_int32(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_int32(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
int32_t *v = pv;
qemu_get_sbe32s(f, v);
return 0;
}
static int put_int32(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_int32(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
int32_t *v = pv;
qemu_put_sbe32s(f, v);
@@ -116,7 +120,7 @@ const VMStateInfo vmstate_info_int32 = {
in the field */
static int get_int32_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
int32_t *v = pv;
int32_t v2;
@@ -142,7 +146,8 @@ const VMStateInfo vmstate_info_int32_equal = {
* and less than or equal to the one in the field.
*/
static int get_int32_le(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_int32_le(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
int32_t *cur = pv;
int32_t loaded;
@@ -166,15 +171,16 @@ const VMStateInfo vmstate_info_int32_le = {
/* 64 bit int */
static int get_int64(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_int64(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
int64_t *v = pv;
qemu_get_sbe64s(f, v);
return 0;
}
static int put_int64(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_int64(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
int64_t *v = pv;
qemu_put_sbe64s(f, v);
@@ -189,15 +195,16 @@ const VMStateInfo vmstate_info_int64 = {
/* 8 bit unsigned int */
static int get_uint8(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_uint8(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
uint8_t *v = pv;
qemu_get_8s(f, v);
return 0;
}
static int put_uint8(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_uint8(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
uint8_t *v = pv;
qemu_put_8s(f, v);
@@ -212,15 +219,16 @@ const VMStateInfo vmstate_info_uint8 = {
/* 16 bit unsigned int */
static int get_uint16(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_uint16(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
uint16_t *v = pv;
qemu_get_be16s(f, v);
return 0;
}
static int put_uint16(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_uint16(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
uint16_t *v = pv;
qemu_put_be16s(f, v);
@@ -235,15 +243,16 @@ const VMStateInfo vmstate_info_uint16 = {
/* 32 bit unsigned int */
static int get_uint32(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_uint32(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
uint32_t *v = pv;
qemu_get_be32s(f, v);
return 0;
}
static int put_uint32(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_uint32(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
uint32_t *v = pv;
qemu_put_be32s(f, v);
@@ -260,7 +269,7 @@ const VMStateInfo vmstate_info_uint32 = {
in the field */
static int get_uint32_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
uint32_t *v = pv;
uint32_t v2;
@@ -284,15 +293,16 @@ const VMStateInfo vmstate_info_uint32_equal = {
/* 64 bit unsigned int */
static int get_uint64(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_uint64(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
uint64_t *v = pv;
qemu_get_be64s(f, v);
return 0;
}
static int put_uint64(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_uint64(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
uint64_t *v = pv;
qemu_put_be64s(f, v);
@@ -305,7 +315,8 @@ const VMStateInfo vmstate_info_uint64 = {
.put = put_uint64,
};
static int get_nullptr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_nullptr(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
if (qemu_get_byte(f) == VMS_NULLPTR_MARKER) {
@@ -316,7 +327,7 @@ static int get_nullptr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
}
static int put_nullptr(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
if (pv == NULL) {
@@ -337,7 +348,7 @@ const VMStateInfo vmstate_info_nullptr = {
in the field */
static int get_uint64_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
uint64_t *v = pv;
uint64_t v2;
@@ -363,7 +374,7 @@ const VMStateInfo vmstate_info_uint64_equal = {
in the field */
static int get_uint8_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
uint8_t *v = pv;
uint8_t v2;
@@ -389,7 +400,7 @@ const VMStateInfo vmstate_info_uint8_equal = {
in the field */
static int get_uint16_equal(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
uint16_t *v = pv;
uint16_t v2;
@@ -414,7 +425,7 @@ const VMStateInfo vmstate_info_uint16_equal = {
/* floating point */
static int get_float64(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
float64 *v = pv;
@@ -422,8 +433,8 @@ static int get_float64(QEMUFile *f, void *pv, size_t size,
return 0;
}
static int put_float64(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_float64(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
uint64_t *v = pv;
@@ -440,7 +451,7 @@ const VMStateInfo vmstate_info_float64 = {
/* CPU_DoubleU type */
static int get_cpudouble(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
CPU_DoubleU *v = pv;
qemu_get_be32s(f, &v->l.upper);
@@ -449,7 +460,7 @@ static int get_cpudouble(QEMUFile *f, void *pv, size_t size,
}
static int put_cpudouble(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
CPU_DoubleU *v = pv;
qemu_put_be32s(f, &v->l.upper);
@@ -466,15 +477,15 @@ const VMStateInfo vmstate_info_cpudouble = {
/* uint8_t buffers */
static int get_buffer(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
uint8_t *v = pv;
qemu_get_buffer(f, v, size);
return 0;
}
static int put_buffer(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_buffer(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
uint8_t *v = pv;
qemu_put_buffer(f, v, size);
@@ -491,7 +502,7 @@ const VMStateInfo vmstate_info_buffer = {
not useful anymore */
static int get_unused_buffer(QEMUFile *f, void *pv, size_t size,
VMStateField *field)
const VMStateField *field)
{
uint8_t buf[1024];
int block_len;
@@ -505,7 +516,7 @@ static int get_unused_buffer(QEMUFile *f, void *pv, size_t size,
}
static int put_unused_buffer(QEMUFile *f, void *pv, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
static const uint8_t buf[1024];
int block_len;
@@ -531,7 +542,8 @@ const VMStateInfo vmstate_info_unused_buffer = {
* in fields that don't really exist in the parent but need to be in the
* stream.
*/
static int get_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_tmp(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
int ret;
const VMStateDescription *vmsd = field->vmsd;
@@ -545,8 +557,8 @@ static int get_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return ret;
}
static int put_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_tmp(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
const VMStateDescription *vmsd = field->vmsd;
void *tmp = g_malloc(size);
@@ -573,7 +585,8 @@ const VMStateInfo vmstate_info_tmp = {
*/
/* This is the number of 64 bit words sent over the wire */
#define BITS_TO_U64S(nr) DIV_ROUND_UP(nr, 64)
static int get_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_bitmap(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
unsigned long *bmp = pv;
int i, idx = 0;
@@ -587,8 +600,8 @@ static int get_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0;
}
static int put_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_bitmap(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
unsigned long *bmp = pv;
int i, idx = 0;
@@ -613,7 +626,7 @@ const VMStateInfo vmstate_info_bitmap = {
* meta data about the QTAILQ is encoded in a VMStateField structure
*/
static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size,
VMStateField *field)
const VMStateField *field)
{
int ret = 0;
const VMStateDescription *vmsd = field->vmsd;
@@ -652,7 +665,7 @@ static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size,
/* put for QTAILQ */
static int put_qtailq(QEMUFile *f, void *pv, size_t unused_size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
const VMStateDescription *vmsd = field->vmsd;
/* offset of the QTAILQ entry in a QTAILQ element*/
+17 -14
View File
@@ -26,7 +26,7 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque);
static int vmstate_n_elems(void *opaque, VMStateField *field)
static int vmstate_n_elems(void *opaque, const VMStateField *field)
{
int n_elems = 1;
@@ -50,7 +50,7 @@ static int vmstate_n_elems(void *opaque, VMStateField *field)
return n_elems;
}
static int vmstate_size(void *opaque, VMStateField *field)
static int vmstate_size(void *opaque, const VMStateField *field)
{
int size = field->size;
@@ -64,7 +64,8 @@ static int vmstate_size(void *opaque, VMStateField *field)
return size;
}
static void vmstate_handle_alloc(void *ptr, VMStateField *field, void *opaque)
static void vmstate_handle_alloc(void *ptr, const VMStateField *field,
void *opaque)
{
if (field->flags & VMS_POINTER && field->flags & VMS_ALLOC) {
gsize size = vmstate_size(opaque, field);
@@ -78,7 +79,7 @@ static void vmstate_handle_alloc(void *ptr, VMStateField *field, void *opaque)
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, int version_id)
{
VMStateField *field = vmsd->fields;
const VMStateField *field = vmsd->fields;
int ret = 0;
trace_vmstate_load_state(vmsd->name, version_id);
@@ -171,9 +172,10 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
return ret;
}
static int vmfield_name_num(VMStateField *start, VMStateField *search)
static int vmfield_name_num(const VMStateField *start,
const VMStateField *search)
{
VMStateField *field;
const VMStateField *field;
int found = 0;
for (field = start; field->name; field++) {
@@ -188,9 +190,10 @@ static int vmfield_name_num(VMStateField *start, VMStateField *search)
return -1;
}
static bool vmfield_name_is_unique(VMStateField *start, VMStateField *search)
static bool vmfield_name_is_unique(const VMStateField *start,
const VMStateField *search)
{
VMStateField *field;
const VMStateField *field;
int found = 0;
for (field = start; field->name; field++) {
@@ -206,7 +209,7 @@ static bool vmfield_name_is_unique(VMStateField *start, VMStateField *search)
return true;
}
static const char *vmfield_get_type_name(VMStateField *field)
static const char *vmfield_get_type_name(const VMStateField *field)
{
const char *type = "unknown";
@@ -221,7 +224,7 @@ static const char *vmfield_get_type_name(VMStateField *field)
return type;
}
static bool vmsd_can_compress(VMStateField *field)
static bool vmsd_can_compress(const VMStateField *field)
{
if (field->field_exists) {
/* Dynamically existing fields mess up compression */
@@ -229,7 +232,7 @@ static bool vmsd_can_compress(VMStateField *field)
}
if (field->flags & VMS_STRUCT) {
VMStateField *sfield = field->vmsd->fields;
const VMStateField *sfield = field->vmsd->fields;
while (sfield->name) {
if (!vmsd_can_compress(sfield)) {
/* Child elements can't compress, so can't we */
@@ -248,7 +251,7 @@ static bool vmsd_can_compress(VMStateField *field)
}
static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
VMStateField *field, int i, int max)
const VMStateField *field, int i, int max)
{
char *name, *old_name;
bool is_array = max > 1;
@@ -287,7 +290,7 @@ static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
}
static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
VMStateField *field, size_t size, int i)
const VMStateField *field, size_t size, int i)
{
if (!vmdesc) {
return;
@@ -323,7 +326,7 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, QJSON *vmdesc, int version_id)
{
int ret = 0;
VMStateField *field = vmsd->fields;
const VMStateField *field = vmsd->fields;
trace_vmstate_save_state_top(vmsd->name);
+1
View File
@@ -978,6 +978,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client,
if (client->opt == NBD_OPT_LIST_META_CONTEXT && !nb_queries) {
/* enable all known contexts */
meta->base_allocation = true;
meta->bitmap = !!meta->exp->export_bitmap;
} else {
for (i = 0; i < nb_queries; ++i) {
ret = nbd_negotiate_meta_query(client, meta, errp);
+2 -1
View File
@@ -20,6 +20,7 @@
#include "hub.h"
#include "qemu/iov.h"
#include "qemu/error-report.h"
#include "sysemu/qtest.h"
/*
* A hub broadcasts incoming packets to all its ports except the source port.
@@ -346,7 +347,7 @@ void net_hub_check_clients(void)
if (has_host_dev && !has_nic) {
warn_report("hub %d with no nics", hub->id);
}
if (has_nic && !has_host_dev) {
if (has_nic && !has_host_dev && !qtest_enabled()) {
warn_report("hub %d is not connected to host network", hub->id);
}
}
+17 -11
View File
@@ -231,6 +231,11 @@ static void qemu_net_client_destructor(NetClientState *nc)
{
g_free(nc);
}
static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
unsigned flags,
const struct iovec *iov,
int iovcnt,
void *opaque);
static void qemu_net_client_setup(NetClientState *nc,
NetClientInfo *info,
@@ -705,22 +710,18 @@ static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov,
return ret;
}
ssize_t qemu_deliver_packet_iov(NetClientState *sender,
unsigned flags,
const struct iovec *iov,
int iovcnt,
void *opaque)
static ssize_t qemu_deliver_packet_iov(NetClientState *sender,
unsigned flags,
const struct iovec *iov,
int iovcnt,
void *opaque)
{
NetClientState *nc = opaque;
size_t size = iov_size(iov, iovcnt);
int ret;
if (size > INT_MAX) {
return size;
}
if (nc->link_down) {
return size;
return iov_size(iov, iovcnt);
}
if (nc->receive_disabled) {
@@ -745,10 +746,15 @@ ssize_t qemu_sendv_packet_async(NetClientState *sender,
NetPacketSent *sent_cb)
{
NetQueue *queue;
size_t size = iov_size(iov, iovcnt);
int ret;
if (size > NET_BUFSIZE) {
return size;
}
if (sender->link_down || !sender->peer) {
return iov_size(iov, iovcnt);
return size;
}
/* Let filters handle the packet first */
+13
View File
@@ -1102,3 +1102,16 @@
'discriminator' : 'type',
'data' : { 'gtk' : 'DisplayGTK',
'egl-headless' : 'DisplayEGLHeadless'} }
##
# @query-display-options:
#
# Returns information about display configuration
#
# Returns: @DisplayOptions
#
# Since: 3.1
#
##
{ 'command': 'query-display-options',
'returns': 'DisplayOptions' }
+2 -1
View File
@@ -261,8 +261,9 @@ static int print_block_option_help(const char *filename, const char *fmt)
return 1;
}
if (!proto_drv->create_opts) {
error_report("Protocal driver '%s' does not support image creation",
error_report("Protocol driver '%s' does not support image creation",
proto_drv->format_name);
qemu_opts_free(create_opts);
return 1;
}
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
+3 -1
View File
@@ -4025,7 +4025,7 @@ Memory backend objects offer more control than the @option{-m} option that is
traditionally used to define guest RAM. Please refer to
@option{memory-backend-file} for a description of the options.
@item -object memory-backend-memfd,id=@var{id},merge=@var{on|off},dump=@var{on|off},prealloc=@var{on|off},size=@var{size},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave},seal=@var{on|off},hugetlb=@var{on|off},hugetlbsize=@var{size}
@item -object memory-backend-memfd,id=@var{id},merge=@var{on|off},dump=@var{on|off},share=@var{on|off},prealloc=@var{on|off},size=@var{size},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave},seal=@var{on|off},hugetlb=@var{on|off},hugetlbsize=@var{size}
Creates an anonymous memory file backend object, which allows QEMU to
share the memory with an external process (e.g. when using
@@ -4047,6 +4047,8 @@ with the @option{seal} option (requires at least Linux 4.16).
Please refer to @option{memory-backend-file} for a description of the
other options.
The @option{share} boolean option is @var{on} by default with memfd.
@item -object rng-random,id=@var{id},filename=@var{/dev/random}
Creates a random number generator backend which obtains entropy from
+2 -1
View File
@@ -2752,7 +2752,8 @@ sub process {
info_vreport|
error_report|
warn_report|
info_report}x;
info_report|
g_test_message}x;
if ($rawline =~ /\b(?:$qemu_error_funcs)\s*\(.*\".*\\n/) {
ERROR("Error messages should not contain newlines\n" . $herecurr);
+1 -1
View File
@@ -236,7 +236,7 @@ static void dm_init(void)
perror("Cannot open " CONTROL_PATH);
exit(1);
}
struct dm_ioctl dm = { 0 };
struct dm_ioctl dm = { };
if (!dm_ioctl(DM_VERSION, &dm)) {
perror("ioctl");
exit(1);
+3 -2
View File
@@ -5,7 +5,8 @@
#include "hw/boards.h"
#include "migration/cpu.h"
static int get_fpcr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
static int get_fpcr(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{
CPUAlphaState *env = opaque;
cpu_alpha_store_fpcr(env, qemu_get_be64(f));
@@ -13,7 +14,7 @@ static int get_fpcr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
}
static int put_fpcr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
CPUAlphaState *env = opaque;
qemu_put_be64(f, cpu_alpha_load_fpcr(env));
+6 -6
View File
@@ -18,7 +18,7 @@ static bool vfp_needed(void *opaque)
}
static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field)
const VMStateField *field)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
@@ -29,7 +29,7 @@ static int get_fpscr(QEMUFile *f, void *opaque, size_t size,
}
static int put_fpscr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
@@ -503,7 +503,7 @@ static const VMStateDescription vmstate_m_security = {
};
static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field)
const VMStateField *field)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
@@ -559,7 +559,7 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
}
static int put_cpsr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
ARMCPU *cpu = opaque;
CPUARMState *env = &cpu->env;
@@ -585,7 +585,7 @@ static const VMStateInfo vmstate_cpsr = {
};
static int get_power(QEMUFile *f, void *opaque, size_t size,
VMStateField *field)
const VMStateField *field)
{
ARMCPU *cpu = opaque;
bool powered_off = qemu_get_byte(f);
@@ -594,7 +594,7 @@ static int get_power(QEMUFile *f, void *opaque, size_t size,
}
static int put_power(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
ARMCPU *cpu = opaque;
+10 -10
View File
@@ -4382,20 +4382,20 @@ static void sve_ld4_r(CPUARMState *env, void *vg, target_ulong addr,
}
#define DO_LDN_1(N) \
void __attribute__((flatten)) HELPER(sve_ld##N##bb_r) \
void QEMU_FLATTEN HELPER(sve_ld##N##bb_r) \
(CPUARMState *env, void *vg, target_ulong addr, uint32_t desc) \
{ \
sve_ld##N##_r(env, vg, addr, desc, 1, GETPC(), sve_ld1bb_tlb); \
}
#define DO_LDN_2(N, SUFF, SIZE) \
void __attribute__((flatten)) HELPER(sve_ld##N##SUFF##_le_r) \
void QEMU_FLATTEN HELPER(sve_ld##N##SUFF##_le_r) \
(CPUARMState *env, void *vg, target_ulong addr, uint32_t desc) \
{ \
sve_ld##N##_r(env, vg, addr, desc, SIZE, GETPC(), \
sve_ld1##SUFF##_le_tlb); \
} \
void __attribute__((flatten)) HELPER(sve_ld##N##SUFF##_be_r) \
void QEMU_FLATTEN HELPER(sve_ld##N##SUFF##_be_r) \
(CPUARMState *env, void *vg, target_ulong addr, uint32_t desc) \
{ \
sve_ld##N##_r(env, vg, addr, desc, SIZE, GETPC(), \
@@ -4832,7 +4832,7 @@ static void sve_st4_r(CPUARMState *env, void *vg, target_ulong addr,
}
#define DO_STN_1(N, NAME, ESIZE) \
void __attribute__((flatten)) HELPER(sve_st##N##NAME##_r) \
void QEMU_FLATTEN HELPER(sve_st##N##NAME##_r) \
(CPUARMState *env, void *vg, target_ulong addr, uint32_t desc) \
{ \
sve_st##N##_r(env, vg, addr, desc, GETPC(), ESIZE, 1, \
@@ -4840,13 +4840,13 @@ void __attribute__((flatten)) HELPER(sve_st##N##NAME##_r) \
}
#define DO_STN_2(N, NAME, ESIZE, MSIZE) \
void __attribute__((flatten)) HELPER(sve_st##N##NAME##_le_r) \
void QEMU_FLATTEN HELPER(sve_st##N##NAME##_le_r) \
(CPUARMState *env, void *vg, target_ulong addr, uint32_t desc) \
{ \
sve_st##N##_r(env, vg, addr, desc, GETPC(), ESIZE, MSIZE, \
sve_st1##NAME##_le_tlb); \
} \
void __attribute__((flatten)) HELPER(sve_st##N##NAME##_be_r) \
void QEMU_FLATTEN HELPER(sve_st##N##NAME##_be_r) \
(CPUARMState *env, void *vg, target_ulong addr, uint32_t desc) \
{ \
sve_st##N##_r(env, vg, addr, desc, GETPC(), ESIZE, MSIZE, \
@@ -4966,7 +4966,7 @@ static void sve_ld1_zd(CPUARMState *env, void *vd, void *vg, void *vm,
}
#define DO_LD1_ZPZ_S(MEM, OFS) \
void __attribute__((flatten)) HELPER(sve_ld##MEM##_##OFS) \
void QEMU_FLATTEN HELPER(sve_ld##MEM##_##OFS) \
(CPUARMState *env, void *vd, void *vg, void *vm, \
target_ulong base, uint32_t desc) \
{ \
@@ -4975,7 +4975,7 @@ void __attribute__((flatten)) HELPER(sve_ld##MEM##_##OFS) \
}
#define DO_LD1_ZPZ_D(MEM, OFS) \
void __attribute__((flatten)) HELPER(sve_ld##MEM##_##OFS) \
void QEMU_FLATTEN HELPER(sve_ld##MEM##_##OFS) \
(CPUARMState *env, void *vd, void *vg, void *vm, \
target_ulong base, uint32_t desc) \
{ \
@@ -5326,7 +5326,7 @@ static void sve_st1_zd(CPUARMState *env, void *vd, void *vg, void *vm,
}
#define DO_ST1_ZPZ_S(MEM, OFS) \
void __attribute__((flatten)) HELPER(sve_st##MEM##_##OFS) \
void QEMU_FLATTEN HELPER(sve_st##MEM##_##OFS) \
(CPUARMState *env, void *vd, void *vg, void *vm, \
target_ulong base, uint32_t desc) \
{ \
@@ -5335,7 +5335,7 @@ void __attribute__((flatten)) HELPER(sve_st##MEM##_##OFS) \
}
#define DO_ST1_ZPZ_D(MEM, OFS) \
void __attribute__((flatten)) HELPER(sve_st##MEM##_##OFS) \
void QEMU_FLATTEN HELPER(sve_st##MEM##_##OFS) \
(CPUARMState *env, void *vd, void *vg, void *vm, \
target_ulong base, uint32_t desc) \
{ \
+6 -4
View File
@@ -46,7 +46,8 @@
VMSTATE_UINTTR_ARRAY_V(_f, _s, _n, 0)
static int get_psw(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
static int get_psw(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{
CPUHPPAState *env = opaque;
cpu_hppa_put_psw(env, qemu_get_betr(f));
@@ -54,7 +55,7 @@ static int get_psw(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
}
static int put_psw(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
CPUHPPAState *env = opaque;
qemu_put_betr(f, cpu_hppa_get_psw(env));
@@ -68,7 +69,8 @@ static const VMStateInfo vmstate_psw = {
};
/* FIXME: Use the PA2.0 format, which is a superset of the PA1.1 format. */
static int get_tlb(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
static int get_tlb(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{
hppa_tlb_entry *ent = opaque;
uint32_t val;
@@ -94,7 +96,7 @@ static int get_tlb(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
}
static int put_tlb(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
hppa_tlb_entry *ent = opaque;
uint32_t val = 0;
+3 -3
View File
@@ -454,9 +454,9 @@ struct decode_x87_tbl {
struct decode_tbl invl_inst = {0x0, 0, 0, false, NULL, NULL, NULL, NULL,
decode_invalid};
struct decode_tbl _decode_tbl1[255];
struct decode_tbl _decode_tbl2[255];
struct decode_x87_tbl _decode_tbl3[255];
struct decode_tbl _decode_tbl1[256];
struct decode_tbl _decode_tbl2[256];
struct decode_x87_tbl _decode_tbl3[256];
static void decode_x87_ins(CPUX86State *env, struct x86_decode *decode)
{
+19 -11
View File
@@ -95,6 +95,7 @@ static bool has_msr_xss;
static bool has_msr_spec_ctrl;
static bool has_msr_virt_ssbd;
static bool has_msr_smi_count;
static bool has_msr_arch_capabs;
static uint32_t has_architectural_pmu_version;
static uint32_t num_architectural_pmu_gp_counters;
@@ -854,6 +855,7 @@ static int hyperv_init_vcpu(X86CPU *cpu)
}
static Error *invtsc_mig_blocker;
static Error *vmx_mig_blocker;
#define KVM_MAX_CPUID_ENTRIES 100
@@ -1246,6 +1248,17 @@ int kvm_arch_init_vcpu(CPUState *cs)
!!(c->ecx & CPUID_EXT_SMX);
}
if ((env->features[FEAT_1_ECX] & CPUID_EXT_VMX) && !vmx_mig_blocker) {
error_setg(&vmx_mig_blocker,
"Nested VMX virtualization does not support live migration yet");
r = migrate_add_blocker(vmx_mig_blocker, &local_err);
if (local_err) {
error_report_err(local_err);
error_free(vmx_mig_blocker);
return r;
}
}
if (env->mcg_cap & MCG_LMCE_P) {
has_msr_mcg_ext_ctl = has_msr_feature_control = true;
}
@@ -1253,7 +1266,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (!env->user_tsc_khz) {
if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) &&
invtsc_mig_blocker == NULL) {
/* for migration */
error_setg(&invtsc_mig_blocker,
"State blocked by non-migratable CPU device"
" (invtsc flag)");
@@ -1263,8 +1275,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
error_free(invtsc_mig_blocker);
return r;
}
/* for savevm */
vmstate_x86_cpu.unmigratable = 1;
}
}
@@ -1481,6 +1491,9 @@ static int kvm_get_supported_msrs(KVMState *s)
case MSR_VIRT_SSBD:
has_msr_virt_ssbd = true;
break;
case MSR_IA32_ARCH_CAPABILITIES:
has_msr_arch_capabs = true;
break;
}
}
}
@@ -2002,14 +2015,9 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
#endif
/* If host supports feature MSR, write down. */
if (kvm_feature_msrs) {
int i;
for (i = 0; i < kvm_feature_msrs->nmsrs; i++)
if (kvm_feature_msrs->indices[i] == MSR_IA32_ARCH_CAPABILITIES) {
kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES,
env->features[FEAT_ARCH_CAPABILITIES]);
break;
}
if (has_msr_arch_capabs) {
kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES,
env->features[FEAT_ARCH_CAPABILITIES]);
}
/*
+20 -15
View File
@@ -1268,10 +1268,30 @@ static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
}
}
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
{
gen_update_cc_op(s);
gen_jmp_im(s, cur_eip);
gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
s->base.is_jmp = DISAS_NORETURN;
}
/* Generate #UD for the current instruction. The assumption here is that
the instruction is known, but it isn't allowed in the current cpu mode. */
static void gen_illegal_opcode(DisasContext *s)
{
gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
}
/* if d == OR_TMP0, it means memory operand (address in A0) */
static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
{
if (d != OR_TMP0) {
if (s1->prefix & PREFIX_LOCK) {
/* Lock prefix when destination is not memory. */
gen_illegal_opcode(s1);
return;
}
gen_op_mov_v_reg(s1, ot, s1->T0, d);
} else if (!(s1->prefix & PREFIX_LOCK)) {
gen_op_ld_v(s1, ot, s1->T0, s1->A0);
@@ -2469,21 +2489,6 @@ static void gen_leave(DisasContext *s)
gen_op_mov_reg_v(s, a_ot, R_ESP, s->T1);
}
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
{
gen_update_cc_op(s);
gen_jmp_im(s, cur_eip);
gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
s->base.is_jmp = DISAS_NORETURN;
}
/* Generate #UD for the current instruction. The assumption here is that
the instruction is known, but it isn't allowed in the current cpu mode. */
static void gen_illegal_opcode(DisasContext *s)
{
gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
}
/* Similarly, except that the assumption here is that we don't decode
the instruction at all -- either a missing opcode, an unimplemented
feature, or just a bogus instruction stream. */
+8 -6
View File
@@ -20,7 +20,8 @@ static int cpu_post_load(void *opaque, int version_id)
/* FPU state */
static int get_fpr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_fpr(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
int i;
fpr_t *v = pv;
@@ -31,8 +32,8 @@ static int get_fpr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0;
}
static int put_fpr(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_fpr(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
int i;
fpr_t *v = pv;
@@ -128,7 +129,8 @@ const VMStateDescription vmstate_mvp = {
/* TLB state */
static int get_tlb(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_tlb(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
r4k_tlb_t *v = pv;
uint16_t flags;
@@ -155,8 +157,8 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0;
}
static int put_tlb(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_tlb(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
r4k_tlb_t *v = pv;
+3 -2
View File
@@ -49,7 +49,8 @@ static const VMStateDescription vmstate_cpu_tlb = {
}
};
static int get_sr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
static int get_sr(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{
CPUOpenRISCState *env = opaque;
cpu_set_sr(env, qemu_get_be32(f));
@@ -57,7 +58,7 @@ static int get_sr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
}
static int put_sr(QEMUFile *f, void *opaque, size_t size,
VMStateField *field, QJSON *vmdesc)
const VMStateField *field, QJSON *vmdesc)
{
CPUOpenRISCState *env = opaque;
qemu_put_be32(f, cpu_get_sr(env));
+8 -6
View File
@@ -110,7 +110,8 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
return 0;
}
static int get_avr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_avr(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
ppc_avr_t *v = pv;
@@ -120,8 +121,8 @@ static int get_avr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0;
}
static int put_avr(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_avr(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
ppc_avr_t *v = pv;
@@ -452,7 +453,8 @@ static const VMStateDescription vmstate_sr = {
};
#ifdef TARGET_PPC64
static int get_slbe(QEMUFile *f, void *pv, size_t size, VMStateField *field)
static int get_slbe(QEMUFile *f, void *pv, size_t size,
const VMStateField *field)
{
ppc_slb_t *v = pv;
@@ -462,8 +464,8 @@ static int get_slbe(QEMUFile *f, void *pv, size_t size, VMStateField *field)
return 0;
}
static int put_slbe(QEMUFile *f, void *pv, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_slbe(QEMUFile *f, void *pv, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
ppc_slb_t *v = pv;
+4 -3
View File
@@ -56,7 +56,8 @@ static const VMStateDescription vmstate_tlb_entry = {
};
#endif
static int get_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
static int get_psr(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field)
{
SPARCCPU *cpu = opaque;
CPUSPARCState *env = &cpu->env;
@@ -69,8 +70,8 @@ static int get_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
return 0;
}
static int put_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field,
QJSON *vmdesc)
static int put_psr(QEMUFile *f, void *opaque, size_t size,
const VMStateField *field, QJSON *vmdesc)
{
SPARCCPU *cpu = opaque;
CPUSPARCState *env = &cpu->env;
-2
View File
@@ -40,8 +40,6 @@
static XtensaConfig dc232b __attribute__((unused)) = {
.name = "dc232b",
.gdb_regmap = {
.num_regs = 120,
.num_core_regs = 52,
.reg = {
#include "core-dc232b/gdb-config.inc.c"
}
@@ -259,3 +259,4 @@
0, 0, 0, 0, 0, 0)
XTREG(119, 476, 32, 4, 4, 0x000f, 0x0006, -2, 8, 0x0100, a15,
0, 0, 0, 0, 0, 0)
XTREG_END
-2
View File
@@ -40,8 +40,6 @@
static XtensaConfig dc233c __attribute__((unused)) = {
.name = "dc233c",
.gdb_regmap = {
.num_regs = 121,
.num_core_regs = 52,
.reg = {
#include "core-dc233c/gdb-config.inc.c"
}
@@ -143,3 +143,4 @@ XTREG(117, 468, 32, 4, 4, 0x000c, 0x0006, -2, 8, 0x0100, a12, 0, 0, 0, 0
XTREG(118, 472, 32, 4, 4, 0x000d, 0x0006, -2, 8, 0x0100, a13, 0, 0, 0, 0, 0, 0)
XTREG(119, 476, 32, 4, 4, 0x000e, 0x0006, -2, 8, 0x0100, a14, 0, 0, 0, 0, 0, 0)
XTREG(120, 480, 32, 4, 4, 0x000f, 0x0006, -2, 8, 0x0100, a15, 0, 0, 0, 0, 0, 0)
XTREG_END
+8 -3
View File
@@ -45,15 +45,20 @@ void xtensa_count_regs(const XtensaConfig *config,
unsigned *n_regs, unsigned *n_core_regs)
{
unsigned i;
bool count_core_regs = true;
for (i = 0; config->gdb_regmap.reg[i].targno >= 0; ++i) {
if (config->gdb_regmap.reg[i].type != xtRegisterTypeTieState &&
config->gdb_regmap.reg[i].type != xtRegisterTypeMapped &&
config->gdb_regmap.reg[i].type != xtRegisterTypeUnmapped) {
++*n_regs;
if ((config->gdb_regmap.reg[i].flags &
XTENSA_REGISTER_FLAGS_PRIVILEGED) == 0) {
++*n_core_regs;
if (count_core_regs) {
if ((config->gdb_regmap.reg[i].flags &
XTENSA_REGISTER_FLAGS_PRIVILEGED) == 0) {
++*n_core_regs;
} else {
count_core_regs = false;
}
}
}
}
+1 -1
View File
@@ -730,7 +730,7 @@ tests/test-hmp$(EXESUF): tests/test-hmp.o
tests/machine-none-test$(EXESUF): tests/machine-none-test.o
tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-virtio-obj-y)
tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y)
tests/nvme-test$(EXESUF): tests/nvme-test.o
tests/nvme-test$(EXESUF): tests/nvme-test.o $(libqos-pc-obj-y)
tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o
tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o
tests/ac97-test$(EXESUF): tests/ac97-test.o
+58 -10
View File
@@ -8,25 +8,73 @@
*/
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "libqtest.h"
#include "libqos/libqos-pc.h"
static QOSState *qnvme_start(const char *extra_opts)
{
QOSState *qs;
const char *arch = qtest_get_arch();
const char *cmd = "-drive id=drv0,if=none,file=null-co://,format=raw "
"-device nvme,addr=0x4.0,serial=foo,drive=drv0 %s";
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
qs = qtest_pc_boot(cmd, extra_opts ? : "");
global_qtest = qs->qts;
return qs;
}
g_printerr("nvme tests are only available on x86\n");
exit(EXIT_FAILURE);
}
static void qnvme_stop(QOSState *qs)
{
qtest_shutdown(qs);
}
/* Tests only initialization so far. TODO: Replace with functional tests */
static void nop(void)
{
QOSState *qs;
qs = qnvme_start(NULL);
qnvme_stop(qs);
}
static void nvmetest_cmb_test(void)
{
const int cmb_bar_size = 2 * MiB;
QOSState *qs;
QPCIDevice *pdev;
QPCIBar bar;
qs = qnvme_start("-global nvme.cmb_size_mb=2");
pdev = qpci_device_find(qs->pcibus, QPCI_DEVFN(4,0));
g_assert(pdev != NULL);
qpci_device_enable(pdev);
bar = qpci_iomap(pdev, 2, NULL);
qpci_io_writel(pdev, bar, 0, 0xccbbaa99);
g_assert_cmpint(qpci_io_readb(pdev, bar, 0), ==, 0x99);
g_assert_cmpint(qpci_io_readw(pdev, bar, 0), ==, 0xaa99);
/* Test partially out-of-bounds accesses. */
qpci_io_writel(pdev, bar, cmb_bar_size - 1, 0x44332211);
g_assert_cmpint(qpci_io_readb(pdev, bar, cmb_bar_size - 1), ==, 0x11);
g_assert_cmpint(qpci_io_readw(pdev, bar, cmb_bar_size - 1), !=, 0x2211);
g_assert_cmpint(qpci_io_readl(pdev, bar, cmb_bar_size - 1), !=, 0x44332211);
g_free(pdev);
qnvme_stop(qs);
}
int main(int argc, char **argv)
{
int ret;
g_test_init(&argc, &argv, NULL);
qtest_add_func("/nvme/nop", nop);
qtest_add_func("/nvme/cmb_test", nvmetest_cmb_test);
qtest_start("-drive id=drv0,if=none,file=null-co://,format=raw "
"-device nvme,drive=drv0,serial=foo");
ret = g_test_run();
qtest_end();
return ret;
return g_test_run();
}
+3 -3
View File
@@ -469,7 +469,7 @@ new_state = "1"
self.assert_qmp(event, 'data/id', 'drive0')
event = self.vm.get_qmp_event(wait=True)
self.assertEquals(event['event'], 'BLOCK_JOB_ERROR')
self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
self.assert_qmp(event, 'data/device', 'drive0')
self.assert_qmp(event, 'data/operation', 'read')
result = self.vm.qmp('query-block-jobs')
@@ -494,7 +494,7 @@ new_state = "1"
self.assert_qmp(event, 'data/id', 'drive0')
event = self.vm.get_qmp_event(wait=True)
self.assertEquals(event['event'], 'BLOCK_JOB_ERROR')
self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
self.assert_qmp(event, 'data/device', 'drive0')
self.assert_qmp(event, 'data/operation', 'read')
result = self.vm.qmp('query-block-jobs')
@@ -625,7 +625,7 @@ new_state = "1"
self.assert_qmp(result, 'return', {})
event = self.vm.event_wait(name='BLOCK_JOB_ERROR')
self.assertEquals(event['event'], 'BLOCK_JOB_ERROR')
self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
self.assert_qmp(event, 'data/device', 'drive0')
self.assert_qmp(event, 'data/operation', 'write')
result = self.vm.qmp('query-block-jobs')
+8 -12
View File
@@ -53,21 +53,17 @@ class ChangeBaseClass(iotests.QMPTestCase):
if not self.has_real_tray:
return
timeout = time.clock() + 3
while not self.has_opened and time.clock() < timeout:
self.process_events()
if not self.has_opened:
self.fail('Timeout while waiting for the tray to open')
with iotests.Timeout(3, 'Timeout while waiting for the tray to open'):
while not self.has_opened:
self.process_events()
def wait_for_close(self):
if not self.has_real_tray:
return
timeout = time.clock() + 3
while not self.has_closed and time.clock() < timeout:
self.process_events()
if not self.has_opened:
self.fail('Timeout while waiting for the tray to close')
with iotests.Timeout(3, 'Timeout while waiting for the tray to close'):
while not self.has_closed:
self.process_events()
class GeneralChangeTestsBaseClass(ChangeBaseClass):
@@ -265,7 +261,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
# Should be a no-op
self.assert_qmp(result, 'return', {})
self.assertEquals(self.vm.get_qmp_events(wait=False), [])
self.assertEqual(self.vm.get_qmp_events(wait=False), [])
def test_remove_on_closed(self):
if not self.has_real_tray:
@@ -452,7 +448,7 @@ class TestChangeReadOnly(ChangeBaseClass):
read_only_mode='retain')
self.assert_qmp(result, 'error/class', 'GenericError')
self.assertEquals(self.vm.get_qmp_events(wait=False), [])
self.assertEqual(self.vm.get_qmp_events(wait=False), [])
result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/ro', False)
+137
View File
@@ -0,0 +1,137 @@
#!/bin/bash
#
# Test reopening a backing image after block-stream and block-commit
#
# Copyright (C) 2018 Igalia, S.L.
#
# 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=berto@igalia.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
rm -f "$TEST_IMG.base"
rm -f "$TEST_IMG.int"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
. ./common.qemu
# Any format implementing BlockDriver.bdrv_change_backing_file
_supported_fmt qcow2 qed
_supported_proto file
_supported_os Linux
IMG_SIZE=1M
# Create the images
TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE | _filter_imgfmt
TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" | _filter_imgfmt
_make_test_img -b "$TEST_IMG.int" | _filter_imgfmt
# First test: reopen $TEST.IMG changing the detect-zeroes option on
# its backing file ($TEST_IMG.int).
echo
echo "*** Change an option on the backing file"
echo
_launch_qemu -drive if=none,file="${TEST_IMG}"
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'qmp_capabilities' }" \
'return'
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'human-monitor-command',
'arguments': { 'command-line':
'qemu-io none0 \"reopen -o backing.detect-zeroes=on\"' } }" \
"return"
_cleanup_qemu
# Second test: stream $TEST_IMG.base into $TEST_IMG.int and then
# reopen $TEST.IMG changing the detect-zeroes option on its new
# backing file ($TEST_IMG.base).
echo
echo "*** Stream and then change an option on the backing file"
echo
_launch_qemu -drive if=none,file="${TEST_IMG}"
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'qmp_capabilities' }" \
'return'
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'block-stream', \
'arguments': { 'device': 'none0',
'base': '${TEST_IMG}.base' } }" \
'return'
# Wait for block-stream to finish
sleep 0.5
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'human-monitor-command',
'arguments': { 'command-line':
'qemu-io none0 \"reopen -o backing.detect-zeroes=on\"' } }" \
"return"
_cleanup_qemu
# Third test: commit $TEST_IMG.int into $TEST_IMG.base and then reopen
# $TEST.IMG changing the detect-zeroes option on its new backing file
# ($TEST_IMG.base).
echo
echo "*** Commit and then change an option on the backing file"
echo
# Create the images again
TEST_IMG="$TEST_IMG.base" _make_test_img $IMG_SIZE | _filter_imgfmt
TEST_IMG="$TEST_IMG.int" _make_test_img -b "$TEST_IMG.base" | _filter_imgfmt
_make_test_img -b "$TEST_IMG.int" | _filter_imgfmt
_launch_qemu -drive if=none,file="${TEST_IMG}"
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'qmp_capabilities' }" \
'return'
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'block-commit', \
'arguments': { 'device': 'none0',
'top': '${TEST_IMG}.int' } }" \
'return'
# Wait for block-commit to finish
sleep 0.5
_send_qemu_cmd $QEMU_HANDLE \
"{ 'execute': 'human-monitor-command',
'arguments': { 'command-line':
'qemu-io none0 \"reopen -o backing.detect-zeroes=on\"' } }" \
"return"
_cleanup_qemu
# success, all done
echo "*** done"
rm -f $seq.full
status=0
+39
View File
@@ -0,0 +1,39 @@
QA output created by 161
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576
Formatting 'TEST_DIR/t.IMGFMT.int', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.int
*** Change an option on the backing file
{"return": {}}
{"return": ""}
*** Stream and then change an option on the backing file
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "stream"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
{"return": ""}
*** Commit and then change an option on the backing file
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576
Formatting 'TEST_DIR/t.IMGFMT.int', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.base
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.IMGFMT.int
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "none0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "none0"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "none0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "none0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "none0", "len": 1048576, "offset": 1048576, "speed": 0, "type": "commit"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "none0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "none0"}}
{"return": ""}
*** done
+35 -8
View File
@@ -57,10 +57,11 @@ run_qemu()
}
echo
echo "=== Create partially sparse image, then add dirty bitmap ==="
echo "=== Create partially sparse image, then add dirty bitmaps ==="
echo
_make_test_img 4M
# Two bitmaps, to contrast granularity issues
_make_test_img -o cluster_size=4k 4M
$QEMU_IO -c 'w -P 0x11 1M 2M' "$TEST_IMG" | _filter_qemu_io
run_qemu <<EOF
{ "execute": "qmp_capabilities" }
@@ -78,7 +79,16 @@ run_qemu <<EOF
"arguments": {
"node": "n",
"name": "b",
"persistent": true
"persistent": true,
"granularity": 65536
}
}
{ "execute": "block-dirty-bitmap-add",
"arguments": {
"node": "n",
"name": "b2",
"persistent": true,
"granularity": 512
}
}
{ "execute": "quit" }
@@ -88,10 +98,11 @@ echo
echo "=== Write part of the file under active bitmap ==="
echo
$QEMU_IO -c 'w -P 0x22 2M 2M' "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c 'w -P 0x22 512 512' -c 'w -P 0x33 2M 2M' "$TEST_IMG" \
| _filter_qemu_io
echo
echo "=== End dirty bitmap, and start serving image over NBD ==="
echo "=== End dirty bitmaps, and start serving image over NBD ==="
echo
_launch_qemu 2> >(_filter_nbd)
@@ -103,6 +114,8 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"blockdev-add",
"file":{"driver":"file", "filename":"'"$TEST_IMG"'"}}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-block-dirty-bitmap-disable",
"arguments":{"node":"n", "name":"b"}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-block-dirty-bitmap-disable",
"arguments":{"node":"n", "name":"b2"}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start",
"arguments":{"addr":{"type":"unix",
"data":{"path":"'"$TEST_DIR/nbd"'"}}}}' "return"
@@ -110,26 +123,40 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
"arguments":{"device":"n"}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap",
"arguments":{"name":"n", "bitmap":"b"}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add",
"arguments":{"device":"n", "name":"n2"}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap",
"arguments":{"name":"n2", "bitmap":"b2"}}' "return"
echo
echo "=== Contrast normal status with dirty-bitmap status ==="
echo "=== Contrast normal status to large granularity dirty-bitmap ==="
echo
QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
IMG="driver=nbd,export=n,server.type=unix,server.path=$TEST_DIR/nbd"
$QEMU_IO -r -c 'r -P 0 0 1m' -c 'r -P 0x11 1m 1m' \
-c 'r -P 0x22 2m 2m' --image-opts "$IMG" | _filter_qemu_io
$QEMU_IO -r -c 'r -P 0x22 512 512' -c 'r -P 0 512k 512k' -c 'r -P 0x11 1m 1m' \
-c 'r -P 0x33 2m 2m' --image-opts "$IMG" | _filter_qemu_io
$QEMU_IMG map --output=json --image-opts \
"$IMG" | _filter_qemu_img_map
$QEMU_IMG map --output=json --image-opts \
"$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b" | _filter_qemu_img_map
echo
echo "=== Contrast to small granularity dirty-bitmap ==="
echo
IMG="driver=nbd,export=n2,server.type=unix,server.path=$TEST_DIR/nbd"
$QEMU_IMG map --output=json --image-opts \
"$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b2" | _filter_qemu_img_map
echo
echo "=== End NBD server ==="
echo
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove",
"arguments":{"name":"n"}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove",
"arguments":{"name":"n2"}}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-stop"}' "return"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"quit"}' "return"
+25 -7
View File
@@ -1,6 +1,6 @@
QA output created by 223
=== Create partially sparse image, then add dirty bitmap ===
=== Create partially sparse image, then add dirty bitmaps ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4194304
wrote 2097152/2097152 bytes at offset 1048576
@@ -11,15 +11,18 @@ QMP_VERSION
{"return": {}}
{"return": {}}
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
=== Write part of the file under active bitmap ===
wrote 512/512 bytes at offset 512
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 2097152/2097152 bytes at offset 2097152
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
=== End dirty bitmap, and start serving image over NBD ===
=== End dirty bitmaps, and start serving image over NBD ===
{"return": {}}
{"return": {}}
@@ -27,18 +30,32 @@ wrote 2097152/2097152 bytes at offset 2097152
{"return": {}}
{"return": {}}
{"return": {}}
{"return": {}}
{"return": {}}
{"return": {}}
=== Contrast normal status with dirty-bitmap status ===
=== Contrast normal status to large granularity dirty-bitmap ===
read 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 512/512 bytes at offset 512
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 524288/524288 bytes at offset 524288
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 1048576/1048576 bytes at offset 1048576
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 2097152/2097152 bytes at offset 2097152
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false},
[{ "start": 0, "length": 4096, "depth": 0, "zero": false, "data": true},
{ "start": 4096, "length": 1044480, "depth": 0, "zero": true, "data": false},
{ "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": true}]
[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true},
[{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false},
{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": true},
{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}]
=== Contrast to small granularity dirty-bitmap ===
[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true},
{ "start": 512, "length": 512, "depth": 0, "zero": false, "data": false},
{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": true},
{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}]
=== End NBD server ===
@@ -46,4 +63,5 @@ read 2097152/2097152 bytes at offset 2097152
{"return": {}}
{"return": {}}
{"return": {}}
{"return": {}}
*** done
+6 -3
View File
@@ -66,7 +66,7 @@ $QEMU_IO -c 'w -P 0x11 1m 1m' "$TEST_IMG" | _filter_qemu_io
echo
echo "== check TLS client to plain server fails =="
nbd_server_start_tcp_socket "$TEST_IMG"
nbd_server_start_tcp_socket -f $IMGFMT "$TEST_IMG"
$QEMU_IMG info --image-opts \
--object tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0 \
@@ -78,7 +78,10 @@ nbd_server_stop
echo
echo "== check plain client to TLS server fails =="
nbd_server_start_tcp_socket --object tls-creds-x509,dir=${tls_dir}/server1,endpoint=server,id=tls0,verify-peer=yes --tls-creds tls0 "$TEST_IMG"
nbd_server_start_tcp_socket \
--object tls-creds-x509,dir=${tls_dir}/server1,endpoint=server,id=tls0,verify-peer=yes \
--tls-creds tls0 \
-f $IMGFMT "$TEST_IMG"
$QEMU_IMG info nbd://localhost:$nbd_tcp_port 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
@@ -104,7 +107,7 @@ $QEMU_IO -c 'r -P 0x11 1m 1m' -c 'w -P 0x22 1m 1m' --image-opts \
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
2>&1 | _filter_qemu_io
$QEMU_IO -f qcow2 -r -U -c 'r -P 0x22 1m 1m' "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -f $IMGFMT -r -U -c 'r -P 0x22 1m 1m' "$TEST_IMG" | _filter_qemu_io
# success, all done
echo "*** done"
+121
View File
@@ -0,0 +1,121 @@
#!/usr/bin/env python
#
# Copyright (C) 2018 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: Kevin Wolf <kwolf@redhat.com>
#
# Check that block node activation and inactivation works with a block graph
# that is built with individually created nodes
import iotests
import os
iotests.verify_image_format(supported_fmts=['qcow2'])
iotests.verify_platform(['linux'])
with iotests.FilePath('img') as img_path, \
iotests.FilePath('backing') as backing_path, \
iotests.FilePath('mig_fifo_a') as fifo_a, \
iotests.FilePath('mig_fifo_b') as fifo_b, \
iotests.VM(path_suffix='a') as vm_a, \
iotests.VM(path_suffix='b') as vm_b:
iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, backing_path, '64M')
iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, img_path, '64M')
os.mkfifo(fifo_a)
os.mkfifo(fifo_b)
iotests.log('Launching source VM...')
(vm_a.add_blockdev('file,filename=%s,node-name=drive0-file' % (img_path))
.add_blockdev('%s,file=drive0-file,node-name=drive0' % (iotests.imgfmt))
.add_blockdev('file,filename=%s,node-name=drive0-backing-file' % (backing_path))
.add_blockdev('%s,file=drive0-backing-file,node-name=drive0-backing' % (iotests.imgfmt))
.launch())
iotests.log('Launching destination VM...')
(vm_b.add_blockdev('file,filename=%s,node-name=drive0-file' % (img_path))
.add_blockdev('%s,file=drive0-file,node-name=drive0' % (iotests.imgfmt))
.add_blockdev('file,filename=%s,node-name=drive0-backing-file' % (backing_path))
.add_blockdev('%s,file=drive0-backing-file,node-name=drive0-backing' % (iotests.imgfmt))
.add_incoming("exec: cat '%s'" % (fifo_a))
.launch())
# Add a child node that was created after the parent node. The reverse case
# is covered by the -blockdev options above.
iotests.log(vm_a.qmp('blockdev-snapshot', node='drive0-backing',
overlay='drive0'))
iotests.log(vm_b.qmp('blockdev-snapshot', node='drive0-backing',
overlay='drive0'))
iotests.log('Enabling migration QMP events on A...')
iotests.log(vm_a.qmp('migrate-set-capabilities', capabilities=[
{
'capability': 'events',
'state': True
}
]))
iotests.log('Starting migration to B...')
iotests.log(vm_a.qmp('migrate', uri='exec:cat >%s' % (fifo_a)))
with iotests.Timeout(3, 'Migration does not complete'):
while True:
event = vm_a.event_wait('MIGRATION')
iotests.log(event, filters=[iotests.filter_qmp_event])
if event['data']['status'] == 'completed':
break
iotests.log(vm_a.qmp('query-migrate')['return']['status'])
iotests.log(vm_b.qmp('query-migrate')['return']['status'])
iotests.log(vm_a.qmp('query-status'))
iotests.log(vm_b.qmp('query-status'))
iotests.log('Add a second parent to drive0-file...')
iotests.log(vm_b.qmp('blockdev-add', driver='raw', file='drive0-file',
node_name='drive0-raw'))
iotests.log('Restart A with -incoming and second parent...')
vm_a.shutdown()
(vm_a.add_blockdev('raw,file=drive0-file,node-name=drive0-raw')
.add_incoming("exec: cat '%s'" % (fifo_b))
.launch())
iotests.log(vm_a.qmp('blockdev-snapshot', node='drive0-backing',
overlay='drive0'))
iotests.log('Enabling migration QMP events on B...')
iotests.log(vm_b.qmp('migrate-set-capabilities', capabilities=[
{
'capability': 'events',
'state': True
}
]))
iotests.log('Starting migration back to A...')
iotests.log(vm_b.qmp('migrate', uri='exec:cat >%s' % (fifo_b)))
with iotests.Timeout(3, 'Migration does not complete'):
while True:
event = vm_b.event_wait('MIGRATION')
iotests.log(event, filters=[iotests.filter_qmp_event])
if event['data']['status'] == 'completed':
break
iotests.log(vm_a.qmp('query-migrate')['return']['status'])
iotests.log(vm_b.qmp('query-migrate')['return']['status'])
iotests.log(vm_a.qmp('query-status'))
iotests.log(vm_b.qmp('query-status'))
+30
View File
@@ -0,0 +1,30 @@
Launching source VM...
Launching destination VM...
{"return": {}}
{"return": {}}
Enabling migration QMP events on A...
{"return": {}}
Starting migration to B...
{"return": {}}
{"data": {"status": "setup"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"status": "active"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
completed
completed
{"return": {"running": false, "singlestep": false, "status": "postmigrate"}}
{"return": {"running": true, "singlestep": false, "status": "running"}}
Add a second parent to drive0-file...
{"return": {}}
Restart A with -incoming and second parent...
{"return": {}}
Enabling migration QMP events on B...
{"return": {}}
Starting migration back to A...
{"return": {}}
{"data": {"status": "setup"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"status": "active"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
completed
completed
{"return": {"running": true, "singlestep": false, "status": "running"}}
{"return": {"running": false, "singlestep": false, "status": "postmigrate"}}
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env python
#
# Simple mirror test
#
# Copyright (c) 2018 Virtuozzo International GmbH. All rights reserved.
#
# 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/>.
#
import sys
import os
import iotests
from iotests import qemu_img_create, qemu_io, file_path, log
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts'))
from qemu import QEMUMachine
# Note:
# This test was added to check that mirror dead-lock was fixed (see previous
# commit before this test addition).
# And it didn't reproduce if at least one of the following:
# 1. use small image size
# 2. use raw format (not qcow2)
# 3. drop kvm and use iotests.VM() (maybe, because of qtest) (however, it still
# reproduces, if just drop kvm, but gdb failed to produce full backtraces
# for me)
# 4. add iothread
size = 1 * 1024 * 1024 * 1024
iotests.verify_image_format(supported_fmts=['qcow2'])
disk = file_path('disk')
# prepare source image
qemu_img_create('-f', iotests.imgfmt, '-o', 'preallocation=metadata', disk,
str(size))
vm = QEMUMachine(iotests.qemu_prog)
vm.add_args('-machine', 'pc,accel=kvm')
vm.add_args('-drive', 'id=src,file=' + disk)
vm.launch()
log(vm.qmp('object-add', qom_type='throttle-group', id='tg0',
props={ 'x-bps-total': size }))
log(vm.qmp('blockdev-add',
**{ 'node-name': 'target',
'driver': 'throttle',
'throttle-group': 'tg0',
'file': {
'driver': 'null-co',
'size': size
} }))
log(vm.qmp('blockdev-mirror', device='src', target='target', sync='full'))
try:
vm.event_wait('BLOCK_JOB_READY', timeout=10.0)
except:
vm.shutdown()
raise
vm.shutdown()
+3
View File
@@ -0,0 +1,3 @@
{"return": {}}
{"return": {}}
{"return": {}}
+3
View File
@@ -31,6 +31,9 @@ tls_x509_cleanup()
tls_x509_init()
{
(certtool --help) >/dev/null 2>&1 || \
_notrun "certtool utility not found, skipping test"
mkdir -p "${tls_dir}"
# use a fixed key so we don't waste system entropy on
+3
View File
@@ -167,6 +167,7 @@
158 rw auto quick
159 rw auto quick
160 rw auto quick
161 rw auto quick
162 auto quick
163 rw auto
165 rw auto quick
@@ -230,3 +231,5 @@
231 auto quick
232 auto quick
233 auto quick
234 auto quick migration
235 auto quick
+1 -1
View File
@@ -581,7 +581,7 @@ class QMPTestCase(unittest.TestCase):
def wait_ready_and_cancel(self, drive='drive0'):
self.wait_ready(drive=drive)
event = self.cancel_and_wait(drive=drive)
self.assertEquals(event['event'], 'BLOCK_JOB_COMPLETED')
self.assertEqual(event['event'], 'BLOCK_JOB_COMPLETED')
self.assert_qmp(event, 'data/type', 'mirror')
self.assert_qmp(event, 'data/offset', event['data']['len'])
+1 -1
View File
@@ -323,7 +323,7 @@ vubr_backend_recv_cb(int sock, void *ctx)
.msg_name = (struct sockaddr *) &vubr->backend_udp_dest,
.msg_namelen = sizeof(struct sockaddr_in),
.msg_iov = sg,
.msg_iovlen = elem->in_num,
.msg_iovlen = num,
.msg_flags = MSG_DONTWAIT,
};
do {
+57 -7
View File
@@ -24,7 +24,6 @@
#define PCI_SLOT_HP 0x06
#define PCI_SLOT 0x04
#define PCI_FN 0x00
#define QVIRTIO_NET_TIMEOUT_US (30 * 1000 * 1000)
#define VNET_HDR_SIZE sizeof(struct virtio_net_hdr_mrg_rxbuf)
@@ -52,17 +51,21 @@ static QVirtioPCIDevice *virtio_net_pci_init(QPCIBus *bus, int slot)
return dev;
}
static QOSState *pci_test_start(int socket)
GCC_FMT_ATTR(1, 2)
static QOSState *pci_test_start(const char *cmd, ...)
{
QOSState *qs;
va_list ap;
const char *arch = qtest_get_arch();
const char *cmd = "-netdev socket,fd=%d,id=hs0 -device "
"virtio-net-pci,netdev=hs0";
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
qs = qtest_pc_boot(cmd, socket);
va_start(ap, cmd);
qs = qtest_pc_vboot(cmd, ap);
va_end(ap);
} else if (strcmp(arch, "ppc64") == 0) {
qs = qtest_spapr_boot(cmd, socket);
va_start(ap, cmd);
qs = qtest_spapr_vboot(cmd, ap);
va_end(ap);
} else {
g_printerr("virtio-net tests are only available on x86 or ppc64\n");
exit(EXIT_FAILURE);
@@ -223,7 +226,8 @@ static void pci_basic(gconstpointer data)
ret = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
g_assert_cmpint(ret, !=, -1);
qs = pci_test_start(sv[1]);
qs = pci_test_start("-netdev socket,fd=%d,id=hs0 -device "
"virtio-net-pci,netdev=hs0", sv[1]);
dev = virtio_net_pci_init(qs->pcibus, PCI_SLOT);
rx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
@@ -241,6 +245,48 @@ static void pci_basic(gconstpointer data)
g_free(dev);
qtest_shutdown(qs);
}
static void large_tx(gconstpointer data)
{
QVirtioPCIDevice *dev;
QOSState *qs;
QVirtQueuePCI *tx, *rx;
QVirtQueue *vq;
uint64_t req_addr;
uint32_t free_head;
size_t alloc_size = (size_t)data / 64;
int i;
qs = pci_test_start("-netdev hubport,id=hp0,hubid=0 "
"-device virtio-net-pci,netdev=hp0");
dev = virtio_net_pci_init(qs->pcibus, PCI_SLOT);
rx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
tx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 1);
driver_init(&dev->vdev);
vq = &tx->vq;
/* Bypass the limitation by pointing several descriptors to a single
* smaller area */
req_addr = guest_alloc(qs->alloc, alloc_size);
free_head = qvirtqueue_add(vq, req_addr, alloc_size, false, true);
for (i = 0; i < 64; i++) {
qvirtqueue_add(vq, req_addr, alloc_size, false, i != 63);
}
qvirtqueue_kick(&dev->vdev, vq, free_head);
qvirtio_wait_used_elem(&dev->vdev, vq, free_head, NULL,
QVIRTIO_NET_TIMEOUT_US);
qvirtqueue_cleanup(dev->vdev.bus, &tx->vq, qs->alloc);
qvirtqueue_cleanup(dev->vdev.bus, &rx->vq, qs->alloc);
qvirtio_pci_device_disable(dev);
g_free(dev->pdev);
g_free(dev);
qtest_shutdown(qs);
}
#endif
static void hotplug(void)
@@ -266,6 +312,10 @@ int main(int argc, char **argv)
qtest_add_data_func("/virtio/net/pci/basic", send_recv_test, pci_basic);
qtest_add_data_func("/virtio/net/pci/rx_stop_cont",
stop_cont_test, pci_basic);
qtest_add_data_func("/virtio/net/pci/large_tx_uint_max",
(gconstpointer)UINT_MAX, large_tx);
qtest_add_data_func("/virtio/net/pci/large_tx_net_bufsize",
(gconstpointer)NET_BUFSIZE, large_tx);
#endif
qtest_add_func("/virtio/net/pci/hotplug", hotplug);
+1 -1
View File
@@ -411,13 +411,13 @@ static int qemu_vfio_init_ramblock(const char *block_name, void *host_addr,
static void qemu_vfio_open_common(QEMUVFIOState *s)
{
qemu_mutex_init(&s->lock);
s->ram_notifier.ram_block_added = qemu_vfio_ram_block_added;
s->ram_notifier.ram_block_removed = qemu_vfio_ram_block_removed;
ram_block_notifier_add(&s->ram_notifier);
s->low_water_mark = QEMU_VFIO_IOVA_MIN;
s->high_water_mark = QEMU_VFIO_IOVA_MAX;
qemu_ram_foreach_block(qemu_vfio_init_ramblock, s);
qemu_mutex_init(&s->lock);
}
/**
+10 -5
View File
@@ -128,6 +128,7 @@ int main(int argc, char **argv)
#include "qapi/qapi-commands-block-core.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-run-state.h"
#include "qapi/qapi-commands-ui.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/iothread.h"
@@ -1522,9 +1523,6 @@ static int machine_help_func(QemuOpts *opts, MachineState *machine)
return 1;
}
/***********************************************************/
/* main execution loop */
struct vm_change_state_entry {
VMChangeStateHandler *cb;
void *opaque;
@@ -2055,6 +2053,11 @@ static void parse_display_qapi(const char *optarg)
visit_free(v);
}
DisplayOptions *qmp_query_display_options(Error **errp)
{
return QAPI_CLONE(DisplayOptions, &dpy);
}
static void parse_display(const char *p)
{
const char *opts;
@@ -2244,8 +2247,10 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */
buf = g_memdup(str, size);
} else {
if (!g_file_get_contents(file, &buf, &size, NULL)) {
error_setg(errp, "can't load %s", file);
GError *err = NULL;
if (!g_file_get_contents(file, &buf, &size, &err)) {
error_setg(errp, "can't load %s: %s", file, err->message);
g_error_free(err);
return -1;
}
}