Compare commits

..
245 Commits
Author SHA1 Message Date
Michael Roth 4cd42653f5 Update version for 2.9.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-09-07 11:25:12 -05:00
Greg Kurz c24c5910b7 virtfs: error out gracefully when mandatory suboptions are missing
We internally convert -virtfs to -fsdev/-device. If the user doesn't
provide the path or security_model suboptions, and the fsdev backend
requires them, we hit an assertion when populating the internal -fsdev
option:

util/qemu-option.c:547: opt_set: Assertion `opt->str' failed.
Aborted (core dumped)

Let's test the suboption presence on the command line before trying
to set it in the internal -fsdev option, and let the backend code
error out gracefully (ie, like it already does when the user passes
-fsdev on the command line).

Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 32b6943699)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-09-05 15:42:17 -05:00
Richard Henderson 2d1bbf51c2 target/arm: Fix aa64 ldp register writeback
For "ldp x0, x1, [x0]", if the second load is on a second page and
the second page is unmapped, the exception would be raised with x0
already modified.  This means the instruction couldn't be restarted.

Cc: qemu-arm@nongnu.org
Cc: qemu-stable@nongnu.org
Reported-by: Andrew <andrew@fubar.geek.nz>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20170825224833.4463-1-richard.henderson@linaro.org
Fixes: https://bugs.launchpad.net/qemu/+bug/1713066
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
[PMM: tweaked comment format]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

(cherry picked from commit 3e4d91b94c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-09-04 23:12:48 -05:00
Anthony PERARD 30b76b2439 exec: Add lock parameter to qemu_ram_ptr_length
Commit 04bf2526ce (exec: use
qemu_ram_ptr_length to access guest ram) start using qemu_ram_ptr_length
instead of qemu_map_ram_ptr, but when used with Xen, the behavior of
both function is different. They both call xen_map_cache, but one with
"lock", meaning the mapping of guest memory is never released
implicitly, and the second one without, which means, mapping can be
release later, when needed.

In the context of address_space_{read,write}_continue, the ptr to those
mapping should not be locked because it is used immediatly and never
used again.

The lock parameter make it explicit in which context qemu_ram_ptr_length
is called.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Message-Id: <20170726165326.10327-1-anthony.perard@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit f5aa69bdc3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-09-01 18:15:39 -05:00
Stefano Stabellini 2f64063f4e xen/mapcache: store dma information in revmapcache entries for debugging
The Xen mapcache is able to create long term mappings, they are called
"locked" mappings. The third parameter of the xen_map_cache call
specifies if a mapping is a "locked" mapping.

>From the QEMU point of view there are two kinds of long term mappings:

[a] device memory mappings, such as option roms and video memory
[b] dma mappings, created by dma_memory_map & friends

After certain operations, ballooning a VM in particular, Xen asks QEMU
kindly to destroy all mappings. However, certainly [a] mappings are
present and cannot be removed. That's not a problem as they are not
affected by balloonning. The *real* problem is that if there are any
mappings of type [b], any outstanding dma operations could fail. This is
a known shortcoming. In other words, when Xen asks QEMU to destroy all
mappings, it is an error if any [b] mappings exist.

However today we have no way of distinguishing [a] from [b]. Because of
that, we cannot even print a decent warning.

This patch introduces a new "dma" bool field to MapCacheRev entires, to
remember if a given mapping is for dma or is a long term device memory
mapping. When xen_invalidate_map_cache is called, we print a warning if
any [b] mappings exist. We ignore [a] mappings.

Mappings created by qemu_map_ram_ptr are assumed to be [a], while
mappings created by address_space_map->qemu_ram_ptr_length are assumed
to be [b].

The goal of the patch is to make debugging and system understanding
easier.

Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Anthony PERARD <anthony.perard@citrix.com>
(cherry picked from commit 1ff7c5986a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-09-01 18:15:24 -05:00
Prasad J Pandit 15d8f91446 exec: use qemu_ram_ptr_length to access guest ram
When accessing guest's ram block during DMA operation, use
'qemu_ram_ptr_length' to get ram block pointer. It ensures
that DMA operation of given length is possible; And avoids
any OOB memory access situations.

Reported-by: Alex <broscutamaker@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <20170712123840.29328-1-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 04bf2526ce)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-09-01 18:10:46 -05:00
Gerd Hoffmann f9c313f70f xhci: only update dequeue ptr on completed transfers
The dequeue pointer should only be updated in case the transfer
is actually completed.  If we update it for inflight transfers
we will not pick them up again after migration, which easily
triggers with HID devices as they typically have a pending
transfer, waiting for user input to happen.

Fixes: 243afe858b
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451631
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Laurent Vivier <lvivier@redhat.com>
Message-id: 20170608074122.32099-1-kraxel@redhat.com
(cherry picked from commit d54fddea98)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-09-01 18:10:36 -05:00
Dr. David Alan Gilbert 53206753ba vl.c/exit: pause cpus before closing block devices
There's a rare exit seg if the guest is accessing
IO during exit.
It's always hitting the atomic_inc(&bs->in_flight) with a NULL
bs. This was added recently in 99723548  but I don't see it
as the cause.

Flip vl.c around so we pause the cpus before closing the block devices,
that way we shouldn't have anything trying to access them when
they're gone.

This was originally Red Hat bz https://bugzilla.redhat.com/show_bug.cgi?id=1451015

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reported-by: Cong Li <coli@redhat.com>

--
This is a very rare race, I'll leave it running in a loop to see if
we hit anything else and to check this really fixes it.

I do worry if there are other cases that can trigger this - e.g.
hot-unplug or ejecting a CD.

Message-Id: <20170713190116.21608-1-dgilbert@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 452589b6b4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 17:09:34 -05:00
Michael Roth 167e76494e PPC: E500: update u-boot to match shipped binary
Previous submodule commit contained some unused files with comments
that made redistribution requirements unclear, and the submodule commit
should really match the blob we're shipped anyway.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 16:59:16 -05:00
Farhan Ali e22e199b2b s390-ccw: Fix alignment for CCW1
The commit 198c0d1f9d s390x/css: check ccw address validity
exposes an alignment issue in ccw bios.

According to PoP the CCW must be doubleword aligned. Let's fix
this in the bios.

Cc: qemu-stable@nongnu.org
Signed-off-by: Farhan Ali <alifm@linux.vnet.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: Eric Farman <farman@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-Id: <3ed8b810b6592daee6a775037ce21f850e40647d.1503667215.git.alifm@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 3a1e4561ad)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 12:01:54 -05:00
Alexander Graf 5035184165 vnc: Set default kbd delay to 10ms
The current VNC default keyboard delay is 1ms. With that we're constantly
typing faster than the guest receives keyboard events from an XHCI attached
USB HID device.

The default keyboard delay time in the input layer however is 10ms. I don't know
how that number came to be, but empirical tests on some OpenQA driven ARM
systems show that 10ms really is a reasonable default number for the delay.

This patch moves the VNC delay also to 10ms. That way our default is much
safer (good!) and also consistent with the input layer default (also good!).

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 1499863425-103133-1-git-send-email-agraf@suse.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit d3b0db6dfe)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:17 -05:00
Max Reitz 20920f4db6 qemu-nbd: Ignore SIGPIPE
qemu proper has done so for 13 years
(8a7ddc38a6), qemu-img and qemu-io have
done so for four years (526eda14a6).
Ignoring this signal is especially important in qemu-nbd because
otherwise a client can easily take down the qemu-nbd server by dropping
the connection when the server wants to send something, for example:

$ qemu-nbd -x foo -f raw -t null-co:// &
[1] 12726
$ qemu-io -c quit nbd://localhost/bar
can't open device nbd://localhost/bar: No export with name 'bar' available
[1]  + 12726 broken pipe  qemu-nbd -x foo -f raw -t null-co://

In this case, the client sends an NBD_OPT_ABORT and closes the
connection (because it is not required to wait for a reply), but the
server replies with an NBD_REP_ACK (because it is required to reply).

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20170611123714.31292-1-mreitz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 041e32b8d9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:17 -05:00
Gerd Hoffmann 4e6889b76b usb-redir: fix stack overflow in usbredir_log_data
Don't reinvent a broken wheel, just use the hexdump function we have.

Impact: low, broken code doesn't run unless you have debug logging
enabled.

Reported-by: 李强 <liqiang6-s@360.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170509110128.27261-1-kraxel@redhat.com
(cherry picked from commit bd4a683505)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Paolo Bonzini 244a3ef947 megasas: do not read SCSI req parameters more than once from frame
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b356807fcd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Paolo Bonzini 578fb5003f megasas: do not read command more than once from frame
Avoid TOC-TOU bugs by passing the frame_cmd down, and checking
cmd->dcmd_opcode instead of cmd->frame->header.frame_cmd.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 36c327a69d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Paolo Bonzini 50b9353315 megasas: do not read DCMD opcode more than once from frame
Avoid TOC-TOU bugs by storing the DCMD opcode in the MegasasCmd

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5104fac853)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Paolo Bonzini d016071ca5 megasas: do not read iovec count more than once from frame
Avoid TOC-TOU bugs depending on how the compiler behaves.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 24c0c77af5)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Paolo Bonzini 20fd62d374 megasas: do not read sense length more than once from frame
Avoid TOC-TOU bugs depending on how the compiler behaves.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 134550bf81)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Greg Kurz 7442018a00 9pfs: local: forbid client access to metadata (CVE-2017-7493)
When using the mapped-file security mode, we shouldn't let the client mess
with the metadata. The current code already tries to hide the metadata dir
from the client by skipping it in local_readdir(). But the client can still
access or modify it through several other operations. This can be used to
escalate privileges in the guest.

Affected backend operations are:
- local_mknod()
- local_mkdir()
- local_open2()
- local_symlink()
- local_link()
- local_unlinkat()
- local_renameat()
- local_rename()
- local_name_to_path()

Other operations are safe because they are only passed a fid path, which
is computed internally in local_name_to_path().

This patch converts all the functions listed above to fail and return
EINVAL when being passed the name of the metadata dir. This may look
like a poor choice for errno, but there's no such thing as an illegal
path name on Linux and I could not think of anything better.

This fixes CVE-2017-7493.

Reported-by: Leo Gaspard <leo@gaspard.io>
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 7a95434e0c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Prasad J Pandit 0f590e798f scsi: avoid an off-by-one error in megasas_mmio_write
While reading magic sequence(MFI_SEQ) in megasas_mmio_write,
an off-by-one error could occur as 's->adp_reset' index is not
reset after reading the last sequence.

Reported-by: YY Z <bigbird475958471@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <20170424120634.12268-1-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 24dfa9fa2f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Gerd Hoffmann 3c69132635 audio: release capture buffers
AUD_add_capture() allocates two buffers which are never released.
Add the missing calls to AUD_del_capture().

Impact: Allows vnc clients to exhaust host memory by repeatedly
starting and stopping audio capture.

Fixes: CVE-2017-8309
Cc: P J P <ppandit@redhat.com>
Cc: Huawei PSIRT <PSIRT@huawei.com>
Reported-by: "Jiangxin (hunter, SCC)" <jiangxin1@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 20170428075612.9997-1-kraxel@redhat.com
(cherry picked from commit 3268a845f4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
P J P 40a7d47c5a vmw_pvscsi: check message ring page count at initialisation
A guest could set the message ring page count to zero, resulting in
infinite loop. Add check to avoid it.

Reported-by: YY Z <bigbird475958471@gmail.com>
Signed-off-by: P J P <ppandit@redhat.com>
Message-Id: <20170425130623.3649-1-ppandit@redhat.com>
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit f68826989c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Thomas Huth 9b9b4423d7 hw/ppc/spapr_iommu: Fix crash when removing the "spapr-tce-table" device
QEMU currently aborts unexpectedly when the user tries to add and
remove a "spapr-tce-table" device:

$ qemu-system-ppc64 -nographic -S -nodefaults -monitor stdio
QEMU 2.9.92 monitor - type 'help' for more information
(qemu) device_add spapr-tce-table,id=x
(qemu) device_del x
**
ERROR:qemu/qdev-monitor.c:872:qdev_unplug: assertion failed: (hotplug_ctrl)
Aborted (core dumped)

The device should not be accessable for the users at all, it's just
used internally, so mark it with user_creatable = false.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 1f98e55385)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Thomas Huth 980e8260e6 hw/ppc/spapr_rtc: Mark the RTC device with user_creatable = false
QEMU currently aborts unexpectedly when a user tries to do something
like this:

$ qemu-system-ppc64 -nographic -S -nodefaults -monitor stdio
QEMU 2.9.92 monitor - type 'help' for more information
(qemu) device_add spapr-rtc,id=spapr-rtc
(qemu) device_del spapr-rtc
**
ERROR:qemu/qdev-monitor.c:872:qdev_unplug: assertion failed: (hotplug_ctrl)
Aborted (core dumped)

The RTC device is not meant to be hot-pluggable - it's an internal
device only and it even should not be possible to create it a
second time with the "-device" parameter, so let's mark this
with "user_creatable = false".

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 8ccccff9dd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Eduardo Habkost aab00230aa qdev: Replace cannot_instantiate_with_device_add_yet with !user_creatable
cannot_instantiate_with_device_add_yet was introduced by commit
efec3dd631 to replace no_user. It was
supposed to be a temporary measure.

When it was introduced, we had 54
cannot_instantiate_with_device_add_yet=true lines in the code.
Today (3 years later) this number has not shrunk: we now have
57 cannot_instantiate_with_device_add_yet=true lines. I think it
is safe to say it is not a temporary measure, and we won't see
the flag go away soon.

Instead of a long field name that misleads people to believe it
is temporary, replace it a shorter and less misleading field:
user_creatable.

Except for code comments, changes were generated using the
following Coccinelle patch:

  @@
  expression DC;
  @@
  (
  -DC->cannot_instantiate_with_device_add_yet = false;
  +DC->user_creatable = true;
  |
  -DC->cannot_instantiate_with_device_add_yet = true;
  +DC->user_creatable = false;
  )

  @@
  typedef ObjectClass;
  expression dc;
  identifier class, data;
  @@
   static void device_class_init(ObjectClass *class, void *data)
   {
   ...
   dc->hotpluggable = true;
  +dc->user_creatable = true;
   ...
   }

  @@
  @@
   struct DeviceClass {
   ...
  -bool cannot_instantiate_with_device_add_yet;
  +bool user_creatable;
   ...
  }

  @@
  expression DC;
  @@
  (
  -!DC->cannot_instantiate_with_device_add_yet
  +DC->user_creatable
  |
  -DC->cannot_instantiate_with_device_add_yet
  +!DC->user_creatable
  )

Cc: Alistair Francis <alistair.francis@xilinx.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Thomas Huth <thuth@redhat.com>
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Acked-by: Marcel Apfelbaum <marcel@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170503203604.31462-2-ehabkost@redhat.com>
[ehabkost: kept "TODO remove once we're there" comment]
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit e90f2a8c3e)
 Conflicts:
	include/hw/qdev-core.h
* remove context dep on 08f00df
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:51:16 -05:00
Eduardo Otubo cfc65be6fb fix qemu-system-unicore32 crashing when calling without -kernel
Starting qemu-system-unicore32 without the -kernel parameter results in
an assert() returns false and aborts qemu. This patch replaces it with a
proper error message followed by exit(1).

Signed-off-by: Eduardo Otubo <otubo@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 36bed541ca)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:24:20 -05:00
Thomas Huth ac0038f182 hw/s390x/ipl: Fix crash with virtio-scsi-pci device
qemu-system-s390x currently crashes when it is started with a
virtio-scsi-pci device, e.g.:

 qemu-system-s390x -nographic -enable-kvm -device virtio-scsi-pci \
                   -drive file=/tmp/disk.dat,if=none,id=d1,format=raw \
                   -device scsi-cd,drive=d1,bootindex=1

The problem is that the code in s390_gen_initial_iplb() currently assumes
that all SCSI devices are also CCW devices, which is not the case for
virtio-scsi-pci of course. Fix it by adding an appropriate check for
TYPE_CCW_DEVICE here.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-Id: <1493126327-13162-1-git-send-email-thuth@redhat.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit 99efaa2696)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:24:04 -05:00
Samuel Thibault 62708c7c12 slirp: fix clearing ifq_so from pending packets
The if_fastq and if_batchq contain not only packets, but queues of packets
for the same socket. When sofree frees a socket, it thus has to clear ifq_so
from all the packets from the queues, not only the first.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 1201d30851)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:22:38 -05:00
Marc-André Lureau 746e1fd000 slirp: tftp, copy sockaddr_size
ASAN detects an "unknown-crash" when running pxe-test:

/ppc64/pxe/spapr-vlan: =================================================================
==7143==ERROR: AddressSanitizer: unknown-crash on address 0x7f6dcd298d30 at pc 0x55e22218830d bp 0x7f6dcd2989e0 sp 0x7f6dcd2989d0
READ of size 128 at 0x7f6dcd298d30 thread T2
    #0 0x55e22218830c in tftp_session_allocate /home/elmarco/src/qq/slirp/tftp.c:73
    #1 0x55e22218a1f8 in tftp_handle_rrq /home/elmarco/src/qq/slirp/tftp.c:289
    #2 0x55e22218b54c in tftp_input /home/elmarco/src/qq/slirp/tftp.c:446
    #3 0x55e2221833fe in udp6_input /home/elmarco/src/qq/slirp/udp6.c:82
    #4 0x55e222137b17 in ip6_input /home/elmarco/src/qq/slirp/ip6_input.c:67

Address 0x7f6dcd298d30 is located in stack of thread T2 at offset 96 in frame
    #0 0x55e222182420 in udp6_input /home/elmarco/src/qq/slirp/udp6.c:13

  This frame has 3 object(s):
    [32, 48) '<unknown>'
    [96, 124) 'lhost' <== Memory access at offset 96 partially overflows this variable
    [160, 200) 'save_ip' <== Memory access at offset 96 partially underflows this variable

The sockaddr_storage pointer is the sockaddr_in6 lhost on the
stack. Copy only the source addr size.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
(cherry picked from commit 17eb587aeb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:22:14 -05:00
Thomas Huth e8679f5b45 monitor: Check whether TCG is enabled before running the "info jit" code
The "info jit" command currently aborts on Mac OS X with the message
"qemu_mutex_lock: Invalid argument" when running with "-M accel=qtest".
We should only call into the TCG code here if TCG has really been
enabled and initialized.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1493179907-22516-1-git-send-email-thuth@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Tested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit b7da97eef7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:21:45 -05:00
Philipp Kern c152efc943 target-s390x: Mask the SIGP order_code to 8bit.
According to "CPU Signaling and Response", "Signal-Processor Orders",
the order field is bit position 56-63. Without this, the Linux
guest kernel is sometimes unable to stop emulation and enters
an infinite loop of "XXX unknown sigp: 0xffffffff00000005".

Signed-off-by: Philipp Kern <phil@philkern.de>
Reviewed-by: Thomas Huth <thuth@tuxfamily.org>
[agraf: add comment according to email]
Signed-off-by: Alexander Graf <agraf@suse.de>

(cherry picked from commit 601b9a9008)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-31 11:21:20 -05:00
Greg Kurz 077a67e929 9pfs: local: fix fchmodat_nofollow() limitations
This function has to ensure it doesn't follow a symlink that could be used
to escape the virtfs directory. This could be easily achieved if fchmodat()
on linux honored the AT_SYMLINK_NOFOLLOW flag as described in POSIX, but
it doesn't. There was a tentative to implement a new fchmodat2() syscall
with the correct semantics:

https://patchwork.kernel.org/patch/9596301/

but it didn't gain much momentum. Also it was suggested to look at an O_PATH
based solution in the first place.

The current implementation covers most use-cases, but it notably fails if:
- the target path has access rights equal to 0000 (openat() returns EPERM),
  => once you've done chmod(0000) on a file, you can never chmod() again
- the target path is UNIX domain socket (openat() returns ENXIO)
  => bind() of UNIX domain sockets fails if the file is on 9pfs

The solution is to use O_PATH: openat() now succeeds in both cases, and we
can ensure the path isn't a symlink with fstat(). The associated entry in
"/proc/self/fd" can hence be safely passed to the regular chmod() syscall.

The previous behavior is kept for older systems that don't have O_PATH.

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Zhi Yong Wu <zhiyong.wu@ucloud.cn>
Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
(cherry picked from commit 4751fd5328)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:42:15 -05:00
Jeff Cody f4f3529cfe block/nfs: fix mutex assertion in nfs_file_close()
Commit c096358e74 introduced assertion
checks for when qemu_mutex() functions are called without the
corresponding qemu_mutex_init() having initialized the mutex.

This uncovered a latent bug in qemu's nfs driver - in
nfs_client_close(), the NFSClient structure is overwritten with zeros,
prior to the mutex being destroyed.

Go ahead and destroy the mutex in nfs_client_close(), and change where
we call qemu_mutex_init() so that it is correctly balanced.

There are also a couple of memory leaks obscured by the memset, so this
fixes those as well.

Finally, we should be able to get rid of the memset(), as it isn't
necessary.

Cc: qemu-stable@nongnu.org
Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 113fe792fd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:41:21 -05:00
Aleksandr Bezzubikov 5f7f7e4f05 hw/i386: allow SHPC for Q35 machine
Unmask previously masked SHPC feature in _OSC method.

Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit a41c78c135)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:40:47 -05:00
Laurent Vivier de9b6728ff cpu: don't allow negative core id
With pseries machine type a negative core-id is not managed properly:
-1 gives an inaccurate error message ("core -1 already populated"),
-2 crashes QEMU (core dump)

As it seems a negative value is invalid for any architecture,
instead of checking this in spapr_core_pre_plug() I think it's better
to check this in the generic part, core_prop_set_core_id()

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Message-Id: <20170802103259.25940-1-lvivier@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit be2960baae)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:40:13 -05:00
Kevin Wolf a0ddbcfb68 block: Skip implicit nodes in query-block/blockstats
Commits 0db832f and 6cdbceb introduced the automatic insertion of filter
nodes above the top layer of mirror and commit block jobs. The
assumption made there was that since libvirt doesn't do node-level
management of the block layer yet, it shouldn't be affected by added
nodes.

This is true as far as commands issued by libvirt are concerned. It only
uses BlockBackend names to address nodes, so any operations it performs
still operate on the root of the tree as intended.

However, the assumption breaks down when you consider query commands,
which return data for the wrong node now. These commands also return
information on some child nodes (bs->file and/or bs->backing), which
libvirt does make use of, and which refer to the wrong nodes, too.

One of the consequences is that oVirt gets wrong information about the
image size and stops the VM in response as long as a mirror or commit
job is running:

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

This patch fixes the problem by hiding the implicit nodes created
automatically by the mirror and commit block jobs in the output of
query-block and BlockBackend-based query-blockstats as long as the user
doesn't indicate that they are aware of those nodes by providing a node
name for them in the QMP command to start the block job.

The node-based commands query-named-block-nodes and query-blockstats
with query-nodes=true still show all nodes, including implicit ones.
This ensures that users that are capable of node-level management can
still access the full information; users that only know BlockBackends
won't use these commands.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Tested-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit d3c8c67469)
 Conflicts:
	block/qapi.c
	include/block/block_int.h
* fix context deps on 46eade7b and 5a9347c6
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:21:56 -05:00
Kevin Wolf d445e0a022 qemu-iotests: Test automatic commit job cancel on hot unplug
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
(cherry picked from commit c3971b883a)
*prereq for d3c8c674
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:18:34 -05:00
Alexander Graf ad480ab20b input: Decrement queue count on kbd delay
Delays in the input layer are special cased input events. Every input
event is accounted for in a global intput queue count. The special cased
delays however did not get removed from the queue, leading to queue overruns
and thus silent key drops after typing quite a few characters.

Signed-off-by: Alexander Graf <agraf@suse.de>
Message-id: 1498117318-162102-1-git-send-email-agraf@suse.de
Fixes: be1a7176 ("input: add support for kbd delays")
Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 77b0359bf4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:07:42 -05:00
Gerd Hoffmann f8d050a20a input: limit kbd queue depth
Apply a limit to the number of items we accept into the keyboard queue.

Impact: Without this limit vnc clients can exhaust host memory by
sending keyboard events faster than qemu feeds them to the guest.

Fixes: CVE-2017-8379
Cc: P J P <ppandit@redhat.com>
Cc: Huawei PSIRT <PSIRT@huawei.com>
Reported-by: jiangxin1@huawei.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170428084237.23960-1-kraxel@redhat.com
(cherry picked from commit fa18f36a46)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:07:25 -05:00
Jason Wang 9527514ceb virtio-net: fix offload ctrl endian
Spec said offloads should be le64, so use virtio_ldq_p() to guarantee
valid endian.

Fixes: 644c98587d ("virtio-net: dynamic network offloads configuration")
Cc: qemu-stable@nongnu.org
Cc: Dmitry Fleytman <dfleytma@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 189ae6bb5c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:07:16 -05:00
Greg Kurz 2a7526b0ce spapr: fix memory leak in spapr_core_pre_plug()
In case of error, we must ensure the dynamically allocated base_core_type
is freed, like it is done everywhere else in this function.

This is a regression introduced in QEMU 2.9 by commit 8149e2992f.

Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit df8658de43)
 Conflicts:
	hw/ppc/spapr.c
* fix context dep on 459264ef2
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:07:16 -05:00
Kevin Wolf 2e40aad231 commit: Add NULL check for overlay_bs
I can't see how overlay_bs could become NULL with the current code, but
other code in this function already checks it and we can make Coverity
happy with this check, so let's add it.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit b1e1fa0c3a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:07:16 -05:00
Jason Wang 70da03f10c virtio-scsi: finalize IOMMU support
After converting to use DMA api for virtio devices, we should use
dma_as instead of address_space_memory. Otherwise it won't work if
IOMMU is enabled.

Fixes: commit 8607f5c307 ("virtio: convert to use DMA api")
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
Message-Id: <1499170866-9068-1-git-send-email-jasowang@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 025bdeab3c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:07:16 -05:00
Laurent Vivier 19284a0141 spapr: fix migration to pseries machine < 2.8
since commit 5c4537bd ("spapr: Fix 2.7<->2.8 migration of PCI host bridge"),
some migration fields are forged from the new ones in spapr_pci_pre_save().

It works well, except when the number of MSI devices is 0,
because in this case the function exits immediately.

This fix moves the migration code before the exit code.

The problem can be reproduced with these commands:

source qemu-2.9:

    qemu-system-ppc64 -monitor stdio -M pseries-2.6 -nodefaults -S

destination qemu-2.6:

    qemu-system-ppc64 -monitor stdio -M pseries-2.6 -nodefaults \
                      -incoming tcp:0:4444

on the source:

    migrate tcp:localhost:4444

Destination fails with the following error:

    qemu-system-ppc64: error while loading state for
                       instance 0x0 of device 'spapr_pci'
    qemu-system-ppc64: load of migration failed: Invalid argument

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit e806b4db14)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 18:07:16 -05:00
Alexander Graf 0060a3e936 hid: Reset kbd modifiers on reset
When resetting the keyboard, we need to reset not just the pending keystrokes,
but also any pending modifiers. Otherwise there's a race when we're getting
reset while running an escape sequence (modifier 0x100).

Cc: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
Message-id: 1498117295-162030-1-git-send-email-agraf@suse.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 51dbea77a2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:59:22 -05:00
Bruce Rogers e0398ccdf4 9pfs: local: remove: use correct path component
Commit a0e640a8 introduced a path processing error.
Pass fstatat the dirpath based path component instead
of the entire path.

Signed-off-by: Bruce Rogers <brogers@suse.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
(cherry picked from commit 790db7efdb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:58:51 -05:00
Max Reitz 438cd1e6aa block: Do not strcmp() with NULL uri->scheme
uri_parse(...)->scheme may be NULL. In fact, probably every field may be
NULL, and the callers do test this for all of the other fields but not
for scheme (except for block/gluster.c; block/vxhs.c does not access
that field at all).

We can easily fix this by using g_strcmp0() instead of strcmp().

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170613205726.13544-1-mreitz@redhat.com
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit f69165a8fe)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:58:11 -05:00
Paolo Bonzini 40ed5cdf72 nbd: fix NBD over TLS
When attaching the NBD QIOChannel to an AioContext, the TLS channel should
be used, not the underlying socket channel.  This is because, trivially,
the TLS channel will be the one that we read/write to and thus the one
that will get the qio_channel_yield() call.

Fixes: ff82911cd3
Cc: qemu-stable@nongnu.org
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Tested-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 96d06835dc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:57:32 -05:00
Max Reitz 2182791734 blkverify: Catch bs->exact_filename overflow
The bs->exact_filename field may not be sufficient to store the full
blkverify node filename. In this case, we should not generate a filename
at all instead of an unusable one.

Cc: qemu-stable@nongnu.org
Reported-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170613172006.19685-3-mreitz@redhat.com
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 05cc758a3d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:57:05 -05:00
Max Reitz 1828d47845 blkdebug: Catch bs->exact_filename overflow
The bs->exact_filename field may not be sufficient to store the full
blkdebug node filename. In this case, we should not generate a filename
at all instead of an unusable one.

Cc: qemu-stable@nongnu.org
Reported-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170613172006.19685-2-mreitz@redhat.com
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit de81d72d3d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:57:00 -05:00
Kevin Wolf 1dd3ba38f6 commit: Fix completion with extra reference
commit_complete() can't assume that after its block_job_completed() the
job is actually immediately freed; someone else may still be holding
references. In this case, the op blockers on the intermediate nodes make
the graph reconfiguration in the completion code fail.

Call block_job_remove_all_bdrv() manually so that we know for sure that
any blockers on intermediate nodes are given up.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 4f78a16fee)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:53:45 -05:00
Eric Blake ecc7a24c11 nbd: Fix regression on resiliency to port scan
Back in qemu 2.5, qemu-nbd was immune to port probes (a transient
server would not quit, regardless of how many probe connections
came and went, until a connection actually negotiated).  But we
broke that in commit ee7d7aa when removing the return value to
nbd_client_new(), although that patch also introduced a bug causing
an assertion failure on a client that fails negotiation.  We then
made it worse during refactoring in commit 1a6245a (a segfault
before we could even assert); the (masked) assertion was cleaned
up in d3780c2 (still in 2.6), and just recently we finally fixed
the segfault ("nbd: Fully intialize client in case of failed
negotiation").  But that still means that ever since we added
TLS support to qemu-nbd, we have been vulnerable to an ill-timed
port-scan being able to cause a denial of service by taking down
qemu-nbd before a real client has a chance to connect.

Since negotiation is now handled asynchronously via coroutines,
we no longer have a synchronous point of return by re-adding a
return value to nbd_client_new().  So this patch instead wires
things up to pass the negotiation status through the close_fn
callback function.

Simple test across two terminals:
$ qemu-nbd -f raw -p 30001 file
$ nmap 127.0.0.1 -p 30001 && \
  qemu-io -c 'r 0 512' -f raw nbd://localhost:30001

Note that this patch does not change what constitutes successful
negotiation (thus, a client must enter transmission phase before
that client can be considered as a reason to terminate the server
when the connection ends).  Perhaps we may want to tweak things
in a later patch to also treat a client that uses NBD_OPT_ABORT
as being a 'successful' negotiation (the client correctly talked
the NBD protocol, and informed us it was not going to use our
export after all), but that's a discussion for another day.

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

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170608222617.20376-1-eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 0c9390d978)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:52:49 -05:00
Eric Blake ec49c8ac57 nbd: Fully initialize client in case of failed negotiation
If a non-NBD client connects to qemu-nbd, we would end up with
a SIGSEGV in nbd_client_put() because we were trying to
unregister the client's association to the export, even though
we skipped inserting the client into that list.  Easy trigger
in two terminals:

$ qemu-nbd -p 30001 --format=raw file
$ nmap 127.0.0.1 -p 30001

nmap claims that it thinks it connected to a pago-services1
server (which probably means nmap could be updated to learn the
NBD protocol and give a more accurate diagnosis of the open
port - but that's not our problem), then terminates immediately,
so our call to nbd_negotiate() fails.  The fix is to reorder
nbd_co_client_start() to ensure that all initialization occurs
before we ever try talking to a client in nbd_negotiate(), so
that the teardown sequence on negotiation failure doesn't fault
while dereferencing a half-initialized object.

While debugging this, I also noticed that nbd_update_server_watch()
called by nbd_client_closed() was still adding a channel to accept
the next client, even when the state was no longer RUNNING.  That
is fixed by making nbd_can_accept() pay attention to the current
state.

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

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170527030421.28366-1-eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit df8ad9f128)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:52:10 -05:00
Kevin Wolf f28b8906dd commit: Fix use after free in completion
The final bdrv_set_backing_hd() could be working on already freed nodes
because the commit job drops its references (through BlockBackends) to
both overlay_bs and top already a bit earlier.

One way to trigger the bug is hot unplugging a disk for which
blockdev_mark_auto_del() cancels the block job.

Fix this by taking BDS-level references while we're still using the
nodes.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 19ebd13ed4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:51:19 -05:00
Max Filippov bace1f90f9 target/xtensa: handle unknown registers in gdbstub
Xtensa cores may have registers of types/sizes not supported by the
gdbstub accessors. Ignore writes to such registers and return zero on
read, but always return correct register size, so that gdb on the other
side is able to access all registers in the packet holding unsupported
registers in the middle. This fixes gdb interaction with cores that have
vector/custom TIE registers.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit dd7b952b79)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:50:05 -05:00
Greg Kurz 3b2f3a4691 spapr: fix memory leak in spapr_memory_pre_plug()
The string returned by object_property_get_str() is dynamically allocated.

(Spotted by Coverity, CID 1375942)

Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 8a9e0e7b89)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:47:06 -05:00
Laurent Vivier 7f4c9f5f3b spapr: add pre_plug function for memory
This allows to manage errors before the memory
has started to be hotplugged. We already have
the function for the CPU cores.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
[dwg: Fixed a couple of style nits]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

(cherry picked from commit c871bc70bb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:46:50 -05:00
Greg Kurz 592ee4007e target/ppc: fix memory leak in kvmppc_is_mem_backend_page_size_ok()
The string returned by object_property_get_str() is dynamically allocated.

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 2d3e302ec2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:39:31 -05:00
Greg Kurz 917a5b9f2f target/ppc: pass const string to kvmppc_is_mem_backend_page_size_ok()
This function has three implementations. Two are stubs that do nothing
and the third one only passes the obj_path argument to:

Object *object_resolve_path(const char *path, bool *ambiguous);

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit ec69355bef)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-24 16:39:25 -05:00
Eduardo Habkost 2401d8a490 pc: Use "min-[x]level" on compat_props
Since the automatic cpuid-level code was introduced in commit
c39c0edf9b ("target-i386: Automatically
set level/xlevel/xlevel2 when needed"), the CPU model tables just define
the default CPUID level code (set using "min-level").  Setting
"[x]level" forces CPUID level to a specific value and disable the
automatic-level logic.

But the PC compat code was not updated and the existing "[x]level"
compat properties broke compatibility for people using features that
triggered the auto-level code.  To keep previous behavior, we should set
"min-[x]level" instead of "[x]level" on compat_props.

This was not a problem for most cases, because old machine-types don't
have full-cpuid-auto-level enabled.  The only common use case it broke
was the CPUID[7] auto-level code, that was already enabled since the
first CPUID[7] feature was introduced (in QEMU 1.4.0).

This causes the regression reported at:
https://bugzilla.redhat.com/show_bug.cgi?id=1454641

Change the PC compat code to use "min-[x]level" instead of "[x]level" on
compat_props, and add new test cases to ensure we don't break this
again.

Reported-by: "Guo, Zhiyi" <zhguo@redhat.com>
Fixes: c39c0edf9b ("target-i386: Automatically set level/xlevel/xlevel2 when needed")
Cc: qemu-stable@nongnu.org
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 1f43571604)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:29 -05:00
Michael Roth 1775fe6148 monitor: fix object_del for command-line-created objects
Currently objects specified on the command-line are only partially
cleaned up when 'object_del' is issued in either HMP or QMP: the
object itself is fully finalized, but the QemuOpts are not removed.
This results in the following behavior:

  x86_64-softmmu/qemu-system-x86_64 -monitor stdio \
    -object memory-backend-ram,id=ram1,size=256M

  QEMU 2.7.91 monitor - type 'help' for more information
  (qemu) object_del ram1
  (qemu) object_del ram1
  object 'ram1' not found
  (qemu) object_add memory-backend-ram,id=ram1,size=256M
  Duplicate ID 'ram1' for object
  Try "help object_add" for more information

which can be an issue for use-cases like memory hotplug.

This happens on the HMP side because hmp_object_add() attempts to
create a temporary QemuOpts entry with ID 'ram1', which ends up
conflicting with the command-line-created entry, since it was never
cleaned up during the previous hmp_object_del() call.

We address this by adding a check in user_creatable_del(), which
is called by both qmp_object_del() and hmp_object_del() to handle
the actual object cleanup, to determine whether an option group entry
matching the object's ID is present and removing it if it is.

Note that qmp_object_add() never attempts to create a temporary
QemuOpts entry, so it does not encounter the duplicate ID error,
which is why this isn't generally visible in libvirt.

Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Cc: Daniel Berrange <berrange@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1496531612-22166-3-git-send-email-mdroth@linux.vnet.ibm.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit c645d5acee)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:28 -05:00
Michael Roth b0a3eadd8c tests: check-qom-proplist: add checks for cmdline-created objects
check-qom-proplist originally added tests for verifying that
object-creation helpers object_new_with_{props,propv} behaved in
similar fashion to the "traditional" method involving setting each
individual property separately after object creation rather than
via a single call.

Another similar "helper" for creating Objects exists in the form of
objects specified via -object command-line parameters. By that
rationale, we extend check-qom-proplist to include similar checks
for command-line-created objects by employing the same
qemu_opts_parse()-based parsing the vl.c employs.

This parser has a side-effect of parsing the object's options into
a QemuOpt structure and registering this in the global QemuOptsList
using the Object's ID. This can conflict with future Object instances
that attempt to use the same ID if we don't ensure this is cleaned
up as part of Object finalization, so we include a FIXME stub to test
for this case, which will then be resolved in a subsequent patch.

Suggested-by: Daniel Berrange <berrange@redhat.com>
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Cc: Daniel Berrange <berrange@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1496531612-22166-2-git-send-email-mdroth@linux.vnet.ibm.com>
[Comment formatting tidied up]
Signed-off-by: Markus Armbruster <armbru@redhat.com>

(cherry picked from commit a1af255f06)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:28 -05:00
Paolo Bonzini 3b428e9512 linuxboot_dma: compile for i486
The ROM uses the cmovne instruction, which is new in Pentium Pro and does not
work when running QEMU with "-cpu 486".  Avoid producing that instruction.

Suggested-by: Richard W.M. Jones <rjones@redhat.com>
Suggested-by: Thomas Huth <thuth@redhat.com>
Reported-by: Rob Landley <rob@landley.net>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7e01838510)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:28 -05:00
Ladi Prosek 11bac2f941 virtio-serial-bus: Unset hotplug handler when unrealize
Virtio serial device controls the lifetime of virtio-serial-bus and
virtio-serial-bus links back to the device via its hotplug-handler
property. This extra ref-count prevents the device from getting
finalized, leaving the VirtIODevice memory listener registered and
leading to use-after-free later on.

This patch addresses the same issue as Fam Zheng's
"virtio-scsi: Unset hotplug handler when unrealize"
only for a different virtio device.

Cc: qemu-stable@nongnu.org
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
(cherry picked from commit f811f97040)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:28 -05:00
Kevin Wolf 0ebbef1fa1 mirror: Drop permissions on s->target on completion
This fixes an assertion failure that was triggered by qemu-iotests 129
on some CI host, while the same test case didn't seem to fail on other
hosts.

Essentially the problem is that the blk_unref(s->target) in
mirror_exit() doesn't necessarily mean that the BlockBackend goes away
immediately. It is possible that the job completion was triggered nested
in mirror_drain(), which looks like this:

    BlockBackend *target = s->target;
    blk_ref(target);
    blk_drain(target);
    blk_unref(target);

In this case, the write permissions for s->target are retained until
after blk_drain(), which makes removing mirror_top_bs fail for the
active commit case (can't have a writable backing file in the chain
without the filter driver).

Explicitly dropping the permissions first means that the additional
reference doesn't hurt and the job can complete successfully even if
called from the nested blk_drain().

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 63c8ef2890)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:28 -05:00
Eric Blake 64945cb5f3 block: Guarantee that *file is set on bdrv_get_block_status()
We document that *file is valid if the return is not an error and
includes BDRV_BLOCK_OFFSET_VALID, but forgot to obey this contract
when a driver (such as blkdebug) lacks a callback.  Messed up in
commit 67a0fd2 (v2.6), when we added the file parameter.

Enhance qemu-iotest 177 to cover this, using a sequence that would
print garbage or even SEGV, because it was dererefencing through
uninitialized memory.  [The resulting test output shows that we
have less-than-ideal block status from the blkdebug driver, but
that's a separate fix coming up soon.]

Setting *file on all paths that return BDRV_BLOCK_OFFSET_VALID is
enough to fix the crash, but we can go one step further: always
setting *file, even on error, means that a broken caller that
blindly dereferences file without checking for error is now more
likely to get a reliable SEGV instead of randomly acting on garbage,
making it easier to diagnose such buggy callers.  Adding an
assertion that file is set where expected doesn't hurt either.

CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 81c219ac6c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:28 -05:00
Eric Blake 6a3f9c5c6e block: Simplify BDRV_BLOCK_RAW recursion
Since we are already in coroutine context during the body of
bdrv_co_get_block_status(), we can shave off a few layers of
wrappers when recursing to query the protocol when a format driver
returned BDRV_BLOCK_RAW.

Note that we are already using the correct recursion later on in
the same function, when probing whether the protocol layer is sparse
in order to find out if we can add BDRV_BLOCK_ZERO to an existing
BDRV_BLOCK_DATA|BDRV_BLOCK_OFFSET_VALID.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 20170504173745.27414-1-eblake@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit ee29d6adef)
* prereq for 81c219a
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:28 -05:00
Eric Blake 3f3fe284ef tests: Add coverage for recent block geometry fixes
Use blkdebug's new geometry constraints to emulate setups that
have needed past regression fixes: write zeroes asserting
when running through a loopback block device with max-transfer
smaller than cluster size, and discard rounding away portions
of requests not aligned to preferred boundaries.  Also, add
coverage that the block layer is honoring max transfer limits.

For now, a single iotest performs all actions, with the idea
that we can add future blkdebug constraint test cases in the
same file; but it can be split into multiple iotests if we find
reason to run one portion of the test in more setups than what
are possible in the other.

For reference, the final portion of the test (checking whether
discard passes as much as possible to the lowest layers of the
stack) works as follows:

qemu-io: discard 30M at 80000001, passed to blkdebug
  blkdebug: discard 511 bytes at 80000001, -ENOTSUP (smaller than
blkdebug's 512 align)
  blkdebug: discard 14371328 bytes at 80000512, passed to qcow2
    qcow2: discard 739840 bytes at 80000512, -ENOTSUP (smaller than
qcow2's 1M align)
    qcow2: discard 13M bytes at 77M, succeeds
  blkdebug: discard 15M bytes at 90M, passed to qcow2
    qcow2: discard 15M bytes at 90M, succeeds
  blkdebug: discard 1356800 bytes at 105M, passed to qcow2
    qcow2: discard 1M at 105M, succeeds
    qcow2: discard 308224 bytes at 106M, -ENOTSUP (smaller than qcow2's
1M align)
  blkdebug: discard 1 byte at 111457280, -ENOTSUP (smaller than
blkdebug's 512 align)

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170429191419.30051-10-eblake@redhat.com
[mreitz: For cooperation with image locking, add -r to the qemu-io
         invocation which verifies the image content]
Signed-off-by: Max Reitz <mreitz@redhat.com>

(cherry picked from commit 40812d9373)
 Conflicts:
	tests/qemu-iotests/group
* dropped context dependency on other test groups
* prereq for 81c219a
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:24 -05:00
Eric Blake 48f2dc0657 blkdebug: Add ability to override unmap geometries
Make it easier to simulate various unusual hardware setups (for
example, recent commits 3482b9b and b8d0a98 affect the Dell
Equallogic iSCSI with its 15M preferred and maximum unmap and
write zero sizing, or b2f95fe deals with the Linux loopback
block device having a max_transfer of 64k), by allowing blkdebug
to wrap any other device with further restrictions on various
alignments.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170429191419.30051-9-eblake@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 430b26a82d)
* prereq for 81c219a
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:19 -05:00
Eric Blake 3ae74003b5 blkdebug: Simplify override logic
Rather than store into a local variable, then copy to the struct
if the value is valid, then reporting errors otherwise, it is
simpler to just store into the struct and report errors if the
value is invalid.  This however requires that the struct store
a 64-bit number, rather than a narrower type.  Likewise, setting
a sane errno value in ret prior to the sequence of parsing and
jumping to out: on error makes it easier for the next patch to
add a chain of similar checks.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-id: 20170429191419.30051-8-eblake@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 3dc834f879)
* prereq for 81c219a
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:15 -05:00
Eric Blake 577cf9e6bb blkdebug: Add pass-through write_zero and discard support
In order to test the effects of artificial geometry constraints
on operations like write zero or discard, we first need blkdebug
to manage these actions.  It also allows us to inject errors on
those operations, just like we can for read/write/flush.

We can also test the contract promised by the block layer; namely,
if a device has specified limits on alignment or maximum size,
then those limits must be obeyed (for now, the blkdebug driver
merely inherits limits from whatever it is wrapping, but the next
patch will further enhance it to allow specific limit overrides).

This patch intentionally refuses to service requests smaller than
the requested alignments; this is because an upcoming patch adds
a qemu-iotest to prove that the block layer is correctly handling
fragmentation, but the test only works if there is a way to tell
the difference at artificial alignment boundaries when blkdebug is
using a larger-than-default alignment.  If we let the blkdebug
layer always defer to the underlying layer, which potentially has
a smaller granularity, the iotest will be thwarted.

Tested by setting up an NBD server with export 'foo', then invoking:
$ ./qemu-io
qemu-io> open -o driver=blkdebug blkdebug::nbd://localhost:10809/foo
qemu-io> d 0 15M
qemu-io> w -z 0 15M

Pre-patch, the server never sees the discard (it was silently
eaten by the block layer); post-patch it is passed across the
wire.  Likewise, pre-patch the write is always passed with
NBD_WRITE (with 15M of zeroes on the wire), while post-patch
it can utilize NBD_WRITE_ZEROES (for less traffic).

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170429191419.30051-7-eblake@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 63188c2450)
* prereq for 81c219a
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:11 -05:00
Eric Blake 138cf638ba blkdebug: Refactor error injection
Rather than repeat the logic at each caller of checking if a Rule
exists that warrants an error injection, fold that logic into
inject_error(); and rename it to rule_check() for legibility.
This will help the next patch, which adds two more callers that
need to check rules for the potential of injecting errors.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170429191419.30051-6-eblake@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit d157ed5f72)
* prereq for 81c219a
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:01:08 -05:00
Eric Blake a1a3d603c4 blkdebug: Sanity check block layer guarantees
Commits 04ed95f4 and 1a62d0ac updated the block layer to auto-fragment
any I/O to fit within device boundaries. Additionally, when using a
minimum alignment of 4k, we want to ensure the block layer does proper
read-modify-write rather than requesting I/O on a slice of a sector.
Let's enforce that the contract is obeyed when using blkdebug.  For
now, blkdebug only allows alignment overrides, and just inherits other
limits from whatever device it is wrapping, but a future patch will
further enhance things.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170429191419.30051-5-eblake@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit e0ef439588)
* prereq for 81c219a
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 16:00:51 -05:00
Yunjian Wang 0b185544c9 virtio-net: fix wild pointer when remove virtio-net queues
The tx_bh or tx_timer will free in virtio_net_del_queue() function, when
removing virtio-net queues if the guest doesn't support multiqueue. But
it might be still referenced by virtio_net_set_status(), which needs to
be set NULL. And also the tx_waiting needs to be set zero to prevent
virtio_net_set_status() accessing tx_bh or tx_timer.

Cc: qemu-stable@nongnu.org
Signed-off-by: Yunjian Wang <wangyunjian@huawei.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit f989c30cf8)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:52:02 -05:00
Halil Pasic f3676379cc s390x/css: catch section mismatch on load
Prior to the virtio-ccw-2.7 machine (and commit 2a79eb1a), our virtio
devices residing under the virtual-css bus do not have qdev_path based
migration stream identifiers (because their qdev_path is NULL). The ids
are instead generated when the device is registered as a composition of
the so called idstr, which takes the vmsd name as its value, and an
instance_id, which is which is calculated as a maximal instance_id
registered with the same idstr plus one, or zero (if none was registered
previously).

That means, under certain circumstances, one device might try, and even
succeed, to load the state of a different device. This can lead to
trouble.

Let us fail the migration if the above problem is detected during load.

How to reproduce the problem:
1) start qemu-system-s390x making sure you have the following devices
   defined on your command line:
     -device virtio-rng-ccw,id=rng1,devno=fe.0.0001
     -device virtio-rng-ccw,id=rng2,devno=fe.0.0002
2) detach the devices and reattach in reverse order using the monitor:
     (qemu) device_del rng1
     (qemu) device_del rng2
     (qemu) device_add virtio-rng-ccw,id=rng2,devno=fe.0.0002
     (qemu) device_add virtio-rng-ccw,id=rng1,devno=fe.0.0001
3) save the state of the vm into a temporary file and quit QEMU:
     (qemu) migrate "exec:gzip -c > /tmp/tmp_vmstate.gz"
     (qemu) q
4) use your command line from step 1 with
     -incoming "exec:gzip -c -d /tmp/tmp_vmstate.gz"
   appended to reproduce the problem (while trying to to load the saved vm)

CC: qemu-stable@nongnu.org
Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Message-Id: <20170518111405.56947-1-pasic@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
(cherry picked from commit 8ed179c937)
* removed context dep on d8d98db5
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:50:49 -05:00
Sameeh Jubran 4921c573c8 e1000e: Fix ICR "Other" causes clear logic
This commit fixes a bug which causes the guest to hang. The bug was
observed upon a "receive overrun" (bit #6 of the ICR register)
interrupt which could be triggered post migration in a heavy traffic
environment. Even though the "receive overrun" bit (#6) is masked out
by the IMS register (refer to the log below) the driver still receives
an interrupt as the "receive overrun" bit (#6) causes the "Other" -
bit #24 of the ICR register - bit to be set as documented below. The
driver handles the interrupt and clears the "Other" bit (#24) but
doesn't clear the "receive overrun" bit (#6) which leads to an
infinite loop. Apparently the Windows driver expects that the "receive
overrun" bit and other ones - documented below - to be cleared when
the "Other" bit (#24) is cleared.

So to sum that up:
1. Bit #6 of the ICR register is set by heavy traffic
2. As a results of setting bit #6, bit #24 is set
3. The driver receives an interrupt for bit 24 (it doesn't receieve an
   interrupt for bit #6 as it is masked out by IMS)
4. The driver handles and clears the interrupt of bit #24
5. Bit #6 is still set.
6. 2 happens all over again

The Interrupt Cause Read - ICR register:

The ICR has the "Other" bit - bit #24 - that is set when one or more
of the following ICR register's bits are set:

LSC - bit #2, RXO - bit #6, MDAC - bit #9, SRPD - bit #16, ACK - bit
#17, MNG - bit #18

This bug can occur with any of these bits depending on the driver's
behaviour and the way it configures the device. However, trying to
reproduce it with any bit other than RX0 is challenging and came to
failure as the drivers don't implement most of these bits, trying to
reproduce it with LSC (Link Status Change - bit #2) bit didn't succeed
too as it seems that Windows handles this bit differently.

Log sample of the storm:

27563@1494850819.411877:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)
27563@1494850819.411900:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.411915:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412380:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412395:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412436:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412441:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
27563@1494850819.412998:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)

* This bug behaviour wasn't observed with the Linux driver.

This commit solves:
https://bugzilla.redhat.com/show_bug.cgi?id=1447935
https://bugzilla.redhat.com/show_bug.cgi?id=1449490

Cc: qemu-stable@nongnu.org
Signed-off-by: Sameeh Jubran <sjubran@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 82342e91b6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:44:08 -05:00
Fam Zheng 952cc38204 virtio-scsi: Unset hotplug handler when unrealize
This matches the qbus_set_hotplug_handler in realize, and it releases
the final reference to the embedded VirtIODevice so that it is
properly finalized.

A use-after-free is fixed with this patch, indirectly:
virtio_device_instance_finalize wasn't called at hot-unplug, and the
vdev->listener would be a dangling pointer in the global and the per
address space listener list. See also RHBZ 1449031.

Cc: qemu-stable@nongnu.org
Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <20170518102808.30046-1-famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 2cbe2de545)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:42:49 -05:00
Greg Kurz c6b510d1e5 virtio: allow broken device to notify guest
According to section 2.1.2 of the virtio-1 specification:

"The device SHOULD set DEVICE_NEEDS_RESET when it enters an error state that
a reset is needed. If DRIVER_OK is set, after it sets DEVICE_NEEDS_RESET,
the device MUST send a device configuration change notification to the
driver."

Commit "f5ed36635d8f virtio: stop virtqueue processing if device is broken"
introduced a virtio_error() call that just does that:

- internally mark the device as broken
- set the DEVICE_NEEDS_RESET bit in the status
- send a configuration change notification

Unfortunately, virtio_notify_vector(), called by virtio_notify_config(),
returns right away when the device is marked as broken and the notification
isn't sent in this case.

The spec doesn't say whether a broken device can send notifications
in other situations or not. But since the driver isn't supposed to do
anything but to reset the device, it makes sense to keep the check in
virtio_notify_config().

Marking the device as broken AFTER the configuration change notification was
sent is enough to fix the issue.

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 66453cff9e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:42:05 -05:00
Hervé Poussineau 636eacb641 vvfat: fix qemu-img map and qemu-img convert
- bs->total_sectors is the number of sectors of the whole disk
- s->sector_count is the number of sectors of the FAT partition

This fixes the following assert in qemu-img map:
qemu-img.c:2641: get_block_status: Assertion `nb_sectors' failed.

This also fixes an infinite loop in qemu-img convert.

Fixes: 4480e0f924
Fixes: https://bugs.launchpad.net/qemu/+bug/1599539
Cc: qemu-stable@nongnu.org
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 139921aaa7)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:35:15 -05:00
Alberto Garcia c60a8ed89b stream: fix crash in stream_start() when block_job_create() fails
The code that tries to reopen a BlockDriverState in stream_start()
when the creation of a new block job fails crashes because it attempts
to dereference a pointer that is known to be NULL.

This is a regression introduced in a170a91fd3,
likely because the code was copied from stream_complete().

Cc: qemu-stable@nongnu.org
Reported-by: Kashyap Chamarthy <kchamart@redhat.com>
Signed-off-by: Alberto Garcia <berto@igalia.com>
Tested-by: Kashyap Chamarthy <kchamart@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 525989a50a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:33:26 -05:00
Paolo Bonzini c79bef68c4 curl: avoid recursive locking of BDRVCURLState mutex
The curl driver has a ugly hack where, if it cannot find an empty CURLState,
it just uses aio_poll to wait for one to be empty.  This is probably
buggy when used together with dataplane, and the simplest way to fix it
is to use coroutines instead.

A more immediate effect of the bug however is that it can cause a
recursive call to curl_readv_bh_cb and recursively taking the
BDRVCURLState mutex.  This causes a deadlock.

The fix is to unlock the mutex around aio_poll, but for cleanliness we
should also take the mutex around all calls to curl_init_state, even if
reaching the unlock/lock pair is impossible.  The same is true for
curl_clean_state.

Reported-by: Kun Wei <kuwei@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 20170515100059.15795-4-pbonzini@redhat.com
Cc: qemu-stable@nongnu.org
Cc: Jeff Cody <jcody@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit 456af34629)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:32:58 -05:00
Paolo Bonzini 4b519b9fd7 curl: never invoke callbacks with s->mutex held
All curl callbacks go through curl_multi_do, and hence are called with
s->mutex held.  Note that with comments, and make curl_read_cb drop the
lock before invoking the callback.

Likewise for curl_find_buf, where the callback can be invoked by the
caller.

Cc: qemu-stable@nongnu.org
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170515100059.15795-3-pbonzini@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit 34db05e7ff)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:32:52 -05:00
Paolo Bonzini f00c08cbac curl: strengthen assertion in curl_clean_state
curl_clean_state should only be called after all AIOCBs have been
completed.  This is not so obvious for the call from curl_detach_aio_context,
so assert that.

Cc: qemu-stable@nongnu.org
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170515100059.15795-2-pbonzini@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit 675a775633)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:32:46 -05:00
Max Filippov d81db0beca target/xtensa: fix return value of read/write simcalls
Return value of read/write simcalls is not calculated correctly in case
of operations crossing page boundary and in case of short reads/writes.
Read and write simcalls should return the size of data actually
read/written or -1 in case of error.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit 347ec03093)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:32:06 -05:00
Max Filippov e442253479 target/xtensa: fix mapping direction in read/write simcalls
Read and write simcalls map physical memory to access I/O buffers, but
'read' simcall need to map it for writing and 'write' simcall need to
map it for reading, i.e. the opposite of what they do now. Fix that.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit 30c2afd151)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:31:52 -05:00
John Snow af8ca55a6b blockdev: use drained_begin/end for qmp_block_resize
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1447551

If one tries to issue a block_resize while a guest is busy
accessing the disk, it is possible that qemu may deadlock
when invoking aio_poll from both the main loop and the iothread.

Replace another instance of bdrv_drain_all that doesn't
quite belong.

Cc: qemu-stable@nongnu.org
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 698bdfa07d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:29:55 -05:00
Max Reitz 5797a36abd block: Add errp to b{lk,drv}_truncate()
For one thing, this allows us to drop the error message generation from
qemu-img.c and blockdev.c and instead have it unified in
bdrv_truncate().

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170328205129.15138-3-mreitz@redhat.com
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit ed3d2ec98a)
* prereq for 698bdfa
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:29:55 -05:00
Max Reitz 73aa7ad7d2 block/vhdx: Make vhdx_create() always set errp
This patch makes vhdx_create() always set errp in case of an error. It
also adds errp parameters to vhdx_create_bat() and
vhdx_create_new_region_table() so we can pass on the error object
generated by blk_truncate() as of a future commit.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 20170328205129.15138-2-mreitz@redhat.com
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 55b9392b98)
* prereq for 698bdfa
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-08-03 14:29:10 -05:00
Anton Nefedov d8cddcc2b9 qemu-img: wait for convert coroutines to complete
On error path (like i/o error in one of the coroutines), it's required to
  - wait for coroutines completion before cleaning the common structures
  - reenter dependent coroutines so they ever finish

Introduced in 2d9187bc65.

Cc: qemu-stable@nongnu.org
Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
Reviewed-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit b91127edd0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 17:23:52 -05:00
Stefan Hajnoczi ce119247a1 aio: add missing aio_notify() to aio_enable_external()
The main loop uses aio_disable_external()/aio_enable_external() to
temporarily disable processing of external AioContext clients like
device emulation.

This allows monitor commands to quiesce I/O and prevent the guest from
submitting new requests while a monitor command is in progress.

The aio_enable_external() API is currently broken when an IOThread is in
aio_poll() waiting for fd activity when the main loop re-enables
external clients.  Incrementing ctx->external_disable_cnt does not wake
the IOThread from ppoll(2) so fd processing remains suspended and leads
to unresponsive emulated devices.

This patch adds an aio_notify() call to aio_enable_external() so the
IOThread is kicked out of ppoll(2) and will re-arm the file descriptors.

The bug can be reproduced as follows:

  $ qemu -M accel=kvm -m 1024 \
         -object iothread,id=iothread0 \
         -device virtio-scsi-pci,iothread=iothread0,id=virtio-scsi-pci0 \
         -drive if=none,id=drive0,aio=native,cache=none,format=raw,file=test.img \
         -device scsi-hd,id=scsi-hd0,drive=drive0 \
         -qmp tcp::5555,server,nowait

  $ scripts/qmp/qmp-shell localhost:5555
  (qemu) blockdev-snapshot-sync device=drive0 snapshot-file=sn1.qcow2
         mode=absolute-paths format=qcow2

After blockdev-snapshot-sync completes the SCSI disk will be
unresponsive.  This leads to request timeouts inside the guest.

Reported-by: Qianqian Zhu <qizhu@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20170508180705.20609-1-stefanha@redhat.com
Suggested-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 321d1dba8b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 17:21:41 -05:00
Zhiyong Yang 0e727a207e hw/virtio: fix vhost user fails to startup when MQ
Qemu2.7~2.9 and vhost user for dpdk 17.02 release work together
to cause failures of new connection when negotiating to set MQ.
(one queue pair works well).
   Because there exist some bugs in qemu code when introducing
VHOST_USER_PROTOCOL_F_REPLY_ACK to qemu. When vhost_user_set_mem_table
is invoked to deal with the vhost message VHOST_USER_SET_MEM_TABLE
for the second time, qemu indeed doesn't send the messge (The message
needs to be sent only once)but still will be waiting for dpdk's reply
ack, then, qemu is always freezing, while DPDK is always waiting for
next vhost message from qemu.
  The patch aims to fix the bug, MQ can work well.
  The same bug is found in function vhost_user_net_set_mtu, it is fixed
at the same time.
  DPDK related patch is as following:
  http://www.dpdk.org/dev/patchwork/patch/23955/

Signed-off-by: Zhiyong Yang <zhiyong.yang@intel.com>
Cc: qemu-stable@nongnu.org
Fixes: ca525ce561 ("vhost-user: Introduce a new protocol feature REPLY_ACK.")
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Jens Freimann <jfreiman@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
(cherry picked from commit 60cd11024f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 17:19:32 -05:00
Fam Zheng d2fcb92b18 block: Reuse bs as backing hd for drive-backup sync=none
Opening the backing image for the second time is bad, especially here
when it is also in use as the active image as the source. The
drive-backup job itself doesn't read from target->backing for COW,
instead it gets data from the write notifier, so it's not a big problem.
However, exporting the target to NBD etc. won't work, because of the
likely stale metadata cache.

Use BDRV_O_NO_BACKING in this case and manually set up the backing
BdrvChild.

Cc: qemu-stable@nongnu.org
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit fc0932fdcf)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 17:11:50 -05:00
Eric Blake e59084b5b2 qobject: Use simpler QDict/QList scalar insertion macros
We now have macros in place to make it less verbose to add a scalar
to QDict and QList, so use them.

Patch created mechanically via:
  spatch --sp-file scripts/coccinelle/qobject.cocci \
    --macro-file scripts/cocci-macro-file.h --dir . --in-place
then touched up manually to fix a couple of '?:' back to original
spacing, as well as avoiding a long line in monitor.c.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20170427215821.19397-7-eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 46f5ac205a)
* prereq for fc0932f
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 17:11:11 -05:00
Eric Blake 1eaf431077 s390x: Drop useless casts
An upcoming Coccinelle cleanup script wanted to reformat the casts
present in this file - but on closer look, we don't need the casts
at all because C automatically converts void* to any other pointer.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170405194741.18956-4-eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit cb55c19a26)
* prereq for 46f5ac2
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 17:09:19 -05:00
Eric Blake 396474a18c qobject: Add helper macros for common scalar insertions
Rather than making lots of callers wrap a scalar in a QInt, QString,
or QBool, provide helper macros that do the wrapping automatically.

Update the Coccinelle script to make mass conversions easy, although
the conversion itself will be done as a separate patches to ease
review and backport efforts.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20170427215821.19397-6-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit a92c21591b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 17:07:14 -05:00
Eric Blake 3f308bf3ac qobject: Drop useless QObject casts
We have macros in place to make it less verbose to add a subtype
of QObject to both QDict and QList. While we have made cleanups
like this in the past (see commit fcfcd8ffc, for example), having
it be automated by Coccinelle makes it easier to maintain.

Patch created mechanically via:
  spatch --sp-file scripts/coccinelle/qobject.cocci \
    --macro-file scripts/cocci-macro-file.h --dir . --in-place
then I verified that no manual touchups were required.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20170427215821.19397-5-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit de6e7951fe)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 17:07:06 -05:00
Eric Blake 21047240d0 coccinelle: Add script to remove useless QObject casts
We have macros in place to make it less verbose to add a subtype
of QObject to both QDict and QList. While we have made cleanups
like this in the past (see commit fcfcd8ffc, for example), having
it be automated by Coccinelle makes it easier to maintain.

The script is separate from the cleanups, for ease of review and
backporting.  A later patch will then add further possible cleanups.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20170427215821.19397-4-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit a2f3453ebc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 17:06:58 -05:00
Greg Kurz 785d9ab216 9pfs: local: fix unlink of alien files in mapped-file mode
When trying to remove a file from a directory, both created in non-mapped
mode, the file remains and EBADF is returned to the guest.

This is a regression introduced by commit "df4938a6651b 9pfs: local:
unlinkat: don't follow symlinks" when fixing CVE-2016-9602. It changed the
way we unlink the metadata file from

    ret = remove("$dir/.virtfs_metadata/$name");
    if (ret < 0 && errno != ENOENT) {
         /* Error out */
    }
    /* Ignore absence of metadata */

to

    fd = openat("$dir/.virtfs_metadata")
    unlinkat(fd, "$name")
    if (ret < 0 && errno != ENOENT) {
         /* Error out */
    }
    /* Ignore absence of metadata */

If $dir was created in non-mapped mode, openat() fails with ENOENT and
we pass -1 to unlinkat(), which fails in turn with EBADF.

We just need to check the return of openat() and ignore ENOENT, in order
to restore the behaviour we had with remove().

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
[groug: rewrote the comments as suggested by Eric]

(cherry picked from commit 6a87e7929f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:56:59 -05:00
Markus Armbruster 45b3eac752 replication: Make --disable-replication compile again
Broken in commit daa33c5.

Cc: qemu-stable@nongnu.org
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Message-id: 1493298053-17140-1-git-send-email-armbru@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 38bb54f323)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:55:42 -05:00
Bruce Rogers c64d184584 ACPI: don't call acpi_pcihp_device_plug_cb on xen
Commit f0c9d64a exposed the issue that with a xenfv machine using
pci passthrough, acpi pci hotplug code was being executed by mistake.
Guard calls to acpi_pcihp_device_plug_cb (and corresponding
acpi_pcihp_device_unplug_cb) with a check for xen_enabled(). Without
this check I am seeing an error that the bus doesn't have the
acpi-pcihp-bsel property set.

Signed-off-by: Bruce Rogers <brogers@suse.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 153eba4726)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:55:12 -05:00
Max Reitz c1059a3a3c block: Do not unref bs->file on error in BD's open
The block layer takes care of removing the bs->file child if the block
driver's bdrv_open()/bdrv_file_open() implementation fails. The block
driver therefore does not need to do so, and indeed should not unless it
sets bs->file to NULL afterwards -- because if this is not done, the
bdrv_unref_child() in bdrv_open_inherit() will dereference the freed
memory block at bs->file afterwards, which is not good.

We can now decide whether to add a "bs->file = NULL;" after each of the
offending bdrv_unref_child() invocations, or just drop them altogether.
The latter is simpler, so let's do that.

Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit de234897b6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:44:54 -05:00
Herongguang (Stephen) 0b906e4d0a pci: deassert intx when pci device unrealize
If a pci device is not reset by VM (by writing into config space)
and unplugged by VM, after that when VM reboots, qemu may assert:
pcibus_reset: Assertion `bus->irq_count[i] == 0' failed

Cc: qemu-stable@nongnu.org
Signed-off-by: herongguang <herongguang.he@huawei.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 3936161f1f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:43:34 -05:00
Daniel P. Berrange 181e005f14 migration: setup bi-directional I/O channel for exec: protocol
Historically the migration data channel has only needed to be
unidirectional. Thus the 'exec:' protocol was requesting an
I/O channel with O_RDONLY on incoming side, and O_WRONLY on
the outgoing side.

This is fine for classic migration, but if you then try to run
TLS over it, this fails because the TLS handshake requires a
bi-directional channel.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
(cherry picked from commit 062d81f0e9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:42:57 -05:00
Max Reitz b8420f7102 iotests/051: Add test for empty filename
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 42dc10f17a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:23:33 -05:00
Max Reitz bd1039b463 block: An empty filename counts as no filename
Reproducer:
    $ ./qemu-img info ''
    qemu-img: ./block.c:1008: bdrv_open_driver: Assertion
        `!drv->bdrv_needs_filename || bs->filename[0]' failed.
    [1]    26105 abort (core dumped)  ./qemu-img info ''

This patch fixes this to be:
    $ ./qemu-img info ''
    qemu-img: Could not open '': The 'file' block driver requires a file
    name

Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 4a0082401a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:23:04 -05:00
Max Reitz bc70597a48 qemu-img/convert: Move bs_n > 1 && -B check down
It does not make much sense to use a backing image for the target when
you concatenate multiple images (because then there is no correspondence
between the source images' backing files and the target's); but it was
still possible to give one by using -o backing_file=X instead of -B X.

Fix this by moving the check.

(Also, change the error message because -B is not the only way to
 specify the backing file, evidently.)

Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
* applied patch from v1 of series as suggested by author
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:22:00 -05:00
Max Reitz a1c850fd9d qemu-img/convert: Use @opts for one thing only
After storing the creation options for the new image into @opts, we
fetch some things for our own information, like the backing file name,
or whether to use encryption or preallocation.

With the -n parameter, there will not be any creation options; this is
not too bad because this just means that querying a NULL @opts will
always return the default value.

However, we also use @opts for the --object options. Therefore, @opts is
not necessarily NULL if -n was specified; instead, it may contain those
options. In practice, this probably does not cause any problems because
there most likely is no object that supports any of the parameters we
query here, but this is neither something we should rely on nor does
this variable reuse make the code very nice to read.

Therefore, just use an own variable for the --object options.

Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
* applied patch from v1 of series as suggested by author
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 16:20:06 -05:00
Max Reitz c37a62b751 qemu-img/convert: Always set ret < 0 on error
Otherwise the qemu-img process will exit with EXIT_SUCCESS instead of
EXIT_FAILURE.

Cc: qemu-stable <qemu-stable@nongnu.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
* applied directly to stable, upstream code has issue fixed via a
  refactoring introduced by 9fd77f9, which isn't targetted for stable
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 15:55:25 -05:00
Eric Blake 4aa16db9cf dirty-bitmap: Report BlockDirtyInfo.count in bytes, as documented
We've been documenting the value in bytes since its introduction
in commit b9a9b3a4 (v1.3), where it was actually reported in bytes.

Commit e4654d2 (v2.0) then removed things from block/qapi.c, in
preparation for a rewrite to a list of dirty sectors in the next
commit 21b5683 in block.c, but the new code mistakenly started
reporting in sectors.

Fixes: https://bugzilla.redhat.com/1441460

CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 6c98c57af3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 15:33:09 -05:00
Sameeh Jubran 27dd31f164 qga-win: Enable 'can-offline' field in 'guest-get-vcpus' reply
The QGA schema states:

@can-offline: Whether offlining the VCPU is possible. This member
               is always filled in by the guest agent when the structure
               is returned, and always ignored on input (hence it can be
               omitted then).

Currently 'can-offline' is missing entirely from the reply. This causes
errors in libvirt which is expecting the reply to be compliant with the
schema docs.

BZ#1438735: https://bugzilla.redhat.com/show_bug.cgi?id=1438735

Signed-off-by: Sameeh Jubran <sameeh@daynix.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
(cherry picked from commit 54858553de)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-07-31 15:25:56 -05:00
Peter Maydell 359c41abe3 Update version for v2.9.0 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-20 15:31:34 +01:00
Peter Maydell ca55019dac Update version for v2.9.0-rc5 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-18 17:13:50 +01:00
Peter Maydell d1263f8f18 Merge remote-tracking branch 'remotes/famz/tags/block-pull-request' into staging
# gpg: Signature made Tue 18 Apr 2017 15:58:32 BST
# gpg:                using RSA key 0xCA35624C6A9171C6
# gpg: Good signature from "Fam Zheng <famz@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 5003 7CB7 9706 0F76 F021  AD56 CA35 624C 6A91 71C6

* remotes/famz/tags/block-pull-request:
  block: Drain BH in bdrv_drained_begin
  block: Walk bs->children carefully in bdrv_drain_recurse

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-18 16:18:15 +01:00
Fam Zheng 91af091f92 block: Drain BH in bdrv_drained_begin
During block job completion, nothing is preventing
block_job_defer_to_main_loop_bh from being called in a nested
aio_poll(), which is a trouble, such as in this code path:

    qmp_block_commit
      commit_active_start
        bdrv_reopen
          bdrv_reopen_multiple
            bdrv_reopen_prepare
              bdrv_flush
                aio_poll
                  aio_bh_poll
                    aio_bh_call
                      block_job_defer_to_main_loop_bh
                        stream_complete
                          bdrv_reopen

block_job_defer_to_main_loop_bh is the last step of the stream job,
which should have been "paused" by the bdrv_drained_begin/end in
bdrv_reopen_multiple, but it is not done because it's in the form of a
main loop BH.

Similar to why block jobs should be paused between drained_begin and
drained_end, BHs they schedule must be excluded as well.  To achieve
this, this patch forces draining the BH in BDRV_POLL_WHILE.

As a side effect this fixes a hang in block_job_detach_aio_context
during system_reset when a block job is ready:

    #0  0x0000555555aa79f3 in bdrv_drain_recurse
    #1  0x0000555555aa825d in bdrv_drained_begin
    #2  0x0000555555aa8449 in bdrv_drain
    #3  0x0000555555a9c356 in blk_drain
    #4  0x0000555555aa3cfd in mirror_drain
    #5  0x0000555555a66e11 in block_job_detach_aio_context
    #6  0x0000555555a62f4d in bdrv_detach_aio_context
    #7  0x0000555555a63116 in bdrv_set_aio_context
    #8  0x0000555555a9d326 in blk_set_aio_context
    #9  0x00005555557e38da in virtio_blk_data_plane_stop
    #10 0x00005555559f9d5f in virtio_bus_stop_ioeventfd
    #11 0x00005555559fa49b in virtio_bus_stop_ioeventfd
    #12 0x00005555559f6a18 in virtio_pci_stop_ioeventfd
    #13 0x00005555559f6a18 in virtio_pci_reset
    #14 0x00005555559139a9 in qdev_reset_one
    #15 0x0000555555916738 in qbus_walk_children
    #16 0x0000555555913318 in qdev_walk_children
    #17 0x0000555555916738 in qbus_walk_children
    #18 0x00005555559168ca in qemu_devices_reset
    #19 0x000055555581fcbb in pc_machine_reset
    #20 0x00005555558a4d96 in qemu_system_reset
    #21 0x000055555577157a in main_loop_should_exit
    #22 0x000055555577157a in main_loop
    #23 0x000055555577157a in main

The rationale is that the loop in block_job_detach_aio_context cannot
make any progress in pausing/completing the job, because bs->in_flight
is 0, so bdrv_drain doesn't process the block_job_defer_to_main_loop
BH. With this patch, it does.

Reported-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <20170418143044.12187-3-famz@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Tested-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
2017-04-18 22:56:28 +08:00
Fam Zheng 178bd438af block: Walk bs->children carefully in bdrv_drain_recurse
The recursive bdrv_drain_recurse may run a block job completion BH that
drops nodes. The coming changes will make that more likely and use-after-free
would happen without this patch

Stash the bs pointer and use bdrv_ref/bdrv_unref in addition to
QLIST_FOREACH_SAFE to prevent such a case from happening.

Since bdrv_unref accesses global state that is not protected by the AioContext
lock, we cannot use bdrv_ref/bdrv_unref unconditionally.  Fortunately the
protection is not needed in IOThread because only main loop can modify a graph
with the AioContext lock held.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <20170418143044.12187-2-famz@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Tested-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
2017-04-18 22:56:28 +08:00
Greg Kurz 9c6b899f7a 9pfs: local: set the path of the export root to "."
The local backend was recently converted to using "at*()" syscalls in order
to ensure all accesses happen below the shared directory. This requires that
we only pass relative paths, otherwise the dirfd argument to the "at*()"
syscalls is ignored and the path is treated as an absolute path in the host.
This is actually the case for paths in all fids, with the notable exception
of the root fid, whose path is "/". This causes the following backend ops to
act on the "/" directory of the host instead of the virtfs shared directory
when the export root is involved:
- lstat
- chmod
- chown
- utimensat

ie, chmod /9p_mount_point in the guest will be converted to chmod / in the
host for example. This could cause security issues with a privileged QEMU.

All "*at()" syscalls are being passed an open file descriptor. In the case
of the export root, this file descriptor points to the path in the host that
was passed to -fsdev.

The fix is thus as simple as changing the path of the export root fid to be
"." instead of "/".

This is CVE-2017-7471.

Cc: qemu-stable@nongnu.org
Reported-by: Léo Gaspard <leo@gaspard.io>
Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-18 14:01:43 +01:00
Peter Maydell 372b3fe0b2 Update version for v2.9.0-rc4 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-11 17:18:03 +01:00
Max Reitz e3e0003a8f block/io: Comment out permission assertions
In case of block migration, there may be writes to BlockBackends that do
not have the write permission taken. Before this issue is fixed (which
is not going to happen in 2.9), we therefore cannot assert that this is
the case.

Suggested-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 20170411145050.31290-1-mreitz@redhat.com
Tested-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-11 16:09:31 +01:00
Kevin Wolf 5eceb01adf sheepdog: Fix crash in co_read_response()
This fixes a regression introduced in commit 9d456654.

aio_co_wake() can only be used to reenter a coroutine that was already
previously entered, otherwise co->ctx is uninitialised and we access
garbage. Using it immediately after qemu_coroutine_create() like in
co_read_response() is wrong and causes segfaults.

Replace the call with aio_co_enter(), which gets an explicit AioContext
parameter and works even for new coroutines.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Kashyap Chamarthy <kchamart@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 1491919733-21065-1-git-send-email-kwolf@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-11 16:08:29 +01:00
Peter Maydell f5ac5cfeb6 Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2017-04-11' into staging
Block patches for 2.9.0-rc4

# gpg: Signature made Tue 11 Apr 2017 14:40:07 BST
# gpg:                using RSA key 0xF407DB0061D5CF40
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>"
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40

* remotes/maxreitz/tags/pull-block-2017-04-11:
  iscsi: Fix iscsi_create
  throttle: Remove block from group on hot-unplug
  block: pass the right options for BlockDriver.bdrv_open()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-11 14:53:33 +01:00
Fam Zheng 2ec9a782d1 iscsi: Fix iscsi_create
Since d5895fcb (iscsi: Split URL into individual options), creating
qcow2 image on an iscsi LUN fails:

    qemu-img create -f qcow2 iscsi://$SERVER/$IQN/0 1G
    qemu-img: iscsi://$SERVER/$IQN/0: Could not create image: Invalid
        argument

The problem is iscsi_open now expects that transport_name, portal and
target are already parsed into structured options by
iscsi_parse_filename, but it is not called in iscsi_create.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 20170410075451.21329-1-famz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
[mreitz: Dropped now superfluous
         qdict_put(bs_options, "filename", ...)]
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-11 15:33:00 +02:00
Eric Blake 1606e4cf8a throttle: Remove block from group on hot-unplug
When a block device that is part of a throttle group is hot-unplugged,
we forgot to remove it from the throttle group. This leaves stale
memory around, and causes an easily reproducible crash:

$ ./x86_64-softmmu/qemu-system-x86_64 -nodefaults -nographic -qmp stdio \
-device virtio-scsi-pci,bus=pci.0 -drive \
id=drive_image2,if=none,format=raw,file=file2,bps=512000,iops=100,group=foo \
-device scsi-hd,id=image2,drive=drive_image2 -drive \
id=drive_image3,if=none,format=raw,file=file3,bps=512000,iops=100,group=foo \
-device scsi-hd,id=image3,drive=drive_image3
{'execute':'qmp_capabilities'}
{'execute':'device_del','arguments':{'id':'image3'}}
{'execute':'system_reset'}

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

Suggested-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-id: 20170406190847.29347-1-eblake@redhat.com
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-11 15:33:00 +02:00
Dong Jia Shi 7a9e51198c block: pass the right options for BlockDriver.bdrv_open()
raw_open() expects the caller always passing in the right actual
@options parameter. But when trying to applying snapshot on a RBD
image, bdrv_snapshot_goto() calls raw_open() (by calling the
bdrv_open callback on the BlockDriver) with a NULL @options, and
that will result in a Segmentation fault.

For the other non-raw format drivers, it also makes sense to passing
in the actual options, althought they don't trigger the problem so
far.

Let's prepare a @options by adding the "file" key-value pair to a
copy of the actual options that were given for the node (i.e.
bs->options), and pass it to the callback.

BlockDriver.bdrv_open() expects bs->file to be NULL and just
overwrites it with the result from bdrv_open_child(). That means we
should actually make sure it's NULL because otherwise the child BDS
will have a reference count that is 1 too high. So we unconditionally
invoke bdrv_unref_child() before calling BlockDriver.bdrv_open(), and
we wrap everything in bdrv_ref()/bdrv_unref() so the BDS isn't
deleted in the meantime.

Suggested-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
Message-id: 20170405091909.36357-2-bjsdjshi@linux.vnet.ibm.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-11 15:33:00 +02:00
Peter Maydell aa388ddc36 Merge remote-tracking branch 'remotes/famz/tags/block-pull-request' into staging
# gpg: Signature made Tue 11 Apr 2017 13:10:55 BST
# gpg:                using RSA key 0xCA35624C6A9171C6
# gpg: Good signature from "Fam Zheng <famz@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 5003 7CB7 9706 0F76 F021  AD56 CA35 624C 6A91 71C6

* remotes/famz/tags/block-pull-request:
  sheepdog: Use bdrv_coroutine_enter before BDRV_POLL_WHILE
  block: Fix bdrv_co_flush early return
  block: Use bdrv_coroutine_enter to start I/O coroutines
  qemu-io-cmds: Use bdrv_coroutine_enter
  blockjob: Use bdrv_coroutine_enter to start coroutine
  block: Introduce bdrv_coroutine_enter
  async: Introduce aio_co_enter
  coroutine: Extract qemu_aio_coroutine_enter
  tests/block-job-txn: Don't start block job before adding to txn
  block: Quiesce old aio context during bdrv_set_aio_context
  block: Make bdrv_parent_drained_begin/end public

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-11 13:27:05 +01:00
Fam Zheng 76296dff97 sheepdog: Use bdrv_coroutine_enter before BDRV_POLL_WHILE
When called from main thread, the coroutine should run in the context of
bs. Use bdrv_coroutine_enter to ensure that.

Signed-off-by: Fam Zheng <famz@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng 49ca625913 block: Fix bdrv_co_flush early return
bdrv_inc_in_flight and bdrv_dec_in_flight are mandatory for
BDRV_POLL_WHILE to work, even for the shortcut case where flush is
unnecessary. Move the if block to below bdrv_dec_in_flight, and BTW fix
the variable declaration position.

Signed-off-by: Fam Zheng <famz@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng e92f0e1910 block: Use bdrv_coroutine_enter to start I/O coroutines
BDRV_POLL_WHILE waits for the started I/O by releasing bs's ctx then polling
the main context, which relies on the yielded coroutine continuing on bs->ctx
before notifying qemu_aio_context with bdrv_wakeup().

Thus, using qemu_coroutine_enter to start I/O is wrong because if the coroutine
is entered from main loop, co->ctx will be qemu_aio_context, as a result of the
"release, poll, acquire" loop of BDRV_POLL_WHILE, race conditions happen when
both main thread and the iothread access the same BDS:

  main loop                                iothread
-----------------------------------------------------------------------
  blockdev_snapshot
    aio_context_acquire(bs->ctx)
                                           virtio_scsi_data_plane_handle_cmd
    bdrv_drained_begin(bs->ctx)
    bdrv_flush(bs)
      bdrv_co_flush(bs)                      aio_context_acquire(bs->ctx).enter
        ...
        qemu_coroutine_yield(co)
      BDRV_POLL_WHILE()
        aio_context_release(bs->ctx)
                                             aio_context_acquire(bs->ctx).return
                                               ...
                                                 aio_co_wake(co)
        aio_poll(qemu_aio_context)               ...
          co_schedule_bh_cb()                    ...
            qemu_coroutine_enter(co)             ...

              /* (A) bdrv_co_flush(bs)           /* (B) I/O on bs */
                      continues... */
                                             aio_context_release(bs->ctx)
        aio_context_acquire(bs->ctx)

Note that in above case, bdrv_drained_begin() doesn't do the "release,
poll, acquire" in BDRV_POLL_WHILE, because bs->in_flight == 0.

Fix this by using bdrv_coroutine_enter and enter coroutine in the right
context.

iotests 109 output is updated because the coroutine reenter flow during
mirror job complete is different (now through co_queue_wakeup, instead
of the unconditional qemu_coroutine_switch before), making the end job
len different.

Signed-off-by: Fam Zheng <famz@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng 324ec3e4f2 qemu-io-cmds: Use bdrv_coroutine_enter
qemu_coroutine_create associates @co to qemu_aio_context but we poll
blk's context below. If the coroutine yields, it may never get resumed
again.

Use bdrv_coroutine_enter to make sure we are starting the I/O on the
right context.

Signed-off-by: Fam Zheng <famz@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng aef4278c5a blockjob: Use bdrv_coroutine_enter to start coroutine
Resuming and especially starting of the block job coroutine, could be issued in
the main thread.  However the coroutine's "home" ctx should be set to the same
context as job->blk. Use bdrv_coroutine_enter to ensure that.

Signed-off-by: Fam Zheng <famz@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng 052a75721f block: Introduce bdrv_coroutine_enter
Signed-off-by: Fam Zheng <famz@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng 8865852e00 async: Introduce aio_co_enter
They start the coroutine on the specified context.

Signed-off-by: Fam Zheng <famz@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng ba9e75ceef coroutine: Extract qemu_aio_coroutine_enter
It's a variant of qemu_coroutine_enter with an explicit AioContext
parameter.

Signed-off-by: Fam Zheng <famz@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng d90fce9446 tests/block-job-txn: Don't start block job before adding to txn
Previously, before test_block_job_start returns, the job can already
complete, as a result, the transactional state of other jobs added to
the same txn later cannot be handled correctly.

Move the block_job_start() calls to callers after
block_job_txn_add_job() calls.

Signed-off-by: Fam Zheng <famz@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng aabf591007 block: Quiesce old aio context during bdrv_set_aio_context
The fact that the bs->aio_context is changing can confuse the dataplane
iothread, because of the now fine granularity aio context lock.
bdrv_drain should rather be a bdrv_drained_begin/end pair, but since
bs->aio_context is changing, we can just use aio_disable_external and
bdrv_parent_drained_begin.

Reported-by: Ed Swierk <eswierk@skyportsystems.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-04-11 20:07:15 +08:00
Fam Zheng 14e9559f46 block: Make bdrv_parent_drained_begin/end public
Signed-off-by: Fam Zheng <famz@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
2017-04-11 20:07:15 +08:00
Peter Maydell 17fa24b79c Merge remote-tracking branch 'remotes/kraxel/tags/pull-fixes-20170411-1' into staging
qxl: bugfixes.

# gpg: Signature made Tue 11 Apr 2017 08:00:00 BST
# gpg:                using RSA key 0x4CB6D8EED3E87138
# 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/pull-fixes-20170411-1:
  qxl: add migration blocker to avoid pre-save assert
  qxl: switch display on entering VGA

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-11 10:03:51 +01:00
Gerd Hoffmann 86dbcdd9c7 qxl: add migration blocker to avoid pre-save assert
Cc: 1635339@bugs.launchpad.net
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20170410113131.2585-1-kraxel@redhat.com
2017-04-11 08:38:17 +02:00
Peter Maydell c322fdd41a Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging
Fixes a memory leak.

# gpg: Signature made Mon 10 Apr 2017 13:20:39 BST
# gpg:                using DSA key 0x02FC3AEB0101DBC2
# gpg: Good signature from "Greg Kurz <groug@kaod.org>"
# gpg:                 aka "Greg Kurz <groug@free.fr>"
# gpg:                 aka "Greg Kurz <gkurz@linux.vnet.ibm.com>"
# gpg:                 aka "Gregory Kurz (Groug) <groug@free.fr>"
# gpg:                 aka "[jpeg image of size 3330]"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 2BD4 3B44 535E C0A7 9894  DBA2 02FC 3AEB 0101 DBC2

* remotes/gkurz/tags/for-upstream:
  9pfs: xattr: fix memory leak in v9fs_list_xattr

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-10 16:08:37 +01:00
Peter Maydell 0a49bfa1ab Merge remote-tracking branch 'remotes/stsquad/tags/pull-mttcg-fixups-for-rc2-100417-1' into staging
Final icount and misc MTTCG fixes for 2.9

Minor differences from:
  Message-Id: <20170405132503.32125-1-alex.bennee@linaro.org>

  - dropped new feature patches
  - last minute typo fix from Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>

# gpg: Signature made Mon 10 Apr 2017 11:38:10 BST
# gpg:                using RSA key 0xFBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>"
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* remotes/stsquad/tags/pull-mttcg-fixups-for-rc2-100417-1:
  replay: assert time only goes forward
  cpus: call cpu_update_icount on read
  cpu-exec: update icount after each TB_EXIT
  cpus: introduce cpu_update_icount helper
  cpus: don't credit executed instructions before they have run
  cpus: move icount preparation out of tcg_exec_cpu
  cpus: check cpu->running in cpu_get_icount_raw()
  cpus: remove icount handling from qemu_tcg_cpu_thread_fn
  target/i386/misc_helper: wrap BQL around another IRQ generator
  cpus: fix wrong define name
  scripts/qemugdb/mtree.py: fix up mtree dump

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-10 15:01:15 +01:00
Peter Maydell ad04d8cb2f configure: on Windows minimum glib version must be 2.30
In the 2.7 release we stated in the ChangeLog that the
minimum glib version for Windows hosts was 2.30, but we
didn't update configure to enforce this because we were
very close to the release at the point where we noticed
the issue, and it only affected building the test suite.
We then forgot that we needed to do it. Fix the omission.

(The reason for the 2.30 requirement is use of
g_dir_make_tmp() -- our fallback implementation uses
mkdtemp(), which isn't available on Windows.)

Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Message-id: 1491224655-5776-1-git-send-email-peter.maydell@linaro.org
2017-04-10 12:54:35 +01:00
Alex Bennée 982263ce71 replay: assert time only goes forward
If we find ourselves trying to add an event to the log where time has
gone backwards it is because a vCPU event has occurred and the
main-loop is not yet aware of time moving forward. This should not
happen and if it does its better to fail early than generate a log
that will have weird behaviour.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
2017-04-10 10:23:38 +01:00
Alex Bennée 1d05906b95 cpus: call cpu_update_icount on read
This ensures each time the vCPU thread reads the icount we update the
master timer_state.qemu_icount field. This way as long as updates are
in BQL protected sections (which they should be) the main-loop can
never come to update the log and find time has gone backwards.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
2017-04-10 10:23:38 +01:00
Alex Bennée eda5f7c6a1 cpu-exec: update icount after each TB_EXIT
There is no particular reason we shouldn't update the global system
icount time as we exit each TranslationBlock run. This ensures the
main-loop doesn't have to wait until we exit to the outer loop for
executed instructions to be credited to timer_state.

The prepare_icount_for_run function is slightly tweaked to match the
logic we run in cpu_loop_exec_tb.

Based on Paolo's original suggestion.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
2017-04-10 10:23:38 +01:00
Alex Bennée 512d3c8071 cpus: introduce cpu_update_icount helper
By holding off updates to timer_state.qemu_icount we can run into
trouble when the non-vCPU thread needs to know the time. This helper
ensures we atomically update timers_state.qemu_icount based on what
has been currently executed.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
2017-04-10 10:23:38 +01:00
Alex Bennée e4cd96571f cpus: don't credit executed instructions before they have run
Outside of the vCPU thread icount time will only be tracked against
timers_state.qemu_icount. We no longer credit cycles until they have
completed the run. Inside the vCPU thread we adjust for passage of
time by looking at how many have run so far. This is only valid inside
the vCPU thread while it is running.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
2017-04-10 10:23:38 +01:00
Alex Bennée 0524838225 cpus: move icount preparation out of tcg_exec_cpu
As icount is only supported for single-threaded execution due to the
requirement for determinism let's remove it from the common
tcg_exec_cpu path.

Also remove the additional fiddling which shouldn't be required as the
icount counters should all be rectified as you enter the loop.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
2017-04-10 10:23:33 +01:00
Alex Bennée 243c5f77f6 cpus: check cpu->running in cpu_get_icount_raw()
The lifetime of current_cpu is now the lifetime of the vCPU thread.
However get_icount_raw() can apply a fudge factor if called while code
is running to take into account the current executed instruction
count.

To ensure this is always the case we also check cpu->running.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2017-04-10 10:22:28 +01:00
Alex Bennée bf51c7206f cpus: remove icount handling from qemu_tcg_cpu_thread_fn
We should never be running in multi-threaded mode with icount enabled.
There is no point calling handle_icount_deadline here so remove it and
assert !use_icount.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2017-04-10 10:14:50 +01:00
Alex Bennée b4e79a502f target/i386/misc_helper: wrap BQL around another IRQ generator
Anything that calls into HW emulation must be protected by the BQL.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
2017-04-10 10:14:50 +01:00
Nikunj A Dadhania 8695350357 cpus: fix wrong define name
While the configure script generates TARGET_SUPPORTS_MTTCG define, one
of the define is cpus.c is checking wrong name: TARGET_SUPPORT_MTTCG

Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
2017-04-10 10:14:28 +01:00
Li Qiang 4ffcdef427 9pfs: xattr: fix memory leak in v9fs_list_xattr
Free 'orig_value' in error path.

Signed-off-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Greg Kurz <groug@kaod.org>
2017-04-10 09:38:05 +02:00
Alex Bennée 8037fa55ac scripts/qemugdb/mtree.py: fix up mtree dump
Since QEMU has been able to build with native Int128 support this was
broken as it attempts to fish values out of the non-existent
structure. Also the alias print was trying to make a %x out of
gdb.ValueType directly which didn't seem to work.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
2017-04-07 15:24:56 +01:00
Peter Maydell 5daf9b3025 Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer fixes for 2.9.0-rc4

# gpg: Signature made Fri 07 Apr 2017 13:44:17 BST
# gpg:                using RSA key 0x7F09B272C88F2FD6
# 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:
  mirror: Fix aio context of mirror_top_bs
  block: Assert attached child node has right aio context
  block: Fix unpaired aio_disable_external in external snapshot
  block: Don't check permissions for copy on read
  qemu-img: img_create does not support image-opts, fix docs
  iotests: Add mirror tests for orphaned source
  block/mirror: Fix use-after-free
  commit: Set commit_top_bs->total_sectors
  commit: Set commit_top_bs->aio_context
  block: Ignore guest dev permissions during incoming migration

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-07 15:23:48 +01:00
Fam Zheng 19dd29e8a7 mirror: Fix aio context of mirror_top_bs
It should be moved to the same context as source, before inserting to the
graph.

Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-04-07 14:44:06 +02:00
Fam Zheng bb2614e991 block: Assert attached child node has right aio context
Suggested-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-04-07 14:44:06 +02:00
Fam Zheng c26a5ab713 block: Fix unpaired aio_disable_external in external snapshot
bdrv_replace_child_noperm tries to hand over the quiesce_counter state
from old bs to the new one, but if they are not on the same aio context
this causes unbalance.

Fix this by setting the correct aio context before calling
bdrv_append().

Reported-by: Ed Swierk <eswierk@skyportsystems.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-04-07 14:44:06 +02:00
Kevin Wolf 1bf03e66fd block: Don't check permissions for copy on read
The assertion is currently failing. We can't require callers to have
write permissions when all they are doing is a read, so comment it out.
Add a FIXME comment in the code so that the check is re-enabled when
copy on read is refactored into its own filter driver.

Reported-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
2017-04-07 14:44:06 +02:00
Jeff Cody 89aa0465b9 qemu-img: img_create does not support image-opts, fix docs
The documentation and help for qemu-img claims that 'qemu-img create'
will take the '--image-opts' argument.  This is not true, so this
patch removes those claims.

Signed-off-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-04-07 14:44:06 +02:00
Max Reitz 5694923ad1 iotests: Add mirror tests for orphaned source
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-04-07 14:44:06 +02:00
Max Reitz 7a25fcd056 block/mirror: Fix use-after-free
If @bs does not have any parents, the only reference to @mirror_top_bs
will be held by the BlockJob object after the bdrv_unref() following
block_job_create(). However, if block_job_create() fails, this reference
will not exist and @mirror_top_bs will have been deleted when we
goto fail.

The issue comes back at all later entries to the fail label: We delete
the BlockJob object before rolling back our changes to the node graph.
This means that we will delete @mirror_top_bs in the process.

All in all, whenever @bs does not have any parents and we go down the
fail path we will dereference @mirror_top_bs after it has been deleted.

Fix this by invoking bdrv_unref() only when block_job_create() was
successful and by bdrv_ref()'ing @mirror_top_bs in the fail path before
deleting the BlockJob object. Finally, bdrv_unref() it at the end of the
fail path after we actually no longer need it.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-04-07 14:44:05 +02:00
Kevin Wolf 0d0676a104 commit: Set commit_top_bs->total_sectors
Like in the mirror filter driver, we also need to set the image size for
the commit filter driver. This is less likely to be a problem in
practice than for the mirror because we're not at the active layer here,
but attaching new parents to a node in the middle of the chain is
possible, so the size needs to be correct anyway.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
2017-04-07 14:44:05 +02:00
Kevin Wolf 02be4aeb93 commit: Set commit_top_bs->aio_context
The filter driver that is inserted by the commit job needs to use the
same AioContext as its parent and child nodes.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
2017-04-07 14:44:05 +02:00
Kevin Wolf d35ff5e6b3 block: Ignore guest dev permissions during incoming migration
Usually guest devices don't like other writers to the same image, so
they use blk_set_perm() to prevent this from happening. In the migration
phase before the VM is actually running, though, they don't have a
problem with writes to the image. On the other hand, storage migration
needs to be able to write to the image in this phase, so the restrictive
blk_set_perm() call of qdev devices breaks it.

This patch flags all BlockBackends with a qdev device as
blk->disable_perm during incoming migration, which means that the
requested permissions are stored in the BlockBackend, but not actually
applied to its root node yet.

Once migration has finished and the VM should be resumed, the
permissions are applied. If they cannot be applied (e.g. because the NBD
server used for block migration hasn't been shut down), resuming the VM
fails.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Tested-by: Kashyap Chamarthy <kchamart@redhat.com>
2017-04-07 14:44:05 +02:00
Marc-André Lureau a703d3aef5 qxl: switch display on entering VGA
Since commit cd958edb1f, same size console resize is skipped. This
change broke QXL incoming migration in VGA mode,
qemu_spice_display_switch() is no longer called during qxl_post_load(),
because default message surface is of the same size, and during
displaychangelistener registration, PCIQXLDevice.mode is
QXL_MODE_UNDEFINED. This triggers a later crash on refresh:

==2634== Invalid read of size 4
==3516== at 0x65F3050: pixman_image_get_data (in /usr/lib64/libpixman-1.so.0.34.0)
==3516== by 0x6F0CEB: qemu_spice_create_update (spice-display.c:215)
==3516== by 0x6F1CC7: qemu_spice_display_refresh (spice-display.c:502)
==3516== by 0x58CF77: display_refresh (qxl.c:1948)
==3516== by 0x6E8084: do_safe_dpy_refresh (console.c:1591)
==3516== by 0x6E80D5: dpy_refresh (console.c:1604)
==3516== by 0x6E4508: gui_update (console.c:201)
==3516== by 0x81898E: timerlist_run_timers (qemu-timer.c:536)
==3516== by 0x8189D6: qemu_clock_run_timers (qemu-timer.c:547)
==3516== by 0x818D98: qemu_clock_run_all_timers (qemu-timer.c:662)
==3516== by 0x81952A: main_loop_wait (main-loop.c:514)
==3516== by 0x4ADD29: main_loop (vl.c:1898)

One way to solve this is to explicitely call qemu_spice_display_switch()
on entering VGA mode, which is called during qxl_post_load().

Fixes:
"null pointer access on migration resume of systemrescuecd boot menu with qxl-vga"
https://bugs.launchpad.net/qemu/+bug/1679126
https://bugzilla.redhat.com/show_bug.cgi?id=1438566

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20170406120513.638-4-marcandre.lureau@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2017-04-07 12:31:46 +02:00
Peter Maydell 5fe2339e6b Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20170406.0' into staging
VFIO fixes 2017-04-06

 - Extra test for NVIDIA BAR5 quirk to avoid segfault (Alex Williamson)

# gpg: Signature made Thu 06 Apr 2017 23:05:53 BST
# gpg:                using RSA key 0x239B9B6E3BB08B22
# gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>"
# gpg:                 aka "Alex Williamson <alex@shazbot.org>"
# gpg:                 aka "Alex Williamson <alwillia@redhat.com>"
# gpg:                 aka "Alex Williamson <alex.l.williamson@gmail.com>"
# Primary key fingerprint: 42F6 C04E 540B D1A9 9E7B  8A90 239B 9B6E 3BB0 8B22

* remotes/awilliam/tags/vfio-updates-20170406.0:
  vfio/pci-quirks: Exclude non-ioport BAR from NVIDIA quirk

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-07 10:29:56 +01:00
Alex Williamson 8f419c5b43 vfio/pci-quirks: Exclude non-ioport BAR from NVIDIA quirk
The NVIDIA BAR5 quirk is targeting an ioport BAR.  Some older devices
have a BAR5 which is not ioport and can induce a segfault here.  Test
the BAR type to skip these devices.

Link: https://bugs.launchpad.net/qemu/+bug/1678466
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2017-04-06 16:03:26 -06:00
Peter Maydell 54d689988c Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* TCO watchdog fix

# gpg: Signature made Wed 05 Apr 2017 16:24:52 BST
# gpg:                using RSA key 0xBFFBD25F78C7AE83
# 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:
  tco: do not generate an NMI

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-06 09:27:49 +01:00
Paolo Bonzini 8c9f42f3cf tco: do not generate an NMI
This behavior is not indicated in the datasheet and can confuse the OS.
The TCO can trap NMIs from SERR# or IOCHK# and convert them to SMIs; but
any other TCO event is either delivered as an SMI or completely disabled.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2017-04-05 17:23:52 +02:00
Peter Maydell 1fde6ee885 Update version for v2.9.0-rc3 release
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-04 18:36:51 +01:00
Peter Maydell 1413c663c9 Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging
Some 9pfs bugs fixes: potential hang at reset, migration blocker leak.

# gpg: Signature made Tue 04 Apr 2017 17:07:55 BST
# gpg:                using DSA key 0x02FC3AEB0101DBC2
# gpg: Good signature from "Greg Kurz <groug@kaod.org>"
# gpg:                 aka "Greg Kurz <groug@free.fr>"
# gpg:                 aka "Greg Kurz <gkurz@linux.vnet.ibm.com>"
# gpg:                 aka "Gregory Kurz (Groug) <groug@free.fr>"
# gpg:                 aka "[jpeg image of size 3330]"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 2BD4 3B44 535E C0A7 9894  DBA2 02FC 3AEB 0101 DBC2

* remotes/gkurz/tags/for-upstream:
  9pfs: clear migration blocker at session reset
  9pfs: fix multiple flush for same request

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-04 18:00:23 +01:00
Peter Maydell 2c9938c5d7 Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pci: fix

A single bugfix for a error handling issue in pci.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Tue 04 Apr 2017 16:33:04 BST
# gpg:                using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream:
  pci: Only unmap bus_master_enabled_region if was added previously

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-04 17:27:32 +01:00
Greg Kurz 6d54af0ea9 9pfs: clear migration blocker at session reset
The migration blocker survives a device reset: if the guest mounts a 9p
share and then gets rebooted with system_reset, it will be unmigratable
until it remounts and umounts the 9p share again.

This happens because the migration blocker is supposed to be cleared when
we put the last reference on the root fid, but virtfs_reset() wrongly calls
free_fid() instead of put_fid().

This patch fixes virtfs_reset() so that it honor the way fids are supposed
to be manipulated: first get a reference and later put it back when you're
done.

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Li Qiang <liqiang6-s@360.cn>
2017-04-04 18:06:01 +02:00
Greg Kurz 18adde86dd 9pfs: fix multiple flush for same request
If a client tries to flush the same outstanding request several times, only
the first flush completes. Subsequent ones keep waiting for the request
completion in v9fs_flush() and, therefore, leak a PDU. This will cause QEMU
to hang when draining active PDUs the next time the device is reset.

Let have each flush request wake up the next one if any. The last waiter
frees the cancelled PDU.

Signed-off-by: Greg Kurz <groug@kaod.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
2017-04-04 18:06:01 +02:00
Alexey Kardashevskiy 193982c6f9 pci: Only unmap bus_master_enabled_region if was added previously
Normally pci_init_bus_master() would be called either via
bus->machine_done.notify or directly from do_pci_register_device().

However if a device's realize() failed, pci_init_bus_master() is not
called, and do_pci_unregister_device() fails on
memory_region_del_subregion() as it was not mapped.

This adds a check that subregion was mapped before unmapping it.

Fixes: c53598ed18 ("pci: Add missing drop of bus master AS reference")
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: John Snow <jsnow@redhat.com>
2017-04-04 18:32:25 +03:00
Peter Maydell fa902c8ca0 Merge remote-tracking branch 'remotes/berrange/tags/pull-qio-2017-04-04-1' into staging
Merge qio 2017/04/04 v1

# gpg: Signature made Tue 04 Apr 2017 16:17:56 BST
# gpg:                using RSA key 0xBE86EBB415104FDF
# gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>"
# gpg:                 aka "Daniel P. Berrange <berrange@redhat.com>"
# Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E  8E3F BE86 EBB4 1510 4FDF

* remotes/berrange/tags/pull-qio-2017-04-04-1:
  io: fix FD socket handling in DNS lookup
  io: fix incoming client socket initialization

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-04 16:25:30 +01:00
Daniel P. Berrange b8a68728b6 io: fix FD socket handling in DNS lookup
The qio_dns_resolver_lookup_sync() method is required to be a no-op
for socket kinds that don't require name resolution. Thus the KIND_FD
handling should not return an error.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-04-04 16:17:03 +01:00
Wang guang 0e5d6327f3 io: fix incoming client socket initialization
The channel socket was initialized manually, but forgot to set
QIO_CHANNEL_FEATURE_SHUTDOWN. Thus, the colo_process_incoming_thread
would hang at recvmsg. This patch just call qio_channel_socket_new to
get channel, Which set QIO_CHANNEL_FEATURE_SHUTDOWN already.

Signed-off-by: Wang Guang<wang.guang55@zte.com.cn>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2017-04-04 16:17:03 +01:00
Peter Maydell 87cc4c6102 Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* MemoryRegionCache revert
* glib optimization workaround
* fix "info lapic" segfault on isapc
* fix QIOChannel memory leak

# gpg: Signature made Mon 03 Apr 2017 18:17:00 BST
# gpg:                using RSA key 0xBFFBD25F78C7AE83
# 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:
  main-loop: Acquire main_context lock around os_host_main_loop_wait.
  exec: revert MemoryRegionCache
  nbd: fix memory leak on socket_connect failed
  ipmi: Fix macro issues
  target-i386: fix "info lapic" segfault on isapc
  iscsi: drop unused IscsiAIOCB.qiov field

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-04 11:40:55 +01:00
Peter Maydell d9123d09f7 tests/libqtest.c: Delete possible stale unix sockets
Occasionally if a test crashes or is interrupted by the user
at the wrong moment it could leave behind a stale UNIX
socket in /tmp/. This will then cause a subsequent test
run to fail spuriously with
 tests/libqtest.c:70:init_socket: assertion failed (ret != -1): (-1 != -1)
if it happens to reuse the same PID.

Defend against this by deleting any stray stale socket before
trying to open the new ones for this test.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 1490963801-27870-1-git-send-email-peter.maydell@linaro.org
2017-04-03 19:05:38 +01:00
Richard W.M. Jones ecbddbb106 main-loop: Acquire main_context lock around os_host_main_loop_wait.
When running virt-rescue the serial console hangs from time to time.
Virt-rescue runs an ordinary Linux kernel "appliance", but there is
only a single idle process running inside, so the qemu main loop is
largely idle.  With virt-rescue >= 1.37 you may be able to observe the
hang by doing:

  $ virt-rescue -e ^] --scratch
  ><rescue> while true; do ls -l /usr/bin; done

The hang in virt-rescue can be resolved by pressing a key on the
serial console.

Possibly with the same root cause, we also observed hangs during very
early boot of regular Linux VMs with a serial console.  Those hangs
are extremely rare, but you may be able to observe them by running
this command on baremetal for a sufficiently long time:

  $ while libguestfs-test-tool -t 60 >& /tmp/log ; do echo -n . ; done

(Check in /tmp/log that the failure was caused by a hang during early
boot, and not some other reason)

During investigation of this bug, Paolo Bonzini wrote:

> glib is expecting QEMU to use g_main_context_acquire around accesses to
> GMainContext.  However QEMU is not doing that, instead it is taking its
> own mutex.  So we should add g_main_context_acquire and
> g_main_context_release in the two implementations of
> os_host_main_loop_wait; these should undo the effect of Frediano's
> glib patch.

This patch exactly implements Paolo's suggestion in that paragraph.

This fixes the serial console hang in my testing, across 3 different
physical machines (AMD, Intel Core i7 and Intel Xeon), over many hours
of automated testing.  I wasn't able to reproduce the early boot hangs
(but as noted above, these are extremely rare in any case).

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1435432
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Message-Id: <20170331205133.23906-1-rjones@redhat.com>
[Paolo: this is actually a glib bug: recent glib versions are also
expecting g_main_context_acquire around g_poll---but that is not
documented and probably not even intended].
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2017-04-03 19:13:12 +02:00
Peter Maydell b1a419ec79 Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2017-04-03' into staging
Block patches for 2.9-rc3

# gpg: Signature made Mon 03 Apr 2017 16:29:49 BST
# gpg:                using RSA key 0xF407DB0061D5CF40
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>"
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40

* remotes/maxreitz/tags/pull-block-2017-04-03:
  block/parallels: Avoid overflows
  iotests: Improve image-clear tests on non-aligned image
  qcow2: Discard unaligned tail when wiping image
  iotests: fix 097 when run with qcow
  qemu-io-cmds: Assert that global and nofile commands don't use ct->perms
  sheepdog: Fix blockdev-add
  nbd: Tidy up blockdev-add interface
  sockets: New helper socket_address_crumple()
  qapi-schema: SocketAddressFlat variants 'vsock' and 'fd'
  gluster: Prepare for SocketAddressFlat extension
  block: Document -drive problematic code and bugs
  io vnc sockets: Clean up SocketAddressKind switches
  char: Fix socket with "type": "vsock" address
  nbd sockets vnc: Mark problematic address family tests TODO
  block: add missed aio_context_acquire into release_drive

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-03 16:43:39 +01:00
Max Reitz 86d1bd7098 block/parallels: Avoid overflows
Change the types of variables in allocate_clusters() to int64_t so we do
not have to worry about potential overflows.

Add an assertion that our accesses to s->bat[] do not result in a buffer
overflow and that the implicit conversion performed when invoking
bat_entry_off() does not result in an integer overflow.

Coverity-id: 1307776
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170331170512.10381-1-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:40 +02:00
Eric Blake f82c5b17ea iotests: Improve image-clear tests on non-aligned image
Tweak 097 and 176 to operate on an image that is not cluster-aligned,
to give further coverage of clearing out an entire image, including
the recent fix to eliminate the difference between fast path (97) and
slow (176) for qcow2.  Also tested on qcow (97 only, since qcow lacks
snapshots).

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-id: 20170331185356.2479-4-eblake@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:40 +02:00
Eric Blake 0c1bd4692f qcow2: Discard unaligned tail when wiping image
There is a subtle difference between the fast (qcow2v3 with no
extra data) and slow path (qcow2v2 format [aka 0.10], or when a
snapshot is present) of qcow2_make_empty().  The slow path fails
to discard the final (partial) cluster of an unaligned image.

The problem stems from the fact that qcow2_discard_clusters() was
silently ignoring sub-cluster head and tail on unaligned requests.
A quick audit of all callers shows that qcow2_snapshot_create() has
always passed a cluster-aligned request since the call was added
in commit 1ebf561; qcow2_co_pdiscard() has passed a cluster-aligned
request since commit ecdbead taught the block layer about preferred
discard alignment; and qcow2_make_empty() was fixed to pass an
aligned start (but not necessarily end) in commit a3e1505.

Asserting that the start is always aligned also points out that we
now have a dead check: rounding the end offset down can never result
in a value less than the aligned start offset (the check was rendered
dead with commit ecdbead).  Meanwhile, we do not want to round the
end cluster down in the one case of the end offset matching the
(unaligned) file size - that final partial cluster should still be
discarded.

With those fixes in place, the fast and slow paths are back in sync
at discarding an entire image; the next patch will update
qemu-iotests to ensure we don't regress.

Note that bdrv_co_pdiscard ignores ALL partial cluster requests,
including the partial cluster at the end of an image; it can be
argued that the partial cluster at the end should be special-cased
so that a guest issuing discard requests at proper alignments
everywhere else can likewise empty the entire image.  But that
optimization is left for another day.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-id: 20170331185356.2479-3-eblake@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:40 +02:00
Daniel P. Berrange 07ff948bd1 iotests: fix 097 when run with qcow
The previous commit:

  commit a3e1505dae
  Author: Eric Blake <eblake@redhat.com>
  Date:   Mon Dec 5 09:49:34 2016 -0600

    qcow2: Don't strand clusters near 2G intervals during commit

extended the 097 test case so that it did two passes, once
with an internal snapshot, once without.

qcow (v1) does not support internal snapshots, so this change
broke test 097 when run against qcow.

This splits 097 in two, creating a new 176 that tests the
internal snapshot codepath, effectively putting 097 back
to its content before the above commit.

Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <20170221115512.21918-8-berrange@redhat.com>
[eblake: test collisions: s/173/176/g]
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-id: 20170331185356.2479-2-eblake@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:40 +02:00
Peter Maydell 6aabeb5839 qemu-io-cmds: Assert that global and nofile commands don't use ct->perms
It would be a bug for a command with the CMD_NOFILE_OK or
CMD_FLAG_GLOBAL flags set to also set the ct->perms field,
because the former says "OK for a file not to be open"
but the latter is a check on a file.

Add an assertion in qemuio_add_command() so we can catch that
sort of buggy command definition immediately rather than it
being a bug that only manifests when a particular set of
command line options is used.

(Coverity gets confused about this (CID 1371723) and reports
that we might dereference a NULL blk pointer in this case,
because it can't tell that that code path never happens with
the cmdinfo_t that we have. This commit won't help unconfuse
it, but it does fix the underlying issue.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1490967529-4767-1-git-send-email-peter.maydell@linaro.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:40 +02:00
Markus Armbruster d1c136885b sheepdog: Fix blockdev-add
Commit 831acdc "sheepdog: Implement bdrv_parse_filename()" and commit
d282f34 "sheepdog: Support blockdev-add" have different ideas on how
the QemuOpts parameters for the server address are named.  Fix that.
While there, rename BlockdevOptionsSheepdog member addr to server, for
consistency with BlockdevOptionsSsh, BlockdevOptionsGluster,
BlockdevOptionsNbd.

Commit 831acdc's example becomes

    --drive driver=sheepdog,server.type=inet,server.host=fido,server.port=7000,vdi=dolly

instead of

    --drive driver=sheepdog,host=fido,vdi=dolly

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Kashyap Chamarthy <kchamart@redhat.com>
Message-id: 1490895797-29094-10-git-send-email-armbru@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Markus Armbruster 9445673ea6 nbd: Tidy up blockdev-add interface
SocketAddress is a simple union, and simple unions are awkward: they
have their variant members wrapped in a "data" object on the wire, and
require additional indirections in C.  I intend to limit its use to
existing external interfaces, and convert all internal interfaces to
SocketAddressFlat.

BlockdevOptionsNbd is an external interface using SocketAddress.  We
already use SocketAddressFlat elsewhere in blockdev-add.  Replace it
by SocketAddressFlat while we can (it's new in 2.9) for simplicity and
consistency.  For example,

    { "execute": "blockdev-add",
      "arguments": { "node-name": "foo", "driver": "nbd",
                     "server": { "type": "inet",
		                 "data": { "host": "localhost",
				           "port": "12345" } } } }

becomes

    { "execute": "blockdev-add",
      "arguments": { "node-name": "foo", "driver": "nbd",
                     "server": { "type": "inet",
		                 "host": "localhost", "port": "12345" } } }

Since the internal interfaces still take SocketAddress, this requires
conversion function socket_address_crumple().  It'll go away when I
update the interfaces.

Unfortunately, SocketAddress is also visible in -drive since 2.8:

    -drive if=none,driver=nbd,server.type=inet,server.data.host=127.0.0.1,server.data.port=12345

Nobody should be using it, as it's fairly new and has never been
documented, so adding still more compatibility gunk to keep it working
isn't worth the trouble.  You now have to use

    -drive if=none,driver=nbd,server.type=inet,server.host=127.0.0.1,server.port=12345

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1490895797-29094-9-git-send-email-armbru@redhat.com

[mreitz: Change iotest 147 accordingly]

Because of this interface change, iotest 147 has to be adapted.
Unfortunately, we cannot just flatten all of the addresses because
nbd-server-start still takes a plain SocketAddress. Therefore, we need
both and this is most easily achieved by writing the SocketAddress into
the code and flattening it where necessary.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170330221243.17333-1-mreitz@redhat.com

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Markus Armbruster 216411b839 sockets: New helper socket_address_crumple()
SocketAddress is a simple union, and simple unions are awkward: they
have their variant members wrapped in a "data" object on the wire, and
require additional indirections in C.  I intend to limit its use to
existing external interfaces.  New ones should use SocketAddressFlat.
I further intend to convert all internal interfaces to
SocketAddressFlat.  This helper should go away then.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1490895797-29094-8-git-send-email-armbru@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Markus Armbruster 8bc0673f6d qapi-schema: SocketAddressFlat variants 'vsock' and 'fd'
Note that the new variants are impossible in qemu_gluster_glfs_init(),
because the gconf->server can only come from qemu_gluster_parse_uri()
or qemu_gluster_parse_json(), and neither can create anything but
'inet' or 'unix'.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1490895797-29094-7-git-send-email-armbru@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Markus Armbruster fce5d5386d gluster: Prepare for SocketAddressFlat extension
qemu_gluster_glfs_init() and qemu_gluster_parse_json() rely on the
fact that SocketAddressFlatType has only two members
SOCKET_ADDRESS_FLAT_TYPE_INET and SOCKET_ADDRESS_FLAT_TYPE_UNIX.
Correct, but won't stay correct.  Make them more robust.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Message-id: 1490895797-29094-6-git-send-email-armbru@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Markus Armbruster 129c7d1c53 block: Document -drive problematic code and bugs
-blockdev and blockdev_add convert their arguments via QObject to
BlockdevOptions for qmp_blockdev_add(), which converts them back to
QObject, then to a flattened QDict.  The QDict's members are typed
according to the QAPI schema.

-drive converts its argument via QemuOpts to a (flat) QDict.  This
QDict's members are all QString.

Thus, the QType of a flat QDict member depends on whether it comes
from -drive or -blockdev/blockdev_add, except when the QAPI type maps
to QString, which is the case for 'str' and enumeration types.

The block layer core extracts generic configuration from the flat
QDict, and the block driver extracts driver-specific configuration.

Both commonly do so by converting (parts of) the flat QDict to
QemuOpts, which turns all values into strings.  Not exactly elegant,
but correct.

However, A few places access the flat QDict directly:

* Most of them access members that are always QString.  Correct.

* bdrv_open_inherit() accesses a boolean, carefully.  Correct.

* nfs_config() uses a QObject input visitor.  Correct only because the
  visited type contains nothing but QStrings.

* nbd_config() and ssh_config() use a QObject input visitor, and the
  visited types contain non-QStrings: InetSocketAddress members
  @numeric, @to, @ipv4, @ipv6.  -drive works as long as you don't try
  to use them (they're all optional).  @to is ignored anyway.

  Reproducer:
  -drive driver=ssh,server.host=h,server.port=22,server.ipv4,path=p
  -drive driver=nbd,server.type=inet,server.data.host=h,server.data.port=22,server.data.ipv4
  both fail with "Invalid parameter type for 'data.ipv4', expected: boolean"

Add suitable comments to all these places.  Mark the buggy ones FIXME.

"Fortunately", -drive's driver-specific options are entirely
undocumented.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-id: 1490895797-29094-5-git-send-email-armbru@redhat.com
[mreitz: Fixed two typos]
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Markus Armbruster a6c76285f2 io vnc sockets: Clean up SocketAddressKind switches
We have quite a few switches over SocketAddressKind.  Some have case
labels for all enumeration values, others rely on a default label.
Some abort when the value isn't a valid SocketAddressKind, others
report an error then.

Unify as follows.  Always provide case labels for all enumeration
values, to clarify intent.  Abort when the value isn't a valid
SocketAddressKind, because the program state is messed up then.

Improve a few error messages while there.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 1490895797-29094-4-git-send-email-armbru@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Markus Armbruster d2e49aad72 char: Fix socket with "type": "vsock" address
Watch this:

    $ qemu-system-x86_64 -nodefaults -S -display none -qmp stdio
    {"QMP": {"version": {"qemu": {"micro": 91, "minor": 8, "major": 2}, "package": " (v2.8.0-1195-gf84141e-dirty)"}, "capabilities": []}}
    { "execute": "qmp_capabilities" }
    {"return": {}}
    { "execute": "chardev-add", "arguments": { "id": "chr0", "backend": { "type": "socket", "data": { "addr": { "type": "vsock", "data": { "cid": "CID", "port": "P" }}}}}}
    Aborted (core dumped)

Crashes because SocketAddress_to_str() is blissfully unaware of
SOCKET_ADDRESS_KIND_VSOCK.  Fix that.  Pick the output format to match
socket_parse(), just like the existing formats.

Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 1490895797-29094-3-git-send-email-armbru@redhat.com
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Markus Armbruster ca0b64e5ed nbd sockets vnc: Mark problematic address family tests TODO
Certain features make sense only with certain address families.  For
instance, passing file descriptors requires AF_UNIX.  Testing
SocketAddress's saddr->type == SOCKET_ADDRESS_KIND_UNIX is obvious,
but problematic: it can't recognize AF_UNIX when type ==
SOCKET_ADDRESS_KIND_FD.

Mark such tests of saddr->type TODO.  We may want to check the address
family with getsockname() there.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1490895797-29094-2-git-send-email-armbru@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Denis V. Lunev 9588c5897b block: add missed aio_context_acquire into release_drive
Recently we expirience hang with iothreads enabled with the following
call trace:
Thread 1 (Thread 0x7fa95efebc80 (LWP 177117)):
0  ppoll () from /lib64/libc.so.6
2  qemu_poll_ns () at qemu-timer.c:313
3  aio_poll () at aio-posix.c:457
4  bdrv_flush () at block/io.c:2641
5  bdrv_close () at block.c:2143
6  bdrv_delete () at block.c:2352
7  bdrv_unref () at block.c:3429
8  blk_remove_bs () at block/block-backend.c:427
9  blk_delete () at block/block-backend.c:178
10 blk_unref () at block/block-backend.c:226
11 object_property_del_all () at qom/object.c:399
12 object_finalize () at qom/object.c:461
13 object_unref () at qom/object.c:898
14 object_property_del_child () at qom/object.c:422
15 qmp_marshal_device_del () at qmp-marshal.c:1145
16 handle_qmp_command () at /usr/src/debug/qemu-2.6.0/monitor.c:3929

Technically bdrv_flush() stucks in
    while (rwco.ret == NOT_DONE) {
        aio_poll(aio_context, true);
    }
but rwco.ret is equal to 0 thus we have missed wakeup. Code investigation
reveals that we do not have performed aio_context_acquire() on this call
stack.

This patch adds missed lock.

Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Max Reitz <mreitz@redhat.com>
CC: Eric Blake <eblake@redhat.com>
CC: Markus Armbruster <armbru@redhat.com>
Message-id: 1490717566-25516-1-git-send-email-den@openvz.org
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-04-03 17:11:39 +02:00
Gerd Hoffmann 102a3d8478 usb-host: switch to LIBUSB_API_VERSION
libusbx doesn't exist any more, the fork got merged back to libusb.  So
stop using LIBUSBX_API_VERSION and use LIBUSB_API_VERSION instead.  For
backward compatibility alias LIBUSB_API_VERSION to LIBUSBX_API_VERSION
in case we figure LIBUSB_API_VERSION isn't defined.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20170403105238.23262-1-kraxel@redhat.com
2017-04-03 14:41:23 +01:00
Peter Maydell 230f4c6bc5 disas/cris.c: Avoid unintentional sign extension
Commit 001ebaca7b fixed some unintended sign extension issues
spotted by Coverity (CID 1005402, 1005403), but didn't catch
all of them. Fix the rest, so we behave consistently whether
'long' is 32 bit or 64 bit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Message-id: 1490970671-20560-1-git-send-email-peter.maydell@linaro.org
2017-04-03 14:06:59 +01:00
Peter Maydell 6499fd151d configure: Mark SPARC as supported
Thanks to John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
and the Debian Project, we now have access to a SPARC Linux
system we can use for build testing. Move SPARC back into
the "supported" list.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1490698718-23762-1-git-send-email-peter.maydell@linaro.org
2017-04-03 12:59:47 +01:00
Peter Maydell 5c32be5baf tcg/sparc: Zero extend address argument to ld/st helpers
The C store helper functions take the address argument as a
target_ulong type; if this is 32 bit but the host is 64 bit
then the SPARC calling convention requires that the caller
must zero extend the value. We weren't doing this, which
meant we could pass values to the caller with high bits set
and QEMU would crash if it was compiled with optimizations.
In particular, the i386 BIOS would not start.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1490871151-29029-3-git-send-email-peter.maydell@linaro.org
Reviewed-by: Richard Henderson <rth@twiddle.net>
2017-04-03 12:59:37 +01:00
Peter Maydell 709a340d67 tcg/sparc: Zero extend data argument to store helpers
The C store helper functions take the data argument as a uint8_t,
uint16_t, etc depending on the store size. The SPARC calling
convention requires that data types smaller than the register
size must be extended by the caller. We weren't doing this,
which meant that if QEMU was compiled with optimizations enabled
we could end up storing incorrect values to guest memory.
(In particular the i386 guest BIOS would crash on startup.)

Add code to the trampolines that call the store helpers to
do the zero extension as required.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 1490871151-29029-2-git-send-email-peter.maydell@linaro.org
Reviewed-by: Richard Henderson <rth@twiddle.net>
2017-04-03 12:59:14 +01:00
Paolo Bonzini 90c4fe5fc5 exec: revert MemoryRegionCache
MemoryRegionCache did not know about virtio support for IOMMUs (because the
two features were developed at the same time).  Revert MemoryRegionCache
to "normal" address_space_* operations for 2.9, as it is simpler than
undoing the virtio patches.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2017-04-03 13:41:53 +02:00
Peter Maydell f9e46d37bd Merge remote-tracking branch 'remotes/kraxel/tags/pull-fixes-20170403-1' into staging
bugfixes: xhci, input-linux and vnc

# gpg: Signature made Mon 03 Apr 2017 11:25:29 BST
# gpg:                using RSA key 0x4CB6D8EED3E87138
# 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/pull-fixes-20170403-1:
  vnc: allow to connect with add_client when -vnc none
  Fix input-linux reading from device
  xhci: flush dequeue pointer to endpoint context

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-03 12:24:25 +01:00
Peter Maydell 9eb5adae26 Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.9-20170403' into staging
ppc patch queue 2017-04-03

A single bugfix in this pull request, for an ugly assert() failure, if
the user ignores the information in query-hotpluggable-cpus and tries
to hot add CPUs to pseries with bad parameters.

# gpg: Signature made Mon 03 Apr 2017 11:06:58 BST
# gpg:                using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.9-20170403:
  pseries: Enforce homogeneous threads-per-core

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-03 11:15:33 +01:00
Marc-André Lureau fa03cb7fd2 vnc: allow to connect with add_client when -vnc none
Do not skip VNC initialization, in particular of auth method when vnc is
configured without sockets, since we should still allow connections
through QMP add_client.

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

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20170328160646.21250-1-marcandre.lureau@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2017-04-03 11:48:55 +02:00
Javier Celaya 1684907c92 Fix input-linux reading from device
The evdev devices in input-linux.c are read in blocks of one whole
event. If there are not enough bytes available, they are discarded,
instead of being kept for the next read operation. This results in
lost events, of even non-working devices.

This patch keeps track of the number of bytes to be read to fill up
a whole event, and then handle it.

Changes from v1 to v2:
- Fix: Calculate offset on each iteration

Changes from v2 to v3:
- Fix coding style
- Store offset instead of bytes to be read

Signed-off-by: Javier Celaya <jcelaya@gmail.com>
Message-id: 20170327182624.2914-1-jcelaya@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2017-04-03 11:44:58 +02:00
Gerd Hoffmann 243afe858b xhci: flush dequeue pointer to endpoint context
When done processing a endpoint ring we must update the dequeue pointer
in the endpoint context in guest memory.  This is needed to make sure
the guest has a correct view of things and also to make live migration
work properly, because xhci post_load restores alot of the state from
xhci data structures in guest memory.

Add xhci_set_ep_state() call to do that.

The recursive calls stopped by commit
ddb603ab6c had the (unintentional) side
effect to hiding this bug.  xhci_set_ep_state() was called before
processing, to set the state to running, which updated the dequeue
pointer too.

Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: 20170331102521.29253-1-kraxel@redhat.com
2017-04-03 11:40:57 +02:00
Peter Maydell 6954cdc070 Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging
# gpg: Signature made Sat 01 Apr 2017 02:23:29 BST
# gpg:                using RSA key 0xBDBE7B27C0DE3057
# gpg: Good signature from "Jeffrey Cody <jcody@redhat.com>"
# gpg:                 aka "Jeffrey Cody <jeff@codyprime.org>"
# gpg:                 aka "Jeffrey Cody <codyprime@gmail.com>"
# Primary key fingerprint: 9957 4B4D 3474 90E7 9D98  D624 BDBE 7B27 C0DE 3057

* remotes/cody/tags/block-pull-request:
  block/curl: Check protocol prefix
  qapi/curl: Extend and fix blockdev-add schema
  rbd: Fix regression in legacy key/values containing escaped :

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-03 10:09:58 +01:00
David Gibson 8149e2992f pseries: Enforce homogeneous threads-per-core
For reasons that may be useful in future, CPU core objects, as used on the
pseries machine type have their own nr-threads property, potentially
allowing cores with different numbers of threads in the same system.

If the user/management uses the values specified in query-hotpluggable-cpus
as they're expected to do, this will never matter in pratice.  But that's
not actually enforced - it's possible to manually specify a core with
a different number of threads from that in -smp.  That will confuse the
platform - most immediately, this can be used to create a CPU thread with
index above max_cpus which leads to an assertion failure in
spapr_cpu_core_realize().

For now, enforce that all cores must have the same, standard, number of
threads.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
2017-04-03 13:46:18 +10:00
yaolujing cc1e139139 nbd: fix memory leak on socket_connect failed
When TCP connection fails between nbd server and client,
the local var, sioc, memory leak.

This patch fixes the memory leak.

Signed-off-by: yaolujing <yaolujing@huawei.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1491005709-29989-1-git-send-email-yaolujing@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2017-04-02 21:18:21 +02:00
Corey Minyard cb9a05a4f1 ipmi: Fix macro issues
Macro parameters should almost always have () around them when used.
llvm reported an error on this.

Remove redundant parenthesis and put parenthesis around the entire
macros with assignments in case they are used in an expression.

Remove some unused macros.

Reported in https://bugs.launchpad.net/bugs/1651167

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <1490894892-8055-1-git-send-email-minyard@acm.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2017-04-02 21:17:47 +02:00
Tejaswini Poluri c7f15bc936 target-i386: fix "info lapic" segfault on isapc
Start QEMU with
"qemu-system-x86_64 -nographic -M isapc -serial none-monitor stdio"
and enter "info lapic" at the monitor prompt ⇒
Segmentation fault

Signed-off-by: Tejaswini Poluri <tejaswinipoluri3@gmail.com>
Message-Id: <1490685583-16987-1-git-send-email-tejaswinipoluri3@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2017-04-02 21:17:47 +02:00
Stefan Hajnoczi b9afaba891 iscsi: drop unused IscsiAIOCB.qiov field
The IscsiAIOCB.qiov field has been unused since commit
063c3378a9 ("block/iscsi: introduce
bdrv_co_{readv, writev, flush_to_disk}") back in 2013.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20170327165005.22038-1-stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2017-04-02 21:17:47 +02:00
Max Reitz 34634ca286 block/curl: Check protocol prefix
If the user has explicitly specified a block driver and thus a protocol,
we have to make sure the URL's protocol prefix matches. Otherwise the
latter will silently override the former which might catch some users by
surprise.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20170331120431.1767-3-mreitz@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
2017-03-31 15:53:22 -04:00
Max Reitz 6b9d62db89 qapi/curl: Extend and fix blockdev-add schema
The curl block driver accepts more options than just "filename"; also,
the URL is actually expected to be passed through the "url" option
instead of "filename".

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20170331120431.1767-2-mreitz@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
2017-03-31 15:52:58 -04:00
Eric Blake e98c6961c8 rbd: Fix regression in legacy key/values containing escaped :
Commit c7cacb3 accidentally broke legacy key-value parsing through
pseudo-filename parsing of -drive file=rbd://..., for any key that
contains an escaped ':'.  Such a key is surprisingly common, thanks
to mon_host specifying a 'host:port' string.  The break happens
because passing things from QDict through QemuOpts back to another
QDict requires that we pack our parsed key/value pairs into a string,
and then reparse that string, but the intermediate string that we
created ("key1=value1:key2=value2") lost the \: escaping that was
present in the original, so that we could no longer see which : were
used as separators vs. those used as part of the original input.

Fix it by collecting the key/value pairs through a QList, and
sending that list on a round trip through a JSON QString (as in
'["key1","value1","key2","value2"]') on its way through QemuOpts,
rather than hand-rolling our own string.  Since the string is only
handled internally, this was faster than creating a full-blown
struct of '[{"key1":"value1"},{"key2":"value2"}]', and safer at
guaranteeing order compared to '{"key1":"value1","key2":"value2"}'.

It would be nicer if we didn't have to round-trip through QemuOpts
in the first place, but that's a much bigger task for later.

Reproducer:
./x86_64-softmmu/qemu-system-x86_64 -nodefaults -nographic -qmp stdio \
-drive 'file=rbd:volumes/volume-ea141b5c-cdb3-4765-910d-e7008b209a70'\
':id=compute:key=AQAVkvxXAAAAABAA9ZxWFYdRmV+DSwKr7BKKXg=='\
':auth_supported=cephx\;none:mon_host=192.168.1.2\:6789'\
',format=raw,if=none,id=drive-virtio-disk0,'\
'serial=ea141b5c-cdb3-4765-910d-e7008b209a70,cache=writeback'

Even without an RBD setup, this serves a test of whether we get
the incorrect parser error of:
qemu-system-x86_64: -drive file=rbd:...cache=writeback: conf option 6789 has no value
or the correct behavior of hanging while trying to connect to
the requested mon_host of 192.168.1.2:6789.

Reported-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20170331152730.12514-1-eblake@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
2017-03-31 13:53:57 -04:00
Peter Maydell 95b31d709b Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20170331.0' into staging
VFIO fixes 2017-03-31

 - We can't disable stolen memory for UPT mode, it breaks Windows
   drivers on Gen9+ IGD (Xiong Zhang)

# gpg: Signature made Fri 31 Mar 2017 17:13:48 BST
# gpg:                using RSA key 0x239B9B6E3BB08B22
# gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>"
# gpg:                 aka "Alex Williamson <alex@shazbot.org>"
# gpg:                 aka "Alex Williamson <alwillia@redhat.com>"
# gpg:                 aka "Alex Williamson <alex.l.williamson@gmail.com>"
# Primary key fingerprint: 42F6 C04E 540B D1A9 9E7B  8A90 239B 9B6E 3BB0 8B22

* remotes/awilliam/tags/vfio-updates-20170331.0:
  Revert "vfio/pci-quirks.c: Disable stolen memory for igd VFIO"

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-31 18:06:13 +01:00
Xiong Zhang 93587e3af3 Revert "vfio/pci-quirks.c: Disable stolen memory for igd VFIO"
This reverts commit c2b2e158cc.

The original patch intend to prevent linux i915 driver from using
stolen meory. But this patch breaks windows IGD driver loading on
Gen9+, as IGD HW will use stolen memory on Gen9+, once windows IGD
driver see zero size stolen memory, it will unload.
Meanwhile stolen memory will be disabled in 915 when i915 run as
a guest.

Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com>
[aw: Gen9+ is SkyLake and newer]
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
2017-03-31 10:04:41 -06:00
Peter Maydell 37c4a85cd2 Merge remote-tracking branch 'remotes/dgilbert/tags/pull-hmp-20170331' into staging
HMP pull (one bugfix)

# gpg: Signature made Fri 31 Mar 2017 11:57:17 BST
# gpg:                using RSA key 0x0516331EBC5BFDE7
# gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 45F5 C71B 4A0C B7FB 977A  9FA9 0516 331E BC5B FDE7

* remotes/dgilbert/tags/pull-hmp-20170331:
  hmp: fix "dump-quest-memory" segfault

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-31 12:43:27 +01:00
Eric Auger e7d54416cf hw/intc/arm_gicv3_kvm: Check KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS in reset
KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS needs to be checked before
attempting to read ICC_CTLR_EL1; otherwise kernel versions not
exposing this kvm device group will be incompatible with qemu 2.9.

Fixes: 07a5628  ("hw/intc/arm_gicv3_kvm: Reset GICv3 cpu interface registers")
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reported-by: Prakash B <bjsprakash.linux@gmail.com>
Tested-by: Alexander Graf <agraf@suse.de>
Message-id: 1490721640-13052-1-git-send-email-eric.auger@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-31 12:41:14 +01:00
Iwona Kotlarska fd5d23babf hmp: fix "dump-quest-memory" segfault
Running QEMU with "qemu-system-x86_64 -M none -nographic -m 256" and executing
"dump-guest-memory /dev/null 0 8192" results in segfault.
Fix by checking if we have CPU.

Signed-off-by: Iwona Kotlarska <iwona260909@gmail.com>
Message-Id: <20170330050924.22134-1-iwona260909@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
   Fixed up title
2017-03-31 11:53:42 +01:00
Peter Maydell 05a6f451eb Merge remote-tracking branch 'remotes/mdroth/tags/qga-pull-2017-03-30-tag' into staging
qemu-ga patch queue for 2.9

* fix make check failure of guest-get-fsinfo when nested virtual block
  device partitions are mounted in the test environment
* fix static compilation for mingw builds

# gpg: Signature made Fri 31 Mar 2017 04:52:40 BST
# gpg:                using RSA key 0x3353C9CEF108B584
# gpg: Good signature from "Michael Roth <flukshun@gmail.com>"
# gpg:                 aka "Michael Roth <mdroth@utexas.edu>"
# gpg:                 aka "Michael Roth <mdroth@linux.vnet.ibm.com>"
# Primary key fingerprint: CEAC C9E1 5534 EBAB B82D  3FA0 3353 C9CE F108 B584

* remotes/mdroth/tags/qga-pull-2017-03-30-tag:
  qga: Make qemu-ga compile statically for Windows
  qga: don't fail if mount doesn't have slave devices

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-31 11:09:51 +01:00
Peter Maydell a0ee3797bf Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
# gpg: Signature made Fri 31 Mar 2017 01:50:55 BST
# gpg:                using RSA key 0xEF04965B398D6211
# gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 215D 46F4 8246 689E C77F  3562 EF04 965B 398D 6211

* remotes/jasowang/tags/net-pull-request:
  e1000: disable debug by default
  virtio-net: avoid call tap_enable when there's only one queue

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-31 10:09:42 +01:00
Sameeh Jubran 4eaf720294 qga: Make qemu-ga compile statically for Windows
Attempting to compile qemu-ga statically as follows for Windows causes
the following error:

Compilation:
    ./configure --disable-docs --target-list=x86_64-softmmu \
    --cross-prefix=x86_64-w64-mingw32- --static \
    --enable-guest-agent-msi --with-vss-sdk=/path/to/VSSSDK72

    make -j8 qemu-ga

Error:
    path/to/qemu/stubs/error-printf.c:7: undefined reference to `__imp_g_test_config_vars'
    collect2: error: ld returned 1 exit status
    Makefile:444: recipe for target 'qemu-ga.exe' failed
    make: *** [qemu-ga.exe] Error 1

This is caused by a bug in the pkg-config file for glib as it doesn't define
GLIB_STATIC_COMPILATION for pkg-config --static.

Signed-off-by: Sameeh Jubran <sameeh@daynix.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2017-03-30 21:47:25 -05:00
Jason Wang b4053c6483 e1000: disable debug by default
Disable debug output by default, the information were not needed for
release.

Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Stefan Hajnoczi <stefanha@gmail.com>
Cc: Leonid Bloch <leonid.bloch@ravellosystems.com>
Cc: Dmitry Fleytman <dmitry.fleytman@ravellosystems.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2017-03-31 08:48:13 +08:00
Jason Wang 1074b879d1 virtio-net: avoid call tap_enable when there's only one queue
We call tap_enable() even if for multiqueue is not enabled. This is
wrong since it should be used for multiqueue codes to enable a
disabled queue. Fixing this by only calling this when multiqueue is
used.

Fixes: 16dbaf905b ("tap: support enabling or disabling a queue")
Reported-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Tested-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
2017-03-31 08:48:13 +08:00
Michael Roth 8251a72f8b qga: don't fail if mount doesn't have slave devices
In some cases the slave devices of a virtual block device are tracked
by the parent in the corresponding sysfs node. For instance, if we
have a loop-back mount of the form:

  /dev/loop3p1 on /home/mdroth/mnt type ext4 (rw,relatime,data=ordered)

this will be reflected in sysfs as:

  /sys/devices/virtual/block/loop3/
  ...
  /sys/devices/virtual/block/loop3/slaves
  /sys/devices/virtual/block/loop3/loop3p1

The current code however assumes the mounted virtual block device,
loop3p1 in this case, contains the slaves directory, and reports an
error otherwise. This breaks 'make check' in certain environments.

Fix this by simply skipping attempts to generate disk topology
information in these cases. Since this information is documented
in QAPI as optionally-reported, this should be ok from an API
perspective.

In the future, this can possibly be improved upon by collecting
topology information from the parent in these cases.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Tested-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-30 14:12:57 -05:00
Peter Maydell ddc2c3a57e Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
vhost, pc: fixes

More fixes for 2.9. Region caching is still causing
issues around reset, but we seem to be getting there.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Thu 30 Mar 2017 17:14:45 BST
# gpg:                using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream:
  tests/acpi: don't pack a structure
  vhost: generalize iommu memory region

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-30 18:02:33 +01:00
Michael S. Tsirkin 0d876080a3 tests/acpi: don't pack a structure
There's no reason to pack structures where we don't care about size or
padding, this applies to AcpiStdTable in tests/acpi-utils.h.

OTOH bios-tables-test happens to be passing the address of a field in
this  struct to a function that expects a pointer to normally aligned
data which results in a SIGBUS on architectures like SPARC that have
strict alignment requirements.

Fixes: 9e8458c02 ("acpi unit-test: compare DSDT and SSDT tables against expected values")
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-30 19:12:44 +03:00
Jason Wang 375f74f473 vhost: generalize iommu memory region
We assumes the iommu_ops were attached to the root region of address
space. This may not be true for all kinds of IOMMU implementation and
especially after commit 3716d5902d ("pci: introduce a bus master
container"). So fix this by not assuming as->root has iommu_ops,
instead depending on the regions reported by memory listener through:

- register a memory listener to dma_as
- during region_add, if it's a region of IOMMU, register a specific
  IOMMU notifier, and store all notifiers in a list.
- during region_del, compare and delete the IOMMU notifier from the list

This is also a must for making vhost device IOTLB works for all types
of IOMMUs. Note, since we register one notifier during each
.region_add, the IOTLB may be flushed more than one times, this is
suboptimal and could be optimized in the future.

Reported-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Fixes: 3716d5902d ("pci: introduce a bus master container")
Cc: Peter Xu <peterx@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Tested-by: Maxime Coquelin <maxime.coquelin@redhat.com>
2017-03-30 19:09:16 +03:00
Peter Maydell e839001d5b Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging
slirp updates

# gpg: Signature made Tue 28 Mar 2017 23:51:51 BST
# gpg:                using RSA key 0xB0A51BF58C9179C5
# gpg: Good signature from "Samuel Thibault <samuel.thibault@aquilenet.fr>"
# gpg:                 aka "Samuel Thibault <sthibault@debian.org>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@gnu.org>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@inria.fr>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@labri.fr>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@ens-lyon.org>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@u-bordeaux.fr>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 900C B024 B679 31D4 0F82  304B D017 8C76 7D06 9EE6
#      Subkey fingerprint: AEBF 7448 FAB9 453A 4552  390E B0A5 1BF5 8C91 79C5

* remotes/thibault/tags/samuel-thibault:
  slirp: Send RDNSS in RA only if host has an IPv6 DNS server
  slirp: Make RA build more flexible
  slirp: fix compilation errors with DEBUG set

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-30 15:28:19 +01:00
Peter Maydell a67ec6ee2d Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.9-20170329' into staging
ppc patch queue for 2017-03-29

Two more bugfixes of sufficient severity to warrant going into 2.9.

# gpg: Signature made Wed 29 Mar 2017 04:33:19 BST
# gpg:                using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.9-20170329:
  spapr: fix memory hot-unplugging
  spapr: fix buffer-overflow

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-30 14:53:03 +01:00
Peter Maydell e68dd68496 Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio, pci: fixes

More fixes for 2.9.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Wed 29 Mar 2017 00:35:49 BST
# gpg:                using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream:
  virtio: fix vring_align() on 64-bit windows
  pci: Add missing drop of bus master AS reference
  event_notifier: prevent accidental use after close

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-30 13:55:40 +01:00
Peter Maydell fb59dabd4f configure: Don't claim 'unsupported host OS' when better message available
The change in commit 898be3e041 which made completely
unrecognized OSes cause an error_exit "Unsupported host OS"
has some unfortunate unintended effects:
 * if you run 'configure --help' on an unsupported host OS
   (eg if intending to use it as a build machine for a
   cross compile to a supported host) then the message
   is printed instead of --help
 * if the C compiler doesn't work or is missing (eg if
   you passed an incorrect --cross-prefix by mistake)
   the message is printed instead of the more useful
   'compiler does not exist or does not work' message

Fix this by postponing the error_exit in this situation
until later, when we have already identified the more
useful cases for this.

The long term fix for this would be to move handling
of --help much further up in the configure script,
and make its output not dependent on checks that configure
runs. However for 2.9 this would be too invasive.

Reported-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Tested-by: Stefan Weil <sw@weilnetz.de>
2017-03-30 12:47:03 +01:00
Peter Maydell b529aec1ee Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging
i386: Fix for "-cpu host,invtsc=on" bug

# gpg: Signature made Tue 28 Mar 2017 20:50:33 BST
# gpg:                using RSA key 0x2807936F984DC5A6
# 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-pull-request:
  i386: Don't override -cpu options on -cpu host/max
  i386: Replace uint32_t* with FeatureWord on feature getter/setter

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-03-30 09:58:46 +01:00
Laurent Vivier fe6824d126 spapr: fix memory hot-unplugging
If, once the kernel has booted, we try to remove a memory
hotplugged while the kernel was not started, QEMU crashes on
an assert:

    qemu-system-ppc64: hw/virtio/vhost.c:651:
                       vhost_commit: Assertion `r >= 0' failed.
    ...
    #4  in vhost_commit
    #5  in memory_region_transaction_commit
    #6  in pc_dimm_memory_unplug
    #7  in spapr_memory_unplug
    #8  spapr_machine_device_unplug
    #9  in hotplug_handler_unplug
    #10 in spapr_lmb_release
    #11 in detach
    #12 in set_allocation_state
    #13 in rtas_set_indicator
    ...

If we take a closer look to the guest kernel log, we can see when
we try to unplug the memory:

    pseries-hotplug-mem: Attempting to hot-add 4 LMB(s)

What happens:

    1- The kernel has ignored the memory hotplug event because
       it was not started when it was generated.

    2- When we hot-unplug the memory,
       QEMU starts to remove the memory,
            generates an hot-unplug event,
        and signals the kernel of the incoming new event

    3- as the kernel is started, on the QEMU signal, it reads
       the event list, decodes the hotplug event and tries to
       finish the hotplugging.

    4- QEMU receive the the hotplug notification while it
       is trying to hot-unplug the memory. This moves the memory
       DRC to an invalid state

This patch prevents this by not allowing to set the allocation
state to USABLE while the DRC is awaiting release.

RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1432382

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-03-29 11:35:16 +11:00
Marc-André Lureau 24ec2863b1 spapr: fix buffer-overflow
Running postcopy-test with ASAN produces the following error:

QTEST_QEMU_BINARY=ppc64-softmmu/qemu-system-ppc64  tests/postcopy-test
...
=================================================================
==23641==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f1556600000 at pc 0x55b8e9d28208 bp 0x7f1555f4d3c0 sp 0x7f1555f4d3b0
READ of size 8 at 0x7f1556600000 thread T6
    #0 0x55b8e9d28207 in htab_save_first_pass /home/elmarco/src/qq/hw/ppc/spapr.c:1528
    #1 0x55b8e9d2939c in htab_save_iterate /home/elmarco/src/qq/hw/ppc/spapr.c:1665
    #2 0x55b8e9beae3a in qemu_savevm_state_iterate /home/elmarco/src/qq/migration/savevm.c:1044
    #3 0x55b8ea677733 in migration_thread /home/elmarco/src/qq/migration/migration.c:1976
    #4 0x7f15845f46c9 in start_thread (/lib64/libpthread.so.0+0x76c9)
    #5 0x7f157d9d0f7e in clone (/lib64/libc.so.6+0x107f7e)

0x7f1556600000 is located 0 bytes to the right of 2097152-byte region [0x7f1556400000,0x7f1556600000)
allocated by thread T0 here:
    #0 0x7f159bb76980 in posix_memalign (/lib64/libasan.so.3+0xc7980)
    #1 0x55b8eab185b2 in qemu_try_memalign /home/elmarco/src/qq/util/oslib-posix.c:106
    #2 0x55b8eab186c8 in qemu_memalign /home/elmarco/src/qq/util/oslib-posix.c:122
    #3 0x55b8e9d268a8 in spapr_reallocate_hpt /home/elmarco/src/qq/hw/ppc/spapr.c:1214
    #4 0x55b8e9d26e04 in ppc_spapr_reset /home/elmarco/src/qq/hw/ppc/spapr.c:1261
    #5 0x55b8ea12e913 in qemu_system_reset /home/elmarco/src/qq/vl.c:1697
    #6 0x55b8ea13fa40 in main /home/elmarco/src/qq/vl.c:4679
    #7 0x7f157d8e9400 in __libc_start_main (/lib64/libc.so.6+0x20400)

Thread T6 created by T0 here:
    #0 0x7f159bae0488 in __interceptor_pthread_create (/lib64/libasan.so.3+0x31488)
    #1 0x55b8eab1d9cb in qemu_thread_create /home/elmarco/src/qq/util/qemu-thread-posix.c:465
    #2 0x55b8ea67874c in migrate_fd_connect /home/elmarco/src/qq/migration/migration.c:2096
    #3 0x55b8ea66cbb0 in migration_channel_connect /home/elmarco/src/qq/migration/migration.c:500
    #4 0x55b8ea678f38 in socket_outgoing_migration /home/elmarco/src/qq/migration/socket.c:87
    #5 0x55b8eaa5a03a in qio_task_complete /home/elmarco/src/qq/io/task.c:142
    #6 0x55b8eaa599cc in gio_task_thread_result /home/elmarco/src/qq/io/task.c:88
    #7 0x7f15823e38e6  (/lib64/libglib-2.0.so.0+0x468e6)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/elmarco/src/qq/hw/ppc/spapr.c:1528 in htab_save_first_pass

index seems to be wrongly incremented, unless I miss something that
would be worth a comment.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2017-03-29 11:35:02 +11:00
Andrew Baumann b8adbc6578 virtio: fix vring_align() on 64-bit windows
long is 32-bits on 64-bit windows, which caused the top half of the
address to be truncated; this patch changes it to use the
QEMU_ALIGN_UP macro which does not suffer the same problem

Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2017-03-29 02:35:24 +03:00
Alexey Kardashevskiy c53598ed18 pci: Add missing drop of bus master AS reference
The recent introduction of a bus master container added
memory_region_add_subregion() into the PCI device registering path but
missed memory_region_del_subregion() in the unregistering path leaving
a reference to the root memory region of the new container.

This adds missing memory_region_del_subregion().

Fixes: 3716d5902d ("pci: introduce a bus master container")
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
2017-03-29 02:35:23 +03:00
Halil Pasic aa26292859 event_notifier: prevent accidental use after close
Let's set the handles to the underlying facilities to their extremal
value so no accidental misuse can happen, and to make it obvious that the
notifier is dysfunctional. E.g. if we just close an fd but do not touch
the int holding the fd eventually a read/write could succeed again when
the fd gets reused, and corrupt the file addressed by the fd.

Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2017-03-29 02:35:23 +03:00
Samuel Thibault a2f80fdfc6 slirp: Send RDNSS in RA only if host has an IPv6 DNS server
Previously we would always send an RDNSS option in the RA, making the guest
try to resolve DNS through IPv6, even if the host does not actually have
and IPv6 DNS server available.

This makes the RDNSS option enabled only when an IPv6 DNS server is
available.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2017-03-29 00:51:25 +02:00
Samuel Thibault e42f869b51 slirp: Make RA build more flexible
Do not hardcode the RA size at all, use a pl_size variable which
accounts the accumulated size, and fill rip->ip_pl at the end.

This will allow to make some blocks optional.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
2017-03-29 00:49:04 +02:00
Laurent Vivier 51149a2ac1 slirp: fix compilation errors with DEBUG set
slirp/slirp.c: In function 'get_dns_addr_resolv_conf':
slirp/slirp.c:202:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
                 char *res = inet_ntop(af, tmp_addr, s, sizeof(s));
                             ^~~~~~~~~
slirp/slirp.c:204:25: error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
                     res = "(string conversion error)";

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
2017-03-29 00:49:04 +02:00
Eduardo Habkost d4a606b38b i386: Don't override -cpu options on -cpu host/max
The existing code for "host" and "max" CPU models overrides every
single feature in the CPU object at realize time, even the ones
that were explicitly enabled or disabled by the user using
"feat=on" or "feat=off", while features set using +feat/-feat are
kept.

This means "-cpu host,+invtsc" works as expected, while
"-cpu host,invtsc=on" doesn't.

This was a known bug, already documented in a comment inside
x86_cpu_expand_features(). What makes this bug worse now is that
libvirt 3.0.0 and newer now use "feat=on|off" instead of
+feat/-feat when it detects a QEMU version that supports it (see
libvirt commit d47db7b16dd5422c7e487c8c8ee5b181a2f9cd66).

Change the feature property getter/setter to set a
env->user_features field, to keep track of features that were
explicitly changed using QOM properties. Then make the
max_features code not override user features when handling "-cpu
host" and "-cpu max".

This will also allow us to remove the plus_features/minus_features
hack in the future, but I plan to do that after 2.9.0 is
released.

Reported-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170327144815.8043-3-ehabkost@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Tested-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2017-03-28 16:41:10 -03:00
Eduardo Habkost a7b0ffacc1 i386: Replace uint32_t* with FeatureWord on feature getter/setter
Instead of passing a pointer to the feature property getter and
setter functions, pass a FeatureWord enum so they can perform
other actions related to the feature flag.

This will be used to add a new "user_features" field to keep
track of features that were explicitly set by the user.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170327144815.8043-2-ehabkost@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Tested-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2017-03-28 16:40:50 -03:00
251 changed files with 3429 additions and 1556 deletions

No files matched your search

+1
View File
@@ -1395,6 +1395,7 @@ S: Supported
F: qobject/
F: include/qapi/qmp/
X: include/qapi/qmp/dispatch.h
F: scripts/coccinelle/qobject.cocci
F: tests/check-qdict.c
F: tests/check-qfloat.c
F: tests/check-qint.c
+1 -1
View File
@@ -1 +1 @@
2.8.92
2.9.1
+2
View File
@@ -2028,6 +2028,8 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
sw = sw1;
}
QLIST_REMOVE (cap, entries);
g_free (cap->hw.mix_buf);
g_free (cap->buf);
g_free (cap);
}
return;
+97 -55
View File
@@ -937,16 +937,14 @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
static void update_options_from_flags(QDict *options, int flags)
{
if (!qdict_haskey(options, BDRV_OPT_CACHE_DIRECT)) {
qdict_put(options, BDRV_OPT_CACHE_DIRECT,
qbool_from_bool(flags & BDRV_O_NOCACHE));
qdict_put_bool(options, BDRV_OPT_CACHE_DIRECT, flags & BDRV_O_NOCACHE);
}
if (!qdict_haskey(options, BDRV_OPT_CACHE_NO_FLUSH)) {
qdict_put(options, BDRV_OPT_CACHE_NO_FLUSH,
qbool_from_bool(flags & BDRV_O_NO_FLUSH));
qdict_put_bool(options, BDRV_OPT_CACHE_NO_FLUSH,
flags & BDRV_O_NO_FLUSH);
}
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
qdict_put(options, BDRV_OPT_READ_ONLY,
qbool_from_bool(!(flags & BDRV_O_RDWR)));
qdict_put_bool(options, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
}
}
@@ -1157,10 +1155,17 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
if (file != NULL) {
filename = blk_bs(file)->filename;
} else {
/*
* Caution: while qdict_get_try_str() is fine, getting
* non-string types would require more care. When @options
* come from -blockdev or blockdev_add, its members are typed
* according to the QAPI schema, but when they come from
* -drive, they're all QString.
*/
filename = qdict_get_try_str(options, "filename");
}
if (drv->bdrv_needs_filename && !filename) {
if (drv->bdrv_needs_filename && (!filename || !filename[0])) {
error_setg(errp, "The '%s' block driver requires a file name",
drv->format_name);
ret = -EINVAL;
@@ -1324,6 +1329,13 @@ static int bdrv_fill_options(QDict **options, const char *filename,
BlockDriver *drv = NULL;
Error *local_err = NULL;
/*
* Caution: while qdict_get_try_str() is fine, getting non-string
* types would require more care. When @options come from
* -blockdev or blockdev_add, its members are typed according to
* the QAPI schema, but when they come from -drive, they're all
* QString.
*/
drvname = qdict_get_try_str(*options, "driver");
if (drvname) {
drv = bdrv_find_format(drvname);
@@ -1348,7 +1360,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
/* Fetch the file name from the options QDict if necessary */
if (protocol && filename) {
if (!qdict_haskey(*options, "filename")) {
qdict_put(*options, "filename", qstring_from_str(filename));
qdict_put_str(*options, "filename", filename);
parse_filename = true;
} else {
error_setg(errp, "Can't specify 'file' and 'filename' options at "
@@ -1358,6 +1370,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
}
/* Find the right block driver */
/* See cautionary note on accessing @options above */
filename = qdict_get_try_str(*options, "filename");
if (!drvname && protocol) {
@@ -1368,7 +1381,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
}
drvname = drv->format_name;
qdict_put(*options, "driver", qstring_from_str(drvname));
qdict_put_str(*options, "driver", drvname);
} else {
error_setg(errp, "Must specify either driver or file");
return -EINVAL;
@@ -1737,6 +1750,9 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
{
BlockDriverState *old_bs = child->bs;
if (old_bs && new_bs) {
assert(bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs));
}
if (old_bs) {
if (old_bs->quiesce_counter && child->role->drained_end) {
child->role->drained_end(child);
@@ -1837,6 +1853,7 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm);
assert(parent_bs->drv);
assert(bdrv_get_aio_context(parent_bs) == bdrv_get_aio_context(child_bs));
parent_bs->drv->bdrv_child_perm(parent_bs, NULL, child_role,
perm, shared_perm, &perm, &shared_perm);
@@ -1987,6 +2004,13 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
qdict_extract_subqdict(parent_options, &options, bdref_key_dot);
g_free(bdref_key_dot);
/*
* Caution: while qdict_get_try_str() is fine, getting non-string
* types would require more care. When @parent_options come from
* -blockdev or blockdev_add, its members are typed according to
* the QAPI schema, but when they come from -drive, they're all
* QString.
*/
reference = qdict_get_try_str(parent_options, bdref_key);
if (reference || qdict_haskey(options, "file.filename")) {
backing_filename[0] = '\0';
@@ -2012,7 +2036,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
}
if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
qdict_put(options, "driver", qstring_from_str(bs->backing_format));
qdict_put_str(options, "driver", bs->backing_format);
}
backing_hd = bdrv_open_inherit(*backing_filename ? backing_filename : NULL,
@@ -2059,6 +2083,13 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
qdict_extract_subqdict(options, &image_options, bdref_key_dot);
g_free(bdref_key_dot);
/*
* Caution: while qdict_get_try_str() is fine, getting non-string
* types would require more care. When @options come from
* -blockdev or blockdev_add, its members are typed according to
* the QAPI schema, but when they come from -drive, they're all
* QString.
*/
reference = qdict_get_try_str(options, bdref_key);
if (!filename && !reference && !qdict_size(image_options)) {
if (!allow_none) {
@@ -2160,12 +2191,9 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
}
/* Prepare options QDict for the temporary file */
qdict_put(snapshot_options, "file.driver",
qstring_from_str("file"));
qdict_put(snapshot_options, "file.filename",
qstring_from_str(tmp_filename));
qdict_put(snapshot_options, "driver",
qstring_from_str("qcow2"));
qdict_put_str(snapshot_options, "file.driver", "file");
qdict_put_str(snapshot_options, "file.filename", tmp_filename);
qdict_put_str(snapshot_options, "driver", "qcow2");
bs_snapshot = bdrv_open(NULL, NULL, snapshot_options, flags, errp);
snapshot_options = NULL;
@@ -2274,9 +2302,13 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
goto fail;
}
/* Set the BDRV_O_RDWR and BDRV_O_ALLOW_RDWR flags.
* FIXME: we're parsing the QDict to avoid having to create a
* QemuOpts just for this, but neither option is optimal. */
/*
* Set the BDRV_O_RDWR and BDRV_O_ALLOW_RDWR flags.
* Caution: getting a boolean member of @options requires care.
* When @options come from -blockdev or blockdev_add, members are
* typed according to the QAPI schema, but when they come from
* -drive, they're all QString.
*/
if (g_strcmp0(qdict_get_try_str(options, BDRV_OPT_READ_ONLY), "on") &&
!qdict_get_try_bool(options, BDRV_OPT_READ_ONLY, false)) {
flags |= (BDRV_O_RDWR | BDRV_O_ALLOW_RDWR);
@@ -2298,6 +2330,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
options = qdict_clone_shallow(options);
/* Find the right image format driver */
/* See cautionary note on accessing @options above */
drvname = qdict_get_try_str(options, "driver");
if (drvname) {
drv = bdrv_find_format(drvname);
@@ -2309,6 +2342,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
assert(drvname || !(flags & BDRV_O_PROTOCOL));
/* See cautionary note on accessing @options above */
backing = qdict_get_try_str(options, "backing");
if (backing && *backing == '\0') {
flags |= BDRV_O_NO_BACKING;
@@ -2334,8 +2368,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
goto fail;
}
qdict_put(options, "file",
qstring_from_str(bdrv_get_node_name(file_bs)));
qdict_put_str(options, "file", bdrv_get_node_name(file_bs));
}
}
@@ -2357,8 +2390,8 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
* sure to update both bs->options (which has the full effective
* options for bs) and options (which has file.* already removed).
*/
qdict_put(bs->options, "driver", qstring_from_str(drv->format_name));
qdict_put(options, "driver", qstring_from_str(drv->format_name));
qdict_put_str(bs->options, "driver", drv->format_name);
qdict_put_str(options, "driver", drv->format_name);
} else if (!drv) {
error_setg(errp, "Must specify either driver or file");
goto fail;
@@ -2733,12 +2766,12 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
* that they are checked at the end of this function. */
value = qemu_opt_get(opts, "node-name");
if (value) {
qdict_put(reopen_state->options, "node-name", qstring_from_str(value));
qdict_put_str(reopen_state->options, "node-name", value);
}
value = qemu_opt_get(opts, "driver");
if (value) {
qdict_put(reopen_state->options, "driver", qstring_from_str(value));
qdict_put_str(reopen_state->options, "driver", value);
}
/* if we are to stay read-only, do not allow permission change
@@ -2787,6 +2820,13 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
do {
QString *new_obj = qobject_to_qstring(entry->value);
const char *new = qstring_get_str(new_obj);
/*
* Caution: while qdict_get_try_str() is fine, getting
* non-string types would require more care. When
* bs->options come from -blockdev or blockdev_add, its
* members are typed according to the QAPI schema, but
* when they come from -drive, they're all QString.
*/
const char *old = qdict_get_try_str(reopen_state->bs->options,
entry->key);
@@ -3222,20 +3262,30 @@ exit:
/**
* Truncate file to 'offset' bytes (needed only for file protocols)
*/
int bdrv_truncate(BdrvChild *child, int64_t offset)
int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp)
{
BlockDriverState *bs = child->bs;
BlockDriver *drv = bs->drv;
int ret;
assert(child->perm & BLK_PERM_RESIZE);
/* FIXME: Some format block drivers use this function instead of implicitly
* growing their file by writing beyond its end.
* See bdrv_aligned_pwritev() for an explanation why we currently
* cannot assert this permission in that case. */
// assert(child->perm & BLK_PERM_RESIZE);
if (!drv)
if (!drv) {
error_setg(errp, "No medium inserted");
return -ENOMEDIUM;
if (!drv->bdrv_truncate)
}
if (!drv->bdrv_truncate) {
error_setg(errp, "Image format driver does not support resize");
return -ENOTSUP;
if (bs->read_only)
}
if (bs->read_only) {
error_setg(errp, "Image is read-only");
return -EACCES;
}
ret = drv->bdrv_truncate(bs, offset);
if (ret == 0) {
@@ -3243,6 +3293,8 @@ int bdrv_truncate(BdrvChild *child, int64_t offset)
bdrv_dirty_bitmap_truncate(bs);
bdrv_parent_cb_resize(bs);
++bs->write_gen;
} else {
error_setg_errno(errp, -ret, "Failed to resize image");
}
return ret;
}
@@ -3811,19 +3863,6 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
return retval;
}
int bdrv_get_backing_file_depth(BlockDriverState *bs)
{
if (!bs->drv) {
return 0;
}
if (!bs->backing) {
return 0;
}
return 1 + bdrv_get_backing_file_depth(bs->backing->bs);
}
void bdrv_init(void)
{
module_call_init(MODULE_INIT_BLOCK);
@@ -4218,8 +4257,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
if (backing_fmt) {
backing_options = qdict_new();
qdict_put(backing_options, "driver",
qstring_from_str(backing_fmt));
qdict_put_str(backing_options, "driver", backing_fmt);
}
bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
@@ -4278,6 +4316,11 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs)
return bs->aio_context;
}
void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co)
{
aio_co_enter(bdrv_get_aio_context(bs), co);
}
static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
{
QLIST_REMOVE(ban, list);
@@ -4350,11 +4393,12 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
{
AioContext *ctx;
AioContext *ctx = bdrv_get_aio_context(bs);
aio_disable_external(ctx);
bdrv_parent_drained_begin(bs);
bdrv_drain(bs); /* ensure there are no in-flight requests */
ctx = bdrv_get_aio_context(bs);
while (aio_poll(ctx, false)) {
/* wait for all bottom halves to execute */
}
@@ -4366,6 +4410,8 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
*/
aio_context_acquire(new_context);
bdrv_attach_aio_context(bs, new_context);
bdrv_parent_drained_end(bs);
aio_enable_external(ctx);
aio_context_release(new_context);
}
@@ -4616,11 +4662,9 @@ void bdrv_refresh_filename(BlockDriverState *bs)
* contain a representation of the filename, therefore the following
* suffices without querying the (exact_)filename of this BDS. */
if (bs->file->bs->full_open_options) {
qdict_put_obj(opts, "driver",
QOBJECT(qstring_from_str(drv->format_name)));
qdict_put_str(opts, "driver", drv->format_name);
QINCREF(bs->file->bs->full_open_options);
qdict_put_obj(opts, "file",
QOBJECT(bs->file->bs->full_open_options));
qdict_put(opts, "file", bs->file->bs->full_open_options);
bs->full_open_options = opts;
} else {
@@ -4636,8 +4680,7 @@ void bdrv_refresh_filename(BlockDriverState *bs)
opts = qdict_new();
append_open_options(opts, bs);
qdict_put_obj(opts, "driver",
QOBJECT(qstring_from_str(drv->format_name)));
qdict_put_str(opts, "driver", drv->format_name);
if (bs->exact_filename[0]) {
/* This may not work for all block protocol drivers (some may
@@ -4647,8 +4690,7 @@ void bdrv_refresh_filename(BlockDriverState *bs)
* needs some special format of the options QDict, it needs to
* implement the driver-specific bdrv_refresh_filename() function.
*/
qdict_put_obj(opts, "filename",
QOBJECT(qstring_from_str(bs->exact_filename)));
qdict_put_str(opts, "filename", bs->exact_filename);
}
bs->full_open_options = opts;
+231 -59
View File
@@ -1,6 +1,7 @@
/*
* Block protocol for I/O error injection
*
* Copyright (C) 2016-2017 Red Hat, Inc.
* Copyright (c) 2010 Kevin Wolf <kwolf@redhat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -37,7 +38,12 @@
typedef struct BDRVBlkdebugState {
int state;
int new_state;
int align;
uint64_t align;
uint64_t max_transfer;
uint64_t opt_write_zero;
uint64_t max_write_zero;
uint64_t opt_discard;
uint64_t max_discard;
/* For blkdebug_refresh_filename() */
char *config_file;
@@ -301,7 +307,7 @@ static void blkdebug_parse_filename(const char *filename, QDict *options,
if (!strstart(filename, "blkdebug:", &filename)) {
/* There was no prefix; therefore, all options have to be already
present in the QDict (except for the filename) */
qdict_put(options, "x-image", qstring_from_str(filename));
qdict_put_str(options, "x-image", filename);
return;
}
@@ -320,7 +326,7 @@ static void blkdebug_parse_filename(const char *filename, QDict *options,
/* TODO Allow multi-level nesting and set file.filename here */
filename = c + 1;
qdict_put(options, "x-image", qstring_from_str(filename));
qdict_put_str(options, "x-image", filename);
}
static QemuOptsList runtime_opts = {
@@ -342,6 +348,31 @@ static QemuOptsList runtime_opts = {
.type = QEMU_OPT_SIZE,
.help = "Required alignment in bytes",
},
{
.name = "max-transfer",
.type = QEMU_OPT_SIZE,
.help = "Maximum transfer size in bytes",
},
{
.name = "opt-write-zero",
.type = QEMU_OPT_SIZE,
.help = "Optimum write zero alignment in bytes",
},
{
.name = "max-write-zero",
.type = QEMU_OPT_SIZE,
.help = "Maximum write zero size in bytes",
},
{
.name = "opt-discard",
.type = QEMU_OPT_SIZE,
.help = "Optimum discard alignment in bytes",
},
{
.name = "max-discard",
.type = QEMU_OPT_SIZE,
.help = "Maximum discard size in bytes",
},
{ /* end of list */ }
},
};
@@ -352,8 +383,8 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
BDRVBlkdebugState *s = bs->opaque;
QemuOpts *opts;
Error *local_err = NULL;
uint64_t align;
int ret;
uint64_t align;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
@@ -382,21 +413,69 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
goto out;
}
/* Set request alignment */
align = qemu_opt_get_size(opts, "align", 0);
if (align < INT_MAX && is_power_of_2(align)) {
s->align = align;
} else if (align) {
error_setg(errp, "Invalid alignment");
ret = -EINVAL;
goto fail_unref;
bs->supported_write_flags = BDRV_REQ_FUA &
bs->file->bs->supported_write_flags;
bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
bs->file->bs->supported_zero_flags;
ret = -EINVAL;
/* Set alignment overrides */
s->align = qemu_opt_get_size(opts, "align", 0);
if (s->align && (s->align >= INT_MAX || !is_power_of_2(s->align))) {
error_setg(errp, "Cannot meet constraints with align %" PRIu64,
s->align);
goto out;
}
align = MAX(s->align, bs->file->bs->bl.request_alignment);
s->max_transfer = qemu_opt_get_size(opts, "max-transfer", 0);
if (s->max_transfer &&
(s->max_transfer >= INT_MAX ||
!QEMU_IS_ALIGNED(s->max_transfer, align))) {
error_setg(errp, "Cannot meet constraints with max-transfer %" PRIu64,
s->max_transfer);
goto out;
}
s->opt_write_zero = qemu_opt_get_size(opts, "opt-write-zero", 0);
if (s->opt_write_zero &&
(s->opt_write_zero >= INT_MAX ||
!QEMU_IS_ALIGNED(s->opt_write_zero, align))) {
error_setg(errp, "Cannot meet constraints with opt-write-zero %" PRIu64,
s->opt_write_zero);
goto out;
}
s->max_write_zero = qemu_opt_get_size(opts, "max-write-zero", 0);
if (s->max_write_zero &&
(s->max_write_zero >= INT_MAX ||
!QEMU_IS_ALIGNED(s->max_write_zero,
MAX(s->opt_write_zero, align)))) {
error_setg(errp, "Cannot meet constraints with max-write-zero %" PRIu64,
s->max_write_zero);
goto out;
}
s->opt_discard = qemu_opt_get_size(opts, "opt-discard", 0);
if (s->opt_discard &&
(s->opt_discard >= INT_MAX ||
!QEMU_IS_ALIGNED(s->opt_discard, align))) {
error_setg(errp, "Cannot meet constraints with opt-discard %" PRIu64,
s->opt_discard);
goto out;
}
s->max_discard = qemu_opt_get_size(opts, "max-discard", 0);
if (s->max_discard &&
(s->max_discard >= INT_MAX ||
!QEMU_IS_ALIGNED(s->max_discard,
MAX(s->opt_discard, align)))) {
error_setg(errp, "Cannot meet constraints with max-discard %" PRIu64,
s->max_discard);
goto out;
}
ret = 0;
goto out;
fail_unref:
bdrv_unref_child(bs, bs->file);
out:
if (ret < 0) {
g_free(s->config_file);
@@ -405,11 +484,30 @@ out:
return ret;
}
static int inject_error(BlockDriverState *bs, BlkdebugRule *rule)
static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes)
{
BDRVBlkdebugState *s = bs->opaque;
int error = rule->options.inject.error;
bool immediately = rule->options.inject.immediately;
BlkdebugRule *rule = NULL;
int error;
bool immediately;
QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
uint64_t inject_offset = rule->options.inject.offset;
if (inject_offset == -1 ||
(bytes && inject_offset >= offset &&
inject_offset < offset + bytes))
{
break;
}
}
if (!rule || !rule->options.inject.error) {
return 0;
}
immediately = rule->options.inject.immediately;
error = rule->options.inject.error;
if (rule->options.inject.once) {
QSIMPLEQ_REMOVE(&s->active_rules, rule, BlkdebugRule, active_next);
@@ -428,21 +526,18 @@ static int coroutine_fn
blkdebug_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags)
{
BDRVBlkdebugState *s = bs->opaque;
BlkdebugRule *rule = NULL;
int err;
QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
uint64_t inject_offset = rule->options.inject.offset;
if (inject_offset == -1 ||
(inject_offset >= offset && inject_offset < offset + bytes))
{
break;
}
/* Sanity check block layer guarantees */
assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
assert(QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment));
if (bs->bl.max_transfer) {
assert(bytes <= bs->bl.max_transfer);
}
if (rule && rule->options.inject.error) {
return inject_error(bs, rule);
err = rule_check(bs, offset, bytes);
if (err) {
return err;
}
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
@@ -452,21 +547,18 @@ static int coroutine_fn
blkdebug_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags)
{
BDRVBlkdebugState *s = bs->opaque;
BlkdebugRule *rule = NULL;
int err;
QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
uint64_t inject_offset = rule->options.inject.offset;
if (inject_offset == -1 ||
(inject_offset >= offset && inject_offset < offset + bytes))
{
break;
}
/* Sanity check block layer guarantees */
assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
assert(QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment));
if (bs->bl.max_transfer) {
assert(bytes <= bs->bl.max_transfer);
}
if (rule && rule->options.inject.error) {
return inject_error(bs, rule);
err = rule_check(bs, offset, bytes);
if (err) {
return err;
}
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
@@ -474,22 +566,81 @@ blkdebug_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
static int blkdebug_co_flush(BlockDriverState *bs)
{
BDRVBlkdebugState *s = bs->opaque;
BlkdebugRule *rule = NULL;
int err = rule_check(bs, 0, 0);
QSIMPLEQ_FOREACH(rule, &s->active_rules, active_next) {
if (rule->options.inject.offset == -1) {
break;
}
}
if (rule && rule->options.inject.error) {
return inject_error(bs, rule);
if (err) {
return err;
}
return bdrv_co_flush(bs->file->bs);
}
static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int count,
BdrvRequestFlags flags)
{
uint32_t align = MAX(bs->bl.request_alignment,
bs->bl.pwrite_zeroes_alignment);
int err;
/* Only pass through requests that are larger than requested
* preferred alignment (so that we test the fallback to writes on
* unaligned portions), and check that the block layer never hands
* us anything unaligned that crosses an alignment boundary. */
if (count < align) {
assert(QEMU_IS_ALIGNED(offset, align) ||
QEMU_IS_ALIGNED(offset + count, align) ||
DIV_ROUND_UP(offset, align) ==
DIV_ROUND_UP(offset + count, align));
return -ENOTSUP;
}
assert(QEMU_IS_ALIGNED(offset, align));
assert(QEMU_IS_ALIGNED(count, align));
if (bs->bl.max_pwrite_zeroes) {
assert(count <= bs->bl.max_pwrite_zeroes);
}
err = rule_check(bs, offset, count);
if (err) {
return err;
}
return bdrv_co_pwrite_zeroes(bs->file, offset, count, flags);
}
static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
int64_t offset, int count)
{
uint32_t align = bs->bl.pdiscard_alignment;
int err;
/* Only pass through requests that are larger than requested
* minimum alignment, and ensure that unaligned requests do not
* cross optimum discard boundaries. */
if (count < bs->bl.request_alignment) {
assert(QEMU_IS_ALIGNED(offset, align) ||
QEMU_IS_ALIGNED(offset + count, align) ||
DIV_ROUND_UP(offset, align) ==
DIV_ROUND_UP(offset + count, align));
return -ENOTSUP;
}
assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
assert(QEMU_IS_ALIGNED(count, bs->bl.request_alignment));
if (align && count >= align) {
assert(QEMU_IS_ALIGNED(offset, align));
assert(QEMU_IS_ALIGNED(count, align));
}
if (bs->bl.max_pdiscard) {
assert(count <= bs->bl.max_pdiscard);
}
err = rule_check(bs, offset, count);
if (err) {
return err;
}
return bdrv_co_pdiscard(bs->file->bs, offset, count);
}
static void blkdebug_close(BlockDriverState *bs)
{
@@ -663,7 +814,7 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
static int blkdebug_truncate(BlockDriverState *bs, int64_t offset)
{
return bdrv_truncate(bs->file, offset);
return bdrv_truncate(bs->file, offset, NULL);
}
static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
@@ -689,16 +840,20 @@ static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
}
if (!force_json && bs->file->bs->exact_filename[0]) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"blkdebug:%s:%s", s->config_file ?: "",
bs->file->bs->exact_filename);
int ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"blkdebug:%s:%s", s->config_file ?: "",
bs->file->bs->exact_filename);
if (ret >= sizeof(bs->exact_filename)) {
/* An overflow makes the filename unusable, so do not report any */
bs->exact_filename[0] = 0;
}
}
opts = qdict_new();
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkdebug")));
qdict_put_str(opts, "driver", "blkdebug");
QINCREF(bs->file->bs->full_open_options);
qdict_put_obj(opts, "image", QOBJECT(bs->file->bs->full_open_options));
qdict_put(opts, "image", bs->file->bs->full_open_options);
for (e = qdict_first(options); e; e = qdict_next(options, e)) {
if (strcmp(qdict_entry_key(e), "x-image")) {
@@ -717,6 +872,21 @@ static void blkdebug_refresh_limits(BlockDriverState *bs, Error **errp)
if (s->align) {
bs->bl.request_alignment = s->align;
}
if (s->max_transfer) {
bs->bl.max_transfer = s->max_transfer;
}
if (s->opt_write_zero) {
bs->bl.pwrite_zeroes_alignment = s->opt_write_zero;
}
if (s->max_write_zero) {
bs->bl.max_pwrite_zeroes = s->max_write_zero;
}
if (s->opt_discard) {
bs->bl.pdiscard_alignment = s->opt_discard;
}
if (s->max_discard) {
bs->bl.max_pdiscard = s->max_discard;
}
}
static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
@@ -744,6 +914,8 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_co_preadv = blkdebug_co_preadv,
.bdrv_co_pwritev = blkdebug_co_pwritev,
.bdrv_co_flush_to_disk = blkdebug_co_flush,
.bdrv_co_pwrite_zeroes = blkdebug_co_pwrite_zeroes,
.bdrv_co_pdiscard = blkdebug_co_pdiscard,
.bdrv_debug_event = blkdebug_debug_event,
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
-3
View File
@@ -37,9 +37,6 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
ret = 0;
fail:
if (ret < 0) {
bdrv_unref_child(bs, bs->file);
}
return ret;
}
+13 -13
View File
@@ -67,7 +67,7 @@ static void blkverify_parse_filename(const char *filename, QDict *options,
if (!strstart(filename, "blkverify:", &filename)) {
/* There was no prefix; therefore, all options have to be already
present in the QDict (except for the filename) */
qdict_put(options, "x-image", qstring_from_str(filename));
qdict_put_str(options, "x-image", filename);
return;
}
@@ -84,7 +84,7 @@ static void blkverify_parse_filename(const char *filename, QDict *options,
/* TODO Allow multi-level nesting and set file.filename here */
filename = c + 1;
qdict_put(options, "x-image", qstring_from_str(filename));
qdict_put_str(options, "x-image", filename);
}
static QemuOptsList runtime_opts = {
@@ -142,9 +142,6 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
ret = 0;
fail:
if (ret < 0) {
bdrv_unref_child(bs, bs->file);
}
qemu_opts_del(opts);
return ret;
}
@@ -291,13 +288,12 @@ static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
&& s->test_file->bs->full_open_options)
{
QDict *opts = qdict_new();
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkverify")));
qdict_put_str(opts, "driver", "blkverify");
QINCREF(bs->file->bs->full_open_options);
qdict_put_obj(opts, "raw", QOBJECT(bs->file->bs->full_open_options));
qdict_put(opts, "raw", bs->file->bs->full_open_options);
QINCREF(s->test_file->bs->full_open_options);
qdict_put_obj(opts, "test",
QOBJECT(s->test_file->bs->full_open_options));
qdict_put(opts, "test", s->test_file->bs->full_open_options);
bs->full_open_options = opts;
}
@@ -305,10 +301,14 @@ static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
if (bs->file->bs->exact_filename[0]
&& s->test_file->bs->exact_filename[0])
{
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"blkverify:%s:%s",
bs->file->bs->exact_filename,
s->test_file->bs->exact_filename);
int ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"blkverify:%s:%s",
bs->file->bs->exact_filename,
s->test_file->bs->exact_filename);
if (ret >= sizeof(bs->exact_filename)) {
/* An overflow makes the filename unusable, so do not report any */
bs->exact_filename[0] = 0;
}
}
}
+47 -5
View File
@@ -61,6 +61,7 @@ struct BlockBackend {
uint64_t perm;
uint64_t shared_perm;
bool disable_perm;
bool allow_write_beyond_eof;
@@ -230,6 +231,9 @@ static void blk_delete(BlockBackend *blk)
assert(!blk->refcnt);
assert(!blk->name);
assert(!blk->dev);
if (blk->public.throttle_state) {
blk_io_limits_disable(blk);
}
if (blk->root) {
blk_remove_bs(blk);
}
@@ -578,7 +582,7 @@ int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
{
int ret;
if (blk->root) {
if (blk->root && !blk->disable_perm) {
ret = bdrv_child_try_set_perm(blk->root, perm, shared_perm, errp);
if (ret < 0) {
return ret;
@@ -597,15 +601,52 @@ void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
*shared_perm = blk->shared_perm;
}
/*
* Notifies the user of all BlockBackends that migration has completed. qdev
* devices can tighten their permissions in response (specifically revoke
* shared write permissions that we needed for storage migration).
*
* If an error is returned, the VM cannot be allowed to be resumed.
*/
void blk_resume_after_migration(Error **errp)
{
BlockBackend *blk;
Error *local_err = NULL;
for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
if (!blk->disable_perm) {
continue;
}
blk->disable_perm = false;
blk_set_perm(blk, blk->perm, blk->shared_perm, &local_err);
if (local_err) {
error_propagate(errp, local_err);
blk->disable_perm = true;
return;
}
}
}
static int blk_do_attach_dev(BlockBackend *blk, void *dev)
{
if (blk->dev) {
return -EBUSY;
}
/* While migration is still incoming, we don't need to apply the
* permissions of guest device BlockBackends. We might still have a block
* job or NBD server writing to the image for storage migration. */
if (runstate_check(RUN_STATE_INMIGRATE)) {
blk->disable_perm = true;
}
blk_ref(blk);
blk->dev = dev;
blk->legacy_dev = false;
blk_iostatus_reset(blk);
return 0;
}
@@ -1007,7 +1048,7 @@ static int blk_prw(BlockBackend *blk, int64_t offset, uint8_t *buf,
co_entry(&rwco);
} else {
Coroutine *co = qemu_coroutine_create(co_entry, &rwco);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(blk_bs(blk), co);
BDRV_POLL_WHILE(blk_bs(blk), rwco.ret == NOT_DONE);
}
@@ -1114,7 +1155,7 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
acb->has_returned = false;
co = qemu_coroutine_create(co_entry, acb);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(blk_bs(blk), co);
acb->has_returned = true;
if (acb->rwco.ret != NOT_DONE) {
@@ -1705,13 +1746,14 @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
BDRV_REQ_WRITE_COMPRESSED);
}
int blk_truncate(BlockBackend *blk, int64_t offset)
int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp)
{
if (!blk_is_available(blk)) {
error_setg(errp, "No medium inserted");
return -ENOMEDIUM;
}
return bdrv_truncate(blk->root, offset);
return bdrv_truncate(blk->root, offset, errp);
}
static void blk_pdiscard_entry(void *opaque)
+25 -2
View File
@@ -89,6 +89,12 @@ static void commit_complete(BlockJob *job, void *opaque)
int ret = data->ret;
bool remove_commit_top_bs = false;
/* Make sure overlay_bs and top stay around until bdrv_set_backing_hd() */
bdrv_ref(top);
if (overlay_bs) {
bdrv_ref(overlay_bs);
}
/* Remove base node parent that still uses BLK_PERM_WRITE/RESIZE before
* the normal backing chain can be restored. */
blk_unref(s->base);
@@ -115,6 +121,13 @@ static void commit_complete(BlockJob *job, void *opaque)
}
g_free(s->backing_file_str);
blk_unref(s->top);
/* If there is more than one reference to the job (e.g. if called from
* block_job_finish_sync()), block_job_completed() won't free it and
* therefore the blockers on the intermediate nodes remain. This would
* cause bdrv_set_backing_hd() to fail. */
block_job_remove_all_bdrv(job);
block_job_completed(&s->common, ret);
g_free(data);
@@ -124,6 +137,9 @@ static void commit_complete(BlockJob *job, void *opaque)
if (remove_commit_top_bs) {
bdrv_set_backing_hd(overlay_bs, top, &error_abort);
}
bdrv_unref(overlay_bs);
bdrv_unref(top);
}
static void coroutine_fn commit_run(void *opaque)
@@ -151,7 +167,7 @@ static void coroutine_fn commit_run(void *opaque)
}
if (base_len < s->common.len) {
ret = blk_truncate(s->base, s->common.len);
ret = blk_truncate(s->base, s->common.len, NULL);
if (ret) {
goto out;
}
@@ -335,6 +351,11 @@ void commit_start(const char *job_id, BlockDriverState *bs,
if (commit_top_bs == NULL) {
goto fail;
}
if (!filter_node_name) {
commit_top_bs->implicit = true;
}
commit_top_bs->total_sectors = top->total_sectors;
bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(top));
bdrv_set_backing_hd(commit_top_bs, top, &local_err);
if (local_err) {
@@ -482,6 +503,7 @@ int bdrv_commit(BlockDriverState *bs)
error_report_err(local_err);
goto ro_cleanup;
}
bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(backing_file_bs));
bdrv_set_backing_hd(commit_top_bs, backing_file_bs, &error_abort);
bdrv_set_backing_hd(bs, commit_top_bs, &error_abort);
@@ -508,8 +530,9 @@ int bdrv_commit(BlockDriverState *bs)
* grow the backing file image if possible. If not possible,
* we must return an error */
if (length > backing_length) {
ret = blk_truncate(backing, length);
ret = blk_truncate(backing, length, &local_err);
if (ret < 0) {
error_report_err(local_err);
goto ro_cleanup;
}
}
+1 -1
View File
@@ -389,7 +389,7 @@ static int block_crypto_truncate(BlockDriverState *bs, int64_t offset)
offset += payload_offset;
return bdrv_truncate(bs->file, offset);
return bdrv_truncate(bs->file, offset, NULL);
}
static void block_crypto_close(BlockDriverState *bs)
+37 -6
View File
@@ -147,6 +147,7 @@ static void curl_multi_do(void *arg);
static void curl_multi_read(void *arg);
#ifdef NEED_CURL_TIMER_CALLBACK
/* Called from curl_multi_do_locked, with s->mutex held. */
static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
{
BDRVCURLState *s = opaque;
@@ -163,6 +164,7 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
}
#endif
/* Called from curl_multi_do_locked, with s->mutex held. */
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
void *userp, void *sp)
{
@@ -212,6 +214,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
return 0;
}
/* Called from curl_multi_do_locked, with s->mutex held. */
static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
BDRVCURLState *s = opaque;
@@ -226,6 +229,7 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
return realsize;
}
/* Called from curl_multi_do_locked, with s->mutex held. */
static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
CURLState *s = ((CURLState*)opaque);
@@ -264,7 +268,9 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
request_length - offset);
}
qemu_mutex_unlock(&s->s->mutex);
acb->common.cb(acb->common.opaque, 0);
qemu_mutex_lock(&s->s->mutex);
qemu_aio_unref(acb);
s->acb[i] = NULL;
}
@@ -275,6 +281,7 @@ read_end:
return size * nmemb;
}
/* Called with s->mutex held. */
static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
CURLAIOCB *acb)
{
@@ -305,8 +312,6 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
if (clamped_len < len) {
qemu_iovec_memset(acb->qiov, clamped_len, 0, len - clamped_len);
}
acb->common.cb(acb->common.opaque, 0);
return FIND_RET_OK;
}
@@ -449,6 +454,7 @@ static void curl_multi_timeout_do(void *arg)
#endif
}
/* Called with s->mutex held. */
static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)
{
CURLState *state = NULL;
@@ -467,7 +473,9 @@ static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)
break;
}
if (!state) {
qemu_mutex_unlock(&s->mutex);
aio_poll(bdrv_get_aio_context(bs), true);
qemu_mutex_lock(&s->mutex);
}
} while(!state);
@@ -530,8 +538,14 @@ static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)
return state;
}
/* Called with s->mutex held. */
static void curl_clean_state(CURLState *s)
{
int j;
for (j = 0; j < CURL_NUM_ACB; j++) {
assert(!s->acb[j]);
}
if (s->s->multi)
curl_multi_remove_handle(s->s->multi, s->curl);
@@ -548,7 +562,7 @@ static void curl_clean_state(CURLState *s)
static void curl_parse_filename(const char *filename, QDict *options,
Error **errp)
{
qdict_put(options, CURL_BLOCK_OPT_URL, qstring_from_str(filename));
qdict_put_str(options, CURL_BLOCK_OPT_URL, filename);
}
static void curl_detach_aio_context(BlockDriverState *bs)
@@ -556,6 +570,7 @@ static void curl_detach_aio_context(BlockDriverState *bs)
BDRVCURLState *s = bs->opaque;
int i;
qemu_mutex_lock(&s->mutex);
for (i = 0; i < CURL_NUM_STATES; i++) {
if (s->states[i].in_use) {
curl_clean_state(&s->states[i]);
@@ -571,6 +586,7 @@ static void curl_detach_aio_context(BlockDriverState *bs)
curl_multi_cleanup(s->multi);
s->multi = NULL;
}
qemu_mutex_unlock(&s->mutex);
timer_del(&s->timer);
}
@@ -659,6 +675,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
const char *cookie;
double d;
const char *secretid;
const char *protocol_delimiter;
static int inited = 0;
@@ -667,6 +684,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
return -EROFS;
}
qemu_mutex_init(&s->mutex);
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
@@ -700,6 +718,15 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
goto out_noclean;
}
if (!strstart(file, bs->drv->protocol_name, &protocol_delimiter) ||
!strstart(protocol_delimiter, "://", NULL))
{
error_setg(errp, "%s curl driver cannot handle the URL '%s' (does not "
"start with '%s://')", bs->drv->protocol_name, file,
bs->drv->protocol_name);
goto out_noclean;
}
s->username = g_strdup(qemu_opt_get(opts, CURL_BLOCK_OPT_USERNAME));
secretid = qemu_opt_get(opts, CURL_BLOCK_OPT_PASSWORD_SECRET);
@@ -728,7 +755,9 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
DPRINTF("CURL: Opening %s\n", file);
s->aio_context = bdrv_get_aio_context(bs);
s->url = g_strdup(file);
qemu_mutex_lock(&s->mutex);
state = curl_init_state(bs, s);
qemu_mutex_unlock(&s->mutex);
if (!state)
goto out_noclean;
@@ -772,11 +801,12 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
}
DPRINTF("CURL: Size = %zd\n", s->len);
qemu_mutex_lock(&s->mutex);
curl_clean_state(state);
qemu_mutex_unlock(&s->mutex);
curl_easy_cleanup(state->curl);
state->curl = NULL;
qemu_mutex_init(&s->mutex);
curl_attach_aio_context(bs, bdrv_get_aio_context(bs));
qemu_opts_del(opts);
@@ -787,6 +817,7 @@ out:
curl_easy_cleanup(state->curl);
state->curl = NULL;
out_noclean:
qemu_mutex_destroy(&s->mutex);
g_free(s->cookie);
g_free(s->url);
qemu_opts_del(opts);
@@ -817,8 +848,8 @@ static void curl_readv_bh_cb(void *p)
// we can just call the callback and be done.
switch (curl_find_buf(s, start, acb->nb_sectors * BDRV_SECTOR_SIZE, acb)) {
case FIND_RET_OK:
qemu_aio_unref(acb);
// fall through
ret = 0;
goto out;
case FIND_RET_WAIT:
goto out;
default:
+1 -1
View File
@@ -345,7 +345,7 @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
info->count = bdrv_get_dirty_count(bm);
info->count = bdrv_get_dirty_count(bm) << BDRV_SECTOR_BITS;
info->granularity = bdrv_dirty_bitmap_granularity(bm);
info->has_name = !!bm->name;
info->name = g_strdup(bm->name);
+10 -4
View File
@@ -377,7 +377,7 @@ static void raw_parse_filename(const char *filename, QDict *options,
* function call can be ignored. */
strstart(filename, "file:", &filename);
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
qdict_put_str(options, "filename", filename);
}
static QemuOptsList raw_runtime_opts = {
@@ -2150,7 +2150,7 @@ static void hdev_parse_filename(const char *filename, QDict *options,
/* The prefix is optional, just as for "file". */
strstart(filename, "host_device:", &filename);
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
qdict_put_str(options, "filename", filename);
}
static bool hdev_is_sg(BlockDriverState *bs)
@@ -2193,6 +2193,12 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
int ret;
#if defined(__APPLE__) && defined(__MACH__)
/*
* Caution: while qdict_get_str() is fine, getting non-string types
* would require more care. When @options come from -blockdev or
* blockdev_add, its members are typed according to the QAPI
* schema, but when they come from -drive, they're all QString.
*/
const char *filename = qdict_get_str(options, "filename");
char bsd_path[MAXPATHLEN] = "";
bool error_occurred = false;
@@ -2233,7 +2239,7 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
goto hdev_open_Mac_error;
}
qdict_put(options, "filename", qstring_from_str(bsd_path));
qdict_put_str(options, "filename", bsd_path);
hdev_open_Mac_error:
g_free(mediaType);
@@ -2443,7 +2449,7 @@ static void cdrom_parse_filename(const char *filename, QDict *options,
/* The prefix is optional, just as for "file". */
strstart(filename, "host_cdrom:", &filename);
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
qdict_put_str(options, "filename", filename);
}
#endif
+2 -2
View File
@@ -282,7 +282,7 @@ static void raw_parse_filename(const char *filename, QDict *options,
* function call can be ignored. */
strstart(filename, "file:", &filename);
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
qdict_put_str(options, "filename", filename);
}
static QemuOptsList raw_runtime_opts = {
@@ -669,7 +669,7 @@ static void hdev_parse_filename(const char *filename, QDict *options,
/* The prefix is optional, just as for "file". */
strstart(filename, "host_device:", &filename);
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
qdict_put_str(options, "filename", filename);
}
static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
+18 -10
View File
@@ -412,10 +412,12 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
glfs_set_preopened(gconf->volume, glfs);
for (server = gconf->server; server; server = server->next) {
if (server->value->type == SOCKET_ADDRESS_FLAT_TYPE_UNIX) {
switch (server->value->type) {
case SOCKET_ADDRESS_FLAT_TYPE_UNIX:
ret = glfs_set_volfile_server(glfs, "unix",
server->value->u.q_unix.path, 0);
} else {
break;
case SOCKET_ADDRESS_FLAT_TYPE_INET:
if (parse_uint_full(server->value->u.inet.port, &port, 10) < 0 ||
port > 65535) {
error_setg(errp, "'%s' is not a valid port number",
@@ -426,6 +428,11 @@ static struct glfs *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf,
ret = glfs_set_volfile_server(glfs, "tcp",
server->value->u.inet.host,
(int)port);
break;
case SOCKET_ADDRESS_FLAT_TYPE_VSOCK:
case SOCKET_ADDRESS_FLAT_TYPE_FD:
default:
abort();
}
if (ret < 0) {
@@ -487,7 +494,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
char *str = NULL;
const char *ptr;
size_t num_servers;
int i;
int i, type;
/* create opts info from runtime_json_opts list */
opts = qemu_opts_create(&runtime_json_opts, NULL, 0, &error_abort);
@@ -539,16 +546,17 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
if (!strcmp(ptr, "tcp")) {
ptr = "inet"; /* accept legacy "tcp" */
}
gsconf->type = qapi_enum_parse(SocketAddressFlatType_lookup, ptr,
SOCKET_ADDRESS_FLAT_TYPE__MAX, -1,
&local_err);
if (local_err) {
error_append_hint(&local_err,
"Parameter '%s' may be 'inet' or 'unix'\n",
GLUSTER_OPT_TYPE);
type = qapi_enum_parse(SocketAddressFlatType_lookup, ptr,
SOCKET_ADDRESS_FLAT_TYPE__MAX, -1, NULL);
if (type != SOCKET_ADDRESS_FLAT_TYPE_INET
&& type != SOCKET_ADDRESS_FLAT_TYPE_UNIX) {
error_setg(&local_err,
"Parameter '%s' may be 'inet' or 'unix'",
GLUSTER_OPT_TYPE);
error_append_hint(&local_err, GERR_INDEX_HINT, i);
goto out;
}
gsconf->type = type;
qemu_opts_del(opts);
if (gsconf->type == SOCKET_ADDRESS_FLAT_TYPE_INET) {
+61 -26
View File
@@ -44,7 +44,7 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque);
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int count, BdrvRequestFlags flags);
static void bdrv_parent_drained_begin(BlockDriverState *bs)
void bdrv_parent_drained_begin(BlockDriverState *bs)
{
BdrvChild *c;
@@ -55,7 +55,7 @@ static void bdrv_parent_drained_begin(BlockDriverState *bs)
}
}
static void bdrv_parent_drained_end(BlockDriverState *bs)
void bdrv_parent_drained_end(BlockDriverState *bs)
{
BdrvChild *c;
@@ -158,7 +158,7 @@ bool bdrv_requests_pending(BlockDriverState *bs)
static bool bdrv_drain_recurse(BlockDriverState *bs)
{
BdrvChild *child;
BdrvChild *child, *tmp;
bool waited;
waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);
@@ -167,8 +167,25 @@ static bool bdrv_drain_recurse(BlockDriverState *bs)
bs->drv->bdrv_drain(bs);
}
QLIST_FOREACH(child, &bs->children, next) {
waited |= bdrv_drain_recurse(child->bs);
QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
BlockDriverState *bs = child->bs;
bool in_main_loop =
qemu_get_current_aio_context() == qemu_get_aio_context();
assert(bs->refcnt > 0);
if (in_main_loop) {
/* In case the recursive bdrv_drain_recurse processes a
* block_job_defer_to_main_loop BH and modifies the graph,
* let's hold a reference to bs until we are done.
*
* IOThread doesn't have such a BH, and it is not safe to call
* bdrv_unref without BQL, so skip doing it there.
*/
bdrv_ref(bs);
}
waited |= bdrv_drain_recurse(bs);
if (in_main_loop) {
bdrv_unref(bs);
}
}
return waited;
@@ -616,7 +633,7 @@ static int bdrv_prwv_co(BdrvChild *child, int64_t offset,
bdrv_rw_co_entry(&rwco);
} else {
co = qemu_coroutine_create(bdrv_rw_co_entry, &rwco);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(child->bs, co);
BDRV_POLL_WHILE(child->bs, rwco.ret == NOT_DONE);
}
return rwco.ret;
@@ -945,7 +962,14 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
size_t skip_bytes;
int ret;
assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
/* FIXME We cannot require callers to have write permissions when all they
* are doing is a read request. If we did things right, write permissions
* would be obtained anyway, but internally by the copy-on-read code. As
* long as it is implemented here rather than in a separat filter driver,
* the copy-on-read code doesn't have its own BdrvChild, however, for which
* it could request permissions. Therefore we have to bypass the permission
* system for the moment. */
// assert(child->perm & (BLK_PERM_WRITE_UNCHANGED | BLK_PERM_WRITE));
/* Cover entire cluster so no additional backing file I/O is required when
* allocating cluster in the image file.
@@ -1338,8 +1362,16 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
assert(!waited || !req->serialising);
assert(req->overlap_offset <= offset);
assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
assert(child->perm & BLK_PERM_WRITE);
assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
/* FIXME: Block migration uses the BlockBackend of the guest device at a
* point when it has not yet taken write permissions. This will be
* fixed by a future patch, but for now we have to bypass this
* assertion for block migration to work. */
// assert(child->perm & BLK_PERM_WRITE);
/* FIXME: Because of the above, we also cannot guarantee that all format
* BDS take the BLK_PERM_RESIZE permission on their file BDS, since
* they are not obligated to do so if they do not have any parent
* that has taken the permission to write to them. */
// assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req);
@@ -1725,6 +1757,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
int64_t n;
int64_t ret, ret2;
*file = NULL;
total_sectors = bdrv_nb_sectors(bs);
if (total_sectors < 0) {
return total_sectors;
@@ -1745,11 +1778,11 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
if (bs->drv->protocol_name) {
ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);
*file = bs;
}
return ret;
}
*file = NULL;
bdrv_inc_in_flight(bs);
ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum,
file);
@@ -1759,9 +1792,9 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
}
if (ret & BDRV_BLOCK_RAW) {
assert(ret & BDRV_BLOCK_OFFSET_VALID);
ret = bdrv_get_block_status(*file, ret >> BDRV_SECTOR_BITS,
*pnum, pnum, file);
assert(ret & BDRV_BLOCK_OFFSET_VALID && *file);
ret = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,
*pnum, pnum, file);
goto out;
}
@@ -1873,7 +1906,7 @@ int64_t bdrv_get_block_status_above(BlockDriverState *bs,
} else {
co = qemu_coroutine_create(bdrv_get_block_status_above_co_entry,
&data);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, !data.done);
}
return data.ret;
@@ -1999,7 +2032,7 @@ bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
};
Coroutine *co = qemu_coroutine_create(bdrv_co_rw_vmstate_entry, &data);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
while (data.ret == -EINPROGRESS) {
aio_poll(bdrv_get_aio_context(bs), true);
}
@@ -2216,7 +2249,7 @@ static BlockAIOCB *bdrv_co_aio_prw_vector(BdrvChild *child,
acb->is_write = is_write;
co = qemu_coroutine_create(bdrv_co_do_rw, acb);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(child->bs, co);
bdrv_co_maybe_schedule_bh(acb);
return &acb->common;
@@ -2247,7 +2280,7 @@ BlockAIOCB *bdrv_aio_flush(BlockDriverState *bs,
acb->req.error = -EINPROGRESS;
co = qemu_coroutine_create(bdrv_aio_flush_co_entry, acb);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
bdrv_co_maybe_schedule_bh(acb);
return &acb->common;
@@ -2271,16 +2304,17 @@ static void coroutine_fn bdrv_flush_co_entry(void *opaque)
int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
{
int ret;
if (!bs || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs) ||
bdrv_is_sg(bs)) {
return 0;
}
int current_gen;
int ret = 0;
bdrv_inc_in_flight(bs);
int current_gen = bs->write_gen;
if (!bs || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs) ||
bdrv_is_sg(bs)) {
goto early_exit;
}
current_gen = bs->write_gen;
/* Wait until any previous flushes are completed */
while (bs->active_flush_req) {
@@ -2363,6 +2397,7 @@ out:
/* Return value is ignored - it's ok if wait queue is empty */
qemu_co_queue_next(&bs->flush_queue);
early_exit:
bdrv_dec_in_flight(bs);
return ret;
}
@@ -2380,7 +2415,7 @@ int bdrv_flush(BlockDriverState *bs)
bdrv_flush_co_entry(&flush_co);
} else {
co = qemu_coroutine_create(bdrv_flush_co_entry, &flush_co);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, flush_co.ret == NOT_DONE);
}
@@ -2527,7 +2562,7 @@ int bdrv_pdiscard(BlockDriverState *bs, int64_t offset, int count)
bdrv_pdiscard_co_entry(&rwco);
} else {
co = qemu_coroutine_create(bdrv_pdiscard_co_entry, &rwco);
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, rwco.ret == NOT_DONE);
}
+8 -3
View File
@@ -103,7 +103,6 @@ typedef struct IscsiTask {
typedef struct IscsiAIOCB {
BlockAIOCB common;
QEMUIOVector *qiov;
QEMUBH *bh;
IscsiLun *iscsilun;
struct scsi_task *task;
@@ -2093,6 +2092,7 @@ static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
BlockDriverState *bs;
IscsiLun *iscsilun = NULL;
QDict *bs_options;
Error *local_err = NULL;
bs = bdrv_new();
@@ -2103,8 +2103,13 @@ static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
iscsilun = bs->opaque;
bs_options = qdict_new();
qdict_put(bs_options, "filename", qstring_from_str(filename));
ret = iscsi_open(bs, bs_options, 0, NULL);
iscsi_parse_filename(filename, bs_options, &local_err);
if (local_err) {
error_propagate(errp, local_err);
ret = -EINVAL;
} else {
ret = iscsi_open(bs, bs_options, 0, NULL);
}
QDECREF(bs_options);
if (ret != 0) {
+21 -4
View File
@@ -514,7 +514,12 @@ static void mirror_exit(BlockJob *job, void *opaque)
/* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
* inserting target_bs at s->to_replace, where we might not be able to get
* these permissions. */
* these permissions.
*
* Note that blk_unref() alone doesn't necessarily drop permissions because
* we might be running nested inside mirror_drain(), which takes an extra
* reference, so use an explicit blk_set_perm() first. */
blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort);
blk_unref(s->target);
s->target = NULL;
@@ -724,7 +729,7 @@ static void coroutine_fn mirror_run(void *opaque)
}
if (s->bdev_length > base_length) {
ret = blk_truncate(s->target, s->bdev_length);
ret = blk_truncate(s->target, s->bdev_length, NULL);
if (ret < 0) {
goto immediate_exit;
}
@@ -1147,10 +1152,14 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
if (mirror_top_bs == NULL) {
return;
}
if (!filter_node_name) {
mirror_top_bs->implicit = true;
}
mirror_top_bs->total_sectors = bs->total_sectors;
bdrv_set_aio_context(mirror_top_bs, bdrv_get_aio_context(bs));
/* bdrv_append takes ownership of the mirror_top_bs reference, need to keep
* it alive until block_job_create() even if bs has no parent. */
* it alive until block_job_create() succeeds even if bs has no parent. */
bdrv_ref(mirror_top_bs);
bdrv_drained_begin(bs);
bdrv_append(mirror_top_bs, bs, &local_err);
@@ -1168,10 +1177,12 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
BLK_PERM_WRITE | BLK_PERM_GRAPH_MOD, speed,
creation_flags, cb, opaque, errp);
bdrv_unref(mirror_top_bs);
if (!s) {
goto fail;
}
/* The block job now has a reference to this node */
bdrv_unref(mirror_top_bs);
s->source = bs;
s->mirror_top_bs = mirror_top_bs;
@@ -1242,6 +1253,10 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
fail:
if (s) {
/* Make sure this BDS does not go away until we have completed the graph
* changes below */
bdrv_ref(mirror_top_bs);
g_free(s->replaces);
blk_unref(s->target);
block_job_unref(&s->common);
@@ -1250,6 +1265,8 @@ fail:
bdrv_child_try_set_perm(mirror_top_bs->backing, 0, BLK_PERM_ALL,
&error_abort);
bdrv_replace_node(mirror_top_bs, backing_bs(mirror_top_bs), &error_abort);
bdrv_unref(mirror_top_bs);
}
void mirror_start(const char *job_id, BlockDriverState *bs,
+2 -2
View File
@@ -352,14 +352,14 @@ int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int count)
void nbd_client_detach_aio_context(BlockDriverState *bs)
{
NBDClientSession *client = nbd_get_client_session(bs);
qio_channel_detach_aio_context(QIO_CHANNEL(client->sioc));
qio_channel_detach_aio_context(QIO_CHANNEL(client->ioc));
}
void nbd_client_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
NBDClientSession *client = nbd_get_client_session(bs);
qio_channel_attach_aio_context(QIO_CHANNEL(client->sioc), new_context);
qio_channel_attach_aio_context(QIO_CHANNEL(client->ioc), new_context);
aio_co_schedule(new_context, client->read_reply_co);
}
+53 -41
View File
@@ -47,7 +47,7 @@ typedef struct BDRVNBDState {
NBDClientSession client;
/* For nbd_refresh_filename() */
SocketAddress *saddr;
SocketAddressFlat *saddr;
char *export, *tlscredsid;
} BDRVNBDState;
@@ -65,11 +65,11 @@ static int nbd_parse_uri(const char *filename, QDict *options)
}
/* transport */
if (!strcmp(uri->scheme, "nbd")) {
if (!g_strcmp0(uri->scheme, "nbd")) {
is_unix = false;
} else if (!strcmp(uri->scheme, "nbd+tcp")) {
} else if (!g_strcmp0(uri->scheme, "nbd+tcp")) {
is_unix = false;
} else if (!strcmp(uri->scheme, "nbd+unix")) {
} else if (!g_strcmp0(uri->scheme, "nbd+unix")) {
is_unix = true;
} else {
ret = -EINVAL;
@@ -79,7 +79,7 @@ static int nbd_parse_uri(const char *filename, QDict *options)
p = uri->path ? uri->path : "/";
p += strspn(p, "/");
if (p[0]) {
qdict_put(options, "export", qstring_from_str(p));
qdict_put_str(options, "export", p);
}
qp = query_params_parse(uri->query);
@@ -94,9 +94,8 @@ static int nbd_parse_uri(const char *filename, QDict *options)
ret = -EINVAL;
goto out;
}
qdict_put(options, "server.type", qstring_from_str("unix"));
qdict_put(options, "server.data.path",
qstring_from_str(qp->p[0].value));
qdict_put_str(options, "server.type", "unix");
qdict_put_str(options, "server.path", qp->p[0].value);
} else {
QString *host;
char *port_str;
@@ -115,11 +114,11 @@ static int nbd_parse_uri(const char *filename, QDict *options)
host = qstring_from_str(uri->server);
}
qdict_put(options, "server.type", qstring_from_str("inet"));
qdict_put(options, "server.data.host", host);
qdict_put_str(options, "server.type", "inet");
qdict_put(options, "server.host", host);
port_str = g_strdup_printf("%d", uri->port ?: NBD_DEFAULT_PORT);
qdict_put(options, "server.data.port", qstring_from_str(port_str));
qdict_put_str(options, "server.port", port_str);
g_free(port_str);
}
@@ -181,7 +180,7 @@ static void nbd_parse_filename(const char *filename, QDict *options,
export_name[0] = 0; /* truncate 'file' */
export_name += strlen(EN_OPTSTR);
qdict_put(options, "export", qstring_from_str(export_name));
qdict_put_str(options, "export", export_name);
}
/* extract the host_spec - fail if it's not nbd:... */
@@ -196,8 +195,8 @@ static void nbd_parse_filename(const char *filename, QDict *options,
/* are we a UNIX or TCP socket? */
if (strstart(host_spec, "unix:", &unixpath)) {
qdict_put(options, "server.type", qstring_from_str("unix"));
qdict_put(options, "server.data.path", qstring_from_str(unixpath));
qdict_put_str(options, "server.type", "unix");
qdict_put_str(options, "server.path", unixpath);
} else {
InetSocketAddress *addr = NULL;
@@ -206,9 +205,9 @@ static void nbd_parse_filename(const char *filename, QDict *options,
goto out;
}
qdict_put(options, "server.type", qstring_from_str("inet"));
qdict_put(options, "server.data.host", qstring_from_str(addr->host));
qdict_put(options, "server.data.port", qstring_from_str(addr->port));
qdict_put_str(options, "server.type", "inet");
qdict_put_str(options, "server.host", addr->host);
qdict_put_str(options, "server.port", addr->port);
qapi_free_InetSocketAddress(addr);
}
@@ -247,21 +246,22 @@ static bool nbd_process_legacy_socket_options(QDict *output_options,
return false;
}
qdict_put(output_options, "server.type", qstring_from_str("unix"));
qdict_put(output_options, "server.data.path", qstring_from_str(path));
qdict_put_str(output_options, "server.type", "unix");
qdict_put_str(output_options, "server.path", path);
} else if (host) {
qdict_put(output_options, "server.type", qstring_from_str("inet"));
qdict_put(output_options, "server.data.host", qstring_from_str(host));
qdict_put(output_options, "server.data.port",
qstring_from_str(port ?: stringify(NBD_DEFAULT_PORT)));
qdict_put_str(output_options, "server.type", "inet");
qdict_put_str(output_options, "server.host", host);
qdict_put_str(output_options, "server.port",
port ?: stringify(NBD_DEFAULT_PORT));
}
return true;
}
static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, Error **errp)
static SocketAddressFlat *nbd_config(BDRVNBDState *s, QDict *options,
Error **errp)
{
SocketAddress *saddr = NULL;
SocketAddressFlat *saddr = NULL;
QDict *addr = NULL;
QObject *crumpled_addr = NULL;
Visitor *iv = NULL;
@@ -278,8 +278,16 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, Error **errp)
goto done;
}
/*
* FIXME .numeric, .to, .ipv4 or .ipv6 don't work with -drive
* server.type=inet. .to doesn't matter, it's ignored anyway.
* That's because when @options come from -blockdev or
* blockdev_add, members are typed according to the QAPI schema,
* but when they come from -drive, they're all QString. The
* visitor expects the former.
*/
iv = qobject_input_visitor_new(crumpled_addr);
visit_type_SocketAddress(iv, NULL, &saddr, &local_err);
visit_type_SocketAddressFlat(iv, NULL, &saddr, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto done;
@@ -298,9 +306,10 @@ NBDClientSession *nbd_get_client_session(BlockDriverState *bs)
return &s->client;
}
static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr,
static QIOChannelSocket *nbd_establish_connection(SocketAddressFlat *saddr_flat,
Error **errp)
{
SocketAddress *saddr = socket_address_crumple(saddr_flat);
QIOChannelSocket *sioc;
Error *local_err = NULL;
@@ -310,7 +319,9 @@ static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr,
qio_channel_socket_connect_sync(sioc,
saddr,
&local_err);
qapi_free_SocketAddress(saddr);
if (local_err) {
object_unref(OBJECT(sioc));
error_propagate(errp, local_err);
return NULL;
}
@@ -401,7 +412,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
goto error;
}
/* Translate @host, @port, and @path to a SocketAddress */
/* Translate @host, @port, and @path to a SocketAddressFlat */
if (!nbd_process_legacy_socket_options(options, opts, errp)) {
goto error;
}
@@ -421,11 +432,12 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
goto error;
}
if (s->saddr->type != SOCKET_ADDRESS_KIND_INET) {
/* TODO SOCKET_ADDRESS_KIND_FD where fd has AF_INET or AF_INET6 */
if (s->saddr->type != SOCKET_ADDRESS_FLAT_TYPE_INET) {
error_setg(errp, "TLS only supported over IP sockets");
goto error;
}
hostname = s->saddr->u.inet.data->host;
hostname = s->saddr->u.inet.host;
}
/* establish TCP connection, return error if it fails
@@ -448,7 +460,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
object_unref(OBJECT(tlscreds));
}
if (ret < 0) {
qapi_free_SocketAddress(s->saddr);
qapi_free_SocketAddressFlat(s->saddr);
g_free(s->export);
g_free(s->tlscredsid);
}
@@ -474,7 +486,7 @@ static void nbd_close(BlockDriverState *bs)
nbd_client_close(bs);
qapi_free_SocketAddress(s->saddr);
qapi_free_SocketAddressFlat(s->saddr);
g_free(s->export);
g_free(s->tlscredsid);
}
@@ -505,17 +517,17 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
Visitor *ov;
const char *host = NULL, *port = NULL, *path = NULL;
if (s->saddr->type == SOCKET_ADDRESS_KIND_INET) {
const InetSocketAddress *inet = s->saddr->u.inet.data;
if (s->saddr->type == SOCKET_ADDRESS_FLAT_TYPE_INET) {
const InetSocketAddress *inet = &s->saddr->u.inet;
if (!inet->has_ipv4 && !inet->has_ipv6 && !inet->has_to) {
host = inet->host;
port = inet->port;
}
} else if (s->saddr->type == SOCKET_ADDRESS_KIND_UNIX) {
path = s->saddr->u.q_unix.data->path;
}
} else if (s->saddr->type == SOCKET_ADDRESS_FLAT_TYPE_UNIX) {
path = s->saddr->u.q_unix.path;
} /* else can't represent as pseudo-filename */
qdict_put(opts, "driver", qstring_from_str("nbd"));
qdict_put_str(opts, "driver", "nbd");
if (path && s->export) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
@@ -532,16 +544,16 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
}
ov = qobject_output_visitor_new(&saddr_qdict);
visit_type_SocketAddress(ov, NULL, &s->saddr, &error_abort);
visit_type_SocketAddressFlat(ov, NULL, &s->saddr, &error_abort);
visit_complete(ov, &saddr_qdict);
visit_free(ov);
qdict_put_obj(opts, "server", saddr_qdict);
if (s->export) {
qdict_put(opts, "export", qstring_from_str(s->export));
qdict_put_str(opts, "export", s->export);
}
if (s->tlscredsid) {
qdict_put(opts, "tls-creds", qstring_from_str(s->tlscredsid));
qdict_put_str(opts, "tls-creds", s->tlscredsid);
}
qdict_flatten(opts);
+33 -30
View File
@@ -83,7 +83,7 @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp)
error_setg(errp, "Invalid URI specified");
goto out;
}
if (strcmp(uri->scheme, "nfs") != 0) {
if (g_strcmp0(uri->scheme, "nfs") != 0) {
error_setg(errp, "URI scheme must be 'nfs'");
goto out;
}
@@ -104,9 +104,9 @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp)
goto out;
}
qdict_put(options, "server.host", qstring_from_str(uri->server));
qdict_put(options, "server.type", qstring_from_str("inet"));
qdict_put(options, "path", qstring_from_str(uri->path));
qdict_put_str(options, "server.host", uri->server);
qdict_put_str(options, "server.type", "inet");
qdict_put_str(options, "path", uri->path);
for (i = 0; i < qp->n; i++) {
unsigned long long val;
@@ -121,23 +121,17 @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp)
goto out;
}
if (!strcmp(qp->p[i].name, "uid")) {
qdict_put(options, "user",
qstring_from_str(qp->p[i].value));
qdict_put_str(options, "user", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "gid")) {
qdict_put(options, "group",
qstring_from_str(qp->p[i].value));
qdict_put_str(options, "group", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "tcp-syncnt")) {
qdict_put(options, "tcp-syn-count",
qstring_from_str(qp->p[i].value));
qdict_put_str(options, "tcp-syn-count", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "readahead")) {
qdict_put(options, "readahead-size",
qstring_from_str(qp->p[i].value));
qdict_put_str(options, "readahead-size", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "pagecache")) {
qdict_put(options, "page-cache-size",
qstring_from_str(qp->p[i].value));
qdict_put_str(options, "page-cache-size", qp->p[i].value);
} else if (!strcmp(qp->p[i].name, "debug")) {
qdict_put(options, "debug",
qstring_from_str(qp->p[i].value));
qdict_put_str(options, "debug", qp->p[i].value);
} else {
error_setg(errp, "Unknown NFS parameter name: %s",
qp->p[i].name);
@@ -440,19 +434,23 @@ static void nfs_client_close(NFSClient *client)
if (client->context) {
if (client->fh) {
nfs_close(client->context, client->fh);
client->fh = NULL;
}
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
false, NULL, NULL, NULL, NULL);
nfs_destroy_context(client->context);
client->context = NULL;
}
memset(client, 0, sizeof(NFSClient));
g_free(client->path);
qemu_mutex_destroy(&client->mutex);
qapi_free_NFSServer(client->server);
client->server = NULL;
}
static void nfs_file_close(BlockDriverState *bs)
{
NFSClient *client = bs->opaque;
nfs_client_close(client);
qemu_mutex_destroy(&client->mutex);
}
static NFSServer *nfs_config(QDict *options, Error **errp)
@@ -474,6 +472,13 @@ static NFSServer *nfs_config(QDict *options, Error **errp)
goto out;
}
/*
* Caution: this works only because all scalar members of
* NFSServer are QString in @crumpled_addr. The visitor expects
* @crumpled_addr to be typed according to the QAPI schema. It
* is when @options come from -blockdev or blockdev_add. But when
* they come from -drive, they're all QString.
*/
iv = qobject_input_visitor_new(crumpled_addr);
visit_type_NFSServer(iv, NULL, &server, &local_error);
if (local_error) {
@@ -498,6 +503,7 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options,
struct stat st;
char *file = NULL, *strp = NULL;
qemu_mutex_init(&client->mutex);
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
@@ -660,7 +666,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
if (ret < 0) {
return ret;
}
qemu_mutex_init(&client->mutex);
bs->total_sectors = ret;
ret = 0;
return ret;
@@ -804,7 +810,7 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
QObject *server_qdict;
Visitor *ov;
qdict_put(opts, "driver", qstring_from_str("nfs"));
qdict_put_str(opts, "driver", "nfs");
if (client->uid && !client->gid) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
@@ -827,28 +833,25 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
visit_type_NFSServer(ov, NULL, &client->server, &error_abort);
visit_complete(ov, &server_qdict);
qdict_put_obj(opts, "server", server_qdict);
qdict_put(opts, "path", qstring_from_str(client->path));
qdict_put_str(opts, "path", client->path);
if (client->uid) {
qdict_put(opts, "user", qint_from_int(client->uid));
qdict_put_int(opts, "user", client->uid);
}
if (client->gid) {
qdict_put(opts, "group", qint_from_int(client->gid));
qdict_put_int(opts, "group", client->gid);
}
if (client->tcp_syncnt) {
qdict_put(opts, "tcp-syn-cnt",
qint_from_int(client->tcp_syncnt));
qdict_put_int(opts, "tcp-syn-cnt", client->tcp_syncnt);
}
if (client->readahead) {
qdict_put(opts, "readahead-size",
qint_from_int(client->readahead));
qdict_put_int(opts, "readahead-size", client->readahead);
}
if (client->pagecache) {
qdict_put(opts, "page-cache-size",
qint_from_int(client->pagecache));
qdict_put_int(opts, "page-cache-size", client->pagecache);
}
if (client->debug) {
qdict_put(opts, "debug", qint_from_int(client->debug));
qdict_put_int(opts, "debug", client->debug);
}
visit_free(ov);
+1 -1
View File
@@ -232,7 +232,7 @@ static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
bs->drv->format_name);
}
qdict_put(opts, "driver", qstring_from_str(bs->drv->format_name));
qdict_put_str(opts, "driver", bs->drv->format_name);
bs->full_open_options = opts;
}
+21 -11
View File
@@ -192,8 +192,7 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum)
{
BDRVParallelsState *s = bs->opaque;
uint32_t idx, to_allocate, i;
int64_t pos, space;
int64_t pos, space, idx, to_allocate, i;
pos = block_status(s, sector_num, nb_sectors, pnum);
if (pos > 0) {
@@ -201,11 +200,19 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
}
idx = sector_num / s->tracks;
if (idx >= s->bat_size) {
return -EINVAL;
}
to_allocate = DIV_ROUND_UP(sector_num + *pnum, s->tracks) - idx;
/* This function is called only by parallels_co_writev(), which will never
* pass a sector_num at or beyond the end of the image (because the block
* layer never passes such a sector_num to that function). Therefore, idx
* is always below s->bat_size.
* block_status() will limit *pnum so that sector_num + *pnum will not
* exceed the image end. Therefore, idx + to_allocate cannot exceed
* s->bat_size.
* Note that s->bat_size is an unsigned int, therefore idx + to_allocate
* will always fit into a uint32_t. */
assert(idx < s->bat_size && idx + to_allocate <= s->bat_size);
space = to_allocate * s->tracks;
if (s->data_end + space > bdrv_getlength(bs->file->bs) >> BDRV_SECTOR_BITS) {
int ret;
@@ -216,7 +223,8 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
space << BDRV_SECTOR_BITS, 0);
} else {
ret = bdrv_truncate(bs->file,
(s->data_end + space) << BDRV_SECTOR_BITS);
(s->data_end + space) << BDRV_SECTOR_BITS,
NULL);
}
if (ret < 0) {
return ret;
@@ -449,8 +457,10 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
size - res->image_end_offset);
res->leaks += count;
if (fix & BDRV_FIX_LEAKS) {
ret = bdrv_truncate(bs->file, res->image_end_offset);
Error *local_err = NULL;
ret = bdrv_truncate(bs->file, res->image_end_offset, &local_err);
if (ret < 0) {
error_report_err(local_err);
res->check_errors++;
return ret;
}
@@ -497,7 +507,7 @@ static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
blk_set_allow_write_beyond_eof(file, true);
ret = blk_truncate(file, 0);
ret = blk_truncate(file, 0, errp);
if (ret < 0) {
goto exit;
}
@@ -689,7 +699,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
}
if (!(flags & BDRV_O_RESIZE) || !bdrv_has_zero_init(bs->file->bs) ||
bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs)) != 0) {
bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs), NULL) != 0) {
s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
}
@@ -732,7 +742,7 @@ static void parallels_close(BlockDriverState *bs)
}
if (bs->open_flags & BDRV_O_RDWR) {
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS);
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, NULL);
}
g_free(s->bat_dirty_bmap);
+28 -6
View File
@@ -64,7 +64,6 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
info->backing_file = g_strdup(bs->backing_file);
}
info->backing_file_depth = bdrv_get_backing_file_depth(bs);
info->detect_zeroes = bs->detect_zeroes;
if (blk && blk_get_public(blk)->throttle_state) {
@@ -125,6 +124,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
bs0 = bs;
p_image_info = &info->image;
info->backing_file_depth = 0;
while (1) {
Error *local_err = NULL;
bdrv_query_image_info(bs0, p_image_info, &local_err);
@@ -133,13 +133,21 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
qapi_free_BlockDeviceInfo(info);
return NULL;
}
if (bs0->drv && bs0->backing) {
info->backing_file_depth++;
bs0 = bs0->backing->bs;
(*p_image_info)->has_backing_image = true;
p_image_info = &((*p_image_info)->backing_image);
} else {
break;
}
/* Skip automatically inserted nodes that the user isn't aware of for
* query-block (blk != NULL), but not for query-named-block-nodes */
while (blk && bs0 && bs0->drv && bs0->implicit) {
bs0 = backing_bs(bs0);
}
}
return info;
@@ -322,6 +330,12 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
{
BlockInfo *info = g_malloc0(sizeof(*info));
BlockDriverState *bs = blk_bs(blk);
/* Skip automatically inserted nodes that the user isn't aware of */
while (bs && bs->drv && bs->implicit) {
bs = backing_bs(bs);
}
info->device = g_strdup(blk_name(blk));
info->type = g_strdup("unknown");
info->locked = blk_dev_is_medium_locked(blk);
@@ -424,8 +438,8 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
}
}
static BlockStats *bdrv_query_bds_stats(const BlockDriverState *bs,
bool query_backing)
static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs,
bool blk_level)
{
BlockStats *s = NULL;
@@ -436,6 +450,14 @@ static BlockStats *bdrv_query_bds_stats(const BlockDriverState *bs,
return s;
}
/* Skip automatically inserted nodes that the user isn't aware of in
* a BlockBackend-level command. Stay at the exact node for a node-level
* command. */
while (blk_level && bs->drv && bs->implicit) {
bs = backing_bs(bs);
assert(bs);
}
if (bdrv_get_node_name(bs)[0]) {
s->has_node_name = true;
s->node_name = g_strdup(bdrv_get_node_name(bs));
@@ -445,12 +467,12 @@ static BlockStats *bdrv_query_bds_stats(const BlockDriverState *bs,
if (bs->file) {
s->has_parent = true;
s->parent = bdrv_query_bds_stats(bs->file->bs, query_backing);
s->parent = bdrv_query_bds_stats(bs->file->bs, blk_level);
}
if (query_backing && bs->backing) {
if (blk_level && bs->backing) {
s->has_backing = true;
s->backing = bdrv_query_bds_stats(bs->backing->bs, query_backing);
s->backing = bdrv_query_bds_stats(bs->backing->bs, blk_level);
}
return s;
+3 -3
View File
@@ -473,7 +473,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
/* round to cluster size */
cluster_offset = (cluster_offset + s->cluster_size - 1) &
~(s->cluster_size - 1);
bdrv_truncate(bs->file, cluster_offset + s->cluster_size);
bdrv_truncate(bs->file, cluster_offset + s->cluster_size, NULL);
/* if encrypted, we must initialize the cluster
content which won't be written */
if (bs->encrypted &&
@@ -833,7 +833,7 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
blk_set_allow_write_beyond_eof(qcow_blk, true);
ret = blk_truncate(qcow_blk, 0);
ret = blk_truncate(qcow_blk, 0, errp);
if (ret < 0) {
goto exit;
}
@@ -916,7 +916,7 @@ static int qcow_make_empty(BlockDriverState *bs)
if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
l1_length) < 0)
return -1;
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, NULL);
if (ret < 0)
return ret;
+4 -6
View File
@@ -1519,12 +1519,10 @@ int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
end_offset = offset + (nb_sectors << BDRV_SECTOR_BITS);
/* Round start up and end down */
offset = align_offset(offset, s->cluster_size);
end_offset = start_of_cluster(s, end_offset);
if (offset > end_offset) {
return 0;
/* The caller must cluster-align start; round end down except at EOF */
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
if (end_offset != bs->total_sectors * BDRV_SECTOR_SIZE) {
end_offset = start_of_cluster(s, end_offset);
}
nb_clusters = size_to_clusters(s, end_offset - offset);
+4 -1
View File
@@ -1728,14 +1728,17 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
if (fix & BDRV_FIX_ERRORS) {
int64_t new_nb_clusters;
Error *local_err = NULL;
if (offset > INT64_MAX - s->cluster_size) {
ret = -EINVAL;
goto resize_fail;
}
ret = bdrv_truncate(bs->file, offset + s->cluster_size);
ret = bdrv_truncate(bs->file, offset + s->cluster_size,
&local_err);
if (ret < 0) {
error_report_err(local_err);
goto resize_fail;
}
size = bdrv_getlength(bs->file->bs);
+11 -7
View File
@@ -2265,7 +2265,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
* table)
*/
options = qdict_new();
qdict_put(options, "driver", qstring_from_str("qcow2"));
qdict_put_str(options, "driver", "qcow2");
blk = blk_new_open(filename, NULL, options,
BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH,
&local_err);
@@ -2294,9 +2294,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
}
/* Okay, now that we have a valid image, let's give it the right size */
ret = blk_truncate(blk, total_size);
ret = blk_truncate(blk, total_size, errp);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not resize image");
error_prepend(errp, "Could not resize image: ");
goto out;
}
@@ -2327,7 +2327,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
/* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */
options = qdict_new();
qdict_put(options, "driver", qstring_from_str("qcow2"));
qdict_put_str(options, "driver", "qcow2");
blk = blk_new_open(filename, NULL, options,
BDRV_O_RDWR | BDRV_O_NO_BACKING, &local_err);
if (blk == NULL) {
@@ -2584,7 +2584,7 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
/* align end of file to a sector boundary to ease reading with
sector based I/Os */
cluster_offset = bdrv_getlength(bs->file->bs);
return bdrv_truncate(bs->file, cluster_offset);
return bdrv_truncate(bs->file, cluster_offset, NULL);
}
buf = qemu_blockalign(bs, s->cluster_size);
@@ -2674,6 +2674,7 @@ fail:
static int make_completely_empty(BlockDriverState *bs)
{
BDRVQcow2State *s = bs->opaque;
Error *local_err = NULL;
int ret, l1_clusters;
int64_t offset;
uint64_t *new_reftable = NULL;
@@ -2798,8 +2799,10 @@ static int make_completely_empty(BlockDriverState *bs)
goto fail;
}
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size);
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size,
&local_err);
if (ret < 0) {
error_report_err(local_err);
goto fail;
}
@@ -3273,9 +3276,10 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
return ret;
}
ret = blk_truncate(blk, new_size);
ret = blk_truncate(blk, new_size, &local_err);
blk_unref(blk);
if (ret < 0) {
error_report_err(local_err);
return ret;
}
}
+1 -1
View File
@@ -635,7 +635,7 @@ static int qed_create(const char *filename, uint32_t cluster_size,
blk_set_allow_write_beyond_eof(blk, true);
/* File must start empty and grow, check truncate is supported */
ret = blk_truncate(blk, 0);
ret = blk_truncate(blk, 0, errp);
if (ret < 0) {
goto out;
}
+6 -10
View File
@@ -1096,19 +1096,15 @@ static void quorum_refresh_filename(BlockDriverState *bs, QDict *options)
children = qlist_new();
for (i = 0; i < s->num_children; i++) {
QINCREF(s->children[i]->bs->full_open_options);
qlist_append_obj(children,
QOBJECT(s->children[i]->bs->full_open_options));
qlist_append(children, s->children[i]->bs->full_open_options);
}
opts = qdict_new();
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("quorum")));
qdict_put_obj(opts, QUORUM_OPT_VOTE_THRESHOLD,
QOBJECT(qint_from_int(s->threshold)));
qdict_put_obj(opts, QUORUM_OPT_BLKVERIFY,
QOBJECT(qbool_from_bool(s->is_blkverify)));
qdict_put_obj(opts, QUORUM_OPT_REWRITE,
QOBJECT(qbool_from_bool(s->rewrite_corrupted)));
qdict_put_obj(opts, "children", QOBJECT(children));
qdict_put_str(opts, "driver", "quorum");
qdict_put_int(opts, QUORUM_OPT_VOTE_THRESHOLD, s->threshold);
qdict_put_bool(opts, QUORUM_OPT_BLKVERIFY, s->is_blkverify);
qdict_put_bool(opts, QUORUM_OPT_REWRITE, s->rewrite_corrupted);
qdict_put(opts, "children", children);
bs->full_open_options = opts;
}
+1 -1
View File
@@ -341,7 +341,7 @@ static int raw_truncate(BlockDriverState *bs, int64_t offset)
s->size = offset;
offset += s->offset;
return bdrv_truncate(bs->file, offset);
return bdrv_truncate(bs->file, offset, NULL);
}
static int raw_media_changed(BlockDriverState *bs)
+54 -47
View File
@@ -20,6 +20,7 @@
#include "crypto/secret.h"
#include "qemu/cutils.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qjson.h"
/*
* When specifying the image filename use:
@@ -135,18 +136,16 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
Error **errp)
{
const char *start;
char *p, *buf, *keypairs;
char *p, *buf;
QList *keypairs = NULL;
char *found_str;
size_t max_keypair_size;
if (!strstart(filename, "rbd:", &start)) {
error_setg(errp, "File name must start with 'rbd:'");
return;
}
max_keypair_size = strlen(start) + 1;
buf = g_strdup(start);
keypairs = g_malloc0(max_keypair_size);
p = buf;
found_str = qemu_rbd_next_tok(p, '/', &p);
@@ -155,20 +154,20 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
goto done;
}
qemu_rbd_unescape(found_str);
qdict_put(options, "pool", qstring_from_str(found_str));
qdict_put_str(options, "pool", found_str);
if (strchr(p, '@')) {
found_str = qemu_rbd_next_tok(p, '@', &p);
qemu_rbd_unescape(found_str);
qdict_put(options, "image", qstring_from_str(found_str));
qdict_put_str(options, "image", found_str);
found_str = qemu_rbd_next_tok(p, ':', &p);
qemu_rbd_unescape(found_str);
qdict_put(options, "snapshot", qstring_from_str(found_str));
qdict_put_str(options, "snapshot", found_str);
} else {
found_str = qemu_rbd_next_tok(p, ':', &p);
qemu_rbd_unescape(found_str);
qdict_put(options, "image", qstring_from_str(found_str));
qdict_put_str(options, "image", found_str);
}
if (!p) {
goto done;
@@ -190,37 +189,34 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
qemu_rbd_unescape(value);
if (!strcmp(name, "conf")) {
qdict_put(options, "conf", qstring_from_str(value));
qdict_put_str(options, "conf", value);
} else if (!strcmp(name, "id")) {
qdict_put(options, "user" , qstring_from_str(value));
qdict_put_str(options, "user", value);
} else {
/* FIXME: This is pretty ugly, and not the right way to do this.
* These should be contained in a structure, and then
* passed explicitly as individual key/value pairs to
* rados. Consider this legacy code that needs to be
* updated. */
char *tmp = g_malloc0(max_keypair_size);
/* only use a delimiter if it is not the first keypair found */
/* These are sets of unknown key/value pairs we'll pass along
* to ceph */
if (keypairs[0]) {
snprintf(tmp, max_keypair_size, ":%s=%s", name, value);
pstrcat(keypairs, max_keypair_size, tmp);
} else {
snprintf(keypairs, max_keypair_size, "%s=%s", name, value);
/*
* We pass these internally to qemu_rbd_set_keypairs(), so
* we can get away with the simpler list of [ "key1",
* "value1", "key2", "value2" ] rather than a raw dict
* { "key1": "value1", "key2": "value2" } where we can't
* guarantee order, or even a more correct but complex
* [ { "key1": "value1" }, { "key2": "value2" } ]
*/
if (!keypairs) {
keypairs = qlist_new();
}
g_free(tmp);
qlist_append_str(keypairs, name);
qlist_append_str(keypairs, value);
}
}
if (keypairs[0]) {
qdict_put(options, "=keyvalue-pairs", qstring_from_str(keypairs));
if (keypairs) {
qdict_put(options, "=keyvalue-pairs",
qobject_to_json(QOBJECT(keypairs)));
}
done:
g_free(buf);
g_free(keypairs);
QDECREF(keypairs);
return;
}
@@ -244,36 +240,41 @@ static int qemu_rbd_set_auth(rados_t cluster, const char *secretid,
return 0;
}
static int qemu_rbd_set_keypairs(rados_t cluster, const char *keypairs,
static int qemu_rbd_set_keypairs(rados_t cluster, const char *keypairs_json,
Error **errp)
{
char *p, *buf;
char *name;
char *value;
QList *keypairs;
QString *name;
QString *value;
const char *key;
size_t remaining;
int ret = 0;
buf = g_strdup(keypairs);
p = buf;
if (!keypairs_json) {
return ret;
}
keypairs = qobject_to_qlist(qobject_from_json(keypairs_json,
&error_abort));
remaining = qlist_size(keypairs) / 2;
assert(remaining);
while (p) {
name = qemu_rbd_next_tok(p, '=', &p);
if (!p) {
error_setg(errp, "conf option %s has no value", name);
ret = -EINVAL;
break;
}
while (remaining--) {
name = qobject_to_qstring(qlist_pop(keypairs));
value = qobject_to_qstring(qlist_pop(keypairs));
assert(name && value);
key = qstring_get_str(name);
value = qemu_rbd_next_tok(p, ':', &p);
ret = rados_conf_set(cluster, name, value);
ret = rados_conf_set(cluster, key, qstring_get_str(value));
QDECREF(name);
QDECREF(value);
if (ret < 0) {
error_setg_errno(errp, -ret, "invalid conf option %s", name);
error_setg_errno(errp, -ret, "invalid conf option %s", key);
ret = -EINVAL;
break;
}
}
g_free(buf);
QDECREF(keypairs);
return ret;
}
@@ -384,6 +385,12 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
goto exit;
}
/*
* Caution: while qdict_get_try_str() is fine, getting non-string
* types would require more care. When @options come from -blockdev
* or blockdev_add, its members are typed according to the QAPI
* schema, but when they come from -drive, they're all QString.
*/
pool = qdict_get_try_str(options, "pool");
conf = qdict_get_try_str(options, "conf");
clientname = qdict_get_try_str(options, "user");
+63 -37
View File
@@ -13,9 +13,11 @@
*/
#include "qemu/osdep.h"
#include "qapi-visit.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qint.h"
#include "qapi/qobject-input-visitor.h"
#include "qemu/uri.h"
#include "qemu/error-report.h"
#include "qemu/sockets.h"
@@ -547,6 +549,47 @@ static SocketAddress *sd_socket_address(const char *path,
return addr;
}
static SocketAddress *sd_server_config(QDict *options, Error **errp)
{
QDict *server = NULL;
QObject *crumpled_server = NULL;
Visitor *iv = NULL;
SocketAddressFlat *saddr_flat = NULL;
SocketAddress *saddr = NULL;
Error *local_err = NULL;
qdict_extract_subqdict(options, &server, "server.");
crumpled_server = qdict_crumple(server, errp);
if (!crumpled_server) {
goto done;
}
/*
* FIXME .numeric, .to, .ipv4 or .ipv6 don't work with -drive
* server.type=inet. .to doesn't matter, it's ignored anyway.
* That's because when @options come from -blockdev or
* blockdev_add, members are typed according to the QAPI schema,
* but when they come from -drive, they're all QString. The
* visitor expects the former.
*/
iv = qobject_input_visitor_new(crumpled_server);
visit_type_SocketAddressFlat(iv, NULL, &saddr_flat, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto done;
}
saddr = socket_address_crumple(saddr_flat);
done:
qapi_free_SocketAddressFlat(saddr_flat);
visit_free(iv);
qobject_decref(crumpled_server);
QDECREF(server);
return saddr;
}
/* Return -EIO in case of error, file descriptor on success */
static int connect_to_sdog(BDRVSheepdogState *s, Error **errp)
{
@@ -693,7 +736,7 @@ static int do_req(int sockfd, BlockDriverState *bs, SheepdogReq *hdr,
} else {
co = qemu_coroutine_create(do_co_req, &srco);
if (bs) {
qemu_coroutine_enter(co);
bdrv_coroutine_enter(bs, co);
BDRV_POLL_WHILE(bs, !srco.finished);
} else {
qemu_coroutine_enter(co);
@@ -899,7 +942,7 @@ static void co_read_response(void *opaque)
s->co_recv = qemu_coroutine_create(aio_read_response, opaque);
}
aio_co_wake(s->co_recv);
aio_co_enter(s->aio_context, s->co_recv);
}
static void co_write_request(void *opaque)
@@ -1009,11 +1052,11 @@ static void sd_parse_uri(SheepdogConfig *cfg, const char *filename,
}
/* transport */
if (!strcmp(uri->scheme, "sheepdog")) {
if (!g_strcmp0(uri->scheme, "sheepdog")) {
is_unix = false;
} else if (!strcmp(uri->scheme, "sheepdog+tcp")) {
} else if (!g_strcmp0(uri->scheme, "sheepdog+tcp")) {
is_unix = false;
} else if (!strcmp(uri->scheme, "sheepdog+unix")) {
} else if (!g_strcmp0(uri->scheme, "sheepdog+unix")) {
is_unix = true;
} else {
error_setg(&err, "URI scheme must be 'sheepdog', 'sheepdog+tcp',"
@@ -1174,15 +1217,15 @@ static void sd_parse_filename(const char *filename, QDict *options,
return;
}
if (cfg.host) {
qdict_set_default_str(options, "host", cfg.host);
}
if (cfg.port) {
snprintf(buf, sizeof(buf), "%d", cfg.port);
qdict_set_default_str(options, "port", buf);
}
if (cfg.path) {
qdict_set_default_str(options, "path", cfg.path);
qdict_set_default_str(options, "server.path", cfg.path);
qdict_set_default_str(options, "server.type", "unix");
} else {
qdict_set_default_str(options, "server.type", "inet");
qdict_set_default_str(options, "server.host",
cfg.host ?: SD_DEFAULT_ADDR);
snprintf(buf, sizeof(buf), "%d", cfg.port ?: SD_DEFAULT_PORT);
qdict_set_default_str(options, "server.port", buf);
}
qdict_set_default_str(options, "vdi", cfg.vdi);
qdict_set_default_str(options, "tag", cfg.tag);
@@ -1509,18 +1552,6 @@ static QemuOptsList runtime_opts = {
.name = "sheepdog",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "host",
.type = QEMU_OPT_STRING,
},
{
.name = "port",
.type = QEMU_OPT_STRING,
},
{
.name = "path",
.type = QEMU_OPT_STRING,
},
{
.name = "vdi",
.type = QEMU_OPT_STRING,
@@ -1543,7 +1574,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
int ret, fd;
uint32_t vid = 0;
BDRVSheepdogState *s = bs->opaque;
const char *host, *port, *path, *vdi, *snap_id_str, *tag;
const char *vdi, *snap_id_str, *tag;
uint64_t snap_id;
char *buf = NULL;
QemuOpts *opts;
@@ -1560,20 +1591,17 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
goto err_no_fd;
}
host = qemu_opt_get(opts, "host");
port = qemu_opt_get(opts, "port");
path = qemu_opt_get(opts, "path");
s->addr = sd_server_config(options, errp);
if (!s->addr) {
ret = -EINVAL;
goto err_no_fd;
}
vdi = qemu_opt_get(opts, "vdi");
snap_id_str = qemu_opt_get(opts, "snap-id");
snap_id = qemu_opt_get_number(opts, "snap-id", CURRENT_VDI_ID);
tag = qemu_opt_get(opts, "tag");
if ((host || port) && path) {
error_setg(errp, "can't use 'path' together with 'host' or 'port'");
ret = -EINVAL;
goto err_no_fd;
}
if (!vdi) {
error_setg(errp, "parameter 'vdi' is missing");
ret = -EINVAL;
@@ -1604,8 +1632,6 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
goto err_no_fd;
}
s->addr = sd_socket_address(path, host, port);
QLIST_INIT(&s->inflight_aio_head);
QLIST_INIT(&s->failed_aio_head);
QLIST_INIT(&s->inflight_aiocb_head);
+23 -3
View File
@@ -27,6 +27,7 @@
#include "block/block_int.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qstring.h"
QemuOptsList internal_snapshot_opts = {
.name = "snapshot",
@@ -189,14 +190,33 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
}
if (bs->file) {
BlockDriverState *file;
QDict *options = qdict_clone_shallow(bs->options);
QDict *file_options;
file = bs->file->bs;
/* Prevent it from getting deleted when detached from bs */
bdrv_ref(file);
qdict_extract_subqdict(options, &file_options, "file.");
QDECREF(file_options);
qdict_put_str(options, "file", bdrv_get_node_name(file));
drv->bdrv_close(bs);
ret = bdrv_snapshot_goto(bs->file->bs, snapshot_id);
open_ret = drv->bdrv_open(bs, NULL, bs->open_flags, NULL);
bdrv_unref_child(bs, bs->file);
bs->file = NULL;
ret = bdrv_snapshot_goto(file, snapshot_id);
open_ret = drv->bdrv_open(bs, options, bs->open_flags, NULL);
QDECREF(options);
if (open_ret < 0) {
bdrv_unref(bs->file->bs);
bdrv_unref(file);
bs->drv = NULL;
return open_ret;
}
assert(bs->file->bs == file);
bdrv_unref(file);
return ret;
}
+16 -10
View File
@@ -205,7 +205,7 @@ static int parse_uri(const char *filename, QDict *options, Error **errp)
return -EINVAL;
}
if (strcmp(uri->scheme, "ssh") != 0) {
if (g_strcmp0(uri->scheme, "ssh") != 0) {
error_setg(errp, "URI scheme must be 'ssh'");
goto err;
}
@@ -227,24 +227,23 @@ static int parse_uri(const char *filename, QDict *options, Error **errp)
}
if(uri->user && strcmp(uri->user, "") != 0) {
qdict_put(options, "user", qstring_from_str(uri->user));
qdict_put_str(options, "user", uri->user);
}
qdict_put(options, "server.host", qstring_from_str(uri->server));
qdict_put_str(options, "server.host", uri->server);
port_str = g_strdup_printf("%d", uri->port ?: 22);
qdict_put(options, "server.port", qstring_from_str(port_str));
qdict_put_str(options, "server.port", port_str);
g_free(port_str);
qdict_put(options, "path", qstring_from_str(uri->path));
qdict_put_str(options, "path", uri->path);
/* Pick out any query parameters that we understand, and ignore
* the rest.
*/
for (i = 0; i < qp->n; ++i) {
if (strcmp(qp->p[i].name, "host_key_check") == 0) {
qdict_put(options, "host_key_check",
qstring_from_str(qp->p[i].value));
qdict_put_str(options, "host_key_check", qp->p[i].value);
}
}
@@ -574,9 +573,8 @@ static bool ssh_process_legacy_socket_options(QDict *output_opts,
}
if (host) {
qdict_put(output_opts, "server.host", qstring_from_str(host));
qdict_put(output_opts, "server.port",
qstring_from_str(port ?: stringify(22)));
qdict_put_str(output_opts, "server.host", host);
qdict_put_str(output_opts, "server.port", port ?: stringify(22));
}
return true;
@@ -601,6 +599,14 @@ static InetSocketAddress *ssh_config(QDict *options, Error **errp)
goto out;
}
/*
* FIXME .numeric, .to, .ipv4 or .ipv6 don't work with -drive.
* .to doesn't matter, it's ignored anyway.
* That's because when @options come from -blockdev or
* blockdev_add, members are typed according to the QAPI schema,
* but when they come from -drive, they're all QString. The
* visitor expects the former.
*/
iv = qobject_input_visitor_new(crumpled_addr);
visit_type_InetSocketAddress(iv, NULL, &inet, &local_error);
if (local_error) {
+1 -1
View File
@@ -280,6 +280,6 @@ void stream_start(const char *job_id, BlockDriverState *bs,
fail:
if (orig_bs_flags != bdrv_get_flags(bs)) {
bdrv_reopen(bs, s->bs_flags, NULL);
bdrv_reopen(bs, orig_bs_flags, NULL);
}
}
+2 -2
View File
@@ -832,9 +832,9 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
}
if (image_type == VDI_TYPE_STATIC) {
ret = blk_truncate(blk, offset + blocks * block_size);
ret = blk_truncate(blk, offset + blocks * block_size, errp);
if (ret < 0) {
error_setg(errp, "Failed to statically allocate %s", filename);
error_prepend(errp, "Failed to statically allocate %s", filename);
goto exit;
}
}
+1 -1
View File
@@ -548,7 +548,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
if (new_file_size % (1024*1024)) {
/* round up to nearest 1MB boundary */
new_file_size = ((new_file_size >> 20) + 1) << 20;
bdrv_truncate(bs->file, new_file_size);
bdrv_truncate(bs->file, new_file_size, NULL);
}
}
qemu_vfree(desc_entries);
+22 -7
View File
@@ -1171,7 +1171,7 @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
/* per the spec, the address for a block is in units of 1MB */
*new_offset = ROUND_UP(*new_offset, 1024 * 1024);
return bdrv_truncate(bs->file, *new_offset + s->block_size);
return bdrv_truncate(bs->file, *new_offset + s->block_size, NULL);
}
/*
@@ -1586,7 +1586,7 @@ exit:
static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
uint64_t image_size, VHDXImageType type,
bool use_zero_blocks, uint64_t file_offset,
uint32_t length)
uint32_t length, Error **errp)
{
int ret = 0;
uint64_t data_file_offset;
@@ -1607,16 +1607,21 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
if (type == VHDX_TYPE_DYNAMIC) {
/* All zeroes, so we can just extend the file - the end of the BAT
* is the furthest thing we have written yet */
ret = blk_truncate(blk, data_file_offset);
ret = blk_truncate(blk, data_file_offset, errp);
if (ret < 0) {
error_setg_errno(errp, -ret,
"Failed to resize the underlying file");
goto exit;
}
} else if (type == VHDX_TYPE_FIXED) {
ret = blk_truncate(blk, data_file_offset + image_size);
ret = blk_truncate(blk, data_file_offset + image_size, errp);
if (ret < 0) {
error_setg_errno(errp, -ret,
"Failed to resize the underlying file");
goto exit;
}
} else {
error_setg(errp, "Unsupported image type");
ret = -ENOTSUP;
goto exit;
}
@@ -1627,6 +1632,7 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
/* for a fixed file, the default BAT entry is not zero */
s->bat = g_try_malloc0(length);
if (length && s->bat == NULL) {
error_setg(errp, "Failed to allocate memory for the BAT");
ret = -ENOMEM;
goto exit;
}
@@ -1646,6 +1652,7 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
}
ret = blk_pwrite(blk, file_offset, s->bat, length, 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to write the BAT");
goto exit;
}
}
@@ -1671,7 +1678,8 @@ static int vhdx_create_new_region_table(BlockBackend *blk,
uint32_t log_size,
bool use_zero_blocks,
VHDXImageType type,
uint64_t *metadata_offset)
uint64_t *metadata_offset,
Error **errp)
{
int ret = 0;
uint32_t offset = 0;
@@ -1740,7 +1748,7 @@ static int vhdx_create_new_region_table(BlockBackend *blk,
/* The region table gives us the data we need to create the BAT,
* so do that now */
ret = vhdx_create_bat(blk, s, image_size, type, use_zero_blocks,
bat_file_offset, bat_length);
bat_file_offset, bat_length, errp);
if (ret < 0) {
goto exit;
}
@@ -1749,12 +1757,14 @@ static int vhdx_create_new_region_table(BlockBackend *blk,
ret = blk_pwrite(blk, VHDX_REGION_TABLE_OFFSET, buffer,
VHDX_HEADER_BLOCK_SIZE, 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to write first region table");
goto exit;
}
ret = blk_pwrite(blk, VHDX_REGION_TABLE2_OFFSET, buffer,
VHDX_HEADER_BLOCK_SIZE, 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to write second region table");
goto exit;
}
@@ -1825,6 +1835,7 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
ret = -ENOTSUP;
goto exit;
} else {
error_setg(errp, "Invalid subformat '%s'", type);
ret = -EINVAL;
goto exit;
}
@@ -1879,12 +1890,14 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature),
0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to write file signature");
goto delete_and_exit;
}
if (creator) {
ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature),
creator, creator_items * sizeof(gunichar2), 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to write creator field");
goto delete_and_exit;
}
}
@@ -1893,13 +1906,14 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
/* Creates (B),(C) */
ret = vhdx_create_new_headers(blk, image_size, log_size);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to write image headers");
goto delete_and_exit;
}
/* Creates (D),(E),(G) explicitly. (F) created as by-product */
ret = vhdx_create_new_region_table(blk, image_size, block_size, 512,
log_size, use_zero_blocks, image_type,
&metadata_offset);
&metadata_offset, errp);
if (ret < 0) {
goto delete_and_exit;
}
@@ -1908,6 +1922,7 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
ret = vhdx_create_new_metadata(blk, image_size, block_size, 512,
metadata_offset, image_type);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to initialize metadata");
goto delete_and_exit;
}
+3 -10
View File
@@ -1714,10 +1714,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
blk_set_allow_write_beyond_eof(blk, true);
if (flat) {
ret = blk_truncate(blk, filesize);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not truncate file");
}
ret = blk_truncate(blk, filesize, errp);
goto exit;
}
magic = cpu_to_be32(VMDK4_MAGIC);
@@ -1780,9 +1777,8 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
goto exit;
}
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9);
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, errp);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not truncate file");
goto exit;
}
@@ -2090,10 +2086,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
* for description file */
if (desc_offset == 0) {
ret = blk_truncate(new_blk, desc_len);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not truncate file");
}
ret = blk_truncate(new_blk, desc_len, errp);
}
exit:
if (new_blk) {
+7 -6
View File
@@ -851,20 +851,21 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
}
static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
int64_t total_size)
int64_t total_size, Error **errp)
{
int ret;
/* Add footer to total size */
total_size += HEADER_SIZE;
ret = blk_truncate(blk, total_size);
ret = blk_truncate(blk, total_size, errp);
if (ret < 0) {
return ret;
}
ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE, 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "Unable to write VHD header");
return ret;
}
@@ -996,11 +997,11 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
if (disk_type == VHD_DYNAMIC) {
ret = create_dynamic_disk(blk, buf, total_sectors);
if (ret < 0) {
error_setg(errp, "Unable to create or write VHD header");
}
} else {
ret = create_fixed_disk(blk, buf, total_size);
}
if (ret < 0) {
error_setg(errp, "Unable to create or write VHD header");
ret = create_fixed_disk(blk, buf, total_size, errp);
}
out:
+6 -7
View File
@@ -1057,10 +1057,10 @@ static void vvfat_parse_filename(const char *filename, QDict *options,
}
/* Fill in the options QDict */
qdict_put(options, "dir", qstring_from_str(filename));
qdict_put(options, "fat-type", qint_from_int(fat_type));
qdict_put(options, "floppy", qbool_from_bool(floppy));
qdict_put(options, "rw", qbool_from_bool(rw));
qdict_put_str(options, "dir", filename);
qdict_put_int(options, "fat-type", fat_type);
qdict_put_bool(options, "floppy", floppy);
qdict_put_bool(options, "rw", rw);
}
static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
@@ -2958,8 +2958,7 @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file)
{
BDRVVVFATState* s = bs->opaque;
*n = s->sector_count - sector_num;
*n = bs->total_sectors - sector_num;
if (*n > nb_sectors) {
*n = nb_sectors;
} else if (*n < 0) {
@@ -3040,7 +3039,7 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
}
options = qdict_new();
qdict_put(options, "write-target.driver", qstring_from_str("qcow"));
qdict_put_str(options, "write-target.driver", "qcow");
s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs,
&child_vvfat_qcow, false, errp);
QDECREF(options);
+6 -1
View File
@@ -27,6 +27,10 @@ typedef struct NBDServerData {
static NBDServerData *nbd_server;
static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
{
nbd_client_put(client);
}
static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
gpointer opaque)
@@ -46,7 +50,7 @@ static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
nbd_client_new(NULL, cioc,
nbd_server->tlscreds, NULL,
nbd_client_put);
nbd_blockdev_client_closed);
object_unref(OBJECT(cioc));
return TRUE;
}
@@ -124,6 +128,7 @@ void qmp_nbd_server_start(SocketAddress *addr,
goto error;
}
/* TODO SOCKET_ADDRESS_KIND_FD where fd has AF_INET or AF_INET6 */
if (addr->type != SOCKET_ADDRESS_KIND_INET) {
error_setg(errp, "TLS is only supported with IPv4/IPv6");
goto error;
+32 -43
View File
@@ -527,7 +527,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
error_setg(errp, "Cannot specify both 'driver' and 'format'");
goto early_err;
}
qdict_put(bs_opts, "driver", qstring_from_str(buf));
qdict_put_str(bs_opts, "driver", buf);
}
on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
@@ -903,10 +903,8 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
copy_on_read = false;
}
qdict_put(bs_opts, BDRV_OPT_READ_ONLY,
qstring_from_str(read_only ? "on" : "off"));
qdict_put(bs_opts, "copy-on-read",
qstring_from_str(copy_on_read ? "on" :"off"));
qdict_put_str(bs_opts, BDRV_OPT_READ_ONLY, read_only ? "on" : "off");
qdict_put_str(bs_opts, "copy-on-read", copy_on_read ? "on" : "off");
/* Controller type */
value = qemu_opt_get(legacy_opts, "if");
@@ -1030,7 +1028,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
new_id = g_strdup_printf("%s%s%i", if_name[type],
mediastr, unit_id);
}
qdict_put(bs_opts, "id", qstring_from_str(new_id));
qdict_put_str(bs_opts, "id", new_id);
g_free(new_id);
}
@@ -1067,7 +1065,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
error_report("werror is not supported by this bus type");
goto fail;
}
qdict_put(bs_opts, "werror", qstring_from_str(werror));
qdict_put_str(bs_opts, "werror", werror);
}
rerror = qemu_opt_get(legacy_opts, "rerror");
@@ -1077,7 +1075,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
error_report("rerror is not supported by this bus type");
goto fail;
}
qdict_put(bs_opts, "rerror", qstring_from_str(rerror));
qdict_put_str(bs_opts, "rerror", rerror);
}
/* Actual block device init: Functionality shared with blockdev-add */
@@ -1737,10 +1735,9 @@ static void external_snapshot_prepare(BlkActionState *common,
options = qdict_new();
if (s->has_snapshot_node_name) {
qdict_put(options, "node-name",
qstring_from_str(snapshot_node_name));
qdict_put_str(options, "node-name", snapshot_node_name);
}
qdict_put(options, "driver", qstring_from_str(format));
qdict_put_str(options, "driver", format);
flags |= BDRV_O_NO_BACKING;
}
@@ -1772,6 +1769,8 @@ static void external_snapshot_prepare(BlkActionState *common,
return;
}
bdrv_set_aio_context(state->new_bs, state->aio_context);
/* This removes our old bs and adds the new bs. This is an operation that
* can fail, so we need to do it in .prepare; undoing it for abort is
* always possible. */
@@ -1789,8 +1788,6 @@ static void external_snapshot_commit(BlkActionState *common)
ExternalSnapshotState *state =
DO_UPCAST(ExternalSnapshotState, common, common);
bdrv_set_aio_context(state->new_bs, state->aio_context);
/* We don't need (or want) to use the transactional
* bdrv_reopen_multiple() across all the entries at once, because we
* don't want to abort all of them if one of them fails the reopen */
@@ -2579,11 +2576,10 @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
options = qdict_new();
detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
qdict_put(options, "detect-zeroes",
qstring_from_str(detect_zeroes ? "on" : "off"));
qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
if (has_format) {
qdict_put(options, "driver", qstring_from_str(format));
qdict_put_str(options, "driver", format);
}
medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
@@ -2927,29 +2923,9 @@ void qmp_block_resize(bool has_device, const char *device,
goto out;
}
/* complete all in-flight operations before resizing the device */
bdrv_drain_all();
ret = blk_truncate(blk, size);
switch (ret) {
case 0:
break;
case -ENOMEDIUM:
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
break;
case -ENOTSUP:
error_setg(errp, QERR_UNSUPPORTED);
break;
case -EACCES:
error_setg(errp, "Device '%s' is read only", device);
break;
case -EBUSY:
error_setg(errp, QERR_DEVICE_IN_USE, device);
break;
default:
error_setg_errno(errp, -ret, "Could not resize");
break;
}
bdrv_drained_begin(bs);
ret = blk_truncate(blk, size, errp);
bdrv_drained_end(bs);
out:
blk_unref(blk);
@@ -3174,6 +3150,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
Error *local_err = NULL;
int flags;
int64_t size;
bool set_backing_hd = false;
if (!backup->has_speed) {
backup->speed = 0;
@@ -3224,6 +3201,8 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
}
if (backup->sync == MIRROR_SYNC_MODE_NONE) {
source = bs;
flags |= BDRV_O_NO_BACKING;
set_backing_hd = true;
}
size = bdrv_getlength(bs);
@@ -3250,8 +3229,10 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
}
if (backup->format) {
options = qdict_new();
qdict_put(options, "driver", qstring_from_str(backup->format));
if (!options) {
options = qdict_new();
}
qdict_put_str(options, "driver", backup->format);
}
target_bs = bdrv_open(backup->target, NULL, options, flags, errp);
@@ -3261,6 +3242,14 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
bdrv_set_aio_context(target_bs, aio_context);
if (set_backing_hd) {
bdrv_set_backing_hd(target_bs, source, &local_err);
if (local_err) {
bdrv_unref(target_bs);
goto out;
}
}
if (backup->has_bitmap) {
bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
if (!bmap) {
@@ -3555,10 +3544,10 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
options = qdict_new();
if (arg->has_node_name) {
qdict_put(options, "node-name", qstring_from_str(arg->node_name));
qdict_put_str(options, "node-name", arg->node_name);
}
if (format) {
qdict_put(options, "driver", qstring_from_str(format));
qdict_put_str(options, "driver", format);
}
/* Mirroring takes care of copy-on-write using the source's backing
+2 -2
View File
@@ -290,7 +290,7 @@ void block_job_start(BlockJob *job)
job->pause_count--;
job->busy = true;
job->paused = false;
qemu_coroutine_enter(job->co);
bdrv_coroutine_enter(blk_bs(job->blk), job->co);
}
void block_job_ref(BlockJob *job)
@@ -532,7 +532,7 @@ void block_job_user_resume(BlockJob *job)
void block_job_enter(BlockJob *job)
{
if (job->co && !job->busy) {
qemu_coroutine_enter(job->co);
bdrv_coroutine_enter(blk_bs(job->blk), job->co);
}
}
+6 -3
View File
@@ -47,7 +47,6 @@ typedef struct {
int max_size;
int do_telnetopt;
int do_nodelay;
int is_unix;
int *read_msgfds;
size_t read_msgfds_num;
int *write_msgfds;
@@ -358,6 +357,10 @@ static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr,
return g_strdup_printf("%sfd:%s%s", prefix, addr->u.fd.data->str,
is_listen ? ",server" : "");
break;
case SOCKET_ADDRESS_KIND_VSOCK:
return g_strdup_printf("%svsock:%s:%s", prefix,
addr->u.vsock.data->cid,
addr->u.vsock.data->port);
default:
abort();
}
@@ -825,7 +828,6 @@ static void qmp_chardev_open_socket(Chardev *chr,
int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0;
QIOChannelSocket *sioc = NULL;
s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX;
s->is_listen = is_listen;
s->is_telnet = is_telnet;
s->do_nodelay = do_nodelay;
@@ -865,7 +867,8 @@ static void qmp_chardev_open_socket(Chardev *chr,
s->addr = QAPI_CLONE(SocketAddress, sock->addr);
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
if (s->is_unix) {
/* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
if (addr->type == SOCKET_ADDRESS_KIND_UNIX) {
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
}
Vendored
+28 -4
View File
@@ -323,6 +323,7 @@ replication="yes"
supported_cpu="no"
supported_os="no"
bogus_os="no"
# parse CC options first
for opt do
@@ -520,11 +521,11 @@ ARCH=
# Normalise host CPU name and set ARCH.
# Note that this case should only have supported host CPUs, not guests.
case "$cpu" in
ppc|ppc64|s390|s390x|x32)
ppc|ppc64|s390|s390x|sparc64|x32)
cpu="$cpu"
supported_cpu="yes"
;;
ia64|sparc64)
ia64)
cpu="$cpu"
;;
i386|i486|i586|i686|i86pc|BePC)
@@ -549,6 +550,7 @@ case "$cpu" in
;;
sparc|sun4[cdmuv])
cpu="sparc"
supported_cpu="yes"
;;
*)
# This will result in either an error or falling back to TCI later
@@ -694,7 +696,10 @@ Linux)
supported_os="yes"
;;
*)
error_exit "Unsupported host OS $targetos"
# This is a fatal error, but don't report it yet, because we
# might be going to just print the --help text, or it might
# be the result of a missing compiler.
bogus_os="yes"
;;
esac
@@ -1460,6 +1465,14 @@ if ! compile_prog ; then
error_exit "\"$cc\" cannot build an executable (is your linker broken?)"
fi
if test "$bogus_os" = "yes"; then
# Now that we know that we're not printing the help and that
# the compiler works (so the results of the check_defines we used
# to identify the OS are reliable), if we didn't recognize the
# host OS we should stop now.
error_exit "Unrecognized host OS $targetos"
fi
# Check that the C++ compiler exists and works with the C compiler
if has $cxx; then
cat > $TMPC <<EOF
@@ -3060,12 +3073,23 @@ fi
##########################################
# glib support probe
glib_req_ver=2.22
if test "$mingw32" = yes; then
glib_req_ver=2.30
else
glib_req_ver=2.22
fi
glib_modules=gthread-2.0
if test "$modules" = yes; then
glib_modules="$glib_modules gmodule-2.0"
fi
# This workaround is required due to a bug in pkg-config file for glib as it
# doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
if test "$static" = yes -a "$mingw32" = yes; then
QEMU_CFLAGS="-DGLIB_STATIC_COMPILATION $QEMU_CFLAGS"
fi
for i in $glib_modules; do
if $pkg_config --atleast-version=$glib_req_ver $i; then
glib_cflags=$($pkg_config --cflags $i)
+7 -7
View File
@@ -600,13 +600,13 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
/* Instruction counter expired. */
assert(use_icount);
#ifndef CONFIG_USER_ONLY
if (cpu->icount_extra) {
/* Refill decrementer and continue execution. */
cpu->icount_extra += insns_left;
insns_left = MIN(0xffff, cpu->icount_extra);
cpu->icount_extra -= insns_left;
cpu->icount_decr.u16.low = insns_left;
} else {
/* Ensure global icount has gone forward */
cpu_update_icount(cpu);
/* Refill decrementer and continue execution. */
insns_left = MIN(0xffff, cpu->icount_budget);
cpu->icount_decr.u16.low = insns_left;
cpu->icount_extra = cpu->icount_budget - insns_left;
if (!cpu->icount_extra) {
/* Execute any remaining instructions, then let the main loop
* handle the next event.
*/
+80 -31
View File
@@ -202,7 +202,7 @@ void qemu_tcg_configure(QemuOpts *opts, Error **errp)
} else if (use_icount) {
error_setg(errp, "No MTTCG when icount is enabled");
} else {
#ifndef TARGET_SUPPORT_MTTCG
#ifndef TARGET_SUPPORTS_MTTCG
error_report("Guest not yet converted to MTTCG - "
"you may get unexpected results");
#endif
@@ -223,20 +223,51 @@ void qemu_tcg_configure(QemuOpts *opts, Error **errp)
}
}
/* The current number of executed instructions is based on what we
* originally budgeted minus the current state of the decrementing
* icount counters in extra/u16.low.
*/
static int64_t cpu_get_icount_executed(CPUState *cpu)
{
return cpu->icount_budget - (cpu->icount_decr.u16.low + cpu->icount_extra);
}
/*
* Update the global shared timer_state.qemu_icount to take into
* account executed instructions. This is done by the TCG vCPU
* thread so the main-loop can see time has moved forward.
*/
void cpu_update_icount(CPUState *cpu)
{
int64_t executed = cpu_get_icount_executed(cpu);
cpu->icount_budget -= executed;
#ifdef CONFIG_ATOMIC64
atomic_set__nocheck(&timers_state.qemu_icount,
atomic_read__nocheck(&timers_state.qemu_icount) +
executed);
#else /* FIXME: we need 64bit atomics to do this safely */
timers_state.qemu_icount += executed;
#endif
}
int64_t cpu_get_icount_raw(void)
{
int64_t icount;
CPUState *cpu = current_cpu;
icount = timers_state.qemu_icount;
if (cpu) {
if (cpu && cpu->running) {
if (!cpu->can_do_io) {
fprintf(stderr, "Bad icount read\n");
exit(1);
}
icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);
/* Take into account what has run */
cpu_update_icount(cpu);
}
return icount;
#ifdef CONFIG_ATOMIC64
return atomic_read__nocheck(&timers_state.qemu_icount);
#else /* FIXME: we need 64bit atomics to do this safely */
return timers_state.qemu_icount;
#endif
}
/* Return the virtual CPU time, based on the instruction counter. */
@@ -1179,6 +1210,41 @@ static void handle_icount_deadline(void)
}
}
static void prepare_icount_for_run(CPUState *cpu)
{
if (use_icount) {
int insns_left;
/* These should always be cleared by process_icount_data after
* each vCPU execution. However u16.high can be raised
* asynchronously by cpu_exit/cpu_interrupt/tcg_handle_interrupt
*/
g_assert(cpu->icount_decr.u16.low == 0);
g_assert(cpu->icount_extra == 0);
cpu->icount_budget = tcg_get_icount_limit();
insns_left = MIN(0xffff, cpu->icount_budget);
cpu->icount_decr.u16.low = insns_left;
cpu->icount_extra = cpu->icount_budget - insns_left;
}
}
static void process_icount_data(CPUState *cpu)
{
if (use_icount) {
/* Account for executed instructions */
cpu_update_icount(cpu);
/* Reset the counters */
cpu->icount_decr.u16.low = 0;
cpu->icount_extra = 0;
cpu->icount_budget = 0;
replay_account_executed_instructions();
}
}
static int tcg_cpu_exec(CPUState *cpu)
{
int ret;
@@ -1189,20 +1255,6 @@ static int tcg_cpu_exec(CPUState *cpu)
#ifdef CONFIG_PROFILER
ti = profile_getclock();
#endif
if (use_icount) {
int64_t count;
int decr;
timers_state.qemu_icount -= (cpu->icount_decr.u16.low
+ cpu->icount_extra);
cpu->icount_decr.u16.low = 0;
cpu->icount_extra = 0;
count = tcg_get_icount_limit();
timers_state.qemu_icount += count;
decr = (count > 0xffff) ? 0xffff : count;
count -= decr;
cpu->icount_decr.u16.low = decr;
cpu->icount_extra = count;
}
qemu_mutex_unlock_iothread();
cpu_exec_start(cpu);
ret = cpu_exec(cpu);
@@ -1211,15 +1263,6 @@ static int tcg_cpu_exec(CPUState *cpu)
#ifdef CONFIG_PROFILER
tcg_time += profile_getclock() - ti;
#endif
if (use_icount) {
/* Fold pending instructions back into the
instruction counter, and clear the interrupt flag. */
timers_state.qemu_icount -= (cpu->icount_decr.u16.low
+ cpu->icount_extra);
cpu->icount_decr.u32 = 0;
cpu->icount_extra = 0;
replay_account_executed_instructions();
}
return ret;
}
@@ -1306,7 +1349,13 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
if (cpu_can_run(cpu)) {
int r;
prepare_icount_for_run(cpu);
r = tcg_cpu_exec(cpu);
process_icount_data(cpu);
if (r == EXCP_DEBUG) {
cpu_handle_guest_debug(cpu);
break;
@@ -1392,6 +1441,8 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
g_assert(!use_icount);
rcu_register_thread();
qemu_mutex_lock_iothread();
@@ -1434,8 +1485,6 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
}
}
handle_icount_deadline();
atomic_mb_set(&cpu->exit_request, 0);
qemu_tcg_wait_io_event(cpu);
}
+2 -2
View File
@@ -2048,7 +2048,7 @@ print_with_operands (const struct cris_opcode *opcodep,
{
/* We're looking at [pc+], i.e. we need to output an immediate
number, where the size can depend on different things. */
long number;
int32_t number;
int signedp
= ((*cs == 'z' && (insn & 0x20))
|| opcodep->match == BDAP_QUICK_OPCODE);
@@ -2290,7 +2290,7 @@ print_with_operands (const struct cris_opcode *opcodep,
if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)
{
long number;
int32_t number;
unsigned int nbytes;
/* It's a value. Get its size. */
+19 -61
View File
@@ -2010,10 +2010,10 @@ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
* In that case just map until the end of the page.
*/
if (block->offset == 0) {
return xen_map_cache(addr, 0, 0);
return xen_map_cache(addr, 0, 0, false);
}
block->host = xen_map_cache(block->offset, block->max_length, 1);
block->host = xen_map_cache(block->offset, block->max_length, 1, false);
}
return ramblock_ptr(block, addr);
}
@@ -2024,7 +2024,7 @@ void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
* Called within RCU critical section.
*/
static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
hwaddr *size)
hwaddr *size, bool lock)
{
RAMBlock *block = ram_block;
if (*size == 0) {
@@ -2043,10 +2043,10 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
* In that case just map the requested area.
*/
if (block->offset == 0) {
return xen_map_cache(addr, *size, 1);
return xen_map_cache(addr, *size, lock, lock);
}
block->host = xen_map_cache(block->offset, block->max_length, 1);
block->host = xen_map_cache(block->offset, block->max_length, 1, lock);
}
return ramblock_ptr(block, addr);
@@ -2765,7 +2765,7 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
}
} else {
/* RAM case */
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
memcpy(ptr, buf, l);
invalidate_and_set_dirty(mr, addr1, l);
}
@@ -2856,7 +2856,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
}
} else {
/* RAM case */
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
memcpy(buf, ptr, l);
}
@@ -3167,7 +3167,7 @@ void *address_space_map(AddressSpace *as,
memory_region_ref(mr);
*plen = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write);
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen);
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
rcu_read_unlock();
return ptr;
@@ -3236,75 +3236,33 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
hwaddr len,
bool is_write)
{
hwaddr l, xlat;
MemoryRegion *mr;
void *ptr;
assert(len > 0);
l = len;
mr = address_space_translate(as, addr, &xlat, &l, is_write);
if (!memory_access_is_direct(mr, is_write)) {
return -EINVAL;
}
l = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write);
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, &l);
cache->xlat = xlat;
cache->is_write = is_write;
cache->mr = mr;
cache->ptr = ptr;
cache->len = l;
memory_region_ref(cache->mr);
return l;
cache->len = len;
cache->as = as;
cache->xlat = addr;
return len;
}
void address_space_cache_invalidate(MemoryRegionCache *cache,
hwaddr addr,
hwaddr access_len)
{
assert(cache->is_write);
invalidate_and_set_dirty(cache->mr, addr + cache->xlat, access_len);
}
void address_space_cache_destroy(MemoryRegionCache *cache)
{
if (!cache->mr) {
return;
}
if (xen_enabled()) {
xen_invalidate_map_cache_entry(cache->ptr);
}
memory_region_unref(cache->mr);
cache->mr = NULL;
}
/* Called from RCU critical section. This function has the same
* semantics as address_space_translate, but it only works on a
* predefined range of a MemoryRegion that was mapped with
* address_space_cache_init.
*/
static inline MemoryRegion *address_space_translate_cached(
MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
hwaddr *plen, bool is_write)
{
assert(addr < cache->len && *plen <= cache->len - addr);
*xlat = addr + cache->xlat;
return cache->mr;
cache->as = NULL;
}
#define ARG1_DECL MemoryRegionCache *cache
#define ARG1 cache
#define SUFFIX _cached
#define TRANSLATE(...) address_space_translate_cached(cache, __VA_ARGS__)
#define TRANSLATE(addr, ...) \
address_space_translate(cache->as, cache->xlat + (addr), __VA_ARGS__)
#define IS_DIRECT(mr, is_write) true
#define MAP_RAM(mr, ofs) (cache->ptr + (ofs - cache->xlat))
#define INVALIDATE(mr, ofs, len) ((void)0)
#define RCU_READ_LOCK() ((void)0)
#define RCU_READ_UNLOCK() ((void)0)
#define MAP_RAM(mr, ofs) qemu_map_ram_ptr((mr)->ram_block, ofs)
#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len)
#define RCU_READ_LOCK() rcu_read_lock()
#define RCU_READ_UNLOCK() rcu_read_unlock()
#include "memory_ldst.inc.c"
/* virtual memory access for debug (includes writing to ROM) */
+113 -30
View File
@@ -278,17 +278,27 @@ update_map_file:
static int fchmodat_nofollow(int dirfd, const char *name, mode_t mode)
{
struct stat stbuf;
int fd, ret;
/* FIXME: this should be handled with fchmodat(AT_SYMLINK_NOFOLLOW).
* Unfortunately, the linux kernel doesn't implement it yet. As an
* alternative, let's open the file and use fchmod() instead. This
* may fail depending on the permissions of the file, but it is the
* best we can do to avoid TOCTTOU. We first try to open read-only
* in case name points to a directory. If that fails, we try write-only
* in case name doesn't point to a directory.
* Unfortunately, the linux kernel doesn't implement it yet.
*/
fd = openat_file(dirfd, name, O_RDONLY, 0);
/* First, we clear non-racing symlinks out of the way. */
if (fstatat(dirfd, name, &stbuf, AT_SYMLINK_NOFOLLOW)) {
return -1;
}
if (S_ISLNK(stbuf.st_mode)) {
errno = ELOOP;
return -1;
}
/* Access modes are ignored when O_PATH is supported. We try O_RDONLY and
* O_WRONLY for old-systems that don't support O_PATH.
*/
fd = openat_file(dirfd, name, O_RDONLY | O_PATH_9P_UTIL, 0);
#if O_PATH_9P_UTIL == 0
if (fd == -1) {
/* In case the file is writable-only and isn't a directory. */
if (errno == EACCES) {
@@ -302,6 +312,24 @@ static int fchmodat_nofollow(int dirfd, const char *name, mode_t mode)
return -1;
}
ret = fchmod(fd, mode);
#else
if (fd == -1) {
return -1;
}
/* Now we handle racing symlinks. */
ret = fstat(fd, &stbuf);
if (!ret) {
if (S_ISLNK(stbuf.st_mode)) {
errno = ELOOP;
ret = -1;
} else {
char *proc_path = g_strdup_printf("/proc/self/fd/%d", fd);
ret = chmod(proc_path, mode);
g_free(proc_path);
}
}
#endif
close_preserve_errno(fd);
return ret;
}
@@ -452,6 +480,11 @@ static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
return telldir(fs->dir.stream);
}
static bool local_is_mapped_file_metadata(FsContext *fs_ctx, const char *name)
{
return !strcmp(name, VIRTFS_META_DIR);
}
static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
{
struct dirent *entry;
@@ -465,8 +498,8 @@ again:
if (ctx->export_flags & V9FS_SM_MAPPED) {
entry->d_type = DT_UNKNOWN;
} else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
if (!strcmp(entry->d_name, VIRTFS_META_DIR)) {
/* skp the meta data directory */
if (local_is_mapped_file_metadata(ctx, entry->d_name)) {
/* skip the meta data directory */
goto again;
}
entry->d_type = DT_UNKNOWN;
@@ -559,6 +592,12 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
int err = -1;
int dirfd;
if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
local_is_mapped_file_metadata(fs_ctx, name)) {
errno = EINVAL;
return -1;
}
dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
if (dirfd == -1) {
return -1;
@@ -605,6 +644,12 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
int err = -1;
int dirfd;
if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
local_is_mapped_file_metadata(fs_ctx, name)) {
errno = EINVAL;
return -1;
}
dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
if (dirfd == -1) {
return -1;
@@ -694,6 +739,12 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
int err = -1;
int dirfd;
if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
local_is_mapped_file_metadata(fs_ctx, name)) {
errno = EINVAL;
return -1;
}
/*
* Mark all the open to not follow symlinks
*/
@@ -752,6 +803,12 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
int err = -1;
int dirfd;
if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
local_is_mapped_file_metadata(fs_ctx, name)) {
errno = EINVAL;
return -1;
}
dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
if (dirfd == -1) {
return -1;
@@ -826,6 +883,12 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
int ret = -1;
int odirfd, ndirfd;
if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
local_is_mapped_file_metadata(ctx, name)) {
errno = EINVAL;
return -1;
}
odirfd = local_opendir_nofollow(ctx, odirpath);
if (odirfd == -1) {
goto out;
@@ -957,6 +1020,14 @@ static int local_unlinkat_common(FsContext *ctx, int dirfd, const char *name,
if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
int map_dirfd;
/* We need to remove the metadata as well:
* - the metadata directory if we're removing a directory
* - the metadata file in the parent's metadata directory
*
* If any of these are missing (ie, ENOENT) then we're probably
* trying to remove something that wasn't created in mapped-file
* mode. We just ignore the error.
*/
if (flags == AT_REMOVEDIR) {
int fd;
@@ -964,32 +1035,20 @@ static int local_unlinkat_common(FsContext *ctx, int dirfd, const char *name,
if (fd == -1) {
goto err_out;
}
/*
* If directory remove .virtfs_metadata contained in the
* directory
*/
ret = unlinkat(fd, VIRTFS_META_DIR, AT_REMOVEDIR);
close_preserve_errno(fd);
if (ret < 0 && errno != ENOENT) {
/*
* We didn't had the .virtfs_metadata file. May be file created
* in non-mapped mode ?. Ignore ENOENT.
*/
goto err_out;
}
}
/*
* Now remove the name from parent directory
* .virtfs_metadata directory.
*/
map_dirfd = openat_dir(dirfd, VIRTFS_META_DIR);
ret = unlinkat(map_dirfd, name, 0);
close_preserve_errno(map_dirfd);
if (ret < 0 && errno != ENOENT) {
/*
* We didn't had the .virtfs_metadata file. May be file created
* in non-mapped mode ?. Ignore ENOENT.
*/
if (map_dirfd != -1) {
ret = unlinkat(map_dirfd, name, 0);
close_preserve_errno(map_dirfd);
if (ret < 0 && errno != ENOENT) {
goto err_out;
}
} else if (errno != ENOENT) {
goto err_out;
}
}
@@ -1013,7 +1072,7 @@ static int local_remove(FsContext *ctx, const char *path)
goto out;
}
if (fstatat(dirfd, path, &stbuf, AT_SYMLINK_NOFOLLOW) < 0) {
if (fstatat(dirfd, name, &stbuf, AT_SYMLINK_NOFOLLOW) < 0) {
goto err_out;
}
@@ -1096,10 +1155,21 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path,
const char *name, V9fsPath *target)
{
if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
local_is_mapped_file_metadata(ctx, name)) {
errno = EINVAL;
return -1;
}
if (dir_path) {
v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
} else {
} else if (strcmp(name, "/")) {
v9fs_path_sprintf(target, "%s", name);
} else {
/* We want the path of the export root to be relative, otherwise
* "*at()" syscalls would treat it as "/" in the host.
*/
v9fs_path_sprintf(target, "%s", ".");
}
return 0;
}
@@ -1111,6 +1181,13 @@ static int local_renameat(FsContext *ctx, V9fsPath *olddir,
int ret;
int odirfd, ndirfd;
if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
(local_is_mapped_file_metadata(ctx, old_name) ||
local_is_mapped_file_metadata(ctx, new_name))) {
errno = EINVAL;
return -1;
}
odirfd = local_opendir_nofollow(ctx, olddir->data);
if (odirfd == -1) {
return -1;
@@ -1201,6 +1278,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
int ret;
int dirfd;
if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
local_is_mapped_file_metadata(ctx, name)) {
errno = EINVAL;
return -1;
}
dirfd = local_opendir_nofollow(ctx, dir->data);
if (dirfd == -1) {
return -1;
+15 -9
View File
@@ -13,6 +13,12 @@
#ifndef QEMU_9P_UTIL_H
#define QEMU_9P_UTIL_H
#ifdef O_PATH
#define O_PATH_9P_UTIL O_PATH
#else
#define O_PATH_9P_UTIL 0
#endif
static inline void close_preserve_errno(int fd)
{
int serrno = errno;
@@ -22,13 +28,8 @@ static inline void close_preserve_errno(int fd)
static inline int openat_dir(int dirfd, const char *name)
{
#ifdef O_PATH
#define OPENAT_DIR_O_PATH O_PATH
#else
#define OPENAT_DIR_O_PATH 0
#endif
return openat(dirfd, name,
O_DIRECTORY | O_RDONLY | O_NOFOLLOW | OPENAT_DIR_O_PATH);
O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_PATH_9P_UTIL);
}
static inline int openat_file(int dirfd, const char *name, int flags,
@@ -43,9 +44,14 @@ static inline int openat_file(int dirfd, const char *name, int flags,
}
serrno = errno;
/* O_NONBLOCK was only needed to open the file. Let's drop it. */
ret = fcntl(fd, F_SETFL, flags);
assert(!ret);
/* O_NONBLOCK was only needed to open the file. Let's drop it. We don't
* do that with O_PATH since fcntl(F_SETFL) isn't supported, and openat()
* ignored it anyway.
*/
if (!(flags & O_PATH_9P_UTIL)) {
ret = fcntl(fd, F_SETFL, flags);
assert(!ret);
}
errno = serrno;
return fd;
}
+1
View File
@@ -108,6 +108,7 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
g_free(name);
close_preserve_errno(dirfd);
if (xattr_len < 0) {
g_free(orig_value);
return -1;
}
+11 -8
View File
@@ -539,14 +539,15 @@ static void coroutine_fn virtfs_reset(V9fsPDU *pdu)
/* Free all fids */
while (s->fid_list) {
/* Get fid */
fidp = s->fid_list;
s->fid_list = fidp->next;
fidp->ref++;
if (fidp->ref) {
fidp->clunked = 1;
} else {
free_fid(pdu, fidp);
}
/* Clunk fid */
s->fid_list = fidp->next;
fidp->clunked = 1;
put_fid(pdu, fidp);
}
}
@@ -2387,8 +2388,10 @@ static void coroutine_fn v9fs_flush(void *opaque)
* Wait for pdu to complete.
*/
qemu_co_queue_wait(&cancel_pdu->complete, NULL);
cancel_pdu->cancelled = 0;
pdu_free(cancel_pdu);
if (!qemu_co_queue_next(&cancel_pdu->complete)) {
cancel_pdu->cancelled = 0;
pdu_free(cancel_pdu);
}
}
pdu_complete(pdu, 7);
}
+9 -4
View File
@@ -385,7 +385,10 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
dev, errp);
}
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp);
if (!xen_enabled()) {
acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
errp);
}
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
if (s->cpu_hotplug_legacy) {
legacy_acpi_cpu_plug_cb(hotplug_dev, &s->gpe_cpu, dev, errp);
@@ -408,8 +411,10 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug,
dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
errp);
if (!xen_enabled()) {
acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
errp);
}
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
!s->cpu_hotplug_legacy) {
acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
@@ -700,7 +705,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
dc->hotpluggable = false;
hc->plug = piix4_device_plug_cb;
hc->unplug_request = piix4_device_unplug_request_cb;
-2
View File
@@ -75,8 +75,6 @@ static void tco_timer_expired(void *opaque)
if (pm->smi_en & ICH9_PMIO_SMI_EN_TCO_EN) {
ich9_generate_smi();
} else {
ich9_generate_nmi();
}
tr->tco.rld = tr->tco.tmr;
tco_timer_reload(tr);
+1 -1
View File
@@ -1076,7 +1076,7 @@ static void sl_nand_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_sl_nand_info;
dc->props = sl_nand_properties;
/* Reason: init() method uses drive_get() */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo sl_nand_info = {
+1 -1
View File
@@ -292,7 +292,7 @@ static void mv88w8618_audio_class_init(ObjectClass *klass, void *data)
dc->vmsd = &mv88w8618_audio_vmsd;
dc->props = mv88w8618_audio_properties;
/* Reason: pointer property "wm8750" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo mv88w8618_audio_info = {
+1 -1
View File
@@ -223,7 +223,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_spk;
dc->props = pcspk_properties;
/* Reason: realize sets global pcspk_state */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo pcspk_info = {
+1 -1
View File
@@ -1082,7 +1082,7 @@ static int blk_connect(struct XenDevice *xendev)
if (strcmp(blkdev->fileproto, "<unset>")) {
options = qdict_new();
qdict_put(options, "driver", qstring_from_str(blkdev->fileproto));
qdict_put_str(options, "driver", blkdev->fileproto);
}
/* setup via xenbus -> create new block driver instance */
+3
View File
@@ -1121,6 +1121,9 @@ static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp)
timer_free(vser->post_load->timer);
g_free(vser->post_load);
}
qbus_set_hotplug_handler(BUS(&vser->bus), NULL, errp);
virtio_cleanup(vdev);
}
+1 -1
View File
@@ -91,7 +91,7 @@ static void or_irq_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_or_irq;
/* Reason: Needs to be wired up to work, e.g. see stm32f205_soc.c */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo or_irq_type_info = {
+4
View File
@@ -124,8 +124,12 @@ static void release_drive(Object *obj, const char *name, void *opaque)
BlockBackend **ptr = qdev_get_prop_ptr(dev, prop);
if (*ptr) {
AioContext *ctx = blk_get_aio_context(*ptr);
aio_context_acquire(ctx);
blockdev_auto_del(*ptr);
blk_detach_dev(*ptr, dev);
aio_context_release(ctx);
}
}
+1
View File
@@ -1159,6 +1159,7 @@ static void device_class_init(ObjectClass *class, void *data)
* should override it in their class_init()
*/
dc->hotpluggable = true;
dc->user_creatable = true;
}
void device_reset(DeviceState *dev)
+1 -1
View File
@@ -288,7 +288,7 @@ static void register_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);
/* Reason: needs to be wired up to work */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo register_info = {
+5
View File
@@ -33,6 +33,11 @@ static void core_prop_set_core_id(Object *obj, Visitor *v, const char *name,
return;
}
if (value < 0) {
error_setg(errp, "Invalid core id %"PRId64, value);
return;
}
core->core_id = value;
}
+32
View File
@@ -26,6 +26,7 @@
#include "qemu/queue.h"
#include "qemu/atomic.h"
#include "sysemu/sysemu.h"
#include "migration/migration.h"
#include "trace.h"
#include "qxl.h"
@@ -639,6 +640,30 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
qxl->guest_primary.commands++;
qxl_track_command(qxl, ext);
qxl_log_command(qxl, "cmd", ext);
{
/*
* Windows 8 drivers place qxl commands in the vram
* (instead of the ram) bar. We can't live migrate such a
* guest, so add a migration blocker in case we detect
* this, to avoid triggering the assert in pre_save().
*
* https://cgit.freedesktop.org/spice/win32/qxl-wddm-dod/commit/?id=f6e099db39e7d0787f294d5fd0dce328b5210faa
*/
void *msg = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
if (msg != NULL && (
msg < (void *)qxl->vga.vram_ptr ||
msg > ((void *)qxl->vga.vram_ptr + qxl->vga.vram_size))) {
if (!qxl->migration_blocker) {
Error *local_err = NULL;
error_setg(&qxl->migration_blocker,
"qxl: guest bug: command not in ram bar");
migrate_add_blocker(qxl->migration_blocker, &local_err);
if (local_err) {
error_report_err(local_err);
}
}
}
}
trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
return true;
default:
@@ -1146,6 +1171,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
update_displaychangelistener(&d->ssd.dcl, GUI_REFRESH_INTERVAL_DEFAULT);
qemu_spice_create_host_primary(&d->ssd);
d->mode = QXL_MODE_VGA;
qemu_spice_display_switch(&d->ssd, d->ssd.ds);
vga_dirty_log_start(&d->vga);
graphic_hw_update(d->vga.con);
}
@@ -1235,6 +1261,12 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
qemu_spice_create_host_memslot(&d->ssd);
qxl_soft_reset(d);
if (d->migration_blocker) {
migrate_del_blocker(d->migration_blocker);
error_free(d->migration_blocker);
d->migration_blocker = NULL;
}
if (startstop) {
qemu_spice_display_start();
}
+1
View File
@@ -40,6 +40,7 @@ typedef struct PCIQXLDevice {
uint32_t cmdlog;
uint32_t guest_bug;
Error *migration_blocker;
enum qxl_mode mode;
uint32_t cmdflags;
+1 -1
View File
@@ -601,7 +601,7 @@ static void i8257_class_init(ObjectClass *klass, void *data)
idc->schedule = i8257_dma_schedule;
idc->register_channel = i8257_dma_register_channel;
/* Reason: needs to be wired up by isa_bus_dma() to work */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo i8257_info = {
+1 -1
View File
@@ -305,7 +305,7 @@ static void sparc32_dma_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_dma;
dc->props = sparc32_dma_properties;
/* Reason: pointer property "iommu_opaque" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo sparc32_dma_info = {
+2 -2
View File
@@ -773,7 +773,7 @@ static void omap_gpio_class_init(ObjectClass *klass, void *data)
dc->reset = omap_gpif_reset;
dc->props = omap_gpio_properties;
/* Reason: pointer property "clk" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo omap_gpio_info = {
@@ -804,7 +804,7 @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data)
dc->reset = omap2_gpif_reset;
dc->props = omap2_gpio_properties;
/* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo omap2_gpio_info = {
+1 -1
View File
@@ -491,7 +491,7 @@ static void omap_i2c_class_init(ObjectClass *klass, void *data)
dc->props = omap_i2c_properties;
dc->reset = omap_i2c_reset;
/* Reason: pointer properties "iclk", "fclk" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
dc->realize = omap_i2c_realize;
}
+1 -1
View File
@@ -123,7 +123,7 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
sc->read_data = eeprom_read_data;
dc->props = smbus_eeprom_properties;
/* Reason: pointer property "data" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo smbus_eeprom_info = {
+1 -1
View File
@@ -103,7 +103,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
* Reason: part of ICH9 southbridge, needs to be wired up by
* pc_q35_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)
+2 -2
View File
@@ -1818,9 +1818,9 @@ static Aml *build_q35_osc_method(void)
/*
* Always allow native PME, AER (no dependencies)
* Never allow SHPC (no SHPC controller in this system)
* Allow SHPC (PCI bridges can have SHPC controller)
*/
aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1D), a_ctrl));
aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl));
if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
/* Unknown revision */
+1 -1
View File
@@ -597,7 +597,7 @@ static void port92_class_initfn(ObjectClass *klass, void *data)
* wiring: its A20 output line needs to be wired up by
* port92_init().
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo port92_info = {
+1
View File
@@ -483,6 +483,7 @@ void hid_reset(HIDState *hs)
memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
hs->kbd.keys = 0;
hs->kbd.modifiers = 0;
break;
case HID_MOUSE:
case HID_TABLET:
+1 -1
View File
@@ -286,7 +286,7 @@ static void vmmouse_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_vmmouse;
dc->props = vmmouse_properties;
/* Reason: pointer property "ps2_mouse" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo vmmouse_info = {
+1 -1
View File
@@ -501,7 +501,7 @@ static void apic_common_class_init(ObjectClass *klass, void *data)
* Reason: APIC and CPU need to be wired up by
* x86_cpu_apic_create()
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo apic_common_type = {
+11 -6
View File
@@ -614,12 +614,6 @@ static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
s = c->gic;
cpu = ARM_CPU(c->cpu);
/* Initialize to actual HW supported configuration */
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
KVM_VGIC_ATTR(ICC_CTLR_EL1, cpu->mp_affinity),
&c->icc_ctlr_el1[GICV3_NS], false);
c->icc_ctlr_el1[GICV3_S] = c->icc_ctlr_el1[GICV3_NS];
c->icc_pmr_el1 = 0;
c->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
c->icc_bpr[GICV3_G1] = GIC_MIN_BPR;
@@ -628,6 +622,17 @@ static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
c->icc_sre_el1 = 0x7;
memset(c->icc_apr, 0, sizeof(c->icc_apr));
memset(c->icc_igrpen, 0, sizeof(c->icc_igrpen));
if (s->migration_blocker) {
return;
}
/* Initialize to actual HW supported configuration */
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
KVM_VGIC_ATTR(ICC_CTLR_EL1, cpu->mp_affinity),
&c->icc_ctlr_el1[GICV3_NS], false);
c->icc_ctlr_el1[GICV3_S] = c->icc_ctlr_el1[GICV3_NS];
}
static void kvm_arm_gicv3_reset(DeviceState *dev)
+1 -1
View File
@@ -173,7 +173,7 @@ static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
dc->props = etraxfs_pic_properties;
/*
* Note: pointer property "interrupt_vector" may remain null, thus
* no need for dc->cannot_instantiate_with_device_add_yet = true;
* no need for dc->user_creatable = false;
*/
}
+1 -1
View File
@@ -360,7 +360,7 @@ static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
dc->reset = grlib_irqmp_reset;
dc->props = grlib_irqmp_properties;
/* Reason: pointer properties "set_pil_in", "set_pil_in_opaque" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
dc->realize = grlib_irqmp_realize;
}
+1 -1
View File
@@ -144,7 +144,7 @@ static void pic_common_class_init(ObjectClass *klass, void *data)
* wiring of the slave to the master is hard-coded in device model
* code.
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo pic_common_type = {
+1 -1
View File
@@ -80,7 +80,7 @@ static void altera_iic_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
/* Reason: needs to be wired up, e.g. by nios2_10m50_ghrd_init() */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
dc->realize = altera_iic_realize;
}
+2 -2
View File
@@ -401,7 +401,7 @@ static void omap_intc_class_init(ObjectClass *klass, void *data)
dc->reset = omap_inth_reset;
dc->props = omap_intc_properties;
/* Reason: pointer property "clk" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
dc->realize = omap_intc_realize;
}
@@ -656,7 +656,7 @@ static void omap2_intc_class_init(ObjectClass *klass, void *data)
dc->reset = omap_inth_reset;
dc->props = omap2_intc_properties;
/* Reason: pointer property "iclk", "fclk" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
dc->realize = omap2_intc_realize;
}
+12 -22
View File
@@ -37,40 +37,30 @@
#define IPMI_BT_HBUSY_BIT 6
#define IPMI_BT_BBUSY_BIT 7
#define IPMI_BT_CLR_WR_MASK (1 << IPMI_BT_CLR_WR_BIT)
#define IPMI_BT_GET_CLR_WR(d) (((d) >> IPMI_BT_CLR_WR_BIT) & 0x1)
#define IPMI_BT_SET_CLR_WR(d, v) (d) = (((d) & ~IPMI_BT_CLR_WR_MASK) | \
(((v & 1) << IPMI_BT_CLR_WR_BIT)))
#define IPMI_BT_CLR_RD_MASK (1 << IPMI_BT_CLR_RD_BIT)
#define IPMI_BT_GET_CLR_RD(d) (((d) >> IPMI_BT_CLR_RD_BIT) & 0x1)
#define IPMI_BT_SET_CLR_RD(d, v) (d) = (((d) & ~IPMI_BT_CLR_RD_MASK) | \
(((v & 1) << IPMI_BT_CLR_RD_BIT)))
#define IPMI_BT_H2B_ATN_MASK (1 << IPMI_BT_H2B_ATN_BIT)
#define IPMI_BT_GET_H2B_ATN(d) (((d) >> IPMI_BT_H2B_ATN_BIT) & 0x1)
#define IPMI_BT_SET_H2B_ATN(d, v) (d) = (((d) & ~IPMI_BT_H2B_ATN_MASK) | \
(((v & 1) << IPMI_BT_H2B_ATN_BIT)))
#define IPMI_BT_B2H_ATN_MASK (1 << IPMI_BT_B2H_ATN_BIT)
#define IPMI_BT_GET_B2H_ATN(d) (((d) >> IPMI_BT_B2H_ATN_BIT) & 0x1)
#define IPMI_BT_SET_B2H_ATN(d, v) (d) = (((d) & ~IPMI_BT_B2H_ATN_MASK) | \
(((v & 1) << IPMI_BT_B2H_ATN_BIT)))
#define IPMI_BT_SET_B2H_ATN(d, v) ((d) = (((d) & ~IPMI_BT_B2H_ATN_MASK) | \
(((v) & 1) << IPMI_BT_B2H_ATN_BIT)))
#define IPMI_BT_SMS_ATN_MASK (1 << IPMI_BT_SMS_ATN_BIT)
#define IPMI_BT_GET_SMS_ATN(d) (((d) >> IPMI_BT_SMS_ATN_BIT) & 0x1)
#define IPMI_BT_SET_SMS_ATN(d, v) (d) = (((d) & ~IPMI_BT_SMS_ATN_MASK) | \
(((v & 1) << IPMI_BT_SMS_ATN_BIT)))
#define IPMI_BT_SET_SMS_ATN(d, v) ((d) = (((d) & ~IPMI_BT_SMS_ATN_MASK) | \
(((v) & 1) << IPMI_BT_SMS_ATN_BIT)))
#define IPMI_BT_HBUSY_MASK (1 << IPMI_BT_HBUSY_BIT)
#define IPMI_BT_GET_HBUSY(d) (((d) >> IPMI_BT_HBUSY_BIT) & 0x1)
#define IPMI_BT_SET_HBUSY(d, v) (d) = (((d) & ~IPMI_BT_HBUSY_MASK) | \
(((v & 1) << IPMI_BT_HBUSY_BIT)))
#define IPMI_BT_SET_HBUSY(d, v) ((d) = (((d) & ~IPMI_BT_HBUSY_MASK) | \
(((v) & 1) << IPMI_BT_HBUSY_BIT)))
#define IPMI_BT_BBUSY_MASK (1 << IPMI_BT_BBUSY_BIT)
#define IPMI_BT_GET_BBUSY(d) (((d) >> IPMI_BT_BBUSY_BIT) & 0x1)
#define IPMI_BT_SET_BBUSY(d, v) (d) = (((d) & ~IPMI_BT_BBUSY_MASK) | \
(((v & 1) << IPMI_BT_BBUSY_BIT)))
#define IPMI_BT_SET_BBUSY(d, v) ((d) = (((d) & ~IPMI_BT_BBUSY_MASK) | \
(((v) & 1) << IPMI_BT_BBUSY_BIT)))
/* Mask register */
@@ -79,13 +69,13 @@
#define IPMI_BT_B2H_IRQ_EN_MASK (1 << IPMI_BT_B2H_IRQ_EN_BIT)
#define IPMI_BT_GET_B2H_IRQ_EN(d) (((d) >> IPMI_BT_B2H_IRQ_EN_BIT) & 0x1)
#define IPMI_BT_SET_B2H_IRQ_EN(d, v) (d) = (((d) & ~IPMI_BT_B2H_IRQ_EN_MASK) | \
(((v & 1) << IPMI_BT_B2H_IRQ_EN_BIT)))
#define IPMI_BT_SET_B2H_IRQ_EN(d, v) ((d) = (((d) & ~IPMI_BT_B2H_IRQ_EN_MASK) |\
(((v) & 1) << IPMI_BT_B2H_IRQ_EN_BIT)))
#define IPMI_BT_B2H_IRQ_MASK (1 << IPMI_BT_B2H_IRQ_BIT)
#define IPMI_BT_GET_B2H_IRQ(d) (((d) >> IPMI_BT_B2H_IRQ_BIT) & 0x1)
#define IPMI_BT_SET_B2H_IRQ(d, v) (d) = (((d) & ~IPMI_BT_B2H_IRQ_MASK) | \
(((v & 1) << IPMI_BT_B2H_IRQ_BIT)))
#define IPMI_BT_SET_B2H_IRQ(d, v) ((d) = (((d) & ~IPMI_BT_B2H_IRQ_MASK) | \
(((v) & 1) << IPMI_BT_B2H_IRQ_BIT)))
typedef struct IPMIBT {
IPMIBmc *bmc;
+1 -6
View File
@@ -312,11 +312,6 @@ void ich9_generate_smi(void)
cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
}
void ich9_generate_nmi(void)
{
cpu_interrupt(first_cpu, CPU_INTERRUPT_NMI);
}
static int ich9_lpc_sci_irq(ICH9LPCState *lpc)
{
switch (lpc->d.config[ICH9_LPC_ACPI_CTRL] &
@@ -810,7 +805,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
* Reason: part of ICH9 southbridge, needs to be wired up by
* pc_q35_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
hc->plug = ich9_pm_device_plug_cb;
hc->unplug_request = ich9_pm_device_unplug_request_cb;
hc->unplug = ich9_pm_device_unplug_cb;
+1 -1
View File
@@ -123,7 +123,7 @@ static void piix4_class_init(ObjectClass *klass, void *data)
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
dc->hotpluggable = false;
}
+1 -1
View File
@@ -494,7 +494,7 @@ static void via_class_init(ObjectClass *klass, void *data)
* Reason: part of VIA VT82C686 southbridge, needs to be wired up,
* e.g. by mips_fulong2e_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo via_info = {
+1 -1
View File
@@ -1224,7 +1224,7 @@ static void gt64120_pci_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo gt64120_pci_info = {
+1 -1
View File
@@ -163,7 +163,7 @@ static void vmport_class_initfn(ObjectClass *klass, void *data)
dc->realize = vmport_realizefn;
/* Reason: realize sets global port_state */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo vmport_info = {
+1 -1
View File
@@ -934,7 +934,7 @@ static void dp8393x_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_dp8393x;
dc->props = dp8393x_properties;
/* Reason: dma_mr property can't be set */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo dp8393x_info = {
+1 -1
View File
@@ -40,7 +40,7 @@
static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
#define E1000_DEBUG
/* #define E1000_DEBUG */
#ifdef E1000_DEBUG
enum {
+8 -2
View File
@@ -2454,14 +2454,20 @@ e1000e_set_ics(E1000ECore *core, int index, uint32_t val)
static void
e1000e_set_icr(E1000ECore *core, int index, uint32_t val)
{
uint32_t icr = 0;
if ((core->mac[ICR] & E1000_ICR_ASSERTED) &&
(core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
trace_e1000e_irq_icr_process_iame();
e1000e_clear_ims_bits(core, core->mac[IAM]);
}
trace_e1000e_irq_icr_write(val, core->mac[ICR], core->mac[ICR] & ~val);
core->mac[ICR] &= ~val;
icr = core->mac[ICR] & ~val;
/* Windows driver expects that the "receive overrun" bit and other
* ones to be cleared when the "Other" bit (#24) is cleared.
*/
icr = (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : icr;
trace_e1000e_irq_icr_write(val, core->mac[ICR], icr);
core->mac[ICR] = icr;
e1000e_update_interrupt_state(core);
}
+1 -1
View File
@@ -630,7 +630,7 @@ static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
k->init = fs_eth_init;
dc->props = etraxfs_eth_properties;
/* Reason: pointer properties "dma_out", "dma_in" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo etraxfs_eth_info = {
+1 -1
View File
@@ -165,7 +165,7 @@ static void lance_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_lance;
dc->props = lance_properties;
/* Reason: pointer property "dma" */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo lance_info = {
+9
View File
@@ -510,6 +510,10 @@ static int peer_attach(VirtIONet *n, int index)
return 0;
}
if (n->max_queues == 1) {
return 0;
}
return tap_enable(nc->peer);
}
@@ -719,6 +723,8 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
uint64_t supported_offloads;
offloads = virtio_ldq_p(vdev, &offloads);
if (!n->has_vnet_hdr) {
return VIRTIO_NET_ERR;
}
@@ -1518,9 +1524,12 @@ static void virtio_net_del_queue(VirtIONet *n, int index)
if (q->tx_timer) {
timer_del(q->tx_timer);
timer_free(q->tx_timer);
q->tx_timer = NULL;
} else {
qemu_bh_delete(q->tx_bh);
q->tx_bh = NULL;
}
q->tx_waiting = 0;
virtio_del_queue(vdev, index * 2 + 1);
}
+1 -1
View File
@@ -128,7 +128,7 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
}
static const TypeInfo dec_21154_pci_host_info = {
+1 -1
View File
@@ -150,7 +150,7 @@ static void pxb_host_class_init(ObjectClass *class, void *data)
dc->fw_name = "pci";
/* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself */
dc->cannot_instantiate_with_device_add_yet = true;
dc->user_creatable = false;
sbc->explicit_ofw_unit_address = pxb_host_ofw_unit_address;
hc->root_bus_path = pxb_host_root_bus_path;
}
Loaded 100 of 251 files, more files were not shown because too many files have changed in this diff. Show more