Compare commits

..
109 Commits
Author SHA1 Message Date
Michael Roth e22f675bdd Update version for 2.12.1 release
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-08-02 15:51:06 -05:00
Fam Zheng aae299a68d file-posix: Handle EINTR in preallocation=full write
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 a1c81f4f16)
 Conflicts:
	block/file-posix.c
* avoid dep on 93f4e2ff by adding check to raw_regular_truncate instead
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-31 11:54:59 -05:00
KONRAD Frederic b102aea574 qcow: fix a reference leak
Since 42a3e1ab36 qemu asserts when using the
vvfat driver:

git clone git://qemu.org/qemu.git
cd qemu
./configure --target-list=ppc-softmmu --enable-debug
make -j8
mkdir foo
touch foo/hello
./ppc-softmmu/qemu-system-ppc -M prep --nographic --monitor null             \
                              -hda fat:rw:./foo

"Ctrl-C"

qemu-system-ppc: block.c:3368: bdrv_close_all: Assertion                     \
   `((&all_bdrv_states)->tqh_first == ((void *)0))' failed.

This is because we reference bs twice in qcow_co_create(..) one time in
bdrv_open_blockdev_ref(..) and in blk_insert_bs(..) but we unref it only once
in blk_unref which leads to the reference leak.

Note that I didn't tested much QCOW after this change as I don't use it much.

Signed-off-by: KONRAD Frederic <frederic.konrad@adacore.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 41b6513436)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-31 11:46:31 -05:00
Christian Borntraeger 336cd382dc s390x/sclp: fix maxram calculation
We clamp down ram_size to match the sclp increment size. We do
not do the same for maxram_size, which means for large guests
with some sizes (e.g. -m 50000) maxram_size differs from ram_size.
This can break other code (e.g. CMMA migration) which uses maxram_size
to calculate the number of pages and then throws some errors.

Fixes: 82fab5c5b9 ("s390x/sclp: remove memory hotplug support")
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
CC: qemu-stable@nongnu.org
CC: David Hildenbrand <david@redhat.com>
Message-Id: <1532959766-53343-1-git-send-email-borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 408e5ace51)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-31 11:27:16 -05:00
Marc-André Lureau bf1cb819e9 qga: process_event() simplification and leak fix
json_parser_parse_err() may return something else than a QDict, in
which case we loose the object. Let's keep track of the original
object to avoid leaks.

When an error occurs, "qdict" contains the response, but we still
check the "execute" key there. Untangle a bit this code, by having a
clear error path.

CC: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
(cherry picked from commit ae7da1e5f6)
* drop context dep on d43b16945a
* drop functional dep on cb3e7f08ae
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-24 17:47:40 -05:00
Markus Armbruster 08c4a51c65 qmp: De-duplicate error response building
All callers of qmp_build_error_object() duplicate the code to wrap it
in a response object.  Replace it by qmp_error_response() that
captures the duplicated code, including error_free().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180703085358.13941-23-armbru@redhat.com>
(cherry picked from commit cee32796ca)
 Conflicts:
	include/qapi/qmp/dispatch.h
	qapi/qmp-dispatch.c
	qga/main.c
* drop context dep on cb3e7f08ae
* prereq for ae7da1e5f6
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-24 15:45:47 -05:00
Markus Armbruster 441784598e qobject: New qdict_from_jsonf_nofail()
Many uses of qobject_from_jsonf() convert JSON objects.  Create new
convenience function qdict_from_jsonf_nofail() that includes the
conversion to QDict.  The next few commits will put it to use.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180703085358.13941-22-armbru@redhat.com>
(cherry picked from commit a193352ff9)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-24 15:05:01 -05:00
Michael Roth 2f36efaeb1 Merge tag 's390x-20180724-212-stable' into stable-2.12-staging
update s390-ccw.img for stable
2018-07-24 14:12:14 -05:00
Marc-André Lureau 90b2d94123 ccid-card-passthru: fix regression in realize()
Since cc847bfd16, CCID card-passthru
fails to intialize, because it changed a debug line to an error,
probably by mistake. Change it back to a DPRINTF debug.

(solves Boxes creating VM with smartcard passthru failing to start)

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20180515153039.27514-1-marcandre.lureau@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit e58d64a16a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-24 14:08:46 -05:00
Cornelia Huck c16427177a pc-bios/s390-ccw.img: update image for stable
Contains the following commits:
- s390-ccw: force diag 308 subcode to unsigned long
- pc-bios/s390-ccw: struct tpi_info must be declared as aligned(4)

Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-07-24 06:08:42 -04:00
Richard Henderson e8488edcb3 tcg/i386: Mark xmm registers call-clobbered
When host vector registers and operations were introduced, I failed
to mark the registers call clobbered as required by the ABI.

Fixes: 770c2fc7bb
Cc: qemu-stable@nongnu.org
Reported-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 672189cd58)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-23 14:24:17 -05:00
Peter Lieven 3afe55ff38 qemu-img: avoid overflow of min_sparse parameter
the min_sparse convert parameter can overflow (e.g. -S 1024G)
in the conversion from int64_t to int resulting in a negative
min_sparse parameter. Avoid this by limiting the valid parameters
to sane values. In fact anything exceeding the convert buffer size
is also pointless. While at it also forbid values that are non
multiple of 512 to avoid undesired behaviour. For instance, values
between 1 and 511 were legal, but resulted in full allocation.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 6360ab278c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-23 14:23:30 -05:00
Yunjian Wang 1b817abcd4 tap: fix memory leak on success to create a tap device
The memory leak on success to create a tap device. And the nfds and
nvhosts may not be the same and need to be processed separately.

Fixes: 07825977 ("tap: fix memory leak on failure to create a multiqueue tap device")
Fixes: 264986e2 ("tap: multiqueue support")
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 323e7c1177)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-23 14:20:45 -05:00
Emilio G. Cota 0935356e43 target/ppc: set is_jmp on ppc_tr_breakpoint_check
The use of GDB breakpoints was broken by b0c2d52 ("target/ppc: convert
to TranslatorOps", 2018-02-16).

Fix it by setting is_jmp, so that we break from the translation loop
as originally intended.

Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 2a8ceefca2)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 16:13:24 -05:00
Pankaj Gupta d109f8eb7e virtio-rng: process pending requests on DRIVER_OK
virtio-rng device causes old guest kernels(2.6.32) to hang on latest qemu.
The driver attempts to read from the virtio-rng device too early in it's
initialization. Qemu detects guest is not ready and returns, resulting in
hang.

To fix handle pending requests when guest is running and driver status is
set to 'VIRTIO_CONFIG_S_DRIVER_OK'.

CC: qemu-stable@nongnu.org
Reported-by: Sergio lopez <slopezpa@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Pankaj Gupta <pagupta@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 5d9c9ea22a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 16:11:30 -05:00
Eric Blake 2379ac134a iscsi: Avoid potential for get_status overflow
Detected by Coverity: Multiplying two 32-bit int and assigning
the result to a 64-bit number is a risk of overflow.  Prior to
the conversion to byte-based interfaces, the block layer took
care of ensuring that a status request never exceeded 2G in
the driver; but after that conversion, the block layer expects
drivers to deal with any size request (the driver can always
truncate the request size back down, as long as it makes
progress).  So, in the off-chance that someone makes a large
request, we are at the mercy of whether iscsi_get_lba_status_task()
will cap things to at most INT_MAX / iscsilun->block_size when
it populates lbasd->num_blocks; since I could not easily audit
that, it's better to be safe than sorry by just forcing a 64-bit
multiply.

Fixes: 92809c36
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180508212718.1482663-1-eblake@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
(cherry picked from commit 8ee1cef459)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 16:10:48 -05:00
Eric Blake f8b3b02933 nbd/server: Reject 0-length block status request
The NBD spec says that behavior is unspecified if the client
requests 0 length for block status; but since the structured
reply is documenting as returning a non-zero length, it's
easier to just diagnose this with an EINVAL error than to
figure out what to return.

CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180621124937.166549-1-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
(cherry picked from commit d8b20291cb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 11:51:25 -05:00
Richard Henderson 78747264b9 tcg: Reduce max TB opcode count
Also, assert that we don't overflow any of two different offsets into
the TB. Both unwind and goto_tb both record a uint16_t for later use.

This fixes an arm-softmmu test case utilizing NEON in which there is
a TB generated that runs to 7800 opcodes, and compiles to 96k on an
x86_64 host.  This overflows the 16-bit offset in which we record the
goto_tb reset offset.  Because of that overflow, we install a jump
destination that goes to neverland.  Boom.

With this reduced op count, the same TB compiles to about 48k for
aarch64, ppc64le, and x86_64 hosts, and neither assertion fires.

Cc: qemu-stable@nongnu.org
Reported-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 9f75462065)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 11:44:56 -05:00
Vladimir Sementsov-Ogievskiy d8a7ec1deb migration/block-dirty-bitmap: fix dirty_bitmap_load
dirty_bitmap_load_header return code is obtained but not handled. Fix
this.

Bug was introduced in b35ebdf076
"migration: add postcopy migration of dirty bitmaps" with the whole
function.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20180530112424.204835-1-vsementsov@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
(cherry picked from commit a36f6ff46f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 11:43:20 -05:00
Alex Williamson 2cb041a82d vfio/pci: Default display option to "off"
Commit a9994687cb ("vfio/display: core & wireup") added display
support to vfio-pci with the default being "auto", which breaks
existing VMs when the vGPU requires GL support but had no previous
requirement for a GL compatible configuration.  "Off" is the safer
default as we impose no new requirements to VM configurations.

Fixes: a9994687cb ("vfio/display: core & wireup")
Cc: qemu-stable@nongnu.org
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
(cherry picked from commit 8151a9c56d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 11:15:01 -05:00
Olaf Hering 6d3ed3798b replace functions which are only available in glib-2.24
Currently the minimal supported version of glib is 2.22.
Since testing is done with a glib that claims to be 2.22, but in fact
has APIs from newer version of glib, this bug was not caught during
submit of the patch referenced below.

Replace g_realloc_n, which is available only since 2.24, with g_renew.

Fixes commit 418026ca43 ("util: Introduce vfio helpers")

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
CC: qemu-stable@nongnu.org
(cherry picked from commit d29eb678bc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 11:12:05 -05:00
Kevin Wolf 58119514f5 nfs: Remove processed options from QDict
Commit c22a03454 QAPIfied option parsing in the NFS block driver, but
forgot to remove all the options we processed. Therefore, we get an
error in bdrv_open_inherit(), which thinks the remaining options are
invalid. Trying to open an NFS image will result in an error like this:

    Block protocol 'nfs' doesn't support the option 'server.host'

Remove all options from the QDict to make the NFS driver work again.

Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-id: 20180516160816.26259-1-kwolf@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit c82be42cc8)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 11:10:19 -05:00
Marc-André Lureau 008ffc7a2f mux: fix ctrl-a b again
Commit fb5e19d2e1 originally fixed the
regression, but was inadvertently broken again in merge commit
2d6752d38d.

Fixes:
https://bugs.launchpad.net/qemu/+bug/1654137

Cc: qemu-stable@nongnu.org
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20180515152500.19460-3-f4bug@amsat.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit eeaa671505)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 11:03:03 -05:00
Philippe Mathieu-Daudé 5e10c00f61 hw/isa/superio: Fix inconsistent use of Chardev->be
4c3119a6e3 and cd9526ab7c introduced an incorrect and inconsistent
use of Chardev->be. Also, this CharBackend member is private and is
not supposed to be accessible.

Fix it by removing the inconsistent check.

Cc: qemu-stable@nongnu.org
Reported-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20180515152500.19460-2-f4bug@amsat.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
(cherry picked from commit d4c8fcd91a)
 Conflicts:
	hw/isa/isa-superio.c
* avoid context dep on 9bca0edb28
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 11:02:03 -05:00
Alex Bennée ca11f0ab77 target/arm: Fix sqrt_f16 exception raising
We are meant to explicitly pass fpst, not cpu_env.

Cc: qemu-stable@nongnu.org
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-12-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 905edee910)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:52:03 -05:00
Alex Bennée ffc3a15018 target/arm: Implement FMOV (immediate) for fp16
All the hard work is already done by vfp_expand_imm, we just need to
make sure we pick up the correct size.

Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180512003217.9105-11-richard.henderson@linaro.org
[rth: Merge unallocated_encoding check with TCGMemOp conversion.]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

(cherry picked from commit 6ba28ddb9b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:51:54 -05:00
Alex Bennée f3816879f9 target/arm: Implement FCSEL for fp16
These were missed out from the rest of the half-precision work.

Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180512003217.9105-10-richard.henderson@linaro.org
[rth: Fix erroneous check vs type]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

(cherry picked from commit ace97feef3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:51:44 -05:00
Alex Bennée 246dad2f3c target/arm: Implement FCMP for fp16
These where missed out from the rest of the half-precision work.

Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180512003217.9105-9-richard.henderson@linaro.org
[rth: Diagnose lack of FP16 before fp_access_check]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

(cherry picked from commit 7a1929256e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:51:31 -05:00
Richard Henderson 0819a17250 target/arm: Implement FP data-processing (3 source) for fp16
We missed all of the scalar fp16 fma operations.

Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-8-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 95f9864fde)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:51:20 -05:00
Richard Henderson 7133cd4cfe target/arm: Implement FP data-processing (2 source) for fp16
We missed all of the scalar fp16 binary operations.

Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-7-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit b8f5171cf0)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:51:05 -05:00
Richard Henderson d1ed4a60ba target/arm: Introduce and use read_fp_hreg
Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-6-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 3d99d93126)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:50:48 -05:00
Richard Henderson 7c38f3703d target/arm: Implement FCVT (scalar, fixed-point) for fp16
Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-5-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 2752728016)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:50:35 -05:00
Richard Henderson baa552e54f target/arm: Implement FCVT (scalar, integer) for fp16
Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-4-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 564a063250)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:49:18 -05:00
Richard Henderson 4ec6a17a04 target/arm: Implement FMOV (general) for fp16
Adding the fp16 moves to/from general registers.

Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180512003217.9105-2-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 68130236e3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:48:36 -05:00
Petr Tesarik 781cde6d94 fpu/softfloat: Fix conversion from uint64 to float128
The significand is passed to normalizeRoundAndPackFloat128() as high
first, low second. The current code passes the integer first, so the
result is incorrectly shifted left by 64 bits.

This bug affects the emulation of s390x instruction CXLGBR (convert
from logical 64-bit binary-integer operand to extended BFP result).

Cc: qemu-stable@nongnu.org
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
Message-Id: <20180511071052.1443-1-ptesarik@suse.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 6603d50648)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:47:49 -05:00
Richard Henderson e5af958dd2 target/arm: Clear SVE high bits for FMOV
Use write_fp_dreg and clear_vec_high to zero the bits
that need zeroing for these cases.

Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180502221552.3873-5-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 9a9f1f5952)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:47:00 -05:00
Richard Henderson c708ce7d6e target/arm: Fix float16 to/from int16
The instruction "ucvtf v0.4h, v04h, #2", with input 0x8000u,
overflows the intermediate float16 to infinity before we have a
chance to scale the output.  Use float64 as the intermediate type
so that no input argument (uint32_t in this case) can overflow
or round before scaling.  Given the declared argument, the signed
int32_t function has the same problem.

When converting from float16 to integer, using u/int32_t instead
of u/int16_t means that the bounding is incorrect.

Cc: qemu-stable@nongnu.org
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180502221552.3873-4-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 88808a022c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:46:52 -05:00
Richard Henderson 0aaf1cca02 target/arm: Implement vector shifted FCVT for fp16
While we have some of the scalar paths for FCVT for fp16,
we failed to decode the fp16 version of these instructions.

Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180502221552.3873-3-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit d0ba8e74ac)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:46:40 -05:00
Richard Henderson 994b0cf997 target/arm: Implement vector shifted SCVF/UCVF for fp16
While we have some of the scalar paths for *CVF for fp16,
we failed to decode the fp16 version of these instructions.

Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180502221552.3873-2-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit a6117fae45)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:46:30 -05:00
Peter Maydell e653eee8d8 fpu/softfloat: Don't set Invalid for float-to-int(MAXINT)
In float-to-integer conversion, if the floating point input
converts exactly to the largest or smallest integer that
fits in to the result type, this is not an overflow.
In this situation we were producing the correct result value,
but were incorrectly setting the Invalid flag.
For example for Arm A64, "FCVTAS w0, d0" on an input of
0x41dfffffffc00000 should produce 0x7fffffff and set no flags.

Fix the boundary case to take the right half of the if()
statements.

This fixes a regression from 2.11 introduced by the softfloat
refactoring.

Cc: qemu-stable@nongnu.org
Fixes: ab52f973a5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180510140141.12120-1-peter.maydell@linaro.org
(cherry picked from commit 333583757c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:45:23 -05:00
Peter Maydell fbaeb1068c target/arm: Fix fp_status_f16 tininess before rounding
In commit d81ce0ef2c we added an extra float_status field
fp_status_fp16 for Arm, but forgot to initialize it correctly
by setting it to float_tininess_before_rounding. This currently
will only cause problems for the new V8_FP16 feature, since the
float-to-float conversion code doesn't use it yet. The effect
would be that we failed to set the Underflow IEEE exception flag
in all the cases where we should.

Add the missing initialization.

Fixes: d81ce0ef2c
Cc: qemu-stable@nongnu.org
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20180512004311.9299-16-richard.henderson@linaro.org
(cherry picked from commit bcc531f036)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:43:45 -05:00
John Snow 0779afdc89 blockjob: expose error string via query
When we've reached the concluded state, we need to expose the error
state if applicable. Add the new field.

This should be sufficient for determining if a job completed
successfully or not after concluding; if we want to discriminate
based on how it failed more mechanically, we can always add an
explicit return code enumeration later.

I didn't bother to make it only show up if we are in the concluded
state; I don't think it's necessary.

Cc: qemu-stable@nongnu.org
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit ab9ba61455)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:35:53 -05:00
Michael Clark 4a67f4a953 RISC-V: Minimal QEMU 2.12 fix for sifive_u machine
The 'sifive_u' board has a bug where the ROM is
created as RAM at the wrong address and marked
readonly. The bug renders the board unusable.
This is a minimal fix and allows booting Linux.

5aec3247c1
"RISC-V: Mark ROM read-only after copying in code"
contains a comprehensive fix using the ROM APIs
memory_region_init_rom and rom_add_blob_fixed_as
which could be backported.

Cc: Sagar Karandikar <sagark@eecs.berkeley.edu>
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Alistair Francis <Alistair.Francis@wdc.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Clark <mjc@sifive.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-18 10:32:06 -05:00
Richard Henderson 9363c34825 tcg: Limit the number of ops in a TB
In 6001f7729e we partially attempt to address the branch
displacement overflow caused by 15fa08f845.

However, gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vqtbX.c
is a testcase that contains a TB so large as to overflow anyway.
The limit here of 8000 ops produces a maximum output TB size of
24112 bytes on a ppc64le host with that test case.  This is still
much less than the maximum forward branch distance of 32764 bytes.

Cc: qemu-stable@nongnu.org
Fixes: 15fa08f845 ("tcg: Dynamically allocate TCGOps")
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit abebf92597)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:22 -05:00
Peter Maydell 51d5decb32 softfloat: Handle default NaN mode after pickNaNMulAdd, not before
It is implementation defined whether a multiply-add of
(0,inf,qnan) or (inf,0,qnan) raises InvalidaOperation or
not, so we let the target-specific pickNaNMulAdd function
handle this. This means that we must do the "return the
default NaN in default NaN mode" check after the call,
not before. Correct the ordering, and restore the comment
from the old propagateFloat64MulAddNaN() that warned about
this corner case.

This fixes a regression from 2.11 for Arm guests where we would
incorrectly fail to set the Invalid flag for these cases.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180504100547.14621-1-peter.maydell@linaro.org
(cherry picked from commit 1839189bbf)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:22 -05:00
Peter Maydell 0e4b4b4fd3 tcg/i386: Fix dup_vec in non-AVX2 codepath
The VPUNPCKLD* instructions are all "non-destructive source",
indicated by "NDS" in the encoding string in the x86 ISA manual.
This means that they take two source operands, one of which is
encoded in the VEX.vvvv field. We were incorrectly treating them
as if they were destructive-source and passing 0 as the 'v'
argument of tcg_out_vex_modrm(). This meant we were always
using %xmm0 as one of the source operands, causing incorrect
results if the register allocator happened to want to use
something else. For instance the input AArch64 insn:
 DUP v26.16b, w21
which becomes TCG IR ops:
 dup_vec v128,e8,tmp2,x21
 st_vec v128,e8,tmp2,env,$0xa40
was assembled to:
0x607c568c:  c4 c1 7a 7e 86 e8 00 00  vmovq    0xe8(%r14), %xmm0
0x607c5694:  00
0x607c5695:  c5 f9 60 c8              vpunpcklbw %xmm0, %xmm0, %xmm1
0x607c5699:  c5 f9 61 c9              vpunpcklwd %xmm1, %xmm0, %xmm1
0x607c569d:  c5 f9 70 c9 00           vpshufd  $0, %xmm1, %xmm1
0x607c56a2:  c4 c1 7a 7f 8e 40 0a 00  vmovdqu  %xmm1, 0xa40(%r14)
0x607c56aa:  00

when the vpunpcklwd insn should be "%xmm1, %xmm1, %xmm1".
This resulted in our incorrectly setting the output vector to
q26=0000320000003200:0000320000003200
when given an input of x21 == 0000000002803200
rather than the expected all-zeroes.

Pass the correct source register number to tcg_out_vex_modrm()
for these insns.

Fixes: 770c2fc7bb
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20180504153431.5169-1-peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 7eb30ef0ba)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:22 -05:00
Eric Blake 6951158023 nbd/client: Relax handling of large NBD_CMD_BLOCK_STATUS reply
The NBD spec is proposing a relaxation of NBD_CMD_BLOCK_STATUS
where a server may have the final extent per context give a
length beyond the original request, if it can easily prove that
subsequent bytes have the same status, on the grounds that a
client can take advantage of this information for fewer block
status requests.  Since qemu 2.12 as a client always sends
NBD_CMD_FLAG_REQ_ONE, and rejects a server that sends extra
length, the upstream NBD spec will probably limit this behavior
to clients that don't request REQ_ONE semantics; but it doesn't
hurt to relax qemu to always be permissive of this server
behavior, even if it continues to use REQ_ONE.

CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180503222626.1303410-1-eblake@redhat.com>
Reviewed-by:  Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
(cherry picked from commit acfd8f7a5f)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:22 -05:00
KONRAD Frederic b129914a8d riscv: requires libfdt
When compiling on a machine without libfdt installed the configure script
should try to get libfdt from the git or should die because otherwise
CONFIG_LIBFDT is not set and the build process end in an error in the link
phase.. eg:

hw/riscv/virt.o: In function `riscv_virt_board_init':
qemu/src/hw/riscv/virt.c:317: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:319: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:345: undefined reference to `qemu_fdt_dumpdtb'
collect2: error: ld returned 1 exit status
make[1]: *** [qemu-system-riscv64] Error 1
make: *** [subdir-riscv64-softmmu] Error 2

Cc: qemu-stable@nongnu.org
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Michael Clark <mjc@sifive.com>
Signed-off-by: KONRAD Frederic <frederic.konrad@adacore.com>
Signed-off-by: Michael Clark <mjc@sifive.com>

Message-Id: <1525360636-18229-4-git-send-email-frederic.konrad@adacore.com>
(cherry picked from commit a666409f0d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:22 -05:00
KONRAD Frederic db6f66eff7 riscv: htif: increase the priority of the htif subregion
The htif device is supposed to be mapped over an other subregion. So increase
its priority to one to avoid any conflict.

Here is the output of info mtree:

Before:
(qemu) info mtree
 address-space: memory
   0000000000000000-ffffffffffffffff (prio 0, i/o): system
     0000000000000000-000000000000000f (prio 0, i/o): riscv.htif.uart
     0000000000000000-0000000000011fff (prio 0, ram): riscv.spike.bootrom
     0000000002000000-000000000200ffff (prio 0, i/o): riscv.sifive.clint
     0000000080000000-0000000087ffffff (prio 0, ram): riscv.spike.ram

 address-space: I/O
   0000000000000000-000000000000ffff (prio 0, i/o): io

 address-space: cpu-memory-0
   0000000000000000-ffffffffffffffff (prio 0, i/o): system
     0000000000000000-000000000000000f (prio 0, i/o): riscv.htif.uart
     0000000000000000-0000000000011fff (prio 0, ram): riscv.spike.bootrom
     0000000002000000-000000000200ffff (prio 0, i/o): riscv.sifive.clint
     0000000080000000-0000000087ffffff (prio 0, ram): riscv.spike.ram

After:
 (qemu) info mtree
 address-space: memory
   0000000000000000-ffffffffffffffff (prio 0, i/o): system
     0000000000000000-000000000000000f (prio 1, i/o): riscv.htif.uart
     0000000000000000-0000000000011fff (prio 0, ram): riscv.spike.bootrom
     0000000002000000-000000000200ffff (prio 0, i/o): riscv.sifive.clint
     0000000080000000-0000000087ffffff (prio 0, ram): riscv.spike.ram

 address-space: I/O
   0000000000000000-000000000000ffff (prio 0, i/o): io

 address-space: cpu-memory-0
   0000000000000000-ffffffffffffffff (prio 0, i/o): system
     0000000000000000-000000000000000f (prio 1, i/o): riscv.htif.uart
     0000000000000000-0000000000011fff (prio 0, ram): riscv.spike.bootrom
     0000000002000000-000000000200ffff (prio 0, i/o): riscv.sifive.clint
     0000000080000000-0000000087ffffff (prio 0, ram): riscv.spike.ram

Reviewed-by: Michael Clark <mjc@sifive.com>
Signed-off-by: KONRAD Frederic <frederic.konrad@adacore.com>
Signed-off-by: Michael Clark <mjc@sifive.com>

Message-Id: <1525360636-18229-3-git-send-email-frederic.konrad@adacore.com>
(cherry picked from commit 6fad7d1893)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:22 -05:00
KONRAD Frederic 26cf05c1a1 riscv: spike: allow base == 0
The sanity check on base doesn't allow htif to be mapped @0. Check if the
symbol exists instead so we can map it where we want.

Reviewed-by: Michael Clark <mjc@sifive.com>
Signed-off-by: KONRAD Frederic <frederic.konrad@adacore.com>
Signed-off-by: Michael Clark <mjc@sifive.com>

Message-Id: <1525360636-18229-2-git-send-email-frederic.konrad@adacore.com>
(cherry picked from commit 17b9751e85)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:22 -05:00
Max Reitz 7bc615f88f iotests: Add test for cancelling a mirror job
We already have an extensive mirror test (041) which does cover
cancelling a mirror job, especially after it has emitted the READY
event.  However, it does not check what exact events are emitted after
block-job-cancel is executed.  More importantly, it does not use
throttling to ensure that it covers the case of block-job-cancel before
READY.

It would be possible to add this case to 041, but considering it is
already our largest test file, it makes sense to create a new file for
these cases.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20180501220509.14152-3-mreitz@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit dc885fff97)
 Conflicts:
	tests/qemu-iotests/group
* fix minor conflicts with test groups
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Max Reitz 1eddfab31c block/mirror: Make cancel always cancel pre-READY
Commit b76e4458b1 made the mirror block
job respect block-job-cancel's @force flag: With that flag set, it would
now always really cancel, even post-READY.

Unfortunately, it had a side effect: Without that flag set, it would now
never cancel, not even before READY.  Considering that is an
incompatible change and not noted anywhere in the commit or the
description of block-job-cancel's @force parameter, this seems
unintentional and we should revert to the previous behavior, which is to
immediately cancel the job when block-job-cancel is called before source
and target are in sync (i.e. before the READY event).

Cc: qemu-stable@nongnu.org
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1572856
Reported-by: Yanan Fu <yfu@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20180501220509.14152-2-mreitz@redhat.com
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit eb36639f7b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Laszlo Ersek 3882183fda qapi: fill in CpuInfoFast.arch in query-cpus-fast
* Commit ca230ff33f added the @arch field to @CpuInfoFast, but it failed
  to set the new field in qmp_query_cpus_fast(), when TARGET_S390X was not
  defined. The updated @query-cpus-fast example in "qapi-schema.json"
  showed "arch":"x86" only because qmp_query_cpus_fast() calls g_malloc0()
  to allocate @CpuInfoFast, and the CPU_INFO_ARCH_X86 enum constant is
  generated with value 0.

  All @arch values other than @s390 implied the @CpuInfoOther sub-struct
  for @CpuInfoFast -- at the time of writing the patch --, thus no fields
  other than @arch needed to be set when TARGET_S390X was not defined. Set
  @arch now, by copying the corresponding assignments from
  qmp_query_cpus().

* Commit 25fa194b7b added the @riscv enum constant to @CpuInfoArch (used
  in both @CpuInfo and @CpuInfoFast -- the return types of the @query-cpus
  and @query-cpus-fast commands, respectively), and assigned, in both
  return structures, the @CpuInfoRISCV sub-structure to the new enum
  value.

  However, qmp_query_cpus_fast() would not populate either the @arch field
  or the @CpuInfoRISCV sub-structure, when TARGET_RISCV was defined; only
  qmp_query_cpus() would.

  Assign @CpuInfoOther to the @riscv enum constant in @CpuInfoFast, and
  populate only the @arch field in qmp_query_cpus_fast(). Getting CPU
  state without interrupting KVM is an exceptional thing that only S390X
  does currently. Quoting Cornelia Huck <cohuck@redhat.com>, "s390x is
  exceptional in that it has state in QEMU that is actually interesting
  for upper layers and can be retrieved without performance penalty". See
  also
  <https://www.redhat.com/archives/libvir-list/2018-February/msg00121.html>.

Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Viktor VM Mihajlovski <mihajlov@linux.vnet.ibm.com>
Cc: qemu-stable@nongnu.org
Fixes: ca230ff33f
Fixes: 25fa194b7b
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20180427192852.15013-2-lersek@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
(cherry picked from commit 96054f5639)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Vladimir Sementsov-Ogievskiy 3b52d47418 migration/block-dirty-bitmap: fix memory leak in dirty_bitmap_load_bits
Release buf on error path too.

Bug was introduced in b35ebdf076 "migration: add postcopy
migration of dirty bitmaps" with the whole function.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20180427142002.21930-3-vsementsov@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 16a2227893)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Vladimir Sementsov-Ogievskiy f155487bef nbd/client: fix nbd_negotiate_simple_meta_context
Initialize received variable. Otherwise, is is possible for server to
answer without any contexts, but we will set context_id to something
random (received_id is not initialized too) and return 1, which is
wrong.

To solve it, just initialize received to false. Initialize received_id
too, just to make all possible checkers happy.

Bug was introduced in 78a33ab587 "nbd: BLOCK_STATUS for
standard get_block_status function: client part" with the whole
function.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20180427142002.21930-2-vsementsov@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 89aa0d8763)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Cédric Le Goater 54eb6cc6d7 cpus: tcg: fix never exiting loop on unplug
Commit 9b0605f983 ("cpus: tcg: unregister thread with RCU, fix
exiting of loop on unplug") changed the exit condition of the loop in
the vCPU thread function but forgot to remove the beginning 'while (1)'
statement. The resulting code :

	while (1) {
	...
	} while (!cpu->unplug || cpu_can_run(cpu));

is a sequence of two distinct two while() loops, the first not exiting
in case of an unplug event.

Remove the first while (1) to fix CPU unplug.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20180425131828.15604-1-clg@kaod.org>
Cc: qemu-stable@nongnu.org
Fixes: 9b0605f983
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
(cherry picked from commit 54961aac19)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Stefan Hajnoczi 9eb3e5a8a8 block/mirror: honor ratelimit again
Commit b76e4458b1 ("block/mirror: change
the semantic of 'force' of block-job-cancel") accidentally removed the
ratelimit in the mirror job.

Reintroduce the ratelimit but keep the block-job-cancel force=true
behavior that was added in commit
b76e4458b1.

Note that block_job_sleep_ns() returns immediately when the job is
cancelled.  Therefore it's safe to unconditionally call
block_job_sleep_ns() - a cancelled job does not sleep.

This commit fixes the non-deterministic qemu-iotests 185 output.  The
test relies on the ratelimit to make the job sleep until the 'quit'
command is processed.  Previously the job could complete before the
'quit' command was received since there was no ratelimit.

Cc: Liang Li <liliang.opensource@gmail.com>
Cc: Jeff Cody <jcody@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20180424123527.19168-1-stefanha@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
(cherry picked from commit ddc4115efd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Gerd Hoffmann 05a3e663b1 vnc: fix use-after-free
When vnc_client_read() return value is -1
vs is not valid any more.

Fixes: d49b87f0d1
Reported-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20180420084820.3873-1-kraxel@redhat.com
(cherry picked from commit 1bc3117aba)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Philippe Mathieu-Daudé 073198b8e8 usb/dev-mtp: Fix use of uninitialized values
This fixes:

  hw/usb/dev-mtp.c:971:5: warning: 4th function call argument is an uninitialized value
      trace_usb_mtp_op_get_partial_object(s->dev.addr, o->handle, o->path,
                                           c->argv[1], c->argv[2]);
                                                       ^~~~~~~~~~
and:

  hw/usb/dev-mtp.c:981:12: warning: Assigned value is garbage or undefined
      offset = c->argv[1];
               ^ ~~~~~~~~~~

Reported-by: Clang Static Analyzer
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20180604151421.23385-3-f4bug@amsat.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 62713a2e50)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Philippe Mathieu-Daudé 5da7e93f51 usb: correctly handle Zero Length Packets
USB Specification Revision 2.0, §5.5.3:
  The Data stage of a control transfer from an endpoint to the host is complete when the endpoint does one of the following:
  • Has transferred exactly the amount of data specified during the Setup stage
  • Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet"

hw/usb/redirect.c:802:9: warning: Declared variable-length array (VLA) has zero size
        uint8_t buf[size];
        ^~~~~~~~~~~ ~~~~

Reported-by: Clang Static Analyzer
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20180604151421.23385-2-f4bug@amsat.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit bf78fb1c1b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:21 -05:00
Shannon Zhao c5dd07b529 arm_gicv3_kvm: kvm_dist_get/put_priority: skip the registers banked by GICR_IPRIORITYR
While for_each_dist_irq_reg loop starts from GIC_INTERNAL, it forgot to
offset the date array and index. This will overlap the GICR registers
value and leave the last GIC_INTERNAL irq's registers out of update.

Fixes: 367b9f527b
Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 1dcf367519)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
Eric Blake 396d79c36c iotests: Add test 221 to catch qemu-img map regression
Although qemu-img creates aligned files (by rounding up), it
must also gracefully handle files that are not sector-aligned.
Test that the bug fixed in the previous patch does not recur.

It's a bit annoying that we can see the (implicit) hole past
the end of the file on to the next sector boundary, so if we
ever reach the point where we report a byte-accurate size rather
than our current behavior of always rounding up, this test will
probably need a slight modification.

Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit c6a9d2f6f9)
 Conflicts:
	tests/qemu-iotests/group
* drop context dep on tests not present in 2.12
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
Eric Blake 26cdf35f69 qemu-img: Fix assert when mapping unaligned raw file
Commit a290f085 exposed a latent bug in qemu-img map introduced
during the conversion of block status to be byte-based.  Earlier in
commit 5e344dd8, the internal interface get_block_status() switched
to take byte-based parameters, but still called a sector-based
block layer function; as such, rounding was added in the lone
caller to obey the contract.  However, commit 237d78f8 changed
get_block_status() to truly be byte-based, at which point rounding
to sector boundaries can result in calling bdrv_block_status() with
'bytes == 0' (a coding error) when the boundary between data and a
hole falls mid-sector (true for the past-EOF implicit hole present
in POSIX files).  Fix things by removing the rounding that is now
no longer necessary.

See also https://bugzilla.redhat.com/1589738

Fixes: 237d78f8
Reported-by: Dan Kenigsberg <danken@redhat.com>
Reported-by: Nir Soffer <nsoffer@redhat.com>
Reported-by: Maor Lipchuk <mlipchuk@redhat.com>
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e0b371ed5e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
linzhecheng fb7f173c2c vhost-user: delete net client if necessary
As qemu_new_net_client create new ncs but error happens later,
ncs will be left in global net_clients list and we can't use them any
more, so we need to cleanup them.

Cc: qemu-stable@nongnu.org
Signed-off-by: linzhecheng <linzhecheng@huawei.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit c67daf4a24)
 Conflicts:
	net/vhost-user.c
* drop functional dep on 4d0cf552
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
Brijesh Singh 2f2b189235 tap: set vhostfd passed from qemu cli to non-blocking
A guest boot hangs while probing the network interface when
iommu_platform=on is used.

The following qemu cli hangs without this patch:

# $QEMU \
  -netdev tap,fd=3,id=hostnet0,vhost=on,vhostfd=4 3<>/dev/tap67 4<>/dev/host-net \
  -device virtio-net-pci,netdev=hostnet0,id=net0,iommu_platform=on,disable-legacy=on \
  ...

Commit: c471ad0e9b (vhost_net: device IOTLB support) took care of
setting vhostfd to non-blocking when QEMU opens /dev/host-net but if
the fd is passed from qemu cli then we need to ensure that fd is set
to non-blocking.

Fixes: c471ad0e9b ("vhost_net: device IOTLB support")
Cc: qemu-stable@nongnu.org
Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit d542800d1e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
Konrad Rzeszutek Wilk 43163837d3 i386: define the AMD 'virt-ssbd' CPUID feature bit (CVE-2018-3639)
AMD Zen expose the Intel equivalant to Speculative Store Bypass Disable
via the 0x80000008_EBX[25] CPUID feature bit.

This needs to be exposed to guest OS to allow them to protect
against CVE-2018-3639.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20180521215424.13520-3-berrange@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit 403503b162)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
Konrad Rzeszutek Wilk 3129ddb943 i386: Define the Virt SSBD MSR and handling of it (CVE-2018-3639)
"Some AMD processors only support a non-architectural means of enabling
speculative store bypass disable (SSBD).  To allow a simplified view of
this to a guest, an architectural definition has been created through a new
CPUID bit, 0x80000008_EBX[25], and a new MSR, 0xc001011f.  With this, a
hypervisor can virtualize the existence of this definition and provide an
architectural method for using SSBD to a guest.

Add the new CPUID feature, the new MSR and update the existing SSBD
support to use this MSR when present." (from x86/speculation: Add virtualized
speculative store bypass disable support in Linux).

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20180521215424.13520-4-berrange@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit cfeea0c021)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
Daniel P. Berrangé 8a302f42a5 i386: define the 'ssbd' CPUID feature bit (CVE-2018-3639)
New microcode introduces the "Speculative Store Bypass Disable"
CPUID feature bit. This needs to be exposed to guest OS to allow
them to protect against CVE-2018-3639.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Message-Id: <20180521215424.13520-2-berrange@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
(cherry picked from commit d19d1f9659)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
Alberto Garcia ef67e67388 throttle: Fix crash on reopen
The throttle block filter can be reopened, and with this it is
possible to change the throttle group that the filter belongs to.

The way the code does that is the following:

  - On throttle_reopen_prepare(): create a new ThrottleGroupMember
    and attach it to the new throttle group.

  - On throttle_reopen_commit(): detach the old ThrottleGroupMember,
    delete it and replace it with the new one.

The problem with this is that by replacing the ThrottleGroupMember the
previous value of io_limits_disabled is lost, causing an assertion
failure in throttle_co_drain_end().

This problem can be reproduced by reopening a throttle node:

   $QEMU -monitor stdio
   -object throttle-group,id=tg0,x-iops-total=1000 \
   -blockdev node-name=hd0,driver=qcow2,file.driver=file,file.filename=hd.qcow2 \
   -blockdev node-name=root,driver=throttle,throttle-group=tg0,file=hd0,read-only=on

   (qemu) block_stream root
   block/throttle.c:214: throttle_co_drain_end: Assertion `tgm->io_limits_disabled' failed.

Since we only want to change the throttle group on reopen there's no
need to create a ThrottleGroupMember and discard the old one. It's
easier if we simply detach it from its current group and attach it to
the new one.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Message-id: 20180608151536.7378-1-berto@igalia.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit bc33c047d1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
Max Reitz 081eac8b30 iotests: Add case for a corrupted inactive image
Reviewed-by: John Snow <jsnow@redhat.com>
Tested-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20180606193702.7113-4-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit c50abd175a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:20 -05:00
Max Reitz 5aa76f3a8c qcow2: Do not mark inactive images corrupt
When signaling a corruption on a read-only image, qcow2 already makes
fatal events non-fatal (i.e., they will not result in the image being
closed, and the image header's corrupt flag will not be set).  This is
necessary because we cannot set the corrupt flag on read-only images,
and it is possible because further corruption of read-only images is
impossible.

Inactive images are effectively read-only, too, so we should do the same
for them.  bdrv_is_writable() can tell us whether an image can actually
be written to, so use its result instead of !bs->read_only.

(Otherwise, the assert(!(bs->open_flags & BDRV_O_INACTIVE)) in
bdrv_co_pwritev() will fail, crashing qemu.)

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20180606193702.7113-3-mreitz@redhat.com
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit ddf3b47ef4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:19 -05:00
Max Reitz bd64fec665 block: Make bdrv_is_writable() public
This is a useful function for the whole block layer, so make it public.
At the same time, users outside of block.c probably do not need to make
use of the reopen functionality, so rename the current function to
bdrv_is_writable_after_reopen() create a new bdrv_is_writable() function
that just passes NULL to it for the reopen queue.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20180606193702.7113-2-mreitz@redhat.com
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit cc02214097)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:19 -05:00
Shannon Zhao 5459c0c458 arm_gicv3_kvm: kvm_dist_get/put: skip the registers banked by GICR
While we skip the GIC_INTERNAL irqs, we don't change the register offset
accordingly. This will overlap the GICR registers value and leave the
last GIC_INTERNAL irq's registers out of update.

Fix this by skipping the registers banked by GICR.

Also for migration compatibility if the migration source (old version
qemu) doesn't send gicd_no_migration_shift_bug = 1 to destination, then
we shift the data of PPI to get the right data for SPI.

Fixes: 367b9f527b
Cc: qemu-stable@nongnu.org
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
Message-id: 1527816987-16108-1-git-send-email-zhaoshenglong@huawei.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 910e204841)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:19 -05:00
John Snow 5c9266fa97 ahci: fix PxCI register race
Fixes: https://bugs.launchpad.net/qemu/+bug/1769189

AHCI presently signals completion prior to the PxCI register being
cleared to indicate completion. If a guest driver attempts to issue
a new command in its IRQ handler, it might be surprised to learn there
is still a command pending.

In the case of Windows 10's boot driver, it will actually poll the IRQ
register hoping to find out when the command is done running -- which
will never happen, as there isn't a command running.

Fix this: clear PxCI in ahci_cmd_done and not in the asynchronous BH.
Because it now runs synchronously, we don't need to check if the command
is actually done by spying on the ATA registers. We know it's done.

CC: qemu-stable <qemu-stable@nongnu.org>
Reported-by: François Guerraz <kubrick@fgv6.net>
Tested-by: Bruce Rogers <brogers@suse.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Message-id: 20180531004323.4611-3-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
(cherry picked from commit 5694c7eacc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:19 -05:00
John Thomson df00a166c4 Fix libusb-1.0.22 deprecated libusb_set_debug with libusb_set_option
libusb-1.0.22 marked libusb_set_debug deprecated
it is replaced with
libusb_set_option(libusb_context, LIBUSB_OPTION_LOG_LEVEL, libusb_log_level);

details here: https://github.com/libusb/libusb/commit/539f22e2fd916558d11ab9a66f10f461c5593168

Warning here:

  CC      hw/usb/host-libusb.o
/builds/xen/src/qemu-xen/hw/usb/host-libusb.c: In function 'usb_host_init':
/builds/xen/src/qemu-xen/hw/usb/host-libusb.c:250:5: error: 'libusb_set_debug' is deprecated: Use libusb_set_option instead [-Werror=deprecated-declarations]
     libusb_set_debug(ctx, loglevel);
     ^~~~~~~~~~~~~~~~
In file included from /builds/xen/src/qemu-xen/hw/usb/host-libusb.c:40:0:
/usr/include/libusb-1.0/libusb.h:1300:18: note: declared here
 void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level);
                  ^~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make: *** [/builds/xen/src/qemu-xen/rules.mak:66: hw/usb/host-libusb.o] Error 1
make: Leaving directory '/builds/xen/src/xen/tools/qemu-xen-build'

Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
Message-id: 20180405132046.4968-1-git@johnthomson.fastmail.com.au
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 9d8fa0df49)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:19 -05:00
Shannon Zhao 77df190051 arm_gicv3_kvm: increase clroffset accordingly
It forgot to increase clroffset during the loop. So it only clear the
first 4 bytes.

Fixes: 367b9f527b
Cc: qemu-stable@nongnu.org
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-id: 1527047633-12368-1-git-send-email-zhaoshenglong@huawei.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 34ffacae08)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:19 -05:00
Peter Xu f4b4095a8f intel-iommu: rework the page walk logic
This patch fixes a potential small window that the DMA page table might
be incomplete or invalid when the guest sends domain/context
invalidations to a device.  This can cause random DMA errors for
assigned devices.

This is a major change to the VT-d shadow page walking logic. It
includes but is not limited to:

- For each VTDAddressSpace, now we maintain what IOVA ranges we have
  mapped and what we have not.  With that information, now we only send
  MAP or UNMAP when necessary.  Say, we don't send MAP notifies if we
  know we have already mapped the range, meanwhile we don't send UNMAP
  notifies if we know we never mapped the range at all.

- Introduce vtd_sync_shadow_page_table[_range] APIs so that we can call
  in any places to resync the shadow page table for a device.

- When we receive domain/context invalidation, we should not really run
  the replay logic, instead we use the new sync shadow page table API to
  resync the whole shadow page table without unmapping the whole
  region.  After this change, we'll only do the page walk once for each
  domain invalidations (before this, it can be multiple, depending on
  number of notifiers per address space).

While at it, the page walking logic is also refactored to be simpler.

CC: QEMU Stable <qemu-stable@nongnu.org>
Reported-by: Jintack Lim <jintack@cs.columbia.edu>
Tested-by: Jintack Lim <jintack@cs.columbia.edu>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 63b88968f1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:19 -05:00
Peter Xu 08aa25f5f8 util: implement simple iova tree
Introduce a simplest iova tree implementation based on GTree.

CC: QEMU Stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit eecf5eedbd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:19 -05:00
Peter Xu d5c60a950a intel-iommu: trace domain id during page walk
This patch only modifies the trace points.

Previously we were tracing page walk levels.  They are redundant since
we have page mask (size) already.  Now we trace something much more
useful which is the domain ID of the page walking.  That can be very
useful when we trace more than one devices on the same system, so that
we can know which map is for which domain.

CC: QEMU Stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit d118c06ebb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:19 -05:00
Peter Xu 78b85a98a3 intel-iommu: pass in address space when page walk
We pass in the VTDAddressSpace too.  It'll be used in the follow up
patches.

CC: QEMU Stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2f764fa87d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Peter Xu 28048f7bcd intel-iommu: introduce vtd_page_walk_info
During the recursive page walking of IOVA page tables, some stack
variables are constant variables and never changed during the whole page
walking procedure.  Isolate them into a struct so that we don't need to
pass those contants down the stack every time and multiple times.

CC: QEMU Stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit fe215b0cbb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Peter Xu 1e5b93f620 intel-iommu: only do page walk for MAP notifiers
For UNMAP-only IOMMU notifiers, we don't need to walk the page tables.
Fasten that procedure by skipping the page table walk.  That should
boost performance for UNMAP-only notifiers like vhost.

CC: QEMU Stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 4f8a62a933)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Peter Xu 5cf61b56a4 intel-iommu: add iommu lock
SECURITY IMPLICATION: this patch fixes a potential race when multiple
threads access the IOMMU IOTLB cache.

Add a per-iommu big lock to protect IOMMU status.  Currently the only
thing to be protected is the IOTLB/context cache, since that can be
accessed even without BQL, e.g., in IO dataplane.

Note that we don't need to protect device page tables since that's fully
controlled by the guest kernel.  However there is still possibility that
malicious drivers will program the device to not obey the rule.  In that
case QEMU can't really do anything useful, instead the guest itself will
be responsible for all uncertainties.

CC: QEMU Stable <qemu-stable@nongnu.org>
Reported-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 1d9efa73e1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Peter Xu d64604326f intel-iommu: remove IntelIOMMUNotifierNode
That is not really necessary.  Removing that node struct and put the
list entry directly into VTDAddressSpace.  It simplfies the code a lot.
Since at it, rename the old notifiers_list into vtd_as_with_notifiers.

CC: QEMU Stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit b4a4ba0d68)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Peter Xu 93a53137be intel-iommu: send PSI always even if across PDEs
SECURITY IMPLICATION: without this patch, any guest with both assigned
device and a vIOMMU might encounter stale IO page mappings even if guest
has already unmapped the page, which may lead to guest memory
corruption.  The stale mappings will only be limited to the guest's own
memory range, so it should not affect the host memory or other guests on
the host.

During IOVA page table walking, there is a special case when the PSI
covers one whole PDE (Page Directory Entry, which contains 512 Page
Table Entries) or more.  In the past, we skip that entry and we don't
notify the IOMMU notifiers.  This is not correct.  We should send UNMAP
notification to registered UNMAP notifiers in this case.

For UNMAP only notifiers, this might cause IOTLBs cached in the devices
even if they were already invalid.  For MAP/UNMAP notifiers like
vfio-pci, this will cause stale page mappings.

This special case doesn't trigger often, but it is very easy to be
triggered by nested device assignments, since in that case we'll
possibly map the whole L2 guest RAM region into the device's IOVA
address space (several GBs at least), which is far bigger than normal
kernel driver usages of the device (tens of MBs normally).

Without this patch applied to L1 QEMU, nested device assignment to L2
guests will dump some errors like:

qemu-system-x86_64: VFIO_MAP_DMA: -17
qemu-system-x86_64: vfio_dma_map(0x557305420c30, 0xad000, 0x1000,
                    0x7f89a920d000) = -17 (File exists)

CC: QEMU Stable <qemu-stable@nongnu.org>
Acked-by: Jason Wang <jasowang@redhat.com>
[peterx: rewrite the commit message]
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

(cherry picked from commit 36d2d52bdb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Jan Kiszka 91f6149592 hw/intc/arm_gicv3: Fix APxR<n> register dispatching
There was a nasty flip in identifying which register group an access is
targeting. The issue caused spuriously raised priorities of the guest
when handing CPUs over in the Jailhouse hypervisor.

Cc: qemu-stable@nongnu.org
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Message-id: 28b927d3-da58-bce4-cc13-bfec7f9b1cb9@siemens.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 887aae10f6)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Michal Privoznik 81e46e3c82 console: Avoid segfault in screendump
After f771c5440e it is possible to select device and
head which to take screendump from. And even though we check if
provided head number falls within range, it may still happen that
the console has no surface yet leading to SIGSEGV:

  qemu.git $ ./x86_64-softmmu/qemu-system-x86_64 \
    -qmp stdio \
    -device virtio-vga,id=video0,max_outputs=4

  {"execute":"qmp_capabilities"}
  {"execute":"screendump", "arguments":{"filename":"/tmp/screen.ppm", "device":"video0", "head":1}}
  Segmentation fault

 #0  0x00005628249dda88 in ppm_save (filename=0x56282826cbc0 "/tmp/screen.ppm", ds=0x0, errp=0x7fff52a6fae0) at ui/console.c:304
 #1  0x00005628249ddd9b in qmp_screendump (filename=0x56282826cbc0 "/tmp/screen.ppm", has_device=true, device=0x5628276902d0 "video0", has_head=true, head=1, errp=0x7fff52a6fae0) at ui/console.c:375
 #2  0x00005628247740df in qmp_marshal_screendump (args=0x562828265e00, ret=0x7fff52a6fb68, errp=0x7fff52a6fb60) at qapi/qapi-commands-ui.c:110

Here, @ds from frame #0 (or @surface from frame #1) is
dereferenced at the very beginning of ppm_save(). And because
it's NULL crash happens.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-id: cb05bb1909daa6ba62145c0194aafa05a14ed3d1.1526569138.git.mprivozn@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 08d9864fa4)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Cornelia Huck a5c8fbbeac s390x/ccw: make sure all ccw devices are properly reset
Thomas reported that the subchannel for a  3270 device that ended up
in a broken state (status pending even though not enabled) did not
get out of that state even after a reboot (which involves a subsytem
reset). The reason for this is that the 3270 device did not define
a reset handler.

Let's fix this by introducing a base reset handler (set up for all
ccw devices) that resets the subchannel and have virtio-ccw call
its virtio-specific reset procedure in addition to that.

CC: qemu-stable@nongnu.org
Reported-by: Thomas Huth <thuth@redhat.com>
Suggested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 838fb84f83)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Cornelia Huck c9bb077871 virtio-ccw: common reset handler
All the different virtio ccw devices use the same reset handler,
so let's move setting it into the base virtio ccw device class.

CC: qemu-stable@nongnu.org
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 0c53057adb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:18 -05:00
Thomas Huth 3372a3168a pc-bios/s390-ccw: struct tpi_info must be declared as aligned(4)
I've run into a compilation error today with the current version of GCC 8:

In file included from s390-ccw.h:49,
                 from main.c:12:
cio.h:128:1: error: alignment 1 of 'struct tpi_info' is less than 4 [-Werror=packed-not-aligned]
 } __attribute__ ((packed));
 ^
cc1: all warnings being treated as errors

Since the struct tpi_info contains an element ("struct subchannel_id schid")
which is marked as aligned(4), we've got to mark the struct tpi_info as
aligned(4), too.

CC: qemu-stable@nongnu.org
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-Id: <1525774672-11913-1-git-send-email-thuth@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit a6e4385dea)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Cornelia Huck 87efdb9820 s390x/css: disabled subchannels cannot be status pending
The 3270 code will try to post an attention interrupt when the
3270 emulator (e.g. x3270) attaches. If the guest has not yet
enabled the subchannel for the 3270 device, we will present a spurious
cc 1 (status pending) when it uses msch on it later on, e.g. when
trying to enable the subchannel.

To fix this, just don't do anything in css_conditional_io_interrupt()
if the subchannel is not enabled. The 3270 code will work fine with
that, and the other user of this function (virtio-ccw) never
attempts to post an interrupt for a disabled device to begin with.

CC: qemu-stable@nongnu.org
Reported-by: Thomas Huth <thuth@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Halil Pasic <pasic@linux.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 6e9c893ecd)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Fam Zheng 51691e9244 raw: Check byte range uniformly
We don't verify the request range against s->size in the I/O callbacks
except for raw_co_pwritev. This is inconsistent (especially for
raw_co_pwrite_zeroes and raw_co_pdiscard), so fix them, in the meanwhile
make the helper reusable by the coming new callbacks.

Note that in most cases the block layer already verifies the request
byte range against our reported image length, before invoking the driver
callbacks.  The exception is during image creating, after
blk_set_allow_write_beyond_eof(blk, true) is called. But in that case,
the requests are not directly from the user or guest. So there is no
visible behavior change in adding the check code.

The int64_t -> uint64_t inconsistency, as shown by the type casting, is
pre-existing due to the interface.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Message-id: 20180601092648.24614-3-famz@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit 3844553852)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Michael Walle 4f9df08749 lm32: take BQL before writing IP/IM register
Writing to these registers may raise an interrupt request. Actually,
this prevents the milkymist board from starting.

Cc: qemu-stable@nongnu.org
Signed-off-by: Michael Walle <michael@walle.cc>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
(cherry picked from commit 81e9cbd0ca)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Max Reitz ca3150da6d iotests: Add test for -U/force-share conflicts
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20180502202051.15493-4-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 4e7d73c5fb)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Max Reitz 9e724c05a0 qemu-img: Use only string options in img_open_opts
img_open_opts() takes a QemuOpts and converts them to a QDict, so all
values therein are strings.  Then it may try to call qdict_get_bool(),
however, which will fail with a segmentation fault every time:

$ ./qemu-img info -U --image-opts \
    driver=file,filename=/dev/null,force-share=off
[1]    27869 segmentation fault (core dumped)  ./qemu-img info -U
--image-opts driver=file,filename=/dev/null,force-share=off

Fix this by using qdict_get_str() and comparing the value as a string.
Also, when adding a force-share value to the QDict, add it as a string
so it fits the rest of the dict.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20180502202051.15493-3-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 4615f87832)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Max Reitz e8d8f6a3aa qemu-io: Use purely string blockdev options
Currently, qemu-io only uses string-valued blockdev options (as all are
converted directly from QemuOpts) -- with one exception: -U adds the
force-share option as a boolean.  This in itself is already a bit
questionable, but a real issue is that it also assumes the value already
existing in the options QDict would be a boolean, which is wrong.

That has the following effect:

$ ./qemu-io -r -U --image-opts \
    driver=file,filename=/dev/null,force-share=off
[1]    15200 segmentation fault (core dumped)  ./qemu-io -r -U
--image-opts driver=file,filename=/dev/null,force-share=off

Since @opts is converted from QemuOpts, the value must be a string, and
we have to compare it as such.  Consequently, it makes sense to also set
it as a string instead of a boolean.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20180502202051.15493-2-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 2a01c01f9e)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Max Reitz b3a18683f9 iotests: Add test for rebasing with relative paths
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20180509182002.8044-3-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 28036a7f70)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Max Reitz f9e0e53add qemu-img: Resolve relative backing paths in rebase
Currently, rebase interprets a relative path for the new backing image
as follows:
(1) Open the new backing image with the given relative path (thus relative to
    qemu-img's working directory).
(2) Write it directly into the overlay's backing path field (thus
    relative to the overlay).

If the overlay is not in qemu-img's working directory, both will be
different interpretations, which may either lead to an error somewhere
(either rebase fails because it cannot open the new backing image, or
your overlay becomes unusable because its backing path does not point to
a file), or, even worse, it may result in your rebase being performed
for a different backing file than what your overlay will point to after
the rebase.

Fix this by interpreting the target backing path as relative to the
overlay, like qemu-img does everywhere else.

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1569835
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20180509182002.8044-2-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit d16699b646)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Olaf Hering f81672a5c6 configure: recognize more rpmbuild macros
Extend the list of recognized, but ignored options from rpms %configure
macro. This fixes build on hosts running SUSE Linux.

Cc: qemu-stable@nongnu.org
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Message-Id: <20180418075045.27393-1-olaf@aepfle.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 181ce1d05c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:17 -05:00
Gerd Hoffmann 9ec09b6542 qxl: fix local renderer crash
Make sure we only ask the spice local renderer for display updates in
case we have a valid primary surface.  Without that spice is confused
and throws errors in case a display update request (triggered by
screendump for example) happens in parallel to a mode switch and hits
the race window where the old primary surface is gone and the new isn't
establisted yet.

Cc: qemu-stable@nongnu.org
Fixes: https://bugzilla.redhat.com//show_bug.cgi?id=1567733
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20180427115528.345-1-kraxel@redhat.com
(cherry picked from commit 5bd5c27c7d)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
Greg Kurz 2dbaba7af0 spapr: don't advertise radix GTSE if max-compat-cpu < power9
On a POWER9 host, if a guest runs in pre POWER9 compat mode, it necessarily
uses the hash MMU mode. In this case, we shouldn't advertise radix GTSE in
the ibm,arch-vec-5-platform-support DT property as the current code does.
The first reason is that it doesn't make sense, and the second one is that
causes the CAS-negotiated options subsection to be migrated. This breaks
backward migration to QEMU 2.7 and older versions on POWER8 hosts:

qemu-system-ppc64: error while loading state for instance 0x0 of device
 'spapr'
qemu-system-ppc64: load of migration failed: No such file or directory

This patch hence initialize CPUs a bit earlier so that we can check the
requested compat mode, and don't set OV5_MMU_RADIX_GTSE for power8 and
older.

Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit 0550b1206a)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
Greg Kurz 62f7a38610 target/ppc: always set PPC_MEM_TLBIE in pre 2.8 migration hack
The pseries-2.7 and older machine types require CPUPPCState::insns_flags
to be strictly equal between source and destination. This checking is
abusive and breaks migration of KVM guests when the host CPU models
are different, even if they are compatible enough to allow the guest
to run transparently. This buggy behaviour was fixed for pseries-2.8
and we added some hacks to allow backward migration of older machine
types. These hacks assume that the CPU belongs to the POWER8 family,
which was true for most KVM based setup we cared about at the time.
But now POWER9 systems are coming, and backward migration of pre 2.8
guests running in POWER8 architected mode from a POWER9 host to a
POWER8 host is broken:

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

This happens because POWER9 doesn't set PPC_MEM_TLBIE in insns_flags,
while POWER8 does. Let's force PPC_MEM_TLBIE in the migration hack to
fix the issue. This is an acceptable hack because these old machine
types only support CPU models that do set PPC_MEM_TLBIE.

Signed-off-by: Greg Kurz <groug@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
(cherry picked from commit bce009645b)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
Peter Maydell 1ace462f9b target/arm: Implement v8M VLLDM and VLSTM
For v8M the instructions VLLDM and VLSTM support lazy saving
and restoring of the secure floating-point registers. Even
if the floating point extension is not implemented, these
instructions must act as NOPs in Secure state, so they can
be used as part of the secure-to-nonsecure call sequence.

Fixes: https://bugs.launchpad.net/qemu/+bug/1768295
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180503105730.5958-1-peter.maydell@linaro.org
(cherry picked from commit b1e5336a98)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
Henry Wertz b90c93106e tcg/arm: Fix memory barrier encoding
I found with qemu 2.11.x or newer that I would get an illegal instruction
error running some Intel binaries on my ARM chromebook.  On investigation,
I found it was quitting on memory barriers.

qemu instruction:
mb $0x31
was translating as:
0x604050cc:  5bf07ff5  blpl     #0x600250a8

After patch it gives:
0x604050cc:  f57ff05b  dmb      ish

In short, I found INSN_DMB_ISH (memory barrier for ARMv7) appeared to be
correct based on online docs, but due to some endian-related shenanigans it
had to be byte-swapped to suit qemu; it appears INSN_DMB_MCR (memory
barrier for ARMv6) also should be byte swapped  (and this patch does so).
I have not checked for correctness of aarch64's barrier instruction.

Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Henry Wertz <hwertz10@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 3f814b8037)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
Cornelia Huck 38b7a3ea72 s390-ccw: force diag 308 subcode to unsigned long
We currently pass an integer as the subcode parameter. However,
the upper bits of the register containing the subcode need to
be 0, which is not guaranteed unless we explicitly specify the
subcode to be an unsigned long value.

Fixes: d046c51dad ("pc-bios/s390-ccw: Get device address via diag 308/6")
Cc: qemu-stable@nongnu.org
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 63d8b5ace3)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
Eric Blake cb7a41f3f9 nbd/client: Fix error messages during NBD_INFO_BLOCK_SIZE
A missing space makes for poor error messages, and sizes can't
go negative.  Also, we missed diagnosing a server that sends
a maximum block size less than the minimum.

Fixes: 081dd1fe
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180501154654.943782-1-eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
(cherry picked from commit e475d108f1)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
Jason Andryuk 8ca471da10 ccid: Fix dwProtocols advertisement of T=0
Commit d7d218ef02 attempted to change
dwProtocols to only advertise support for T=0 and not T=1.  The change
was incorrect as it changed 0x00000003 to 0x00010000.

lsusb -v in a linux guest shows:
"dwProtocols         65536  (Invalid values detected)", though the
smart card could still be accessed.  Windows 7 does not detect inserted
smart cards and logs the the following Error in the Event Logs:

    Source: Smart Card Service
    Event ID: 610
    Smart Card Reader 'QEMU QEMU USB CCID 0' rejected IOCTL SET_PROTOCOL:
    Incorrect function. If this error persists, your smart card or reader
    may not be functioning correctly

    Command Header: 03 00 00 00

Setting to 0x00000001 fixes the Windows issue.

Signed-off-by: Jason Andryuk <jandryuk@gmail.com>
Message-id: 20180420183219.20722-1-jandryuk@gmail.com
Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 0ee86bb6c5)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
Geert Uytterhoeven 1783745673 device_tree: Increase FDT_MAX_SIZE to 1 MiB
It is not uncommon for a contemporary FDT to be larger than 64 KiB,
leading to failures loading the device tree from sysfs:

    qemu-system-aarch64: qemu_fdt_setprop: Couldn't set ...: FDT_ERR_NOSPACE

Hence increase the limit to 1 MiB, like on PPC.

For reference, the largest arm64 DTB created from the Linux sources is
ca. 75 KiB large (100 KiB when built with symbols/fixup support).

Cc: qemu-stable@nongnu.org
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Message-id: 1523541337-23919-1-git-send-email-geert+renesas@glider.be
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 14ec3cbd7c)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
Marc-André Lureau 4319ae939c tests: fix tpm-crb tpm-tis tests race
No need to close the TPM data socket on the emulator end, qemu will
close it after a SHUTDOWN. This avoids a race between close() and
read() in the TPM data thread.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 7647d5c6b5)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2018-07-11 11:48:16 -05:00
1821 changed files with 45911 additions and 99200 deletions

No files matched your search

-6
View File
@@ -36,7 +36,6 @@
/qapi/qapi-commands-common.[ch]
/qapi/qapi-commands-crypto.[ch]
/qapi/qapi-commands-introspect.[ch]
/qapi/qapi-commands-job.[ch]
/qapi/qapi-commands-migration.[ch]
/qapi/qapi-commands-misc.[ch]
/qapi/qapi-commands-net.[ch]
@@ -54,7 +53,6 @@
/qapi/qapi-events-common.[ch]
/qapi/qapi-events-crypto.[ch]
/qapi/qapi-events-introspect.[ch]
/qapi/qapi-events-job.[ch]
/qapi/qapi-events-migration.[ch]
/qapi/qapi-events-misc.[ch]
/qapi/qapi-events-net.[ch]
@@ -73,7 +71,6 @@
/qapi/qapi-types-common.[ch]
/qapi/qapi-types-crypto.[ch]
/qapi/qapi-types-introspect.[ch]
/qapi/qapi-types-job.[ch]
/qapi/qapi-types-migration.[ch]
/qapi/qapi-types-misc.[ch]
/qapi/qapi-types-net.[ch]
@@ -91,7 +88,6 @@
/qapi/qapi-visit-common.[ch]
/qapi/qapi-visit-crypto.[ch]
/qapi/qapi-visit-introspect.[ch]
/qapi/qapi-visit-job.[ch]
/qapi/qapi-visit-migration.[ch]
/qapi/qapi-visit-misc.[ch]
/qapi/qapi-visit-net.[ch]
@@ -155,7 +151,6 @@
.sdk
*.gcda
*.gcno
*.gcov
/pc-bios/bios-pq/status
/pc-bios/vgabios-pq/status
/pc-bios/optionrom/linuxboot.asm
@@ -211,4 +206,3 @@ trace-dtrace-root.h
trace-dtrace-root.dtrace
trace-ust-all.h
trace-ust-all.c
/target/arm/decode-sve.inc.c
+3
View File
@@ -1,3 +1,6 @@
[submodule "roms/vgabios"]
path = roms/vgabios
url = git://git.qemu-project.org/vgabios.git/
[submodule "roms/seabios"]
path = roms/seabios
url = git://git.qemu-project.org/seabios.git/
+8
View File
@@ -35,5 +35,13 @@ build:
options: "-e HOME=/root"
ci:
- unset CC
# some targets require newer up to date packages, for example TARGET_LIST matching
# aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu)
# see the configure script:
# error_exit "DTC (libfdt) version >= 1.4.2 not present. Your options:"
# " (1) Preferred: Install the DTC (libfdt) devel package"
# " (2) Fetch the DTC submodule, using:"
# " git submodule update --init dtc"
- dpkg --compare-versions `dpkg-query --showformat='${Version}' --show libfdt-dev` ge 1.4.2 || git submodule update --init dtc
- ./configure ${QEMU_CONFIGURE_OPTS} --target-list=${TARGET_LIST}
- make -j$(($(getconf _NPROCESSORS_ONLN) + 1))
+74 -41
View File
@@ -1,8 +1,4 @@
# The current Travis default is a container based 14.04 Trust on EC2
# Additional builds with specific requirements for a full VM need to
# be added as additional matrix: entries later on
sudo: false
dist: trusty
language: c
python:
- "2.6"
@@ -38,7 +34,6 @@ addons:
- libvte-2.90-dev
- sparse
- uuid-dev
- gcovr
# The channel name "irc.oftc.net#qemu" is encrypted against qemu/qemu
# to prevent IRC notifications from forks. This was created using:
@@ -51,8 +46,6 @@ notifications:
on_failure: always
env:
global:
- SRC_DIR="."
- BUILD_DIR="."
- TEST_CMD="make check"
- MAKEFLAGS="-j3"
matrix:
@@ -69,39 +62,31 @@ git:
before_install:
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update ; fi
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install libffi gettext glib pixman ; fi
- git submodule update --init --recursive capstone dtc ui/keycodemapdb
- wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
- git submodule update --init --recursive
before_script:
- mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR}
- ${SRC_DIR}/configure ${CONFIG} || { cat config.log && exit 1; }
- ./configure ${CONFIG}
script:
- make ${MAKEFLAGS} && ${TEST_CMD}
matrix:
include:
# Test out-of-tree builds
- env: CONFIG="--enable-debug --enable-debug-tcg"
BUILD_DIR="out-of-tree/build/dir" SRC_DIR="../../.."
# Test with Clang for compile portability (Travis uses clang-5.0)
- env: CONFIG="--disable-system"
compiler: clang
- env: CONFIG="--disable-user"
# Test with CLang for compile portability
- env: CONFIG=""
compiler: clang
# gprof/gcov are GCC features
- env: CONFIG="--enable-gprof --enable-gcov --disable-pie --target-list=aarch64-softmmu,arm-softmmu,i386-softmmu,mips-softmmu,mips64-softmmu,ppc64-softmmu,riscv64-softmmu,s390x-softmmu,x86_64-softmmu"
after_success:
- ${SRC_DIR}/scripts/travis/coverage-summary.sh
- env: CONFIG="--enable-gprof --enable-gcov --disable-pie"
compiler: gcc
# We manually include builds which we disable "make check" for
- env: CONFIG="--enable-debug --enable-tcg-interpreter"
TEST_CMD=""
compiler: gcc
# We don't need to exercise every backend with every front-end
- env: CONFIG="--enable-trace-backends=log,simple,syslog --disable-system"
- env: CONFIG="--enable-trace-backends=simple"
TEST_CMD=""
compiler: gcc
- env: CONFIG="--enable-trace-backends=ftrace --target-list=x86_64-softmmu"
- env: CONFIG="--enable-trace-backends=ftrace"
TEST_CMD=""
compiler: gcc
- env: CONFIG="--enable-trace-backends=ust --target-list=x86_64-softmmu"
- env: CONFIG="--enable-trace-backends=ust"
TEST_CMD=""
compiler: gcc
- env: CONFIG="--disable-tcg"
@@ -110,24 +95,80 @@ matrix:
- env: CONFIG=""
os: osx
compiler: clang
# Python builds
- env: CONFIG="--target-list=x86_64-softmmu"
# Plain Trusty System Build
- env: CONFIG="--disable-linux-user"
sudo: required
addons:
dist: trusty
compiler: gcc
before_install:
- sudo apt-get update -qq
- sudo apt-get build-dep -qq qemu
- wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
- git submodule update --init --recursive
# Plain Trusty Linux User Build
- env: CONFIG="--disable-system"
sudo: required
addons:
dist: trusty
compiler: gcc
before_install:
- sudo apt-get update -qq
- sudo apt-get build-dep -qq qemu
- wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
- git submodule update --init --recursive
# Trusty System build with latest stable clang & python 3.0
- sudo: required
addons:
dist: trusty
language: generic
compiler: none
python:
- "3.0"
- env: CONFIG="--target-list=x86_64-softmmu"
env:
- COMPILER_NAME=clang CXX=clang++-3.9 CC=clang-3.9
- CONFIG="--disable-linux-user --cc=clang-3.9 --cxx=clang++-3.9 --python=/usr/bin/python3"
before_install:
- wget -nv -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
- sudo apt-add-repository -y 'deb http://llvm.org/apt/trusty llvm-toolchain-trusty-3.9 main'
- sudo apt-get update -qq
- sudo apt-get install -qq -y clang-3.9
- sudo apt-get build-dep -qq qemu
- wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
- git submodule update --init --recursive
before_script:
- ./configure ${CONFIG} || cat config.log
# Trusty Linux User build with latest stable clang & python 3.6
- sudo: required
addons:
dist: trusty
language: generic
compiler: none
python:
- "3.6"
env:
- COMPILER_NAME=clang CXX=clang++-3.9 CC=clang-3.9
- CONFIG="--disable-system --cc=clang-3.9 --cxx=clang++-3.9 --python=/usr/bin/python3"
before_install:
- wget -nv -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
- sudo apt-add-repository -y 'deb http://llvm.org/apt/trusty llvm-toolchain-trusty-3.9 main'
- sudo apt-get update -qq
- sudo apt-get install -qq -y clang-3.9
- sudo apt-get build-dep -qq qemu
- wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
- git submodule update --init --recursive
before_script:
- ./configure ${CONFIG} || cat config.log
# Using newer GCC with sanitizers
- addons:
apt:
update: true
sources:
# PPAs for newer toolchains
- ubuntu-toolchain-r-test
packages:
# Extra toolchains
- gcc-7
- g++-7
- gcc-5
- g++-5
# Build dependencies
- libaio-dev
- libattr1-dev
@@ -156,16 +197,8 @@ matrix:
language: generic
compiler: none
env:
- COMPILER_NAME=gcc CXX=g++-7 CC=gcc-7
- CONFIG="--cc=gcc-7 --cxx=g++-7 --disable-pie --disable-linux-user"
- COMPILER_NAME=gcc CXX=g++-5 CC=gcc-5
- CONFIG="--cc=gcc-5 --cxx=g++-5 --disable-pie --disable-linux-user"
- TEST_CMD=""
before_script:
- ./configure ${CONFIG} --extra-cflags="-g3 -O0 -fsanitize=thread -fuse-ld=gold" || { cat config.log && exit 1; }
- env:
- CONFIG="--disable-system --disable-docs"
- TEST_CMD="make check-tcg"
script:
- make ${MAKEFLAGS} && ${TEST_CMD} ${MAKEFLAGS}
sudo: required
dist: trusty
compiler: gcc
- ./configure ${CONFIG} --extra-cflags="-g3 -O0 -fsanitize=thread -fuse-ld=gold" || cat config.log
-17
View File
@@ -124,23 +124,6 @@ We use traditional C-style /* */ comments and avoid // comments.
Rationale: The // form is valid in C99, so this is purely a matter of
consistency of style. The checkpatch script will warn you about this.
Multiline comment blocks should have a row of stars on the left,
and the initial /* and terminating */ both on their own lines:
/*
* like
* this
*/
This is the same format required by the Linux kernel coding style.
(Some of the existing comments in the codebase use the GNU Coding
Standards form which does not have stars on the left, or other
variations; avoid these when writing new comments, but don't worry
about converting to the preferred form unless you're editing that
comment anyway.)
Rationale: Consistency, and ease of visually picking out a multiline
comment from the surrounding code.
8. trace-events style
8.1 0x prefix
+270
View File
@@ -0,0 +1,270 @@
A. HISTORY OF THE SOFTWARE
==========================
Python was created in the early 1990s by Guido van Rossum at Stichting
Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
as a successor of a language called ABC. Guido remains Python's
principal author, although it includes many contributions from others.
In 1995, Guido continued his work on Python at the Corporation for
National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
in Reston, Virginia where he released several versions of the
software.
In May 2000, Guido and the Python core development team moved to
BeOpen.com to form the BeOpen PythonLabs team. In October of the same
year, the PythonLabs team moved to Digital Creations (now Zope
Corporation, see http://www.zope.com). In 2001, the Python Software
Foundation (PSF, see http://www.python.org/psf/) was formed, a
non-profit organization created specifically to own Python-related
Intellectual Property. Zope Corporation is a sponsoring member of
the PSF.
All Python releases are Open Source (see http://www.opensource.org for
the Open Source Definition). Historically, most, but not all, Python
releases have also been GPL-compatible; the table below summarizes
the various releases.
Release Derived Year Owner GPL-
from compatible? (1)
0.9.0 thru 1.2 1991-1995 CWI yes
1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
1.6 1.5.2 2000 CNRI no
2.0 1.6 2000 BeOpen.com no
1.6.1 1.6 2001 CNRI yes (2)
2.1 2.0+1.6.1 2001 PSF no
2.0.1 2.0+1.6.1 2001 PSF yes
2.1.1 2.1+2.0.1 2001 PSF yes
2.2 2.1.1 2001 PSF yes
2.1.2 2.1.1 2002 PSF yes
2.1.3 2.1.2 2002 PSF yes
2.2.1 2.2 2002 PSF yes
2.2.2 2.2.1 2002 PSF yes
2.2.3 2.2.2 2003 PSF yes
2.3 2.2.2 2002-2003 PSF yes
2.3.1 2.3 2002-2003 PSF yes
2.3.2 2.3.1 2002-2003 PSF yes
2.3.3 2.3.2 2002-2003 PSF yes
2.3.4 2.3.3 2004 PSF yes
2.3.5 2.3.4 2005 PSF yes
2.4 2.3 2004 PSF yes
2.4.1 2.4 2005 PSF yes
2.4.2 2.4.1 2005 PSF yes
2.4.3 2.4.2 2006 PSF yes
2.5 2.4 2006 PSF yes
2.7 2.6 2010 PSF yes
Footnotes:
(1) GPL-compatible doesn't mean that we're distributing Python under
the GPL. All Python licenses, unlike the GPL, let you distribute
a modified version without making your changes open source. The
GPL-compatible licenses make it possible to combine Python with
other software that is released under the GPL; the others don't.
(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
because its license has a choice of law clause. According to
CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
is "not incompatible" with the GPL.
Thanks to the many outside volunteers who have worked under Guido's
direction to make these releases possible.
B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
===============================================================
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
--------------------------------------------
1. This LICENSE AGREEMENT is between the Python Software Foundation
("PSF"), and the Individual or Organization ("Licensee") accessing and
otherwise using this software ("Python") in source or binary form and
its associated documentation.
2. Subject to the terms and conditions of this License Agreement, PSF
hereby grants Licensee a nonexclusive, royalty-free, world-wide
license to reproduce, analyze, test, perform and/or display publicly,
prepare derivative works, distribute, and otherwise use Python
alone or in any derivative version, provided, however, that PSF's
License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights
Reserved" are retained in Python alone or in any derivative version
prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on
or incorporates Python or any part thereof, and wants to make
the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to Python.
4. PSF is making Python available to Licensee on an "AS IS"
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any
relationship of agency, partnership, or joint venture between PSF and
Licensee. This License Agreement does not grant permission to use PSF
trademarks or trade name in a trademark sense to endorse or promote
products or services of Licensee, or any third party.
8. By copying, installing or otherwise using Python, Licensee
agrees to be bound by the terms and conditions of this License
Agreement.
BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
-------------------------------------------
BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
Individual or Organization ("Licensee") accessing and otherwise using
this software in source or binary form and its associated
documentation ("the Software").
2. Subject to the terms and conditions of this BeOpen Python License
Agreement, BeOpen hereby grants Licensee a non-exclusive,
royalty-free, world-wide license to reproduce, analyze, test, perform
and/or display publicly, prepare derivative works, distribute, and
otherwise use the Software alone or in any derivative version,
provided, however, that the BeOpen Python License is retained in the
Software, alone or in any derivative version prepared by Licensee.
3. BeOpen is making the Software available to Licensee on an "AS IS"
basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.
4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
5. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
6. This License Agreement shall be governed by and interpreted in all
respects by the law of the State of California, excluding conflict of
law provisions. Nothing in this License Agreement shall be deemed to
create any relationship of agency, partnership, or joint venture
between BeOpen and Licensee. This License Agreement does not grant
permission to use BeOpen trademarks or trade names in a trademark
sense to endorse or promote products or services of Licensee, or any
third party. As an exception, the "BeOpen Python" logos available at
http://www.pythonlabs.com/logos.html may be used according to the
permissions granted on that web page.
7. By copying, installing or otherwise using the software, Licensee
agrees to be bound by the terms and conditions of this License
Agreement.
CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
---------------------------------------
1. This LICENSE AGREEMENT is between the Corporation for National
Research Initiatives, having an office at 1895 Preston White Drive,
Reston, VA 20191 ("CNRI"), and the Individual or Organization
("Licensee") accessing and otherwise using Python 1.6.1 software in
source or binary form and its associated documentation.
2. Subject to the terms and conditions of this License Agreement, CNRI
hereby grants Licensee a nonexclusive, royalty-free, world-wide
license to reproduce, analyze, test, perform and/or display publicly,
prepare derivative works, distribute, and otherwise use Python 1.6.1
alone or in any derivative version, provided, however, that CNRI's
License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
1995-2001 Corporation for National Research Initiatives; All Rights
Reserved" are retained in Python 1.6.1 alone or in any derivative
version prepared by Licensee. Alternately, in lieu of CNRI's License
Agreement, Licensee may substitute the following text (omitting the
quotes): "Python 1.6.1 is made available subject to the terms and
conditions in CNRI's License Agreement. This Agreement together with
Python 1.6.1 may be located on the Internet using the following
unique, persistent identifier (known as a handle): 1895.22/1013. This
Agreement may also be obtained from a proxy server on the Internet
using the following URL: http://hdl.handle.net/1895.22/1013".
3. In the event Licensee prepares a derivative work that is based on
or incorporates Python 1.6.1 or any part thereof, and wants to make
the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to Python 1.6.1.
4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.
5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
7. This License Agreement shall be governed by the federal
intellectual property law of the United States, including without
limitation the federal copyright law, and, to the extent such
U.S. federal law does not apply, by the law of the Commonwealth of
Virginia, excluding Virginia's conflict of law provisions.
Notwithstanding the foregoing, with regard to derivative works based
on Python 1.6.1 that incorporate non-separable material that was
previously distributed under the GNU General Public License (GPL), the
law of the Commonwealth of Virginia shall govern this License
Agreement only as to issues arising under or with respect to
Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
License Agreement shall be deemed to create any relationship of
agency, partnership, or joint venture between CNRI and Licensee. This
License Agreement does not grant permission to use CNRI trademarks or
trade name in a trademark sense to endorse or promote products or
services of Licensee, or any third party.
8. By clicking on the "ACCEPT" button where indicated, or by copying,
installing or otherwise using Python 1.6.1, Licensee agrees to be
bound by the terms and conditions of this License Agreement.
ACCEPT
CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
--------------------------------------------------
Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
The Netherlands. All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-9
View File
@@ -118,15 +118,6 @@ Please note that g_malloc will exit on allocation failure, so there
is no need to test for failure (as you would have to with malloc).
Calling g_malloc with a zero size is valid and will return NULL.
Prefer g_new(T, n) instead of g_malloc(sizeof(T) * n) for the following
reasons:
a. It catches multiplication overflowing size_t;
b. It returns T * instead of void *, letting compiler catch more type
errors.
Declarations like T *v = g_malloc(sizeof(*v)) are acceptable, though.
Memory allocated by qemu_memalign or qemu_blockalign must be freed with
qemu_vfree, since breaking this will cause problems on Win32.
+12 -100
View File
@@ -135,8 +135,6 @@ M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: target/arm/
F: tests/tcg/arm/
F: tests/tcg/aarch64/
F: hw/arm/
F: hw/cpu/a*mpcore.c
F: include/hw/cpu/a*mpcore.h
@@ -187,7 +185,7 @@ F: disas/microblaze.c
MIPS
M: Aurelien Jarno <aurelien@aurel32.net>
M: Aleksandar Markovic <aleksandar.markovic@mips.com>
M: Yongbok Kim <yongbok.kim@mips.com>
S: Maintained
F: target/mips/
F: hw/mips/
@@ -285,8 +283,6 @@ M: Richard Henderson <rth@twiddle.net>
M: Eduardo Habkost <ehabkost@redhat.com>
S: Maintained
F: target/i386/
F: tests/tcg/i386/
F: tests/tcg/x86_64/
F: hw/i386/
F: disas/i386.c
T: git git://github.com/ehabkost/qemu.git x86-next
@@ -307,10 +303,6 @@ F: target/tricore/
F: hw/tricore/
F: include/hw/tricore/
Multiarch Linux User Tests
M: Alex Bennée <alex.bennee@linaro.org>
F: tests/tcg/multiarch/
Guest CPU Cores (KVM):
----------------------
@@ -455,10 +447,6 @@ F: hw/timer/cmsdk-apb-timer.c
F: include/hw/timer/cmsdk-apb-timer.h
F: hw/char/cmsdk-apb-uart.c
F: include/hw/char/cmsdk-apb-uart.h
F: hw/misc/tz-ppc.c
F: include/hw/misc/tz-ppc.h
F: hw/misc/tz-mpc.c
F: include/hw/misc/tz-mpc.h
ARM cores
M: Peter Maydell <peter.maydell@linaro.org>
@@ -501,10 +489,9 @@ F: include/hw/arm/digic.h
F: hw/*/digic*
Gumstix
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
L: qemu-devel@nongnu.org
L: qemu-arm@nongnu.org
S: Odd Fixes
S: Orphan
F: hw/arm/gumstix.c
i.MX31
@@ -528,11 +515,8 @@ M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/arm/mps2.c
F: hw/arm/mps2-tz.c
F: hw/misc/mps2-*.c
F: include/hw/misc/mps2-*.h
F: hw/arm/iotkit.c
F: include/hw/arm/iotkit.h
F: hw/misc/mps2-scc.c
F: include/hw/misc/mps2-scc.h
Musicpal
M: Jan Kiszka <jan.kiszka@web.de>
@@ -645,17 +629,6 @@ M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
S: Maintained
F: hw/arm/msf2-som.c
ASPEED BMCs
M: Cédric Le Goater <clg@kaod.org>
R: Andrew Jeffery <andrew@aj.id.au>
R: Joel Stanley <joel@jms.id.au>
L: qemu-arm@nongnu.org
S: Maintained
F: hw/*/*aspeed*
F: include/hw/*/*aspeed*
F: hw/net/ftgmac100.c
F: include/hw/net/ftgmac100.h
CRIS Machines
-------------
Axis Dev88
@@ -718,7 +691,7 @@ S: Maintained
F: hw/mips/mips_malta.c
Mipssim
M: Aleksandar Markovic <aleksandar.markovic@mips.com>
M: Yongbok Kim <yongbok.kim@mips.com>
S: Odd Fixes
F: hw/mips/mips_mipssim.c
F: hw/net/mipsnet.c
@@ -729,7 +702,7 @@ S: Maintained
F: hw/mips/mips_r4k.c
Fulong 2E
M: Aleksandar Markovic <aleksandar.markovic@mips.com>
M: Yongbok Kim <yongbok.kim@mips.com>
S: Odd Fixes
F: hw/mips/mips_fulong2e.c
F: hw/isa/vt82c686.c
@@ -788,11 +761,8 @@ F: hw/ppc/mac_newworld.c
F: hw/pci-host/uninorth.c
F: hw/pci-bridge/dec.[hc]
F: hw/misc/macio/
F: hw/misc/mos6522.c
F: hw/nvram/mac_nvram.c
F: include/hw/misc/macio/
F: include/hw/misc/mos6522.h
F: include/hw/ppc/mac_dbdma.h
F: hw/nvram/mac_nvram.c
Old World
M: Alexander Graf <agraf@suse.de>
@@ -851,7 +821,6 @@ M: BALATON Zoltan <balaton@eik.bme.hu>
L: qemu-ppc@nongnu.org
S: Maintained
F: hw/ide/sii3112.c
F: hw/timer/m41t80.c
SH4 Machines
------------
@@ -940,7 +909,7 @@ X86 Machines
------------
PC
M: Michael S. Tsirkin <mst@redhat.com>
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
M: Marcel Apfelbaum <marcel@redhat.com>
S: Supported
F: include/hw/i386/
F: hw/i386/
@@ -990,7 +959,7 @@ F: include/hw/timer/mc146818rtc*
Machine core
M: Eduardo Habkost <ehabkost@redhat.com>
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
M: Marcel Apfelbaum <marcel@redhat.com>
S: Supported
F: hw/core/machine.c
F: hw/core/null-machine.c
@@ -1029,7 +998,6 @@ F: hw/block/cdrom.c
F: hw/block/hd-geometry.c
F: tests/ide-test.c
F: tests/ahci-test.c
F: tests/cdrom-test.c
F: tests/libqos/ahci*
T: git git://github.com/jnsnow/qemu.git ide
@@ -1065,7 +1033,7 @@ F: hw/ipack/
PCI
M: Michael S. Tsirkin <mst@redhat.com>
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
M: Marcel Apfelbaum <marcel@redhat.com>
S: Supported
F: include/hw/pci/*
F: hw/misc/pci-testdev.c
@@ -1346,33 +1314,6 @@ S: Maintained
F: include/hw/misc/unimp.h
F: hw/misc/unimp.c
Standard VGA
M: Gerd Hoffmann <kraxel@redhat.com>
S: Maintained
F: hw/display/vga*
F: hw/display/bochs-display.c
F: include/hw/display/vga.h
F: include/hw/display/bochs-vbe.h
ramfb
M: Gerd Hoffmann <kraxel@redhat.com>
S: Maintained
F: hw/display/ramfb*.c
F: include/hw/display/ramfb.h
virtio-gpu
M: Gerd Hoffmann <kraxel@redhat.com>
S: Maintained
F: hw/display/virtio-gpu*
F: hw/display/virtio-vga.c
F: include/hw/virtio/virtio-gpu.h
Cirrus VGA
M: Gerd Hoffmann <kraxel@redhat.com>
S: Odd Fixes
W: https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/
F: hw/display/cirrus*
Subsystems
----------
Audio
@@ -1398,8 +1339,6 @@ F: qemu-img*
F: qemu-io*
F: tests/qemu-iotests/
F: util/qemu-progress.c
F: qobject/block-qdict.c
F: test/check-block-qdict.c
T: git git://repo.or.cz/qemu/kevin.git block
Block I/O path
@@ -1430,14 +1369,10 @@ L: qemu-block@nongnu.org
S: Supported
F: blockjob.c
F: include/block/blockjob.h
F: job.c
F: job-qmp.c
F: include/block/job.h
F: block/backup.c
F: block/commit.c
F: block/stream.c
F: block/mirror.c
F: qapi/job.json
T: git git://github.com/codyprime/qemu-kvm-jtc.git block
Block QAPI, monitor, command line
@@ -1638,8 +1573,7 @@ F: tests/test-*-visitor.c
F: tests/test-qapi-*.c
F: tests/test-qmp-*.c
F: tests/test-visitor-serialization.c
F: scripts/qapi-gen.py
F: scripts/qapi/*
F: scripts/qapi*
F: docs/devel/qapi*
T: git git://repo.or.cz/qemu/armbru.git qapi-next
@@ -1711,7 +1645,6 @@ S: Maintained
F: slirp/
F: net/slirp.c
F: include/net/slirp.h
T: git https://people.debian.org/~sthibault/qemu.git slirp
T: git git://git.kiszka.org/qemu.git queues/slirp
Stubs
@@ -1723,8 +1656,6 @@ Tracing
M: Stefan Hajnoczi <stefanha@redhat.com>
S: Maintained
F: trace/
F: trace-events
F: qemu-option-trace.texi
F: scripts/tracetool.py
F: scripts/tracetool/
F: docs/devel/tracing.txt
@@ -1996,7 +1927,6 @@ F: nbd/
F: include/block/nbd*
F: qemu-nbd.*
F: blockdev-nbd.c
F: docs/interop/nbd.txt
T: git git://repo.or.cz/qemu/ericb.git nbd
NFS
@@ -2052,12 +1982,6 @@ S: Supported
F: block/quorum.c
L: qemu-block@nongnu.org
blklogwrites
M: Ari Sundholm <ari@tuxera.com>
L: qemu-block@nongnu.org
S: Supported
F: block/blklogwrites.c
blkverify
M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
@@ -2157,7 +2081,7 @@ F: docs/block-replication.txt
PVRDMA
M: Yuval Shaia <yuval.shaia@oracle.com>
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
M: Marcel Apfelbaum <marcel@redhat.com>
S: Maintained
F: hw/rdma/*
F: hw/rdma/vmw/*
@@ -2172,7 +2096,6 @@ R: Philippe Mathieu-Daudé <f4bug@amsat.org>
L: qemu-devel@nongnu.org
S: Maintained
F: .travis.yml
F: scripts/travis/
F: .shippable.yml
F: tests/docker/
F: tests/vm/
@@ -2180,13 +2103,6 @@ W: https://travis-ci.org/qemu/qemu
W: https://app.shippable.com/github/qemu/qemu
W: http://patchew.org/QEMU/
Guest Test Compilation Support
M: Alex Bennée <alex.bennee@linaro.org>
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
F: tests/tcg/Makefile
F: tests/tcg/Makefile.include
L: qemu-devel@nongnu.org
Documentation
-------------
Build system architecture
@@ -2194,10 +2110,6 @@ M: Daniel P. Berrange <berrange@redhat.com>
S: Odd Fixes
F: docs/devel/build-system.txt
Incompatible changes
R: libvir-list@redhat.com
F: qemu-deprecated.texi
Build System
------------
GIT submodules
+10 -38
View File
@@ -20,6 +20,8 @@ ifneq ($(wildcard config-host.mak),)
all:
include config-host.mak
PYTHON_UTF8 = LC_ALL= LANG=C LC_CTYPE=en_US.UTF-8 $(PYTHON)
git-submodule-update:
.PHONY: git-submodule-update
@@ -96,7 +98,6 @@ GENERATED_FILES += qapi/qapi-types-char.h qapi/qapi-types-char.c
GENERATED_FILES += qapi/qapi-types-common.h qapi/qapi-types-common.c
GENERATED_FILES += qapi/qapi-types-crypto.h qapi/qapi-types-crypto.c
GENERATED_FILES += qapi/qapi-types-introspect.h qapi/qapi-types-introspect.c
GENERATED_FILES += qapi/qapi-types-job.h qapi/qapi-types-job.c
GENERATED_FILES += qapi/qapi-types-migration.h qapi/qapi-types-migration.c
GENERATED_FILES += qapi/qapi-types-misc.h qapi/qapi-types-misc.c
GENERATED_FILES += qapi/qapi-types-net.h qapi/qapi-types-net.c
@@ -115,7 +116,6 @@ GENERATED_FILES += qapi/qapi-visit-char.h qapi/qapi-visit-char.c
GENERATED_FILES += qapi/qapi-visit-common.h qapi/qapi-visit-common.c
GENERATED_FILES += qapi/qapi-visit-crypto.h qapi/qapi-visit-crypto.c
GENERATED_FILES += qapi/qapi-visit-introspect.h qapi/qapi-visit-introspect.c
GENERATED_FILES += qapi/qapi-visit-job.h qapi/qapi-visit-job.c
GENERATED_FILES += qapi/qapi-visit-migration.h qapi/qapi-visit-migration.c
GENERATED_FILES += qapi/qapi-visit-misc.h qapi/qapi-visit-misc.c
GENERATED_FILES += qapi/qapi-visit-net.h qapi/qapi-visit-net.c
@@ -133,7 +133,6 @@ GENERATED_FILES += qapi/qapi-commands-char.h qapi/qapi-commands-char.c
GENERATED_FILES += qapi/qapi-commands-common.h qapi/qapi-commands-common.c
GENERATED_FILES += qapi/qapi-commands-crypto.h qapi/qapi-commands-crypto.c
GENERATED_FILES += qapi/qapi-commands-introspect.h qapi/qapi-commands-introspect.c
GENERATED_FILES += qapi/qapi-commands-job.h qapi/qapi-commands-job.c
GENERATED_FILES += qapi/qapi-commands-migration.h qapi/qapi-commands-migration.c
GENERATED_FILES += qapi/qapi-commands-misc.h qapi/qapi-commands-misc.c
GENERATED_FILES += qapi/qapi-commands-net.h qapi/qapi-commands-net.c
@@ -151,7 +150,6 @@ GENERATED_FILES += qapi/qapi-events-char.h qapi/qapi-events-char.c
GENERATED_FILES += qapi/qapi-events-common.h qapi/qapi-events-common.c
GENERATED_FILES += qapi/qapi-events-crypto.h qapi/qapi-events-crypto.c
GENERATED_FILES += qapi/qapi-events-introspect.h qapi/qapi-events-introspect.c
GENERATED_FILES += qapi/qapi-events-job.h qapi/qapi-events-job.c
GENERATED_FILES += qapi/qapi-events-migration.h qapi/qapi-events-migration.c
GENERATED_FILES += qapi/qapi-events-misc.h qapi/qapi-events-misc.c
GENERATED_FILES += qapi/qapi-events-net.h qapi/qapi-events-net.c
@@ -320,7 +318,6 @@ KEYCODEMAP_FILES = \
ui/input-keymap-xorgkbd-to-qcode.c \
ui/input-keymap-xorgxquartz-to-qcode.c \
ui/input-keymap-xorgxwin-to-qcode.c \
ui/input-keymap-osx-to-qcode.c \
$(NULL)
GENERATED_FILES += $(KEYCODEMAP_FILES)
@@ -350,7 +347,7 @@ $(call set-vpath, $(SRC_PATH))
LIBS+=-lz $(LIBS_TOOLS)
HELPERS-$(call land,$(CONFIG_SOFTMMU),$(CONFIG_LINUX)) = qemu-bridge-helper$(EXESUF)
HELPERS-$(CONFIG_LINUX) = qemu-bridge-helper$(EXESUF)
ifdef BUILD_DOCS
DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
@@ -488,7 +485,7 @@ subdir-dtc: .git-submodule-status dtc/libfdt dtc/tests
$(call quiet-command,$(MAKE) $(DTC_MAKE_ARGS) CPPFLAGS="$(DTC_CPPFLAGS)" CFLAGS="$(DTC_CFLAGS)" LDFLAGS="$(LDFLAGS)" ARFLAGS="$(ARFLAGS)" CC="$(CC)" AR="$(AR)" LD="$(LD)" $(SUBDIR_MAKEFLAGS) libfdt/libfdt.a,)
dtc/%: .git-submodule-status
@mkdir -p $@
mkdir -p $@
# Overriding CFLAGS causes us to lose defines added in the sub-makefile.
# Not overriding CFLAGS leads to mis-matches between compilation modes.
@@ -566,6 +563,7 @@ $(SRC_PATH)/scripts/qapi/types.py \
$(SRC_PATH)/scripts/qapi/visit.py \
$(SRC_PATH)/scripts/qapi/common.py \
$(SRC_PATH)/scripts/qapi/doc.py \
$(SRC_PATH)/scripts/ordereddict.py \
$(SRC_PATH)/scripts/qapi-gen.py
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h \
@@ -574,7 +572,7 @@ qga/qapi-generated/qga-qapi-commands.h qga/qapi-generated/qga-qapi-commands.c \
qga/qapi-generated/qga-qapi-doc.texi: \
qga/qapi-generated/qapi-gen-timestamp ;
qga/qapi-generated/qapi-gen-timestamp: $(SRC_PATH)/qga/qapi-schema.json $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
$(call quiet-command,$(PYTHON_UTF8) $(SRC_PATH)/scripts/qapi-gen.py \
-o qga/qapi-generated -p "qga-" $<, \
"GEN","$(@:%-timestamp=%)")
@>$@
@@ -584,7 +582,6 @@ qapi-modules = $(SRC_PATH)/qapi/qapi-schema.json $(SRC_PATH)/qapi/common.json \
$(SRC_PATH)/qapi/char.json \
$(SRC_PATH)/qapi/crypto.json \
$(SRC_PATH)/qapi/introspect.json \
$(SRC_PATH)/qapi/job.json \
$(SRC_PATH)/qapi/migration.json \
$(SRC_PATH)/qapi/misc.json \
$(SRC_PATH)/qapi/net.json \
@@ -604,7 +601,6 @@ qapi/qapi-types-char.c qapi/qapi-types-char.h \
qapi/qapi-types-common.c qapi/qapi-types-common.h \
qapi/qapi-types-crypto.c qapi/qapi-types-crypto.h \
qapi/qapi-types-introspect.c qapi/qapi-types-introspect.h \
qapi/qapi-types-job.c qapi/qapi-types-job.h \
qapi/qapi-types-migration.c qapi/qapi-types-migration.h \
qapi/qapi-types-misc.c qapi/qapi-types-misc.h \
qapi/qapi-types-net.c qapi/qapi-types-net.h \
@@ -623,7 +619,6 @@ qapi/qapi-visit-char.c qapi/qapi-visit-char.h \
qapi/qapi-visit-common.c qapi/qapi-visit-common.h \
qapi/qapi-visit-crypto.c qapi/qapi-visit-crypto.h \
qapi/qapi-visit-introspect.c qapi/qapi-visit-introspect.h \
qapi/qapi-visit-job.c qapi/qapi-visit-job.h \
qapi/qapi-visit-migration.c qapi/qapi-visit-migration.h \
qapi/qapi-visit-misc.c qapi/qapi-visit-misc.h \
qapi/qapi-visit-net.c qapi/qapi-visit-net.h \
@@ -641,7 +636,6 @@ qapi/qapi-commands-char.c qapi/qapi-commands-char.h \
qapi/qapi-commands-common.c qapi/qapi-commands-common.h \
qapi/qapi-commands-crypto.c qapi/qapi-commands-crypto.h \
qapi/qapi-commands-introspect.c qapi/qapi-commands-introspect.h \
qapi/qapi-commands-job.c qapi/qapi-commands-job.h \
qapi/qapi-commands-migration.c qapi/qapi-commands-migration.h \
qapi/qapi-commands-misc.c qapi/qapi-commands-misc.h \
qapi/qapi-commands-net.c qapi/qapi-commands-net.h \
@@ -659,7 +653,6 @@ qapi/qapi-events-char.c qapi/qapi-events-char.h \
qapi/qapi-events-common.c qapi/qapi-events-common.h \
qapi/qapi-events-crypto.c qapi/qapi-events-crypto.h \
qapi/qapi-events-introspect.c qapi/qapi-events-introspect.h \
qapi/qapi-events-job.c qapi/qapi-events-job.h \
qapi/qapi-events-migration.c qapi/qapi-events-migration.h \
qapi/qapi-events-misc.c qapi/qapi-events-misc.h \
qapi/qapi-events-net.c qapi/qapi-events-net.h \
@@ -674,7 +667,7 @@ qapi/qapi-introspect.h qapi/qapi-introspect.c \
qapi/qapi-doc.texi: \
qapi-gen-timestamp ;
qapi-gen-timestamp: $(qapi-modules) $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-gen.py \
$(call quiet-command,$(PYTHON_UTF8) $(SRC_PATH)/scripts/qapi-gen.py \
-o "qapi" -b $<, \
"GEN","$(@:%-timestamp=%)")
@>$@
@@ -723,14 +716,6 @@ module_block.h: $(SRC_PATH)/scripts/modules/module_block.py config-host.mak
$(addprefix $(SRC_PATH)/,$(patsubst %.mo,%.c,$(block-obj-m))), \
"GEN","$@")
ifdef CONFIG_GCOV
.PHONY: clean-coverage
clean-coverage:
$(call quiet-command, \
find . \( -name '*.gcda' -o -name '*.gcov' \) -type f -exec rm {} +, \
"CLEAN", "coverage files")
endif
clean:
# avoid old build problems by removing potentially incorrect old files
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
@@ -986,16 +971,6 @@ docs/interop/qemu-qmp-ref.dvi docs/interop/qemu-qmp-ref.html \
docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7: \
docs/interop/qemu-qmp-ref.texi docs/interop/qemu-qmp-qapi.texi
# Reports/Analysis
%/coverage-report.html:
@mkdir -p $*
$(call quiet-command,\
gcovr -p --html --html-details -o $@, \
"GEN", "coverage-report.html")
.PHONY: coverage-report
coverage-report: $(CURDIR)/reports/coverage/coverage-report.html
ifdef CONFIG_WIN32
@@ -1072,6 +1047,9 @@ endif
include $(SRC_PATH)/tests/docker/Makefile.include
include $(SRC_PATH)/tests/vm/Makefile.include
printgen:
@echo $(GENERATED_FILES)
.PHONY: help
help:
@echo 'Generic targets:'
@@ -1091,9 +1069,6 @@ endif
echo '')
@echo 'Cleaning targets:'
@echo ' clean - Remove most generated files but keep the config'
ifdef CONFIG_GCOV
@echo ' clean-coverage - Remove coverage files'
endif
@echo ' distclean - Remove all generated files'
@echo ' dist - Build a distributable tarball'
@echo ''
@@ -1105,9 +1080,6 @@ endif
@echo 'Documentation targets:'
@echo ' html info pdf txt'
@echo ' - Build documentation in specified format'
ifdef CONFIG_GCOV
@echo ' coverage-report - Create code coverage report'
endif
@echo ''
ifdef CONFIG_WIN32
@echo 'Windows targets:'
+42 -48
View File
@@ -10,7 +10,6 @@ util-obj-y += qapi/qapi-types-char.o
util-obj-y += qapi/qapi-types-common.o
util-obj-y += qapi/qapi-types-crypto.o
util-obj-y += qapi/qapi-types-introspect.o
util-obj-y += qapi/qapi-types-job.o
util-obj-y += qapi/qapi-types-migration.o
util-obj-y += qapi/qapi-types-misc.o
util-obj-y += qapi/qapi-types-net.o
@@ -29,7 +28,6 @@ util-obj-y += qapi/qapi-visit-char.o
util-obj-y += qapi/qapi-visit-common.o
util-obj-y += qapi/qapi-visit-crypto.o
util-obj-y += qapi/qapi-visit-introspect.o
util-obj-y += qapi/qapi-visit-job.o
util-obj-y += qapi/qapi-visit-migration.o
util-obj-y += qapi/qapi-visit-misc.o
util-obj-y += qapi/qapi-visit-net.o
@@ -47,7 +45,6 @@ util-obj-y += qapi/qapi-events-char.o
util-obj-y += qapi/qapi-events-common.o
util-obj-y += qapi/qapi-events-crypto.o
util-obj-y += qapi/qapi-events-introspect.o
util-obj-y += qapi/qapi-events-job.o
util-obj-y += qapi/qapi-events-migration.o
util-obj-y += qapi/qapi-events-misc.o
util-obj-y += qapi/qapi-events-net.o
@@ -66,7 +63,7 @@ chardev-obj-y = chardev/
# block-obj-y is code used by both qemu system emulation and qemu-img
block-obj-y += nbd/
block-obj-y += block.o blockjob.o job.o
block-obj-y += block.o blockjob.o
block-obj-y += block/ scsi/
block-obj-y += qemu-io-cmds.o
block-obj-$(CONFIG_REPLICATION) += replication.o
@@ -97,7 +94,6 @@ io-obj-y = io/
ifeq ($(CONFIG_SOFTMMU),y)
common-obj-y = blockdev.o blockdev-nbd.o block/
common-obj-y += bootdevice.o iothread.o
common-obj-y += job-qmp.o
common-obj-y += net/
common-obj-y += qdev-monitor.o device-hotplug.o
common-obj-$(CONFIG_WIN32) += os-win32.o
@@ -144,7 +140,6 @@ common-obj-y += qapi/qapi-commands-char.o
common-obj-y += qapi/qapi-commands-common.o
common-obj-y += qapi/qapi-commands-crypto.o
common-obj-y += qapi/qapi-commands-introspect.o
common-obj-y += qapi/qapi-commands-job.o
common-obj-y += qapi/qapi-commands-migration.o
common-obj-y += qapi/qapi-commands-misc.o
common-obj-y += qapi/qapi-commands-net.o
@@ -196,67 +191,66 @@ vhost-user-blk-obj-y = contrib/vhost-user-blk/
######################################################################
trace-events-subdirs =
trace-events-subdirs += accel/kvm
trace-events-subdirs += accel/tcg
trace-events-subdirs += audio
trace-events-subdirs += util
trace-events-subdirs += crypto
trace-events-subdirs += io
trace-events-subdirs += migration
trace-events-subdirs += block
trace-events-subdirs += chardev
trace-events-subdirs += crypto
trace-events-subdirs += hw/9pfs
trace-events-subdirs += hw/acpi
trace-events-subdirs += hw/alpha
trace-events-subdirs += hw/arm
trace-events-subdirs += hw/audio
trace-events-subdirs += hw/block
trace-events-subdirs += hw/block/dataplane
trace-events-subdirs += hw/char
trace-events-subdirs += hw/display
trace-events-subdirs += hw/dma
trace-events-subdirs += hw/hppa
trace-events-subdirs += hw/i2c
trace-events-subdirs += hw/i386
trace-events-subdirs += hw/i386/xen
trace-events-subdirs += hw/ide
trace-events-subdirs += hw/input
trace-events-subdirs += hw/intc
trace-events-subdirs += hw/isa
trace-events-subdirs += hw/mem
trace-events-subdirs += hw/misc
trace-events-subdirs += hw/misc/macio
trace-events-subdirs += hw/net
trace-events-subdirs += hw/nvram
trace-events-subdirs += hw/pci
trace-events-subdirs += hw/pci-host
trace-events-subdirs += hw/ppc
trace-events-subdirs += hw/rdma
trace-events-subdirs += hw/rdma/vmw
trace-events-subdirs += hw/s390x
trace-events-subdirs += hw/virtio
trace-events-subdirs += hw/audio
trace-events-subdirs += hw/misc
trace-events-subdirs += hw/misc/macio
trace-events-subdirs += hw/usb
trace-events-subdirs += hw/scsi
trace-events-subdirs += hw/sd
trace-events-subdirs += hw/nvram
trace-events-subdirs += hw/display
trace-events-subdirs += hw/input
trace-events-subdirs += hw/timer
trace-events-subdirs += hw/dma
trace-events-subdirs += hw/sparc
trace-events-subdirs += hw/sparc64
trace-events-subdirs += hw/timer
trace-events-subdirs += hw/tpm
trace-events-subdirs += hw/usb
trace-events-subdirs += hw/sd
trace-events-subdirs += hw/isa
trace-events-subdirs += hw/mem
trace-events-subdirs += hw/i386
trace-events-subdirs += hw/i386/xen
trace-events-subdirs += hw/9pfs
trace-events-subdirs += hw/ppc
trace-events-subdirs += hw/pci
trace-events-subdirs += hw/pci-host
trace-events-subdirs += hw/s390x
trace-events-subdirs += hw/vfio
trace-events-subdirs += hw/virtio
trace-events-subdirs += hw/acpi
trace-events-subdirs += hw/arm
trace-events-subdirs += hw/alpha
trace-events-subdirs += hw/hppa
trace-events-subdirs += hw/xen
trace-events-subdirs += io
trace-events-subdirs += linux-user
trace-events-subdirs += migration
trace-events-subdirs += nbd
trace-events-subdirs += hw/ide
trace-events-subdirs += hw/tpm
trace-events-subdirs += ui
trace-events-subdirs += audio
trace-events-subdirs += net
trace-events-subdirs += qapi
trace-events-subdirs += qom
trace-events-subdirs += scsi
trace-events-subdirs += target/arm
trace-events-subdirs += target/i386
trace-events-subdirs += target/mips
trace-events-subdirs += target/ppc
trace-events-subdirs += target/s390x
trace-events-subdirs += target/sparc
trace-events-subdirs += ui
trace-events-subdirs += util
trace-events-subdirs += target/s390x
trace-events-subdirs += target/ppc
trace-events-subdirs += qom
trace-events-subdirs += linux-user
trace-events-subdirs += qapi
trace-events-subdirs += accel/tcg
trace-events-subdirs += accel/kvm
trace-events-subdirs += nbd
trace-events-subdirs += scsi
trace-events-files = $(SRC_PATH)/trace-events $(trace-events-subdirs:%=$(SRC_PATH)/%/trace-events)
+1 -7
View File
@@ -36,11 +36,6 @@ endif
PROGS=$(QEMU_PROG) $(QEMU_PROGW)
STPFILES=
# Makefile Tests
ifdef CONFIG_USER_ONLY
include $(SRC_PATH)/tests/tcg/Makefile.include
endif
config-target.h: config-target.h-timestamp
config-target.h-timestamp: config-target.mak
@@ -102,7 +97,7 @@ obj-$(CONFIG_TCG) += tcg/tcg.o tcg/tcg-op.o tcg/tcg-op-vec.o tcg/tcg-op-gvec.o
obj-$(CONFIG_TCG) += tcg/tcg-common.o tcg/optimize.o
obj-$(CONFIG_TCG_INTERPRETER) += tcg/tci.o
obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
obj-$(CONFIG_TCG) += fpu/softfloat.o
obj-y += fpu/softfloat.o
obj-y += target/$(TARGET_BASE_ARCH)/
obj-y += disas.o
obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
@@ -143,7 +138,6 @@ obj-y += hw/
obj-y += memory.o
obj-y += memory_mapping.o
obj-y += dump.o
obj-$(TARGET_X86_64) += win_dump.o
obj-y += migration/ram.o
LIBS := $(libs_softmmu) $(LIBS)
+1 -1
View File
@@ -1 +1 @@
3.0.0
2.12.1
+9 -16
View File
@@ -70,8 +70,8 @@ static int accel_init_machine(AccelClass *acc, MachineState *ms)
void configure_accelerator(MachineState *ms)
{
const char *accel;
char **accel_list, **tmp;
const char *accel, *p;
char buf[10];
int ret;
bool accel_initialised = false;
bool init_failed = false;
@@ -83,10 +83,13 @@ void configure_accelerator(MachineState *ms)
accel = "tcg";
}
accel_list = g_strsplit(accel, ":", 0);
for (tmp = accel_list; !accel_initialised && tmp && *tmp; tmp++) {
acc = accel_find(*tmp);
p = accel;
while (!accel_initialised && *p != '\0') {
if (*p == ':') {
p++;
}
p = get_opt_name(buf, sizeof(buf), p, ':');
acc = accel_find(buf);
if (!acc) {
continue;
}
@@ -104,7 +107,6 @@ void configure_accelerator(MachineState *ms)
accel_initialised = true;
}
}
g_strfreev(accel_list);
if (!accel_initialised) {
if (!init_failed) {
@@ -124,15 +126,6 @@ void accel_register_compat_props(AccelState *accel)
register_compat_props_array(class->global_props);
}
void accel_setup_post(MachineState *ms)
{
AccelState *accel = ms->accelerator;
AccelClass *acc = ACCEL_GET_CLASS(accel);
if (acc->setup_post) {
acc->setup_post(ms, accel);
}
}
static void register_accel_types(void)
{
type_register_static(&accel_type);
+9 -8
View File
@@ -256,7 +256,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram,
return 0;
}
static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, bool new)
static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot)
{
KVMState *s = kvm_state;
struct kvm_userspace_memory_region mem;
@@ -267,7 +267,7 @@ static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, boo
mem.userspace_addr = (unsigned long)slot->ram;
mem.flags = slot->flags;
if (slot->memory_size && !new && (mem.flags ^ slot->old_flags) & KVM_MEM_READONLY) {
if (slot->memory_size && mem.flags & KVM_MEM_READONLY) {
/* Set the slot size to 0 before setting the slot to the desired
* value. This is needed based on KVM commit 75d61fbc. */
mem.memory_size = 0;
@@ -275,7 +275,6 @@ static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot, boo
}
mem.memory_size = slot->memory_size;
ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
slot->old_flags = mem.flags;
trace_kvm_set_user_memory(mem.slot, mem.flags, mem.guest_phys_addr,
mem.memory_size, mem.userspace_addr, ret);
return ret;
@@ -392,14 +391,17 @@ static int kvm_mem_flags(MemoryRegion *mr)
static int kvm_slot_update_flags(KVMMemoryListener *kml, KVMSlot *mem,
MemoryRegion *mr)
{
int old_flags;
old_flags = mem->flags;
mem->flags = kvm_mem_flags(mr);
/* If nothing changed effectively, no need to issue ioctl */
if (mem->flags == mem->old_flags) {
if (mem->flags == old_flags) {
return 0;
}
return kvm_set_user_memory_region(kml, mem, false);
return kvm_set_user_memory_region(kml, mem);
}
static int kvm_section_update_flags(KVMMemoryListener *kml,
@@ -753,8 +755,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
/* unregister the slot */
mem->memory_size = 0;
mem->flags = 0;
err = kvm_set_user_memory_region(kml, mem, false);
err = kvm_set_user_memory_region(kml, mem);
if (err) {
fprintf(stderr, "%s: error unregistering slot: %s\n",
__func__, strerror(-err));
@@ -770,7 +771,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
mem->ram = ram;
mem->flags = kvm_mem_flags(mr);
err = kvm_set_user_memory_region(kml, mem, true);
err = kvm_set_user_memory_region(kml, mem);
if (err) {
fprintf(stderr, "%s: error registering slot: %s\n", __func__,
strerror(-err));
+4
View File
@@ -21,6 +21,10 @@ void tb_flush(CPUState *cpu)
{
}
void tb_unlock(void)
{
}
void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
{
}
+44 -155
View File
@@ -18,37 +18,26 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "trace/mem.h"
#if DATA_SIZE == 16
# define SUFFIX o
# define DATA_TYPE Int128
# define BSWAP bswap128
# define SHIFT 4
#elif DATA_SIZE == 8
# define SUFFIX q
# define DATA_TYPE uint64_t
# define SDATA_TYPE int64_t
# define BSWAP bswap64
# define SHIFT 3
#elif DATA_SIZE == 4
# define SUFFIX l
# define DATA_TYPE uint32_t
# define SDATA_TYPE int32_t
# define BSWAP bswap32
# define SHIFT 2
#elif DATA_SIZE == 2
# define SUFFIX w
# define DATA_TYPE uint16_t
# define SDATA_TYPE int16_t
# define BSWAP bswap16
# define SHIFT 1
#elif DATA_SIZE == 1
# define SUFFIX b
# define DATA_TYPE uint8_t
# define SDATA_TYPE int8_t
# define BSWAP
# define SHIFT 0
#else
# error unsupported data size
#endif
@@ -59,37 +48,14 @@
# define ABI_TYPE uint32_t
#endif
#define ATOMIC_TRACE_RMW do { \
uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false); \
\
trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info); \
trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, \
info | TRACE_MEM_ST); \
} while (0)
#define ATOMIC_TRACE_LD do { \
uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false); \
\
trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info); \
} while (0)
# define ATOMIC_TRACE_ST do { \
uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, true); \
\
trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info); \
} while (0)
/* Define host-endian atomic operations. Note that END is used within
the ATOMIC_NAME macro, and redefined below. */
#if DATA_SIZE == 1
# define END
# define MEND _be /* either le or be would be fine */
#elif defined(HOST_WORDS_BIGENDIAN)
# define END _be
# define MEND _be
#else
# define END _le
# define MEND _le
#endif
ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
@@ -97,10 +63,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
{
ATOMIC_MMU_DECLS;
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
DATA_TYPE ret;
ATOMIC_TRACE_RMW;
ret = atomic_cmpxchg__nocheck(haddr, cmpv, newv);
DATA_TYPE ret = atomic_cmpxchg__nocheck(haddr, cmpv, newv);
ATOMIC_MMU_CLEANUP;
return ret;
}
@@ -110,8 +73,6 @@ ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
{
ATOMIC_MMU_DECLS;
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
ATOMIC_TRACE_LD;
__atomic_load(haddr, &val, __ATOMIC_RELAXED);
ATOMIC_MMU_CLEANUP;
return val;
@@ -122,8 +83,6 @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
{
ATOMIC_MMU_DECLS;
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
ATOMIC_TRACE_ST;
__atomic_store(haddr, &val, __ATOMIC_RELAXED);
ATOMIC_MMU_CLEANUP;
}
@@ -133,10 +92,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
{
ATOMIC_MMU_DECLS;
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
DATA_TYPE ret;
ATOMIC_TRACE_RMW;
ret = atomic_xchg__nocheck(haddr, val);
DATA_TYPE ret = atomic_xchg__nocheck(haddr, val);
ATOMIC_MMU_CLEANUP;
return ret;
}
@@ -147,10 +103,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
{ \
ATOMIC_MMU_DECLS; \
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
DATA_TYPE ret; \
\
ATOMIC_TRACE_RMW; \
ret = atomic_##X(haddr, val); \
DATA_TYPE ret = atomic_##X(haddr, val); \
ATOMIC_MMU_CLEANUP; \
return ret; \
}
@@ -165,48 +118,9 @@ GEN_ATOMIC_HELPER(or_fetch)
GEN_ATOMIC_HELPER(xor_fetch)
#undef GEN_ATOMIC_HELPER
/* These helpers are, as a whole, full barriers. Within the helper,
* the leading barrier is explicit and the trailing barrier is within
* cmpxchg primitive.
*
* Trace this load + RMW loop as a single RMW op. This way, regardless
* of CF_PARALLEL's value, we'll trace just a read and a write.
*/
#define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
ABI_TYPE xval EXTRA_ARGS) \
{ \
ATOMIC_MMU_DECLS; \
XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
XDATA_TYPE cmp, old, new, val = xval; \
\
ATOMIC_TRACE_RMW; \
smp_mb(); \
cmp = atomic_read__nocheck(haddr); \
do { \
old = cmp; new = FN(old, val); \
cmp = atomic_cmpxchg__nocheck(haddr, old, new); \
} while (cmp != old); \
ATOMIC_MMU_CLEANUP; \
return RET; \
}
GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
GEN_ATOMIC_HELPER_FN(fetch_umin, MIN, DATA_TYPE, old)
GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
GEN_ATOMIC_HELPER_FN(fetch_umax, MAX, DATA_TYPE, old)
GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
GEN_ATOMIC_HELPER_FN(umin_fetch, MIN, DATA_TYPE, new)
GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
#undef GEN_ATOMIC_HELPER_FN
#endif /* DATA SIZE >= 16 */
#undef END
#undef MEND
#if DATA_SIZE > 1
@@ -214,10 +128,8 @@ GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
within the ATOMIC_NAME macro. */
#ifdef HOST_WORDS_BIGENDIAN
# define END _le
# define MEND _le
#else
# define END _be
# define MEND _be
#endif
ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
@@ -225,10 +137,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
{
ATOMIC_MMU_DECLS;
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
DATA_TYPE ret;
ATOMIC_TRACE_RMW;
ret = atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
DATA_TYPE ret = atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
ATOMIC_MMU_CLEANUP;
return BSWAP(ret);
}
@@ -238,8 +147,6 @@ ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
{
ATOMIC_MMU_DECLS;
DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
ATOMIC_TRACE_LD;
__atomic_load(haddr, &val, __ATOMIC_RELAXED);
ATOMIC_MMU_CLEANUP;
return BSWAP(val);
@@ -250,8 +157,6 @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
{
ATOMIC_MMU_DECLS;
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
ATOMIC_TRACE_ST;
val = BSWAP(val);
__atomic_store(haddr, &val, __ATOMIC_RELAXED);
ATOMIC_MMU_CLEANUP;
@@ -262,10 +167,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
{
ATOMIC_MMU_DECLS;
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
ABI_TYPE ret;
ATOMIC_TRACE_RMW;
ret = atomic_xchg__nocheck(haddr, BSWAP(val));
ABI_TYPE ret = atomic_xchg__nocheck(haddr, BSWAP(val));
ATOMIC_MMU_CLEANUP;
return BSWAP(ret);
}
@@ -276,10 +178,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
{ \
ATOMIC_MMU_DECLS; \
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
DATA_TYPE ret; \
\
ATOMIC_TRACE_RMW; \
ret = atomic_##X(haddr, BSWAP(val)); \
DATA_TYPE ret = atomic_##X(haddr, BSWAP(val)); \
ATOMIC_MMU_CLEANUP; \
return BSWAP(ret); \
}
@@ -293,64 +192,54 @@ GEN_ATOMIC_HELPER(xor_fetch)
#undef GEN_ATOMIC_HELPER
/* These helpers are, as a whole, full barriers. Within the helper,
* the leading barrier is explicit and the trailing barrier is within
* cmpxchg primitive.
*
* Trace this load + RMW loop as a single RMW op. This way, regardless
* of CF_PARALLEL's value, we'll trace just a read and a write.
*/
#define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
ABI_TYPE xval EXTRA_ARGS) \
{ \
ATOMIC_MMU_DECLS; \
XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
XDATA_TYPE ldo, ldn, old, new, val = xval; \
\
ATOMIC_TRACE_RMW; \
smp_mb(); \
ldn = atomic_read__nocheck(haddr); \
do { \
ldo = ldn; old = BSWAP(ldo); new = FN(old, val); \
ldn = atomic_cmpxchg__nocheck(haddr, ldo, BSWAP(new)); \
} while (ldo != ldn); \
ATOMIC_MMU_CLEANUP; \
return RET; \
}
GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
GEN_ATOMIC_HELPER_FN(fetch_umin, MIN, DATA_TYPE, old)
GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
GEN_ATOMIC_HELPER_FN(fetch_umax, MAX, DATA_TYPE, old)
GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
GEN_ATOMIC_HELPER_FN(umin_fetch, MIN, DATA_TYPE, new)
GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
/* Note that for addition, we need to use a separate cmpxchg loop instead
of bswaps for the reverse-host-endian helpers. */
#define ADD(X, Y) (X + Y)
GEN_ATOMIC_HELPER_FN(fetch_add, ADD, DATA_TYPE, old)
GEN_ATOMIC_HELPER_FN(add_fetch, ADD, DATA_TYPE, new)
#undef ADD
ABI_TYPE ATOMIC_NAME(fetch_add)(CPUArchState *env, target_ulong addr,
ABI_TYPE val EXTRA_ARGS)
{
ATOMIC_MMU_DECLS;
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
DATA_TYPE ldo, ldn, ret, sto;
#undef GEN_ATOMIC_HELPER_FN
ldo = atomic_read__nocheck(haddr);
while (1) {
ret = BSWAP(ldo);
sto = BSWAP(ret + val);
ldn = atomic_cmpxchg__nocheck(haddr, ldo, sto);
if (ldn == ldo) {
ATOMIC_MMU_CLEANUP;
return ret;
}
ldo = ldn;
}
}
ABI_TYPE ATOMIC_NAME(add_fetch)(CPUArchState *env, target_ulong addr,
ABI_TYPE val EXTRA_ARGS)
{
ATOMIC_MMU_DECLS;
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
DATA_TYPE ldo, ldn, ret, sto;
ldo = atomic_read__nocheck(haddr);
while (1) {
ret = BSWAP(ldo) + val;
sto = BSWAP(ret);
ldn = atomic_cmpxchg__nocheck(haddr, ldo, sto);
if (ldn == ldo) {
ATOMIC_MMU_CLEANUP;
return ret;
}
ldo = ldn;
}
}
#endif /* DATA_SIZE >= 16 */
#undef END
#undef MEND
#endif /* DATA_SIZE > 1 */
#undef ATOMIC_TRACE_ST
#undef ATOMIC_TRACE_LD
#undef ATOMIC_TRACE_RMW
#undef BSWAP
#undef ABI_TYPE
#undef DATA_TYPE
#undef SDATA_TYPE
#undef SUFFIX
#undef DATA_SIZE
#undef SHIFT
+59 -47
View File
@@ -25,6 +25,7 @@
#include "qemu/atomic.h"
#include "sysemu/qtest.h"
#include "qemu/timer.h"
#include "exec/address-spaces.h"
#include "qemu/rcu.h"
#include "exec/tb-hash.h"
#include "exec/tb-lookup.h"
@@ -155,14 +156,11 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)
&& qemu_log_in_addr_range(itb->pc)) {
qemu_log_lock();
int flags = 0;
if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) {
flags |= CPU_DUMP_FPU;
}
#if defined(TARGET_I386)
flags |= CPU_DUMP_CCOP;
log_cpu_state(cpu, CPU_DUMP_CCOP);
#else
log_cpu_state(cpu, 0);
#endif
log_cpu_state(cpu, flags);
qemu_log_unlock();
}
#endif /* DEBUG_DISAS */
@@ -212,20 +210,20 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
We only end up here when an existing TB is too long. */
cflags |= MIN(max_cycles, CF_COUNT_MASK);
mmap_lock();
tb_lock();
tb = tb_gen_code(cpu, orig_tb->pc, orig_tb->cs_base,
orig_tb->flags, cflags);
tb->orig_tb = orig_tb;
mmap_unlock();
tb_unlock();
/* execute the generated code */
trace_exec_tb_nocache(tb, tb->pc);
cpu_tb_exec(cpu, tb);
mmap_lock();
tb_lock();
tb_phys_invalidate(tb, -1);
mmap_unlock();
tcg_tb_remove(tb);
tb_remove(tb);
tb_unlock();
}
#endif
@@ -244,7 +242,12 @@ void cpu_exec_step_atomic(CPUState *cpu)
tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask);
if (tb == NULL) {
mmap_lock();
tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);
tb_lock();
tb = tb_htable_lookup(cpu, pc, cs_base, flags, cf_mask);
if (likely(tb == NULL)) {
tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);
}
tb_unlock();
mmap_unlock();
}
@@ -259,14 +262,15 @@ void cpu_exec_step_atomic(CPUState *cpu)
cpu_tb_exec(cpu, tb);
cc->cpu_exec_exit(cpu);
} else {
/*
/* We may have exited due to another problem here, so we need
* to reset any tb_locks we may have taken but didn't release.
* The mmap_lock is dropped by tb_gen_code if it runs out of
* memory.
*/
#ifndef CONFIG_SOFTMMU
tcg_debug_assert(!have_mmap_lock());
#endif
assert_no_pages_locked();
tb_lock_reset();
}
if (in_exclusive_region) {
@@ -289,7 +293,7 @@ struct tb_desc {
uint32_t trace_vcpu_dstate;
};
static bool tb_lookup_cmp(const void *p, const void *d)
static bool tb_cmp(const void *p, const void *d)
{
const TranslationBlock *tb = p;
const struct tb_desc *desc = d;
@@ -334,7 +338,7 @@ TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
phys_pc = get_page_addr_code(desc.env, pc);
desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
h = tb_hash_func(phys_pc, pc, flags, cf_mask, *cpu->trace_dstate);
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
return qht_lookup(&tb_ctx.htable, tb_cmp, &desc, h);
}
void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr)
@@ -348,43 +352,28 @@ void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr)
}
}
/* Called with tb_lock held. */
static inline void tb_add_jump(TranslationBlock *tb, int n,
TranslationBlock *tb_next)
{
uintptr_t old;
assert(n < ARRAY_SIZE(tb->jmp_list_next));
qemu_spin_lock(&tb_next->jmp_lock);
/* make sure the destination TB is valid */
if (tb_next->cflags & CF_INVALID) {
goto out_unlock_next;
if (tb->jmp_list_next[n]) {
/* Another thread has already done this while we were
* outside of the lock; nothing to do in this case */
return;
}
/* Atomically claim the jump destination slot only if it was NULL */
old = atomic_cmpxchg(&tb->jmp_dest[n], (uintptr_t)NULL, (uintptr_t)tb_next);
if (old) {
goto out_unlock_next;
}
/* patch the native jump address */
tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc.ptr);
/* add in TB jmp list */
tb->jmp_list_next[n] = tb_next->jmp_list_head;
tb_next->jmp_list_head = (uintptr_t)tb | n;
qemu_spin_unlock(&tb_next->jmp_lock);
qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc,
"Linking TBs %p [" TARGET_FMT_lx
"] index %d -> %p [" TARGET_FMT_lx "]\n",
tb->tc.ptr, tb->pc, n,
tb_next->tc.ptr, tb_next->pc);
return;
out_unlock_next:
qemu_spin_unlock(&tb_next->jmp_lock);
return;
/* patch the native jump address */
tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc.ptr);
/* add in TB jmp circular list */
tb->jmp_list_next[n] = tb_next->jmp_list_first;
tb_next->jmp_list_first = (uintptr_t)tb | n;
}
static inline TranslationBlock *tb_find(CPUState *cpu,
@@ -394,11 +383,27 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
TranslationBlock *tb;
target_ulong cs_base, pc;
uint32_t flags;
bool acquired_tb_lock = false;
tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask);
if (tb == NULL) {
/* mmap_lock is needed by tb_gen_code, and mmap_lock must be
* taken outside tb_lock. As system emulation is currently
* single threaded the locks are NOPs.
*/
mmap_lock();
tb = tb_gen_code(cpu, pc, cs_base, flags, cf_mask);
tb_lock();
acquired_tb_lock = true;
/* There's a chance that our desired tb has been translated while
* taking the locks so we check again inside the lock.
*/
tb = tb_htable_lookup(cpu, pc, cs_base, flags, cf_mask);
if (likely(tb == NULL)) {
/* if no translated code available, then translate it now */
tb = tb_gen_code(cpu, pc, cs_base, flags, cf_mask);
}
mmap_unlock();
/* We add the TB in the virtual pc hash table for the fast lookup */
atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
@@ -414,7 +419,16 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
#endif
/* See if we can patch the calling TB. */
if (last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
tb_add_jump(last_tb, tb_exit, tb);
if (!acquired_tb_lock) {
tb_lock();
acquired_tb_lock = true;
}
if (!(tb->cflags & CF_INVALID)) {
tb_add_jump(last_tb, tb_exit, tb);
}
}
if (acquired_tb_lock) {
tb_unlock();
}
return tb;
}
@@ -690,9 +704,7 @@ int cpu_exec(CPUState *cpu)
g_assert(cpu == current_cpu);
g_assert(cc == CPU_GET_CLASS(cpu));
#endif /* buggy compiler */
#ifndef CONFIG_SOFTMMU
tcg_debug_assert(!have_mmap_lock());
#endif
tb_lock_reset();
if (qemu_mutex_iothread_locked()) {
qemu_mutex_unlock_iothread();
}
+75 -191
View File
@@ -125,6 +125,8 @@ static void tlb_flush_nocheck(CPUState *cpu)
atomic_set(&env->tlb_flush_count, env->tlb_flush_count + 1);
tlb_debug("(count: %zu)\n", tlb_flush_count());
tb_lock();
memset(env->tlb_table, -1, sizeof(env->tlb_table));
memset(env->tlb_v_table, -1, sizeof(env->tlb_v_table));
cpu_tb_jmp_cache_clear(cpu);
@@ -133,6 +135,8 @@ static void tlb_flush_nocheck(CPUState *cpu)
env->tlb_flush_addr = -1;
env->tlb_flush_mask = 0;
tb_unlock();
atomic_mb_set(&cpu->pending_tlb_flush, 0);
}
@@ -176,6 +180,8 @@ static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
assert_cpu_is_self(cpu);
tb_lock();
tlb_debug("start: mmu_idx:0x%04lx\n", mmu_idx_bitmask);
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
@@ -191,6 +197,8 @@ static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data)
cpu_tb_jmp_cache_clear(cpu);
tlb_debug("done\n");
tb_unlock();
}
void tlb_flush_by_mmuidx(CPUState *cpu, uint16_t idxmap)
@@ -235,30 +243,20 @@ void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
async_safe_run_on_cpu(src_cpu, fn, RUN_ON_CPU_HOST_INT(idxmap));
}
static inline bool tlb_hit_page_anyprot(CPUTLBEntry *tlb_entry,
target_ulong page)
{
return tlb_hit_page(tlb_entry->addr_read, page) ||
tlb_hit_page(tlb_entry->addr_write, page) ||
tlb_hit_page(tlb_entry->addr_code, page);
}
static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong page)
static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
{
if (tlb_hit_page_anyprot(tlb_entry, page)) {
if (addr == (tlb_entry->addr_read &
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
addr == (tlb_entry->addr_write &
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
addr == (tlb_entry->addr_code &
(TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
memset(tlb_entry, -1, sizeof(*tlb_entry));
}
}
static inline void tlb_flush_vtlb_page(CPUArchState *env, int mmu_idx,
target_ulong page)
{
int k;
for (k = 0; k < CPU_VTLB_SIZE; k++) {
tlb_flush_entry(&env->tlb_v_table[mmu_idx][k], page);
}
}
static void tlb_flush_page_async_work(CPUState *cpu, run_on_cpu_data data)
{
CPUArchState *env = cpu->env_ptr;
@@ -284,7 +282,14 @@ static void tlb_flush_page_async_work(CPUState *cpu, run_on_cpu_data data)
i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
tlb_flush_vtlb_page(env, mmu_idx, addr);
}
/* check whether there are entries that need to be flushed in the vtlb */
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
int k;
for (k = 0; k < CPU_VTLB_SIZE; k++) {
tlb_flush_entry(&env->tlb_v_table[mmu_idx][k], addr);
}
}
tb_flush_jmp_cache(cpu, addr);
@@ -316,6 +321,7 @@ static void tlb_flush_page_by_mmuidx_async_work(CPUState *cpu,
unsigned long mmu_idx_bitmap = addr_and_mmuidx & ALL_MMUIDX_BITS;
int page = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
int mmu_idx;
int i;
assert_cpu_is_self(cpu);
@@ -325,7 +331,11 @@ static void tlb_flush_page_by_mmuidx_async_work(CPUState *cpu,
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
if (test_bit(mmu_idx, &mmu_idx_bitmap)) {
tlb_flush_entry(&env->tlb_table[mmu_idx][page], addr);
tlb_flush_vtlb_page(env, mmu_idx, addr);
/* check whether there are vltb entries that need to be flushed */
for (i = 0; i < CPU_VTLB_SIZE; i++) {
tlb_flush_entry(&env->tlb_v_table[mmu_idx][i], addr);
}
}
}
@@ -610,42 +620,27 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
target_ulong address;
target_ulong code_address;
uintptr_t addend;
CPUTLBEntry *te, tn;
hwaddr iotlb, xlat, sz, paddr_page;
target_ulong vaddr_page;
CPUTLBEntry *te, *tv, tn;
hwaddr iotlb, xlat, sz;
unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE;
int asidx = cpu_asidx_from_attrs(cpu, attrs);
assert_cpu_is_self(cpu);
if (size < TARGET_PAGE_SIZE) {
sz = TARGET_PAGE_SIZE;
} else {
if (size > TARGET_PAGE_SIZE) {
tlb_add_large_page(env, vaddr, size);
}
sz = size;
assert(size >= TARGET_PAGE_SIZE);
if (size != TARGET_PAGE_SIZE) {
tlb_add_large_page(env, vaddr, size);
}
vaddr_page = vaddr & TARGET_PAGE_MASK;
paddr_page = paddr & TARGET_PAGE_MASK;
section = address_space_translate_for_iotlb(cpu, asidx, paddr_page,
&xlat, &sz, attrs, &prot);
sz = size;
section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz);
assert(sz >= TARGET_PAGE_SIZE);
tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
" prot=%x idx=%d\n",
vaddr, paddr, prot, mmu_idx);
address = vaddr_page;
if (size < TARGET_PAGE_SIZE) {
/*
* Slow-path the TLB entries; we will repeat the MMU check and TLB
* fill on every access.
*/
address |= TLB_RECHECK;
}
if (!memory_region_is_ram(section->mr) &&
!memory_region_is_romd(section->mr)) {
address = vaddr;
if (!memory_region_is_ram(section->mr) && !memory_region_is_romd(section->mr)) {
/* IO memory case */
address |= TLB_MMIO;
addend = 0;
@@ -654,47 +649,26 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) + xlat;
}
/* Make sure there's no cached translation for the new page. */
tlb_flush_vtlb_page(env, mmu_idx, vaddr_page);
code_address = address;
iotlb = memory_region_section_get_iotlb(cpu, section, vaddr_page,
paddr_page, xlat, prot, &address);
iotlb = memory_region_section_get_iotlb(cpu, section, vaddr, paddr, xlat,
prot, &address);
index = (vaddr_page >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
te = &env->tlb_table[mmu_idx][index];
/* do not discard the translation in te, evict it into a victim tlb */
tv = &env->tlb_v_table[mmu_idx][vidx];
/*
* Only evict the old entry to the victim tlb if it's for a
* different page; otherwise just overwrite the stale data.
*/
if (!tlb_hit_page_anyprot(te, vaddr_page)) {
unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE;
CPUTLBEntry *tv = &env->tlb_v_table[mmu_idx][vidx];
/* addr_write can race with tlb_reset_dirty_range */
copy_tlb_helper(tv, te, true);
/* Evict the old entry into the victim tlb. */
copy_tlb_helper(tv, te, true);
env->iotlb_v[mmu_idx][vidx] = env->iotlb[mmu_idx][index];
}
env->iotlb_v[mmu_idx][vidx] = env->iotlb[mmu_idx][index];
/* refill the tlb */
/*
* At this point iotlb contains a physical section number in the lower
* TARGET_PAGE_BITS, and either
* + the ram_addr_t of the page base of the target RAM (if NOTDIRTY or ROM)
* + the offset within section->mr of the page base (otherwise)
* We subtract the vaddr_page (which is page aligned and thus won't
* disturb the low bits) to give an offset which can be added to the
* (non-page-aligned) vaddr of the eventual memory access to get
* the MemoryRegion offset for the access. Note that the vaddr we
* subtract here is that of the page base, and not the same as the
* vaddr we add back in io_readx()/io_writex()/get_page_addr_code().
*/
env->iotlb[mmu_idx][index].addr = iotlb - vaddr_page;
env->iotlb[mmu_idx][index].addr = iotlb - vaddr;
env->iotlb[mmu_idx][index].attrs = attrs;
/* Now calculate the new entry */
tn.addend = addend - vaddr_page;
tn.addend = addend - vaddr;
if (prot & PAGE_READ) {
tn.addr_read = address;
} else {
@@ -715,7 +689,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
tn.addr_write = address | TLB_MMIO;
} else if (memory_region_is_ram(section->mr)
&& cpu_physical_memory_is_clean(
memory_region_get_ram_addr(section->mr) + xlat)) {
memory_region_get_ram_addr(section->mr) + xlat)) {
tn.addr_write = address | TLB_NOTDIRTY;
} else {
tn.addr_write = address;
@@ -788,43 +762,16 @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
int mmu_idx,
target_ulong addr, uintptr_t retaddr,
bool recheck, int size)
target_ulong addr, uintptr_t retaddr, int size)
{
CPUState *cpu = ENV_GET_CPU(env);
hwaddr mr_offset;
MemoryRegionSection *section;
MemoryRegion *mr;
hwaddr physaddr = iotlbentry->addr;
MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
uint64_t val;
bool locked = false;
MemTxResult r;
if (recheck) {
/*
* This is a TLB_RECHECK access, where the MMU protection
* covers a smaller range than a target page, and we must
* repeat the MMU check here. This tlb_fill() call might
* longjump out if this access should cause a guest exception.
*/
int index;
target_ulong tlb_addr;
tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
/* RAM access */
uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
return ldn_p((void *)haddr, size);
}
/* Fall through for handling IO accesses */
}
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
mr = section->mr;
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
cpu->mem_io_pc = retaddr;
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
cpu_io_recompile(cpu, retaddr);
@@ -836,13 +783,9 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
qemu_mutex_lock_iothread();
locked = true;
}
r = memory_region_dispatch_read(mr, mr_offset,
r = memory_region_dispatch_read(mr, physaddr,
&val, size, iotlbentry->attrs);
if (r != MEMTX_OK) {
hwaddr physaddr = mr_offset +
section->offset_within_address_space -
section->offset_within_region;
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_LOAD,
mmu_idx, iotlbentry->attrs, r, retaddr);
}
@@ -856,42 +799,15 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
int mmu_idx,
uint64_t val, target_ulong addr,
uintptr_t retaddr, bool recheck, int size)
uintptr_t retaddr, int size)
{
CPUState *cpu = ENV_GET_CPU(env);
hwaddr mr_offset;
MemoryRegionSection *section;
MemoryRegion *mr;
hwaddr physaddr = iotlbentry->addr;
MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
bool locked = false;
MemTxResult r;
if (recheck) {
/*
* This is a TLB_RECHECK access, where the MMU protection
* covers a smaller range than a target page, and we must
* repeat the MMU check here. This tlb_fill() call might
* longjump out if this access should cause a guest exception.
*/
int index;
target_ulong tlb_addr;
tlb_fill(cpu, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
/* RAM access */
uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
stn_p((void *)haddr, size, val);
return;
}
/* Fall through for handling IO accesses */
}
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
mr = section->mr;
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
cpu_io_recompile(cpu, retaddr);
}
@@ -902,13 +818,9 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
qemu_mutex_lock_iothread();
locked = true;
}
r = memory_region_dispatch_write(mr, mr_offset,
r = memory_region_dispatch_write(mr, physaddr,
val, size, iotlbentry->attrs);
if (r != MEMTX_OK) {
hwaddr physaddr = mr_offset +
section->offset_within_address_space -
section->offset_within_region;
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
mmu_idx, iotlbentry->attrs, r, retaddr);
}
@@ -956,51 +868,24 @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
*/
tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
{
int mmu_idx, index;
int mmu_idx, index, pd;
void *p;
MemoryRegion *mr;
MemoryRegionSection *section;
CPUState *cpu = ENV_GET_CPU(env);
CPUIOTLBEntry *iotlbentry;
hwaddr physaddr, mr_offset;
hwaddr physaddr;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = cpu_mmu_index(env, true);
if (unlikely(!tlb_hit(env->tlb_table[mmu_idx][index].addr_code, addr))) {
if (!VICTIM_TLB_HIT(addr_code, addr)) {
if (unlikely(env->tlb_table[mmu_idx][index].addr_code !=
(addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK)))) {
if (!VICTIM_TLB_HIT(addr_read, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
}
assert(tlb_hit(env->tlb_table[mmu_idx][index].addr_code, addr));
}
if (unlikely(env->tlb_table[mmu_idx][index].addr_code & TLB_RECHECK)) {
/*
* This is a TLB_RECHECK access, where the MMU protection
* covers a smaller range than a target page, and we must
* repeat the MMU check here. This tlb_fill() call might
* longjump out if this access should cause a guest exception.
*/
int index;
target_ulong tlb_addr;
tlb_fill(cpu, addr, 0, MMU_INST_FETCH, mmu_idx, 0);
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
tlb_addr = env->tlb_table[mmu_idx][index].addr_code;
if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
/* RAM access. We can't handle this, so for now just stop */
cpu_abort(cpu, "Unable to handle guest executing from RAM within "
"a small MPU region at 0x" TARGET_FMT_lx, addr);
}
/*
* Fall through to handle IO accesses (which will almost certainly
* also result in failure)
*/
}
iotlbentry = &env->iotlb[mmu_idx][index];
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
mr = section->mr;
pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(cpu, pd, iotlbentry->attrs);
if (memory_region_is_unassigned(mr)) {
qemu_mutex_lock_iothread();
if (memory_region_request_mmio_ptr(mr, addr)) {
@@ -1021,10 +906,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
* and use the MemTXResult it produced). However it is the
* simplest place we have currently available for the check.
*/
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
physaddr = mr_offset +
section->offset_within_address_space -
section->offset_within_region;
physaddr = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
cpu_transaction_failed(cpu, physaddr, addr, 0, MMU_INST_FETCH, mmu_idx,
iotlbentry->attrs, MEMTX_DECODE_ERROR, 0);
@@ -1052,7 +934,8 @@ void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
if (!tlb_hit(tlb_addr, addr)) {
if ((addr & TARGET_PAGE_MASK)
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
/* TLB entry is for a different page */
if (!VICTIM_TLB_HIT(addr_write, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, size, MMU_DATA_STORE,
@@ -1096,7 +979,8 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
}
/* Check TLB entry and enforce page permissions. */
if (!tlb_hit(tlb_addr, addr)) {
if ((addr & TARGET_PAGE_MASK)
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
if (!VICTIM_TLB_HIT(addr_write, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, 1 << s_bits, MMU_DATA_STORE,
mmu_idx, retaddr);
@@ -1104,8 +988,8 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
tlb_addr = tlbe->addr_write & ~TLB_INVALID_MASK;
}
/* Notice an IO access or a needs-MMU-lookup access */
if (unlikely(tlb_addr & (TLB_MMIO | TLB_RECHECK))) {
/* Notice an IO access */
if (unlikely(tlb_addr & TLB_MMIO)) {
/* There's really nothing that can be done to
support this apart from stop-the-world. */
goto stop_the_world;
+18 -22
View File
@@ -98,12 +98,10 @@
static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
size_t mmu_idx, size_t index,
target_ulong addr,
uintptr_t retaddr,
bool recheck)
uintptr_t retaddr)
{
CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, recheck,
DATA_SIZE);
return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, DATA_SIZE);
}
#endif
@@ -123,7 +121,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
}
/* If the TLB entry is for a different page, reload and try again. */
if (!tlb_hit(tlb_addr, addr)) {
if ((addr & TARGET_PAGE_MASK)
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
if (!VICTIM_TLB_HIT(ADDR_READ, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
mmu_idx, retaddr);
@@ -139,8 +138,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
/* ??? Note that the io helpers always read data in the target
byte ordering. We should push the LE/BE request down into io. */
res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr,
tlb_addr & TLB_RECHECK);
res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
res = TGT_LE(res);
return res;
}
@@ -190,7 +188,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
}
/* If the TLB entry is for a different page, reload and try again. */
if (!tlb_hit(tlb_addr, addr)) {
if ((addr & TARGET_PAGE_MASK)
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
if (!VICTIM_TLB_HIT(ADDR_READ, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
mmu_idx, retaddr);
@@ -206,8 +205,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
/* ??? Note that the io helpers always read data in the target
byte ordering. We should push the LE/BE request down into io. */
res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr,
tlb_addr & TLB_RECHECK);
res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
res = TGT_BE(res);
return res;
}
@@ -261,12 +259,10 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
size_t mmu_idx, size_t index,
DATA_TYPE val,
target_ulong addr,
uintptr_t retaddr,
bool recheck)
uintptr_t retaddr)
{
CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr,
recheck, DATA_SIZE);
return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr, DATA_SIZE);
}
void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
@@ -284,7 +280,8 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
}
/* If the TLB entry is for a different page, reload and try again. */
if (!tlb_hit(tlb_addr, addr)) {
if ((addr & TARGET_PAGE_MASK)
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
if (!VICTIM_TLB_HIT(addr_write, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
mmu_idx, retaddr);
@@ -301,8 +298,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
/* ??? Note that the io helpers always read data in the target
byte ordering. We should push the LE/BE request down into io. */
val = TGT_LE(val);
glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr,
retaddr, tlb_addr & TLB_RECHECK);
glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr);
return;
}
@@ -319,7 +315,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write;
if (!tlb_hit_page(tlb_addr2, page2)
if (page2 != (tlb_addr2 & (TARGET_PAGE_MASK | TLB_INVALID_MASK))
&& !VICTIM_TLB_HIT(addr_write, page2)) {
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
mmu_idx, retaddr);
@@ -361,7 +357,8 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
}
/* If the TLB entry is for a different page, reload and try again. */
if (!tlb_hit(tlb_addr, addr)) {
if ((addr & TARGET_PAGE_MASK)
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
if (!VICTIM_TLB_HIT(addr_write, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
mmu_idx, retaddr);
@@ -378,8 +375,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
/* ??? Note that the io helpers always read data in the target
byte ordering. We should push the LE/BE request down into io. */
val = TGT_BE(val);
glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr,
tlb_addr & TLB_RECHECK);
glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr);
return;
}
@@ -396,7 +392,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write;
if (!tlb_hit_page(tlb_addr2, page2)
if (page2 != (tlb_addr2 & (TARGET_PAGE_MASK | TLB_INVALID_MASK))
&& !VICTIM_TLB_HIT(addr_write, page2)) {
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
mmu_idx, retaddr);
-8
View File
@@ -125,19 +125,11 @@ GEN_ATOMIC_HELPERS(fetch_add)
GEN_ATOMIC_HELPERS(fetch_and)
GEN_ATOMIC_HELPERS(fetch_or)
GEN_ATOMIC_HELPERS(fetch_xor)
GEN_ATOMIC_HELPERS(fetch_smin)
GEN_ATOMIC_HELPERS(fetch_umin)
GEN_ATOMIC_HELPERS(fetch_smax)
GEN_ATOMIC_HELPERS(fetch_umax)
GEN_ATOMIC_HELPERS(add_fetch)
GEN_ATOMIC_HELPERS(and_fetch)
GEN_ATOMIC_HELPERS(or_fetch)
GEN_ATOMIC_HELPERS(xor_fetch)
GEN_ATOMIC_HELPERS(smin_fetch)
GEN_ATOMIC_HELPERS(umin_fetch)
GEN_ATOMIC_HELPERS(smax_fetch)
GEN_ATOMIC_HELPERS(umax_fetch)
GEN_ATOMIC_HELPERS(xchg)
+354 -756
View File
File diff suppressed because it is too large. Load diff
+2 -5
View File
@@ -23,13 +23,10 @@
/* translate-all.c */
struct page_collection *page_collection_lock(tb_page_addr_t start,
tb_page_addr_t end);
void page_collection_unlock(struct page_collection *set);
void tb_invalidate_phys_page_fast(struct page_collection *pages,
tb_page_addr_t start, int len);
void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len);
void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
int is_cpu_write_access);
void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end);
void tb_check_watchpoint(CPUState *cpu);
#ifdef CONFIG_USER_ONLY
+11 -10
View File
@@ -34,6 +34,8 @@ void translator_loop_temp_check(DisasContextBase *db)
void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
CPUState *cpu, TranslationBlock *tb)
{
int max_insns;
/* Initialize DisasContext */
db->tb = tb;
db->pc_first = tb->pc;
@@ -43,18 +45,18 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
db->singlestep_enabled = cpu->singlestep_enabled;
/* Instruction counting */
db->max_insns = tb_cflags(db->tb) & CF_COUNT_MASK;
if (db->max_insns == 0) {
db->max_insns = CF_COUNT_MASK;
max_insns = tb_cflags(db->tb) & CF_COUNT_MASK;
if (max_insns == 0) {
max_insns = CF_COUNT_MASK;
}
if (db->max_insns > TCG_MAX_INSNS) {
db->max_insns = TCG_MAX_INSNS;
if (max_insns > TCG_MAX_INSNS) {
max_insns = TCG_MAX_INSNS;
}
if (db->singlestep_enabled || singlestep) {
db->max_insns = 1;
max_insns = 1;
}
ops->init_disas_context(db, cpu);
max_insns = ops->init_disas_context(db, cpu, max_insns);
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
/* Reset the temp count so that we can identify leaks */
@@ -93,8 +95,7 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
update db->pc_next and db->is_jmp to indicate what should be
done next -- either exiting this loop or locate the start of
the next instruction. */
if (db->num_insns == db->max_insns
&& (tb_cflags(db->tb) & CF_LAST_IO)) {
if (db->num_insns == max_insns && (tb_cflags(db->tb) & CF_LAST_IO)) {
/* Accept I/O on the last instruction. */
gen_io_start();
ops->translate_insn(db, cpu);
@@ -110,7 +111,7 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
/* Stop translation if the output buffer is full,
or we have executed all of the allowed instructions. */
if (tcg_op_buf_full() || db->num_insns >= db->max_insns) {
if (tcg_op_buf_full() || db->num_insns >= max_insns) {
db->is_jmp = DISAS_TOO_MANY;
break;
}
-3
View File
@@ -2,9 +2,6 @@
#include "qemu-common.h"
#include "qom/cpu.h"
#include "sysemu/replay.h"
#include "sysemu/sysemu.h"
bool enable_cpu_pm = false;
void cpu_resume(CPUState *cpu)
{
+9 -11
View File
@@ -29,7 +29,6 @@
#include "hw/pci/pci.h"
#include "hw/audio/soundhw.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/error.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "hw/acpi/acpi.h"
@@ -52,14 +51,14 @@ int graphic_depth = 32;
#define QEMU_ARCH QEMU_ARCH_ARM
#elif defined(TARGET_CRIS)
#define QEMU_ARCH QEMU_ARCH_CRIS
#elif defined(TARGET_HPPA)
#define QEMU_ARCH QEMU_ARCH_HPPA
#elif defined(TARGET_I386)
#define QEMU_ARCH QEMU_ARCH_I386
#elif defined(TARGET_LM32)
#define QEMU_ARCH QEMU_ARCH_LM32
#elif defined(TARGET_HPPA)
#define QEMU_ARCH QEMU_ARCH_HPPA
#elif defined(TARGET_M68K)
#define QEMU_ARCH QEMU_ARCH_M68K
#elif defined(TARGET_LM32)
#define QEMU_ARCH QEMU_ARCH_LM32
#elif defined(TARGET_MICROBLAZE)
#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
#elif defined(TARGET_MIPS)
@@ -80,12 +79,12 @@ int graphic_depth = 32;
#define QEMU_ARCH QEMU_ARCH_SH4
#elif defined(TARGET_SPARC)
#define QEMU_ARCH QEMU_ARCH_SPARC
#elif defined(TARGET_TRICORE)
#define QEMU_ARCH QEMU_ARCH_TRICORE
#elif defined(TARGET_UNICORE32)
#define QEMU_ARCH QEMU_ARCH_UNICORE32
#elif defined(TARGET_XTENSA)
#define QEMU_ARCH QEMU_ARCH_XTENSA
#elif defined(TARGET_UNICORE32)
#define QEMU_ARCH QEMU_ARCH_UNICORE32
#elif defined(TARGET_TRICORE)
#define QEMU_ARCH QEMU_ARCH_TRICORE
#endif
const uint32_t arch_type = QEMU_ARCH;
@@ -113,8 +112,7 @@ TargetInfo *qmp_query_target(Error **errp)
{
TargetInfo *info = g_malloc0(sizeof(*info));
info->arch = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME, -1,
&error_abort);
info->arch = g_strdup(TARGET_NAME);
return info;
}
+5 -26
View File
@@ -29,7 +29,6 @@
#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
#include "sysemu/replay.h"
#include "trace.h"
#define AUDIO_CAP "audio"
#include "audio_int.h"
@@ -336,8 +335,9 @@ static int audio_get_conf_int (const char *key, int defval, int *defaultp)
char *strval;
strval = getenv (key);
if (strval && !qemu_strtoi(strval, NULL, 10, &val)) {
if (strval) {
*defaultp = 0;
val = atoi (strval);
return val;
}
else {
@@ -1130,10 +1130,6 @@ static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
/*
* Timer
*/
static bool audio_timer_running;
static uint64_t audio_timer_last;
static int audio_is_timer_needed (void)
{
HWVoiceIn *hwi = NULL;
@@ -1153,31 +1149,14 @@ static void audio_reset_timer (AudioState *s)
if (audio_is_timer_needed ()) {
timer_mod_anticipate_ns(s->ts,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + conf.period.ticks);
if (!audio_timer_running) {
audio_timer_running = true;
audio_timer_last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
trace_audio_timer_start(conf.period.ticks / SCALE_MS);
}
} else {
timer_del(s->ts);
if (audio_timer_running) {
audio_timer_running = false;
trace_audio_timer_stop();
}
}
else {
timer_del (s->ts);
}
}
static void audio_timer (void *opaque)
{
int64_t now, diff;
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
diff = now - audio_timer_last;
if (diff > conf.period.ticks * 3 / 2) {
trace_audio_timer_delayed(diff / SCALE_MS);
}
audio_timer_last = now;
audio_run ("timer");
audio_reset_timer (opaque);
}
-5
View File
@@ -15,8 +15,3 @@ alsa_no_frames(int state) "No frames available and ALSA state is %d"
# audio/ossaudio.c
oss_version(int version) "OSS version = 0x%x"
oss_invalid_available_size(int size, int bufsize) "Invalid available size, size=%d bufsize=%d"
# audio/audio.c
audio_timer_start(int interval) "interval %d ms"
audio_timer_stop(void) ""
audio_timer_delayed(int interval) "interval %d ms"
+6 -19
View File
@@ -26,7 +26,6 @@
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
#include "hw/virtio/vhost-user.h"
#include "standard-headers/linux/virtio_crypto.h"
#include "sysemu/cryptodev-vhost.h"
#include "chardev/char-fe.h"
@@ -47,7 +46,6 @@
typedef struct CryptoDevBackendVhostUser {
CryptoDevBackend parent_obj;
VhostUserState *vhost_user;
CharBackend chr;
char *chr_name;
bool opened;
@@ -104,7 +102,7 @@ cryptodev_vhost_user_start(int queues,
continue;
}
options.opaque = s->vhost_user;
options.opaque = &s->chr;
options.backend_type = VHOST_BACKEND_TYPE_USER;
options.cc = b->conf.peers.ccs[i];
s->vhost_crypto[i] = cryptodev_vhost_init(&options);
@@ -157,6 +155,7 @@ static void cryptodev_vhost_user_event(void *opaque, int event)
{
CryptoDevBackendVhostUser *s = opaque;
CryptoDevBackend *b = CRYPTODEV_BACKEND(s);
Error *err = NULL;
int queues = b->conf.peers.queues;
assert(queues < MAX_CRYPTO_QUEUE_NUM);
@@ -173,6 +172,10 @@ static void cryptodev_vhost_user_event(void *opaque, int event)
cryptodev_vhost_user_stop(queues, s);
break;
}
if (err) {
error_report_err(err);
}
}
static void cryptodev_vhost_user_init(
@@ -182,7 +185,6 @@ static void cryptodev_vhost_user_init(
size_t i;
Error *local_err = NULL;
Chardev *chr;
VhostUserState *user;
CryptoDevBackendClient *cc;
CryptoDevBackendVhostUser *s =
CRYPTODEV_BACKEND_VHOST_USER(backend);
@@ -213,15 +215,6 @@ static void cryptodev_vhost_user_init(
}
}
user = vhost_user_init();
if (!user) {
error_setg(errp, "Failed to init vhost_user");
return;
}
user->chr = &s->chr;
s->vhost_user = user;
qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
cryptodev_vhost_user_event, NULL, s, NULL, true);
@@ -306,12 +299,6 @@ static void cryptodev_vhost_user_cleanup(
backend->conf.peers.ccs[i] = NULL;
}
}
if (s->vhost_user) {
vhost_user_cleanup(s->vhost_user);
g_free(s->vhost_user);
s->vhost_user = NULL;
}
}
static void cryptodev_vhost_user_set_chardev(Object *obj,
+28 -19
View File
@@ -18,7 +18,6 @@
#include "qapi/visitor.h"
#include "qemu/config-file.h"
#include "qom/object_interfaces.h"
#include "qemu/mmap-alloc.h"
#ifdef CONFIG_NUMA
#include <numaif.h>
@@ -247,7 +246,8 @@ bool host_memory_backend_mr_inited(HostMemoryBackend *backend)
return memory_region_size(&backend->mr) != 0;
}
MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend)
MemoryRegion *
host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
{
return host_memory_backend_mr_inited(backend) ? &backend->mr : NULL;
}
@@ -262,23 +262,6 @@ bool host_memory_backend_is_mapped(HostMemoryBackend *backend)
return backend->is_mapped;
}
#ifdef __linux__
size_t host_memory_backend_pagesize(HostMemoryBackend *memdev)
{
Object *obj = OBJECT(memdev);
char *path = object_property_get_str(obj, "mem-path", NULL);
size_t pagesize = qemu_mempath_getpagesize(path);
g_free(path);
return pagesize;
}
#else
size_t host_memory_backend_pagesize(HostMemoryBackend *memdev)
{
return getpagesize();
}
#endif
static void
host_memory_backend_memory_complete(UserCreatable *uc, Error **errp)
{
@@ -368,6 +351,24 @@ host_memory_backend_can_be_deleted(UserCreatable *uc)
}
}
static char *get_id(Object *o, Error **errp)
{
HostMemoryBackend *backend = MEMORY_BACKEND(o);
return g_strdup(backend->id);
}
static void set_id(Object *o, const char *str, Error **errp)
{
HostMemoryBackend *backend = MEMORY_BACKEND(o);
if (backend->id) {
error_setg(errp, "cannot change property value");
return;
}
backend->id = g_strdup(str);
}
static bool host_memory_backend_get_share(Object *o, Error **errp)
{
HostMemoryBackend *backend = MEMORY_BACKEND(o);
@@ -415,11 +416,18 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
&HostMemPolicy_lookup,
host_memory_backend_get_policy,
host_memory_backend_set_policy, &error_abort);
object_class_property_add_str(oc, "id", get_id, set_id, &error_abort);
object_class_property_add_bool(oc, "share",
host_memory_backend_get_share, host_memory_backend_set_share,
&error_abort);
}
static void host_memory_backend_finalize(Object *o)
{
HostMemoryBackend *backend = MEMORY_BACKEND(o);
g_free(backend->id);
}
static const TypeInfo host_memory_backend_info = {
.name = TYPE_MEMORY_BACKEND,
.parent = TYPE_OBJECT,
@@ -428,6 +436,7 @@ static const TypeInfo host_memory_backend_info = {
.class_init = host_memory_backend_class_init,
.instance_size = sizeof(HostMemoryBackend),
.instance_init = host_memory_backend_init,
.instance_finalize = host_memory_backend_finalize,
.interfaces = (InterfaceInfo[]) {
{ TYPE_USER_CREATABLE },
{ }
+131 -138
View File
@@ -27,7 +27,6 @@
#include "block/block_int.h"
#include "block/blockjob.h"
#include "block/nbd.h"
#include "block/qdict.h"
#include "qemu/error-report.h"
#include "module_block.h"
#include "qemu/module.h"
@@ -333,10 +332,6 @@ BlockDriverState *bdrv_new(void)
qemu_co_queue_init(&bs->flush_queue);
for (i = 0; i < bdrv_drain_all_count; i++) {
bdrv_drained_begin(bs);
}
QTAILQ_INSERT_TAIL(&all_bdrv_states, bs, bs_list);
return bs;
@@ -725,7 +720,7 @@ static int find_image_format(BlockBackend *file, const char *filename,
* Set the current 'total_sectors' value
* Return 0 on success, -errno on error.
*/
int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
{
BlockDriver *drv = bs->drv;
@@ -822,13 +817,7 @@ static char *bdrv_child_get_parent_desc(BdrvChild *c)
static void bdrv_child_cb_drained_begin(BdrvChild *child)
{
BlockDriverState *bs = child->opaque;
bdrv_do_drained_begin_quiesce(bs, NULL, false);
}
static bool bdrv_child_cb_drained_poll(BdrvChild *child)
{
BlockDriverState *bs = child->opaque;
return bdrv_drain_poll(bs, false, NULL, false);
bdrv_drained_begin(bs);
}
static void bdrv_child_cb_drained_end(BdrvChild *child)
@@ -912,11 +901,9 @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
}
const BdrvChildRole child_file = {
.parent_is_bds = true,
.get_parent_desc = bdrv_child_get_parent_desc,
.inherit_options = bdrv_inherited_options,
.drained_begin = bdrv_child_cb_drained_begin,
.drained_poll = bdrv_child_cb_drained_poll,
.drained_end = bdrv_child_cb_drained_end,
.attach = bdrv_child_cb_attach,
.detach = bdrv_child_cb_detach,
@@ -938,11 +925,9 @@ static void bdrv_inherited_fmt_options(int *child_flags, QDict *child_options,
}
const BdrvChildRole child_format = {
.parent_is_bds = true,
.get_parent_desc = bdrv_child_get_parent_desc,
.inherit_options = bdrv_inherited_fmt_options,
.drained_begin = bdrv_child_cb_drained_begin,
.drained_poll = bdrv_child_cb_drained_poll,
.drained_end = bdrv_child_cb_drained_end,
.attach = bdrv_child_cb_attach,
.detach = bdrv_child_cb_detach,
@@ -1057,13 +1042,11 @@ static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
}
const BdrvChildRole child_backing = {
.parent_is_bds = true,
.get_parent_desc = bdrv_child_get_parent_desc,
.attach = bdrv_backing_attach,
.detach = bdrv_backing_detach,
.inherit_options = bdrv_backing_options,
.drained_begin = bdrv_child_cb_drained_begin,
.drained_poll = bdrv_child_cb_drained_poll,
.drained_end = bdrv_child_cb_drained_end,
.inactivate = bdrv_child_cb_inactivate,
.update_filename = bdrv_backing_update_filename,
@@ -1156,12 +1139,6 @@ static void bdrv_assign_node_name(BlockDriverState *bs,
goto out;
}
/* Make sure that the node name isn't truncated */
if (strlen(node_name) >= sizeof(bs->node_name)) {
error_setg(errp, "Node name too long");
goto out;
}
/* copy node name into the bs and insert it into the graph list */
pstrcpy(bs->node_name, sizeof(bs->node_name), node_name);
QTAILQ_INSERT_TAIL(&graph_bdrv_states, bs, node_list);
@@ -1174,7 +1151,7 @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
int open_flags, Error **errp)
{
Error *local_err = NULL;
int i, ret;
int ret;
bdrv_assign_node_name(bs, node_name, &local_err);
if (local_err) {
@@ -1222,12 +1199,6 @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
assert(bdrv_min_mem_align(bs) != 0);
assert(is_power_of_2(bs->bl.request_alignment));
for (i = 0; i < bs->quiesce_counter; i++) {
if (drv->bdrv_co_drain_begin) {
drv->bdrv_co_drain_begin(bs);
}
}
return 0;
open_failed:
bs->drv = NULL;
@@ -1256,9 +1227,9 @@ BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
ret = bdrv_open_driver(bs, drv, node_name, bs->options, flags, errp);
if (ret < 0) {
qobject_unref(bs->explicit_options);
QDECREF(bs->explicit_options);
bs->explicit_options = NULL;
qobject_unref(bs->options);
QDECREF(bs->options);
bs->options = NULL;
bdrv_unref(bs);
return NULL;
@@ -1489,7 +1460,7 @@ static QDict *parse_json_filename(const char *filename, Error **errp)
options = qobject_to(QDict, options_obj);
if (!options) {
qobject_unref(options_obj);
qobject_decref(options_obj);
error_setg(errp, "Invalid JSON object given");
return NULL;
}
@@ -1519,7 +1490,7 @@ static void parse_json_protocol(QDict *options, const char **pfilename,
/* Options given in the filename have lower priority than options
* specified directly */
qdict_join(options, json_options, false);
qobject_unref(json_options);
QDECREF(json_options);
*pfilename = NULL;
}
@@ -1954,6 +1925,12 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
return 0;
}
#define DEFAULT_PERM_PASSTHROUGH (BLK_PERM_CONSISTENT_READ \
| BLK_PERM_WRITE \
| BLK_PERM_WRITE_UNCHANGED \
| BLK_PERM_RESIZE)
#define DEFAULT_PERM_UNCHANGED (BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH)
void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
@@ -2043,12 +2020,7 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
child->role->detach(child);
}
if (old_bs->quiesce_counter && child->role->drained_end) {
int num = old_bs->quiesce_counter;
if (child->role->parent_is_bds) {
num -= bdrv_drain_all_count;
}
assert(num >= 0);
for (i = 0; i < num; i++) {
for (i = 0; i < old_bs->quiesce_counter; i++) {
child->role->drained_end(child);
}
}
@@ -2060,13 +2032,8 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
if (new_bs) {
QLIST_INSERT_HEAD(&new_bs->parents, child, next_parent);
if (new_bs->quiesce_counter && child->role->drained_begin) {
int num = new_bs->quiesce_counter;
if (child->role->parent_is_bds) {
num -= bdrv_drain_all_count;
}
assert(num >= 0);
for (i = 0; i < num; i++) {
bdrv_parent_drained_begin_single(child, true);
for (i = 0; i < new_bs->quiesce_counter; i++) {
child->role->drained_begin(child);
}
}
@@ -2226,6 +2193,16 @@ static void bdrv_parent_cb_change_media(BlockDriverState *bs, bool load)
}
}
static void bdrv_parent_cb_resize(BlockDriverState *bs)
{
BdrvChild *c;
QLIST_FOREACH(c, &bs->parents, next_parent) {
if (c->role->resize) {
c->role->resize(c);
}
}
}
/*
* Sets the backing file link of a BDS. A new reference is created; callers
* which don't need their own reference any more must call bdrv_unref().
@@ -2307,7 +2284,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
if (reference || qdict_haskey(options, "file.filename")) {
backing_filename[0] = '\0';
} else if (bs->backing_file[0] == '\0' && qdict_size(options) == 0) {
qobject_unref(options);
QDECREF(options);
goto free_exit;
} else {
bdrv_get_full_backing_filename(bs, backing_filename, PATH_MAX,
@@ -2315,7 +2292,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
if (local_err) {
ret = -EINVAL;
error_propagate(errp, local_err);
qobject_unref(options);
QDECREF(options);
goto free_exit;
}
}
@@ -2323,7 +2300,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
if (!bs->drv || !bs->drv->supports_backing) {
ret = -EINVAL;
error_setg(errp, "Driver doesn't support backing files");
qobject_unref(options);
QDECREF(options);
goto free_exit;
}
@@ -2357,7 +2334,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
free_exit:
g_free(backing_filename);
qobject_unref(tmp_parent_options);
QDECREF(tmp_parent_options);
return ret;
}
@@ -2390,7 +2367,7 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
error_setg(errp, "A block device must be specified for \"%s\"",
bdref_key);
}
qobject_unref(image_options);
QDECREF(image_options);
goto done;
}
@@ -2483,7 +2460,7 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
obj = NULL;
fail:
qobject_unref(obj);
qobject_decref(obj);
visit_free(v);
return bs;
}
@@ -2553,7 +2530,7 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
}
out:
qobject_unref(snapshot_options);
QDECREF(snapshot_options);
g_free(tmp_filename);
return bs_snapshot;
}
@@ -2564,7 +2541,7 @@ out:
* options is a QDict of options to pass to the block drivers, or NULL for an
* empty set of options. The reference to the QDict belongs to the block layer
* after the call (even on failure), so if the caller intends to reuse the
* dictionary, it needs to use qobject_ref() before calling bdrv_open.
* dictionary, it needs to use QINCREF() before calling bdrv_open.
*
* If *pbs is NULL, a new BDS will be created with a pointer to it stored there.
* If it is not NULL, the referenced BDS will be reused.
@@ -2595,7 +2572,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
if (reference) {
bool options_non_empty = options ? qdict_size(options) : false;
qobject_unref(options);
QDECREF(options);
if (filename || options_non_empty) {
error_setg(errp, "Cannot reference an existing block device with "
@@ -2786,7 +2763,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
bdrv_parent_cb_change_media(bs, true);
qobject_unref(options);
QDECREF(options);
/* For snapshot=on, create a temporary qcow2 overlay. bs points to the
* temporary snapshot afterwards. */
@@ -2810,10 +2787,10 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
fail:
blk_unref(file);
qobject_unref(snapshot_options);
qobject_unref(bs->explicit_options);
qobject_unref(bs->options);
qobject_unref(options);
QDECREF(snapshot_options);
QDECREF(bs->explicit_options);
QDECREF(bs->options);
QDECREF(options);
bs->options = NULL;
bs->explicit_options = NULL;
bdrv_unref(bs);
@@ -2822,8 +2799,8 @@ fail:
close_and_fail:
bdrv_unref(bs);
qobject_unref(snapshot_options);
qobject_unref(options);
QDECREF(snapshot_options);
QDECREF(options);
error_propagate(errp, local_err);
return NULL;
}
@@ -2918,7 +2895,7 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
old_options = qdict_clone_shallow(bs->explicit_options);
}
bdrv_join_options(bs, options, old_options);
qobject_unref(old_options);
QDECREF(old_options);
explicit_options = qdict_clone_shallow(options);
@@ -2933,13 +2910,13 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
qemu_opts_absorb_qdict(opts, options_copy, NULL);
update_flags_from_options(&flags, opts);
qemu_opts_del(opts);
qobject_unref(options_copy);
QDECREF(options_copy);
}
/* Old values are used for options that aren't set yet */
old_options = qdict_clone_shallow(bs->options);
bdrv_join_options(bs, options, old_options);
qobject_unref(old_options);
QDECREF(old_options);
/* bdrv_open_inherit() sets and clears some additional flags internally */
flags &= ~BDRV_O_PROTOCOL;
@@ -2951,8 +2928,8 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
bs_entry = g_new0(BlockReopenQueueEntry, 1);
QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
} else {
qobject_unref(bs_entry->state.options);
qobject_unref(bs_entry->state.explicit_options);
QDECREF(bs_entry->state.options);
QDECREF(bs_entry->state.explicit_options);
}
bs_entry->state.bs = bs;
@@ -3002,7 +2979,7 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
*
* Reopens all BDS specified in the queue, with the appropriate
* flags. All devices are prepared for reopen, and failure of any
* device will cause all device changes to be abandoned, and intermediate
* device will cause all device changes to be abandonded, and intermediate
* data cleaned up.
*
* If all devices prepare successfully, then the changes are committed
@@ -3042,9 +3019,9 @@ cleanup:
if (ret && bs_entry->prepared) {
bdrv_reopen_abort(&bs_entry->state);
} else if (ret) {
qobject_unref(bs_entry->state.explicit_options);
QDECREF(bs_entry->state.explicit_options);
}
qobject_unref(bs_entry->state.options);
QDECREF(bs_entry->state.options);
g_free(bs_entry);
}
g_free(bs_queue);
@@ -3287,7 +3264,7 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
}
/* set BDS specific flags now */
qobject_unref(bs->explicit_options);
QDECREF(bs->explicit_options);
bs->explicit_options = reopen_state->explicit_options;
bs->open_flags = reopen_state->flags;
@@ -3330,7 +3307,7 @@ void bdrv_reopen_abort(BDRVReopenState *reopen_state)
drv->bdrv_reopen_abort(reopen_state);
}
qobject_unref(reopen_state->explicit_options);
QDECREF(reopen_state->explicit_options);
bdrv_abort_perm_update(reopen_state->bs);
}
@@ -3377,11 +3354,11 @@ static void bdrv_close(BlockDriverState *bs)
bs->total_sectors = 0;
bs->encrypted = false;
bs->sg = false;
qobject_unref(bs->options);
qobject_unref(bs->explicit_options);
QDECREF(bs->options);
QDECREF(bs->explicit_options);
bs->options = NULL;
bs->explicit_options = NULL;
qobject_unref(bs->full_open_options);
QDECREF(bs->full_open_options);
bs->full_open_options = NULL;
bdrv_release_named_dirty_bitmaps(bs);
@@ -3396,7 +3373,7 @@ static void bdrv_close(BlockDriverState *bs)
void bdrv_close_all(void)
{
assert(job_next(NULL) == NULL);
block_job_cancel_sync_all();
nbd_export_close_all();
/* Drop references from requests still in flight, such as canceled block
@@ -3417,39 +3394,16 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
return false;
}
/* If the child @c belongs to the BDS @to, replacing the current
* c->bs by @to would mean to create a loop.
*
* Such a case occurs when appending a BDS to a backing chain.
* For instance, imagine the following chain:
*
* guest device -> node A -> further backing chain...
*
* Now we create a new BDS B which we want to put on top of this
* chain, so we first attach A as its backing node:
*
* node B
* |
* v
* guest device -> node A -> further backing chain...
*
* Finally we want to replace A by B. When doing that, we want to
* replace all pointers to A by pointers to B -- except for the
* pointer from B because (1) that would create a loop, and (2)
* that pointer should simply stay intact:
*
* guest device -> node B
* |
* v
* node A -> further backing chain...
*
* In general, when replacing a node A (c->bs) by a node B (@to),
* if A is a child of B, that means we cannot replace A by B there
* because that would create a loop. Silently detaching A from B
* is also not really an option. So overall just leaving A in
* place there is the most sensible choice. */
QLIST_FOREACH(to_c, &to->children, next) {
if (to_c == c) {
if (c->role == &child_backing) {
/* If @from is a backing file of @to, ignore the child to avoid
* creating a loop. We only want to change the pointer of other
* parents. */
QLIST_FOREACH(to_c, &to->children, next) {
if (to_c == c) {
break;
}
}
if (to_c) {
return false;
}
}
@@ -3475,7 +3429,6 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
/* Put all parents into @list and calculate their cumulative permissions */
QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
assert(c->bs == from);
if (!should_update_child(c, to)) {
continue;
}
@@ -3775,6 +3728,58 @@ exit:
return ret;
}
/**
* Truncate file to 'offset' bytes (needed only for file protocols)
*/
int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc,
Error **errp)
{
BlockDriverState *bs = child->bs;
BlockDriver *drv = bs->drv;
int ret;
assert(child->perm & BLK_PERM_RESIZE);
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
if (!drv) {
error_setg(errp, "No medium inserted");
return -ENOMEDIUM;
}
if (offset < 0) {
error_setg(errp, "Image size cannot be negative");
return -EINVAL;
}
if (!drv->bdrv_truncate) {
if (bs->file && drv->is_filter) {
return bdrv_truncate(bs->file, offset, prealloc, errp);
}
error_setg(errp, "Image format driver does not support resize");
return -ENOTSUP;
}
if (bs->read_only) {
error_setg(errp, "Image is read-only");
return -EACCES;
}
assert(!(bs->open_flags & BDRV_O_INACTIVE));
ret = drv->bdrv_truncate(bs, offset, prealloc, errp);
if (ret < 0) {
return ret;
}
ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not refresh total sector count");
} else {
offset = bs->total_sectors * BDRV_SECTOR_SIZE;
}
bdrv_dirty_bitmap_truncate(bs, offset);
bdrv_parent_cb_resize(bs);
atomic_inc(&bs->write_gen);
return ret;
}
/**
* Length of a allocated file in bytes. Sparse files are counted by actual
* allocated space. Return < 0 if error or unknown.
@@ -4031,14 +4036,6 @@ BlockDriverState *bdrv_next_node(BlockDriverState *bs)
return QTAILQ_NEXT(bs, node_list);
}
BlockDriverState *bdrv_next_all_states(BlockDriverState *bs)
{
if (!bs) {
return QTAILQ_FIRST(&all_bdrv_states);
}
return QTAILQ_NEXT(bs, bs_list);
}
const char *bdrv_get_node_name(const BlockDriverState *bs)
{
return bs->node_name;
@@ -4950,7 +4947,7 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
AioContext *ctx = bdrv_get_aio_context(bs);
aio_disable_external(ctx);
bdrv_parent_drained_begin(bs, NULL, false);
bdrv_parent_drained_begin(bs, NULL);
bdrv_drain(bs); /* ensure there are no in-flight requests */
while (aio_poll(ctx, false)) {
@@ -4964,7 +4961,7 @@ 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, NULL, false);
bdrv_parent_drained_end(bs, NULL);
aio_enable_external(ctx);
aio_context_release(new_context);
}
@@ -5010,19 +5007,15 @@ void bdrv_remove_aio_context_notifier(BlockDriverState *bs,
}
int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts,
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
Error **errp)
BlockDriverAmendStatusCB *status_cb, void *cb_opaque)
{
if (!bs->drv) {
error_setg(errp, "Node is ejected");
return -ENOMEDIUM;
}
if (!bs->drv->bdrv_amend_options) {
error_setg(errp, "Block driver '%s' does not support option amendment",
bs->drv->format_name);
return -ENOTSUP;
}
return bs->drv->bdrv_amend_options(bs, opts, status_cb, cb_opaque, errp);
return bs->drv->bdrv_amend_options(bs, opts, status_cb, cb_opaque);
}
/* This function will be called by the bdrv_recurse_is_first_non_filter method
@@ -5152,8 +5145,8 @@ static bool append_open_options(QDict *d, BlockDriverState *bs)
continue;
}
qdict_put_obj(d, qdict_entry_key(entry),
qobject_ref(qdict_entry_value(entry)));
qobject_incref(qdict_entry_value(entry));
qdict_put_obj(d, qdict_entry_key(entry), qdict_entry_value(entry));
found_any = true;
}
@@ -5192,21 +5185,21 @@ void bdrv_refresh_filename(BlockDriverState *bs)
* information before refreshing it */
bs->exact_filename[0] = '\0';
if (bs->full_open_options) {
qobject_unref(bs->full_open_options);
QDECREF(bs->full_open_options);
bs->full_open_options = NULL;
}
opts = qdict_new();
append_open_options(opts, bs);
drv->bdrv_refresh_filename(bs, opts);
qobject_unref(opts);
QDECREF(opts);
} else if (bs->file) {
/* Try to reconstruct valid information from the underlying file */
bool has_open_options;
bs->exact_filename[0] = '\0';
if (bs->full_open_options) {
qobject_unref(bs->full_open_options);
QDECREF(bs->full_open_options);
bs->full_open_options = NULL;
}
@@ -5225,12 +5218,12 @@ void bdrv_refresh_filename(BlockDriverState *bs)
* suffices without querying the (exact_)filename of this BDS. */
if (bs->file->bs->full_open_options) {
qdict_put_str(opts, "driver", drv->format_name);
qdict_put(opts, "file",
qobject_ref(bs->file->bs->full_open_options));
QINCREF(bs->file->bs->full_open_options);
qdict_put(opts, "file", bs->file->bs->full_open_options);
bs->full_open_options = opts;
} else {
qobject_unref(opts);
QDECREF(opts);
}
} else if (!bs->full_open_options && qdict_size(bs->options)) {
/* There is no underlying file BDS (at least referenced by BDS.file),
@@ -5264,7 +5257,7 @@ void bdrv_refresh_filename(BlockDriverState *bs)
QString *json = qobject_to_json(QOBJECT(bs->full_open_options));
snprintf(bs->filename, sizeof(bs->filename), "json:%s",
qstring_get_str(json));
qobject_unref(json);
QDECREF(json);
}
}
+1 -2
View File
@@ -5,7 +5,6 @@ block-obj-y += qed-check.o
block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
block-obj-y += quorum.o
block-obj-y += parallels.o blkdebug.o blkverify.o blkreplay.o
block-obj-y += blklogwrites.o
block-obj-y += block-backend.o snapshot.o qapi.o
block-obj-$(CONFIG_WIN32) += file-win32.o win32-aio.o
block-obj-$(CONFIG_POSIX) += file-posix.o
@@ -27,7 +26,7 @@ block-obj-y += accounting.o dirty-bitmap.o
block-obj-y += write-threshold.o
block-obj-y += backup.o
block-obj-$(CONFIG_REPLICATION) += replication.o
block-obj-y += throttle.o copy-on-read.o
block-obj-y += throttle.o
block-obj-y += crypto.o
+100 -169
View File
@@ -27,6 +27,7 @@
#include "qemu/error-report.h"
#define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16)
#define SLICE_TIME 100000000ULL /* ns */
typedef struct BackupBlockJob {
BlockJob common;
@@ -34,10 +35,10 @@ typedef struct BackupBlockJob {
/* bitmap for sync=incremental */
BdrvDirtyBitmap *sync_bitmap;
MirrorSyncMode sync_mode;
RateLimit limit;
BlockdevOnError on_source_error;
BlockdevOnError on_target_error;
CoRwlock flush_rwlock;
uint64_t len;
uint64_t bytes_read;
int64_t cluster_size;
bool compress;
@@ -45,14 +46,8 @@ typedef struct BackupBlockJob {
QLIST_HEAD(, CowRequest) inflight_reqs;
HBitmap *copy_bitmap;
bool use_copy_range;
int64_t copy_range_size;
bool serialize_target_writes;
} BackupBlockJob;
static const BlockJobDriver backup_job_driver;
/* See if in-flight requests overlap and wait for them to complete */
static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job,
int64_t start,
@@ -90,104 +85,19 @@ static void cow_request_end(CowRequest *req)
qemu_co_queue_restart_all(&req->wait_queue);
}
/* Copy range to target with a bounce buffer and return the bytes copied. If
* error occurred, return a negative error number */
static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
int64_t start,
int64_t end,
bool is_write_notifier,
bool *error_is_read,
void **bounce_buffer)
{
int ret;
struct iovec iov;
QEMUIOVector qiov;
BlockBackend *blk = job->common.blk;
int nbytes;
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1);
nbytes = MIN(job->cluster_size, job->len - start);
if (!*bounce_buffer) {
*bounce_buffer = blk_blockalign(blk, job->cluster_size);
}
iov.iov_base = *bounce_buffer;
iov.iov_len = nbytes;
qemu_iovec_init_external(&qiov, &iov, 1);
ret = blk_co_preadv(blk, start, qiov.size, &qiov, read_flags);
if (ret < 0) {
trace_backup_do_cow_read_fail(job, start, ret);
if (error_is_read) {
*error_is_read = true;
}
goto fail;
}
if (qemu_iovec_is_zero(&qiov)) {
ret = blk_co_pwrite_zeroes(job->target, start,
qiov.size, write_flags | BDRV_REQ_MAY_UNMAP);
} else {
ret = blk_co_pwritev(job->target, start,
qiov.size, &qiov, write_flags |
(job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
}
if (ret < 0) {
trace_backup_do_cow_write_fail(job, start, ret);
if (error_is_read) {
*error_is_read = false;
}
goto fail;
}
return nbytes;
fail:
hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1);
return ret;
}
/* Copy range to target and return the bytes copied. If error occurred, return a
* negative error number. */
static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
int64_t start,
int64_t end,
bool is_write_notifier)
{
int ret;
int nr_clusters;
BlockBackend *blk = job->common.blk;
int nbytes;
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size));
nbytes = MIN(job->copy_range_size, end - start);
nr_clusters = DIV_ROUND_UP(nbytes, job->cluster_size);
hbitmap_reset(job->copy_bitmap, start / job->cluster_size,
nr_clusters);
ret = blk_co_copy_range(blk, start, job->target, start, nbytes,
read_flags, write_flags);
if (ret < 0) {
trace_backup_do_cow_copy_range_fail(job, start, ret);
hbitmap_set(job->copy_bitmap, start / job->cluster_size,
nr_clusters);
return ret;
}
return nbytes;
}
static int coroutine_fn backup_do_cow(BackupBlockJob *job,
int64_t offset, uint64_t bytes,
bool *error_is_read,
bool is_write_notifier)
{
BlockBackend *blk = job->common.blk;
CowRequest cow_request;
struct iovec iov;
QEMUIOVector bounce_qiov;
void *bounce_buffer = NULL;
int ret = 0;
int64_t start, end; /* bytes */
void *bounce_buffer = NULL;
int n; /* bytes */
qemu_co_rwlock_rdlock(&job->flush_rwlock);
@@ -199,38 +109,60 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
wait_for_overlapping_requests(job, start, end);
cow_request_begin(&cow_request, job, start, end);
while (start < end) {
for (; start < end; start += job->cluster_size) {
if (!hbitmap_get(job->copy_bitmap, start / job->cluster_size)) {
trace_backup_do_cow_skip(job, start);
start += job->cluster_size;
continue; /* already copied */
}
hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1);
trace_backup_do_cow_process(job, start);
if (job->use_copy_range) {
ret = backup_cow_with_offload(job, start, end, is_write_notifier);
if (ret < 0) {
job->use_copy_range = false;
}
n = MIN(job->cluster_size, job->common.len - start);
if (!bounce_buffer) {
bounce_buffer = blk_blockalign(blk, job->cluster_size);
}
if (!job->use_copy_range) {
ret = backup_cow_with_bounce_buffer(job, start, end, is_write_notifier,
error_is_read, &bounce_buffer);
iov.iov_base = bounce_buffer;
iov.iov_len = n;
qemu_iovec_init_external(&bounce_qiov, &iov, 1);
ret = blk_co_preadv(blk, start, bounce_qiov.size, &bounce_qiov,
is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
if (ret < 0) {
trace_backup_do_cow_read_fail(job, start, ret);
if (error_is_read) {
*error_is_read = true;
}
hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1);
goto out;
}
if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
ret = blk_co_pwrite_zeroes(job->target, start,
bounce_qiov.size, BDRV_REQ_MAY_UNMAP);
} else {
ret = blk_co_pwritev(job->target, start,
bounce_qiov.size, &bounce_qiov,
job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
}
if (ret < 0) {
break;
trace_backup_do_cow_write_fail(job, start, ret);
if (error_is_read) {
*error_is_read = false;
}
hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1);
goto out;
}
/* Publish progress, guest I/O counts as progress too. Note that the
* offset field is an opaque progress value, it is not a disk offset.
*/
start += ret;
job->bytes_read += ret;
job_progress_update(&job->common.job, ret);
ret = 0;
job->bytes_read += n;
job->common.offset += n;
}
out:
if (bounce_buffer) {
qemu_vfree(bounce_buffer);
}
@@ -258,6 +190,17 @@ static int coroutine_fn backup_before_write_notify(
return backup_do_cow(job, req->offset, req->bytes, NULL, true);
}
static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)
{
BackupBlockJob *s = container_of(job, BackupBlockJob, common);
if (speed < 0) {
error_setg(errp, QERR_INVALID_PARAMETER, "speed");
return;
}
ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
}
static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
{
BdrvDirtyBitmap *bm;
@@ -274,25 +217,25 @@ static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
}
}
static void backup_commit(Job *job)
static void backup_commit(BlockJob *job)
{
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
BackupBlockJob *s = container_of(job, BackupBlockJob, common);
if (s->sync_bitmap) {
backup_cleanup_sync_bitmap(s, 0);
}
}
static void backup_abort(Job *job)
static void backup_abort(BlockJob *job)
{
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
BackupBlockJob *s = container_of(job, BackupBlockJob, common);
if (s->sync_bitmap) {
backup_cleanup_sync_bitmap(s, -1);
}
}
static void backup_clean(Job *job)
static void backup_clean(BlockJob *job)
{
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
BackupBlockJob *s = container_of(job, BackupBlockJob, common);
assert(s->target);
blk_unref(s->target);
s->target = NULL;
@@ -310,7 +253,7 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
int64_t len;
assert(block_job_driver(job) == &backup_job_driver);
assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP);
if (backup_job->sync_mode != MIRROR_SYNC_MODE_NONE) {
error_setg(errp, "The backup job only supports block checkpoint in"
@@ -318,7 +261,7 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
return;
}
len = DIV_ROUND_UP(backup_job->len, backup_job->cluster_size);
len = DIV_ROUND_UP(backup_job->common.len, backup_job->cluster_size);
hbitmap_set(backup_job->copy_bitmap, 0, len);
}
@@ -328,7 +271,7 @@ void backup_wait_for_overlapping_requests(BlockJob *job, int64_t offset,
BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
int64_t start, end;
assert(block_job_driver(job) == &backup_job_driver);
assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP);
start = QEMU_ALIGN_DOWN(offset, backup_job->cluster_size);
end = QEMU_ALIGN_UP(offset + bytes, backup_job->cluster_size);
@@ -341,7 +284,7 @@ void backup_cow_request_begin(CowRequest *req, BlockJob *job,
BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
int64_t start, end;
assert(block_job_driver(job) == &backup_job_driver);
assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP);
start = QEMU_ALIGN_DOWN(offset, backup_job->cluster_size);
end = QEMU_ALIGN_UP(offset + bytes, backup_job->cluster_size);
@@ -384,29 +327,33 @@ typedef struct {
int ret;
} BackupCompleteData;
static void backup_complete(Job *job, void *opaque)
static void backup_complete(BlockJob *job, void *opaque)
{
BackupCompleteData *data = opaque;
job_completed(job, data->ret, NULL);
block_job_completed(job, data->ret);
g_free(data);
}
static bool coroutine_fn yield_and_check(BackupBlockJob *job)
{
uint64_t delay_ns;
if (job_is_cancelled(&job->common.job)) {
if (block_job_is_cancelled(&job->common)) {
return true;
}
/* We need to yield even for delay_ns = 0 so that bdrv_drain_all() can
* return. Without a yield, the VM would not reboot. */
delay_ns = block_job_ratelimit_get_delay(&job->common, job->bytes_read);
job->bytes_read = 0;
job_sleep_ns(&job->common.job, delay_ns);
/* we need to yield so that bdrv_drain_all() returns.
* (without, VM does not reboot)
*/
if (job->common.speed) {
uint64_t delay_ns = ratelimit_calculate_delay(&job->limit,
job->bytes_read);
job->bytes_read = 0;
block_job_sleep_ns(&job->common, delay_ns);
} else {
block_job_sleep_ns(&job->common, 0);
}
if (job_is_cancelled(&job->common.job)) {
if (block_job_is_cancelled(&job->common)) {
return true;
}
@@ -421,7 +368,7 @@ static int coroutine_fn backup_run_incremental(BackupBlockJob *job)
HBitmapIter hbi;
hbitmap_iter_init(&hbi, job->copy_bitmap, 0);
while ((cluster = hbitmap_iter_next(&hbi, true)) != -1) {
while ((cluster = hbitmap_iter_next(&hbi)) != -1) {
do {
if (yield_and_check(job)) {
return 0;
@@ -473,9 +420,8 @@ static void backup_incremental_init_copy_bitmap(BackupBlockJob *job)
bdrv_set_dirty_iter(dbi, next_cluster * job->cluster_size);
}
/* TODO job_progress_set_remaining() would make more sense */
job_progress_update(&job->common.job,
job->len - hbitmap_count(job->copy_bitmap) * job->cluster_size);
job->common.offset = job->common.len -
hbitmap_count(job->copy_bitmap) * job->cluster_size;
bdrv_dirty_iter_free(dbi);
}
@@ -491,9 +437,7 @@ static void coroutine_fn backup_run(void *opaque)
QLIST_INIT(&job->inflight_reqs);
qemu_co_rwlock_init(&job->flush_rwlock);
nb_clusters = DIV_ROUND_UP(job->len, job->cluster_size);
job_progress_set_remaining(&job->common.job, job->len);
nb_clusters = DIV_ROUND_UP(job->common.len, job->cluster_size);
job->copy_bitmap = hbitmap_alloc(nb_clusters, 0);
if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
backup_incremental_init_copy_bitmap(job);
@@ -508,16 +452,16 @@ static void coroutine_fn backup_run(void *opaque)
if (job->sync_mode == MIRROR_SYNC_MODE_NONE) {
/* All bits are set in copy_bitmap to allow any cluster to be copied.
* This does not actually require them to be copied. */
while (!job_is_cancelled(&job->common.job)) {
while (!block_job_is_cancelled(&job->common)) {
/* Yield until the job is cancelled. We just let our before_write
* notify callback service CoW requests. */
job_yield(&job->common.job);
block_job_yield(&job->common);
}
} else if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
ret = backup_run_incremental(job);
} else {
/* Both FULL and TOP SYNC_MODE's require copying.. */
for (offset = 0; offset < job->len;
for (offset = 0; offset < job->common.len;
offset += job->cluster_size) {
bool error_is_read;
int alloced = 0;
@@ -586,21 +530,17 @@ static void coroutine_fn backup_run(void *opaque)
data = g_malloc(sizeof(*data));
data->ret = ret;
job_defer_to_main_loop(&job->common.job, backup_complete, data);
block_job_defer_to_main_loop(&job->common, backup_complete, data);
}
static const BlockJobDriver backup_job_driver = {
.job_driver = {
.instance_size = sizeof(BackupBlockJob),
.job_type = JOB_TYPE_BACKUP,
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.start = backup_run,
.commit = backup_commit,
.abort = backup_abort,
.clean = backup_clean,
},
.instance_size = sizeof(BackupBlockJob),
.job_type = BLOCK_JOB_TYPE_BACKUP,
.start = backup_run,
.set_speed = backup_set_speed,
.commit = backup_commit,
.abort = backup_abort,
.clean = backup_clean,
.attached_aio_context = backup_attached_aio_context,
.drain = backup_drain,
};
@@ -613,7 +553,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
BlockdevOnError on_target_error,
int creation_flags,
BlockCompletionFunc *cb, void *opaque,
JobTxn *txn, Error **errp)
BlockJobTxn *txn, Error **errp)
{
int64_t len;
BlockDriverInfo bdi;
@@ -680,7 +620,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
goto error;
}
/* job->len is fixed, so we can't allow resize */
/* job->common.len is fixed, so we can't allow resize */
job = block_job_create(job_id, &backup_job_driver, txn, bs,
BLK_PERM_CONSISTENT_READ,
BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
@@ -706,9 +646,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
sync_bitmap : NULL;
job->compress = compress;
/* Detect image-fleecing (and similar) schemes */
job->serialize_target_writes = bdrv_chain_contains(target, bs);
/* If there is no backing file on the target, we cannot rely on COW if our
* backup cluster size is smaller than the target cluster size. Even for
* targets with a backing file, try to avoid COW if possible. */
@@ -735,17 +672,11 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
} else {
job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
}
job->use_copy_range = true;
job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk),
blk_get_max_transfer(job->target));
job->copy_range_size = MAX(job->cluster_size,
QEMU_ALIGN_UP(job->copy_range_size,
job->cluster_size));
/* Required permissions are already taken with target's blk_new() */
block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
&error_abort);
job->len = len;
job->common.len = len;
return &job->common;
@@ -754,8 +685,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL);
}
if (job) {
backup_clean(&job->common.job);
job_early_fail(&job->common.job);
backup_clean(&job->common);
block_job_early_fail(&job->common);
}
return NULL;
+10 -10
View File
@@ -305,7 +305,7 @@ static void blkdebug_parse_filename(const char *filename, QDict *options,
if (c != filename) {
QString *config_path;
config_path = qstring_from_substr(filename, 0, c - filename);
config_path = qstring_from_substr(filename, 0, c - filename - 1);
qdict_put(options, "config", config_path);
}
@@ -398,11 +398,10 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
goto out;
}
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
bs->file->bs->supported_zero_flags);
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 */
@@ -625,7 +624,7 @@ static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
return err;
}
return bdrv_co_pdiscard(bs->file, offset, bytes);
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
}
static int coroutine_fn blkdebug_co_block_status(BlockDriverState *bs,
@@ -846,12 +845,13 @@ static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
opts = qdict_new();
qdict_put_str(opts, "driver", "blkdebug");
qdict_put(opts, "image", qobject_ref(bs->file->bs->full_open_options));
QINCREF(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")) {
qdict_put_obj(opts, qdict_entry_key(e),
qobject_ref(qdict_entry_value(e)));
qobject_incref(qdict_entry_value(e));
qdict_put_obj(opts, qdict_entry_key(e), qdict_entry_value(e));
}
}
-550
View File
@@ -1,550 +0,0 @@
/*
* Write logging blk driver based on blkverify and blkdebug.
*
* Copyright (c) 2017 Tuomas Tynkkynen <tuomas@tuxera.com>
* Copyright (c) 2018 Aapo Vienamo <aapo@tuxera.com>
* Copyright (c) 2018 Ari Sundholm <ari@tuxera.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
#include "block/block_int.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "qemu/cutils.h"
#include "qemu/option.h"
/* Disk format stuff - taken from Linux drivers/md/dm-log-writes.c */
#define LOG_FLUSH_FLAG (1 << 0)
#define LOG_FUA_FLAG (1 << 1)
#define LOG_DISCARD_FLAG (1 << 2)
#define LOG_MARK_FLAG (1 << 3)
#define LOG_FLAG_MASK (LOG_FLUSH_FLAG \
| LOG_FUA_FLAG \
| LOG_DISCARD_FLAG \
| LOG_MARK_FLAG)
#define WRITE_LOG_VERSION 1ULL
#define WRITE_LOG_MAGIC 0x6a736677736872ULL
/* All fields are little-endian. */
struct log_write_super {
uint64_t magic;
uint64_t version;
uint64_t nr_entries;
uint32_t sectorsize;
} QEMU_PACKED;
struct log_write_entry {
uint64_t sector;
uint64_t nr_sectors;
uint64_t flags;
uint64_t data_len;
} QEMU_PACKED;
/* End of disk format structures. */
typedef struct {
BdrvChild *log_file;
uint32_t sectorsize;
uint32_t sectorbits;
uint64_t cur_log_sector;
uint64_t nr_entries;
uint64_t update_interval;
} BDRVBlkLogWritesState;
static QemuOptsList runtime_opts = {
.name = "blklogwrites",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "log-append",
.type = QEMU_OPT_BOOL,
.help = "Append to an existing log",
},
{
.name = "log-sector-size",
.type = QEMU_OPT_SIZE,
.help = "Log sector size",
},
{
.name = "log-super-update-interval",
.type = QEMU_OPT_NUMBER,
.help = "Log superblock update interval (# of write requests)",
},
{ /* end of list */ }
},
};
static inline uint32_t blk_log_writes_log2(uint32_t value)
{
assert(value > 0);
return 31 - clz32(value);
}
static inline bool blk_log_writes_sector_size_valid(uint32_t sector_size)
{
return is_power_of_2(sector_size) &&
sector_size >= sizeof(struct log_write_super) &&
sector_size >= sizeof(struct log_write_entry) &&
sector_size < (1ull << 24);
}
static uint64_t blk_log_writes_find_cur_log_sector(BdrvChild *log,
uint32_t sector_size,
uint64_t nr_entries,
Error **errp)
{
uint64_t cur_sector = 1;
uint64_t cur_idx = 0;
uint32_t sector_bits = blk_log_writes_log2(sector_size);
struct log_write_entry cur_entry;
while (cur_idx < nr_entries) {
int read_ret = bdrv_pread(log, cur_sector << sector_bits, &cur_entry,
sizeof(cur_entry));
if (read_ret < 0) {
error_setg_errno(errp, -read_ret,
"Failed to read log entry %"PRIu64, cur_idx);
return (uint64_t)-1ull;
}
if (cur_entry.flags & ~cpu_to_le64(LOG_FLAG_MASK)) {
error_setg(errp, "Invalid flags 0x%"PRIx64" in log entry %"PRIu64,
le64_to_cpu(cur_entry.flags), cur_idx);
return (uint64_t)-1ull;
}
/* Account for the sector of the entry itself */
++cur_sector;
/*
* Account for the data of the write.
* For discards, this data is not present.
*/
if (!(cur_entry.flags & cpu_to_le64(LOG_DISCARD_FLAG))) {
cur_sector += le64_to_cpu(cur_entry.nr_sectors);
}
++cur_idx;
}
return cur_sector;
}
static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
BDRVBlkLogWritesState *s = bs->opaque;
QemuOpts *opts;
Error *local_err = NULL;
int ret;
uint64_t log_sector_size;
bool log_append;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
ret = -EINVAL;
error_propagate(errp, local_err);
goto fail;
}
/* Open the file */
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
&local_err);
if (local_err) {
ret = -EINVAL;
error_propagate(errp, local_err);
goto fail;
}
/* Open the log file */
s->log_file = bdrv_open_child(NULL, options, "log", bs, &child_file, false,
&local_err);
if (local_err) {
ret = -EINVAL;
error_propagate(errp, local_err);
goto fail;
}
log_append = qemu_opt_get_bool(opts, "log-append", false);
if (log_append) {
struct log_write_super log_sb = { 0, 0, 0, 0 };
if (qemu_opt_find(opts, "log-sector-size")) {
ret = -EINVAL;
error_setg(errp, "log-append and log-sector-size are mutually "
"exclusive");
goto fail_log;
}
/* Read log superblock or fake one for an empty log */
if (!bdrv_getlength(s->log_file->bs)) {
log_sb.magic = cpu_to_le64(WRITE_LOG_MAGIC);
log_sb.version = cpu_to_le64(WRITE_LOG_VERSION);
log_sb.nr_entries = cpu_to_le64(0);
log_sb.sectorsize = cpu_to_le32(BDRV_SECTOR_SIZE);
} else {
ret = bdrv_pread(s->log_file, 0, &log_sb, sizeof(log_sb));
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not read log superblock");
goto fail_log;
}
}
if (log_sb.magic != cpu_to_le64(WRITE_LOG_MAGIC)) {
ret = -EINVAL;
error_setg(errp, "Invalid log superblock magic");
goto fail_log;
}
if (log_sb.version != cpu_to_le64(WRITE_LOG_VERSION)) {
ret = -EINVAL;
error_setg(errp, "Unsupported log version %"PRIu64,
le64_to_cpu(log_sb.version));
goto fail_log;
}
log_sector_size = le32_to_cpu(log_sb.sectorsize);
s->cur_log_sector = 1;
s->nr_entries = 0;
if (blk_log_writes_sector_size_valid(log_sector_size)) {
s->cur_log_sector =
blk_log_writes_find_cur_log_sector(s->log_file, log_sector_size,
le64_to_cpu(log_sb.nr_entries), &local_err);
if (local_err) {
ret = -EINVAL;
error_propagate(errp, local_err);
goto fail_log;
}
s->nr_entries = le64_to_cpu(log_sb.nr_entries);
}
} else {
log_sector_size = qemu_opt_get_size(opts, "log-sector-size",
BDRV_SECTOR_SIZE);
s->cur_log_sector = 1;
s->nr_entries = 0;
}
if (!blk_log_writes_sector_size_valid(log_sector_size)) {
ret = -EINVAL;
error_setg(errp, "Invalid log sector size %"PRIu64, log_sector_size);
goto fail_log;
}
s->sectorsize = log_sector_size;
s->sectorbits = blk_log_writes_log2(log_sector_size);
s->update_interval = qemu_opt_get_number(opts, "log-super-update-interval",
4096);
if (!s->update_interval) {
ret = -EINVAL;
error_setg(errp, "Invalid log superblock update interval %"PRIu64,
s->update_interval);
goto fail_log;
}
ret = 0;
fail_log:
if (ret < 0) {
bdrv_unref_child(bs, s->log_file);
s->log_file = NULL;
}
fail:
if (ret < 0) {
bdrv_unref_child(bs, bs->file);
bs->file = NULL;
}
qemu_opts_del(opts);
return ret;
}
static void blk_log_writes_close(BlockDriverState *bs)
{
BDRVBlkLogWritesState *s = bs->opaque;
bdrv_unref_child(bs, s->log_file);
s->log_file = NULL;
}
static int64_t blk_log_writes_getlength(BlockDriverState *bs)
{
return bdrv_getlength(bs->file->bs);
}
static void blk_log_writes_refresh_filename(BlockDriverState *bs,
QDict *options)
{
BDRVBlkLogWritesState *s = bs->opaque;
/* bs->file->bs has already been refreshed */
bdrv_refresh_filename(s->log_file->bs);
if (bs->file->bs->full_open_options
&& s->log_file->bs->full_open_options)
{
QDict *opts = qdict_new();
qdict_put_str(opts, "driver", "blklogwrites");
qobject_ref(bs->file->bs->full_open_options);
qdict_put_obj(opts, "file", QOBJECT(bs->file->bs->full_open_options));
qobject_ref(s->log_file->bs->full_open_options);
qdict_put_obj(opts, "log",
QOBJECT(s->log_file->bs->full_open_options));
qdict_put_int(opts, "log-sector-size", s->sectorsize);
bs->full_open_options = opts;
}
}
static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *ro_q,
uint64_t perm, uint64_t shrd,
uint64_t *nperm, uint64_t *nshrd)
{
if (!c) {
*nperm = perm & DEFAULT_PERM_PASSTHROUGH;
*nshrd = (shrd & DEFAULT_PERM_PASSTHROUGH) | DEFAULT_PERM_UNCHANGED;
return;
}
if (!strcmp(c->name, "log")) {
bdrv_format_default_perms(bs, c, role, ro_q, perm, shrd, nperm, nshrd);
} else {
bdrv_filter_default_perms(bs, c, role, ro_q, perm, shrd, nperm, nshrd);
}
}
static void blk_log_writes_refresh_limits(BlockDriverState *bs, Error **errp)
{
BDRVBlkLogWritesState *s = bs->opaque;
bs->bl.request_alignment = s->sectorsize;
}
static int coroutine_fn
blk_log_writes_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags)
{
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
}
typedef struct BlkLogWritesFileReq {
BlockDriverState *bs;
uint64_t offset;
uint64_t bytes;
int file_flags;
QEMUIOVector *qiov;
int (*func)(struct BlkLogWritesFileReq *r);
int file_ret;
} BlkLogWritesFileReq;
typedef struct {
BlockDriverState *bs;
QEMUIOVector *qiov;
struct log_write_entry entry;
uint64_t zero_size;
int log_ret;
} BlkLogWritesLogReq;
static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
{
BDRVBlkLogWritesState *s = lr->bs->opaque;
uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
s->nr_entries++;
s->cur_log_sector +=
ROUND_UP(lr->qiov->size, s->sectorsize) >> s->sectorbits;
lr->log_ret = bdrv_co_pwritev(s->log_file, cur_log_offset, lr->qiov->size,
lr->qiov, 0);
/* Logging for the "write zeroes" operation */
if (lr->log_ret == 0 && lr->zero_size) {
cur_log_offset = s->cur_log_sector << s->sectorbits;
s->cur_log_sector +=
ROUND_UP(lr->zero_size, s->sectorsize) >> s->sectorbits;
lr->log_ret = bdrv_co_pwrite_zeroes(s->log_file, cur_log_offset,
lr->zero_size, 0);
}
/* Update super block on flush or every update interval */
if (lr->log_ret == 0 && ((lr->entry.flags & LOG_FLUSH_FLAG)
|| (s->nr_entries % s->update_interval == 0)))
{
struct log_write_super super = {
.magic = cpu_to_le64(WRITE_LOG_MAGIC),
.version = cpu_to_le64(WRITE_LOG_VERSION),
.nr_entries = cpu_to_le64(s->nr_entries),
.sectorsize = cpu_to_le32(s->sectorsize),
};
void *zeroes = g_malloc0(s->sectorsize - sizeof(super));
QEMUIOVector qiov;
qemu_iovec_init(&qiov, 2);
qemu_iovec_add(&qiov, &super, sizeof(super));
qemu_iovec_add(&qiov, zeroes, s->sectorsize - sizeof(super));
lr->log_ret =
bdrv_co_pwritev(s->log_file, 0, s->sectorsize, &qiov, 0);
if (lr->log_ret == 0) {
lr->log_ret = bdrv_co_flush(s->log_file->bs);
}
qemu_iovec_destroy(&qiov);
g_free(zeroes);
}
}
static void coroutine_fn blk_log_writes_co_do_file(BlkLogWritesFileReq *fr)
{
fr->file_ret = fr->func(fr);
}
static int coroutine_fn
blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
int (*file_func)(BlkLogWritesFileReq *r),
uint64_t entry_flags, bool is_zero_write)
{
QEMUIOVector log_qiov;
size_t niov = qiov ? qiov->niov : 0;
BDRVBlkLogWritesState *s = bs->opaque;
BlkLogWritesFileReq fr = {
.bs = bs,
.offset = offset,
.bytes = bytes,
.file_flags = flags,
.qiov = qiov,
.func = file_func,
};
BlkLogWritesLogReq lr = {
.bs = bs,
.qiov = &log_qiov,
.entry = {
.sector = cpu_to_le64(offset >> s->sectorbits),
.nr_sectors = cpu_to_le64(bytes >> s->sectorbits),
.flags = cpu_to_le64(entry_flags),
.data_len = 0,
},
.zero_size = is_zero_write ? bytes : 0,
};
void *zeroes = g_malloc0(s->sectorsize - sizeof(lr.entry));
assert((1 << s->sectorbits) == s->sectorsize);
assert(bs->bl.request_alignment == s->sectorsize);
assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
assert(QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment));
qemu_iovec_init(&log_qiov, niov + 2);
qemu_iovec_add(&log_qiov, &lr.entry, sizeof(lr.entry));
qemu_iovec_add(&log_qiov, zeroes, s->sectorsize - sizeof(lr.entry));
if (qiov) {
qemu_iovec_concat(&log_qiov, qiov, 0, qiov->size);
}
blk_log_writes_co_do_file(&fr);
blk_log_writes_co_do_log(&lr);
qemu_iovec_destroy(&log_qiov);
g_free(zeroes);
if (lr.log_ret < 0) {
return lr.log_ret;
}
return fr.file_ret;
}
static int coroutine_fn
blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr)
{
return bdrv_co_pwritev(fr->bs->file, fr->offset, fr->bytes,
fr->qiov, fr->file_flags);
}
static int coroutine_fn
blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr)
{
return bdrv_co_pwrite_zeroes(fr->bs->file, fr->offset, fr->bytes,
fr->file_flags);
}
static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
{
return bdrv_co_flush(fr->bs->file->bs);
}
static int coroutine_fn
blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
{
return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
}
static int coroutine_fn
blk_log_writes_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags)
{
return blk_log_writes_co_log(bs, offset, bytes, qiov, flags,
blk_log_writes_co_do_file_pwritev, 0, false);
}
static int coroutine_fn
blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes,
BdrvRequestFlags flags)
{
return blk_log_writes_co_log(bs, offset, bytes, NULL, flags,
blk_log_writes_co_do_file_pwrite_zeroes, 0,
true);
}
static int coroutine_fn blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
{
return blk_log_writes_co_log(bs, 0, 0, NULL, 0,
blk_log_writes_co_do_file_flush,
LOG_FLUSH_FLAG, false);
}
static int coroutine_fn
blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int count)
{
return blk_log_writes_co_log(bs, offset, count, NULL, 0,
blk_log_writes_co_do_file_pdiscard,
LOG_DISCARD_FLAG, false);
}
static BlockDriver bdrv_blk_log_writes = {
.format_name = "blklogwrites",
.instance_size = sizeof(BDRVBlkLogWritesState),
.bdrv_open = blk_log_writes_open,
.bdrv_close = blk_log_writes_close,
.bdrv_getlength = blk_log_writes_getlength,
.bdrv_refresh_filename = blk_log_writes_refresh_filename,
.bdrv_child_perm = blk_log_writes_child_perm,
.bdrv_refresh_limits = blk_log_writes_refresh_limits,
.bdrv_co_preadv = blk_log_writes_co_preadv,
.bdrv_co_pwritev = blk_log_writes_co_pwritev,
.bdrv_co_pwrite_zeroes = blk_log_writes_co_pwrite_zeroes,
.bdrv_co_flush_to_disk = blk_log_writes_co_flush_to_disk,
.bdrv_co_pdiscard = blk_log_writes_co_pdiscard,
.bdrv_co_block_status = bdrv_co_block_status_from_file,
.is_filter = true,
};
static void bdrv_blk_log_writes_init(void)
{
bdrv_register(&bdrv_blk_log_writes);
}
block_init(bdrv_blk_log_writes_init);
+1 -4
View File
@@ -35,9 +35,6 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED;
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED;
ret = 0;
fail:
return ret;
@@ -113,7 +110,7 @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
int64_t offset, int bytes)
{
uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_pdiscard(bs->file, offset, bytes);
int ret = bdrv_co_pdiscard(bs->file->bs, offset, bytes);
block_request_create(reqid, bs, qemu_coroutine_self());
qemu_coroutine_yield();
+5 -8
View File
@@ -80,7 +80,7 @@ static void blkverify_parse_filename(const char *filename, QDict *options,
}
/* TODO Implement option pass-through and set raw.filename here */
raw_path = qstring_from_substr(filename, 0, c - filename);
raw_path = qstring_from_substr(filename, 0, c - filename - 1);
qdict_put(options, "x-raw", raw_path);
/* TODO Allow multi-level nesting and set file.filename here */
@@ -141,9 +141,6 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED;
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED;
ret = 0;
fail:
qemu_opts_del(opts);
@@ -294,10 +291,10 @@ static void blkverify_refresh_filename(BlockDriverState *bs, QDict *options)
QDict *opts = qdict_new();
qdict_put_str(opts, "driver", "blkverify");
qdict_put(opts, "raw",
qobject_ref(bs->file->bs->full_open_options));
qdict_put(opts, "test",
qobject_ref(s->test_file->bs->full_open_options));
QINCREF(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(opts, "test", s->test_file->bs->full_open_options);
bs->full_open_options = opts;
}
+8 -26
View File
@@ -768,11 +768,6 @@ void blk_remove_bs(BlockBackend *blk)
blk_update_root_state(blk);
/* bdrv_root_unref_child() will cause blk->root to become stale and may
* switch to a completion coroutine later on. Let's drain all I/O here
* to avoid that and a potential QEMU crash.
*/
blk_drain(blk);
bdrv_root_unref_child(blk->root);
blk->root = NULL;
}
@@ -1560,7 +1555,7 @@ int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
return ret;
}
return bdrv_co_pdiscard(blk->root, offset, bytes);
return bdrv_co_pdiscard(blk_bs(blk), offset, bytes);
}
int blk_co_flush(BlockBackend *blk)
@@ -1870,7 +1865,13 @@ void blk_op_unblock_all(BlockBackend *blk, Error *reason)
AioContext *blk_get_aio_context(BlockBackend *blk)
{
return bdrv_get_aio_context(blk_bs(blk));
BlockDriverState *bs = blk_bs(blk);
if (bs) {
return bdrv_get_aio_context(bs);
} else {
return qemu_get_aio_context();
}
}
static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
@@ -2216,22 +2217,3 @@ void blk_unregister_buf(BlockBackend *blk, void *host)
{
bdrv_unregister_buf(blk_bs(blk), host);
}
int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
BlockBackend *blk_out, int64_t off_out,
int bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
int r;
r = blk_check_byte_request(blk_in, off_in, bytes);
if (r) {
return r;
}
r = blk_check_byte_request(blk_out, off_out, bytes);
if (r) {
return r;
}
return bdrv_co_copy_range(blk_in->root, off_in,
blk_out->root, off_out,
bytes, read_flags, write_flags);
}
+42 -33
View File
@@ -31,8 +31,11 @@ enum {
COMMIT_BUFFER_SIZE = 512 * 1024, /* in bytes */
};
#define SLICE_TIME 100000000ULL /* ns */
typedef struct CommitBlockJob {
BlockJob common;
RateLimit limit;
BlockDriverState *commit_top_bs;
BlockBackend *top;
BlockBackend *base;
@@ -72,10 +75,9 @@ typedef struct {
int ret;
} CommitCompleteData;
static void commit_complete(Job *job, void *opaque)
static void commit_complete(BlockJob *job, void *opaque)
{
CommitBlockJob *s = container_of(job, CommitBlockJob, common.job);
BlockJob *bjob = &s->common;
CommitBlockJob *s = container_of(job, CommitBlockJob, common);
CommitCompleteData *data = opaque;
BlockDriverState *top = blk_bs(s->top);
BlockDriverState *base = blk_bs(s->base);
@@ -91,7 +93,7 @@ static void commit_complete(Job *job, void *opaque)
* the normal backing chain can be restored. */
blk_unref(s->base);
if (!job_is_cancelled(job) && ret == 0) {
if (!block_job_is_cancelled(&s->common) && ret == 0) {
/* success */
ret = bdrv_drop_intermediate(s->commit_top_bs, base,
s->backing_file_str);
@@ -112,12 +114,12 @@ static void commit_complete(Job *job, void *opaque)
blk_unref(s->top);
/* If there is more than one reference to the job (e.g. if called from
* job_finish_sync()), 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(bjob);
* 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);
job_completed(job, ret, NULL);
block_job_completed(&s->common, ret);
g_free(data);
/* If bdrv_drop_intermediate() didn't already do that, remove the commit
@@ -144,21 +146,21 @@ static void coroutine_fn commit_run(void *opaque)
int64_t n = 0; /* bytes */
void *buf = NULL;
int bytes_written = 0;
int64_t len, base_len;
int64_t base_len;
ret = len = blk_getlength(s->top);
if (len < 0) {
ret = s->common.len = blk_getlength(s->top);
if (s->common.len < 0) {
goto out;
}
job_progress_set_remaining(&s->common.job, len);
ret = base_len = blk_getlength(s->base);
if (base_len < 0) {
goto out;
}
if (base_len < len) {
ret = blk_truncate(s->base, len, PREALLOC_MODE_OFF, NULL);
if (base_len < s->common.len) {
ret = blk_truncate(s->base, s->common.len, PREALLOC_MODE_OFF, NULL);
if (ret) {
goto out;
}
@@ -166,14 +168,14 @@ static void coroutine_fn commit_run(void *opaque)
buf = blk_blockalign(s->top, COMMIT_BUFFER_SIZE);
for (offset = 0; offset < len; offset += n) {
for (offset = 0; offset < s->common.len; offset += n) {
bool copy;
/* Note that even when no rate limit is applied we need to yield
* with no pending I/O here so that bdrv_drain_all() returns.
*/
job_sleep_ns(&s->common.job, delay_ns);
if (job_is_cancelled(&s->common.job)) {
block_job_sleep_ns(&s->common, delay_ns);
if (block_job_is_cancelled(&s->common)) {
break;
}
/* Copy if allocated above the base */
@@ -196,10 +198,10 @@ static void coroutine_fn commit_run(void *opaque)
}
}
/* Publish progress */
job_progress_update(&s->common.job, n);
s->common.offset += n;
if (copy) {
delay_ns = block_job_ratelimit_get_delay(&s->common, n);
if (copy && s->common.speed) {
delay_ns = ratelimit_calculate_delay(&s->limit, n);
} else {
delay_ns = 0;
}
@@ -212,18 +214,25 @@ out:
data = g_malloc(sizeof(*data));
data->ret = ret;
job_defer_to_main_loop(&s->common.job, commit_complete, data);
block_job_defer_to_main_loop(&s->common, commit_complete, data);
}
static void commit_set_speed(BlockJob *job, int64_t speed, Error **errp)
{
CommitBlockJob *s = container_of(job, CommitBlockJob, common);
if (speed < 0) {
error_setg(errp, QERR_INVALID_PARAMETER, "speed");
return;
}
ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
}
static const BlockJobDriver commit_job_driver = {
.job_driver = {
.instance_size = sizeof(CommitBlockJob),
.job_type = JOB_TYPE_COMMIT,
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.start = commit_run,
},
.instance_size = sizeof(CommitBlockJob),
.job_type = BLOCK_JOB_TYPE_COMMIT,
.set_speed = commit_set_speed,
.start = commit_run,
};
static int coroutine_fn bdrv_commit_top_preadv(BlockDriverState *bs,
@@ -283,7 +292,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
}
s = block_job_create(job_id, &commit_job_driver, NULL, bs, 0, BLK_PERM_ALL,
speed, JOB_DEFAULT, NULL, NULL, errp);
speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);
if (!s) {
return;
}
@@ -373,7 +382,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
s->on_error = on_error;
trace_commit_start(bs, base, top, s);
job_start(&s->common.job);
block_job_start(&s->common);
return;
fail:
@@ -386,7 +395,7 @@ fail:
if (commit_top_bs) {
bdrv_replace_node(commit_top_bs, top, &error_abort);
}
job_early_fail(&s->common.job);
block_job_early_fail(&s->common);
}
-173
View File
@@ -1,173 +0,0 @@
/*
* Copy-on-read filter block driver
*
* Copyright (c) 2018 Red Hat, Inc.
*
* Author:
* Max Reitz <mreitz@redhat.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 or
* (at your option) version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "block/block_int.h"
static int cor_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
errp);
if (!bs->file) {
return -EINVAL;
}
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
(BDRV_REQ_FUA &
bs->file->bs->supported_write_flags);
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
bs->file->bs->supported_zero_flags);
return 0;
}
static void cor_close(BlockDriverState *bs)
{
}
#define PERM_PASSTHROUGH (BLK_PERM_CONSISTENT_READ \
| BLK_PERM_WRITE \
| BLK_PERM_RESIZE)
#define PERM_UNCHANGED (BLK_PERM_ALL & ~PERM_PASSTHROUGH)
static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{
if (c == NULL) {
*nperm = (perm & PERM_PASSTHROUGH) | BLK_PERM_WRITE_UNCHANGED;
*nshared = (shared & PERM_PASSTHROUGH) | PERM_UNCHANGED;
return;
}
*nperm = (perm & PERM_PASSTHROUGH) |
(c->perm & PERM_UNCHANGED);
*nshared = (shared & PERM_PASSTHROUGH) |
(c->shared_perm & PERM_UNCHANGED);
}
static int64_t cor_getlength(BlockDriverState *bs)
{
return bdrv_getlength(bs->file->bs);
}
static int coroutine_fn cor_co_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
return bdrv_co_truncate(bs->file, offset, prealloc, errp);
}
static int coroutine_fn cor_co_preadv(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags)
{
return bdrv_co_preadv(bs->file, offset, bytes, qiov,
flags | BDRV_REQ_COPY_ON_READ);
}
static int coroutine_fn cor_co_pwritev(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags)
{
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
}
static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int bytes,
BdrvRequestFlags flags)
{
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs,
int64_t offset, int bytes)
{
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
static void cor_eject(BlockDriverState *bs, bool eject_flag)
{
bdrv_eject(bs->file->bs, eject_flag);
}
static void cor_lock_medium(BlockDriverState *bs, bool locked)
{
bdrv_lock_medium(bs->file->bs, locked);
}
static bool cor_recurse_is_first_non_filter(BlockDriverState *bs,
BlockDriverState *candidate)
{
return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
}
BlockDriver bdrv_copy_on_read = {
.format_name = "copy-on-read",
.bdrv_open = cor_open,
.bdrv_close = cor_close,
.bdrv_child_perm = cor_child_perm,
.bdrv_getlength = cor_getlength,
.bdrv_co_truncate = cor_co_truncate,
.bdrv_co_preadv = cor_co_preadv,
.bdrv_co_pwritev = cor_co_pwritev,
.bdrv_co_pwrite_zeroes = cor_co_pwrite_zeroes,
.bdrv_co_pdiscard = cor_co_pdiscard,
.bdrv_eject = cor_eject,
.bdrv_lock_medium = cor_lock_medium,
.bdrv_co_block_status = bdrv_co_block_status_from_file,
.bdrv_recurse_is_first_non_filter = cor_recurse_is_first_non_filter,
.has_variable_length = true,
.is_filter = true,
};
static void bdrv_copy_on_read_init(void)
{
bdrv_register(&bdrv_copy_on_read);
}
block_init(bdrv_copy_on_read_init);
+21 -46
View File
@@ -24,51 +24,28 @@
#include "qemu/osdep.h"
#include "block/block_int.h"
#include "qemu/job.h"
#include "qapi/qapi-commands-block-core.h"
#include "qapi/qapi-visit-block-core.h"
#include "qapi/clone-visitor.h"
#include "qapi/error.h"
typedef struct BlockdevCreateJob {
Job common;
typedef struct BlockdevCreateCo {
BlockDriver *drv;
BlockdevCreateOptions *opts;
int ret;
Error *err;
} BlockdevCreateJob;
Error **errp;
} BlockdevCreateCo;
static void blockdev_create_complete(Job *job, void *opaque)
static void coroutine_fn bdrv_co_create_co_entry(void *opaque)
{
BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
job_completed(job, s->ret, s->err);
BlockdevCreateCo *cco = opaque;
cco->ret = cco->drv->bdrv_co_create(cco->opts, cco->errp);
}
static void coroutine_fn blockdev_create_run(void *opaque)
void qmp_x_blockdev_create(BlockdevCreateOptions *options, Error **errp)
{
BlockdevCreateJob *s = opaque;
job_progress_set_remaining(&s->common, 1);
s->ret = s->drv->bdrv_co_create(s->opts, &s->err);
job_progress_update(&s->common, 1);
qapi_free_BlockdevCreateOptions(s->opts);
job_defer_to_main_loop(&s->common, blockdev_create_complete, NULL);
}
static const JobDriver blockdev_create_job_driver = {
.instance_size = sizeof(BlockdevCreateJob),
.job_type = JOB_TYPE_CREATE,
.start = blockdev_create_run,
};
void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
Error **errp)
{
BlockdevCreateJob *s;
const char *fmt = BlockdevDriver_str(options->driver);
BlockDriver *drv = bdrv_find_format(fmt);
Coroutine *co;
BlockdevCreateCo cco;
/* If the driver is in the schema, we know that it exists. But it may not
* be whitelisted. */
@@ -78,24 +55,22 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
return;
}
/* Error out if the driver doesn't support .bdrv_co_create */
/* Call callback if it exists */
if (!drv->bdrv_co_create) {
error_setg(errp, "Driver does not support blockdev-create");
return;
}
/* Create the block job */
/* TODO Running in the main context. Block drivers need to error out or add
* locking when they use a BDS in a different AioContext. */
s = job_create(job_id, &blockdev_create_job_driver, NULL,
qemu_get_aio_context(), JOB_DEFAULT | JOB_MANUAL_DISMISS,
NULL, NULL, errp);
if (!s) {
return;
cco = (BlockdevCreateCo) {
.drv = drv,
.opts = options,
.ret = -EINPROGRESS,
.errp = errp,
};
co = qemu_coroutine_create(bdrv_co_create_co_entry, &cco);
qemu_coroutine_enter(co);
while (cco.ret == -EINPROGRESS) {
aio_poll(qemu_get_aio_context(), true);
}
s->drv = drv,
s->opts = QAPI_CLONE(BlockdevCreateOptions, options),
job_start(&s->common);
}
+90 -26
View File
@@ -21,15 +21,15 @@
#include "qemu/osdep.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "crypto/block.h"
#include "qapi/opts-visitor.h"
#include "qapi/qapi-visit-crypto.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/error.h"
#include "qemu/option.h"
#include "crypto.h"
#include "block/crypto.h"
typedef struct BlockCrypto BlockCrypto;
@@ -148,36 +148,102 @@ static QemuOptsList block_crypto_create_opts_luks = {
QCryptoBlockOpenOptions *
block_crypto_open_opts_init(QDict *opts, Error **errp)
block_crypto_open_opts_init(QCryptoBlockFormat format,
QDict *opts,
Error **errp)
{
Visitor *v;
QCryptoBlockOpenOptions *ret;
QCryptoBlockOpenOptions *ret = NULL;
Error *local_err = NULL;
v = qobject_input_visitor_new_flat_confused(opts, errp);
if (!v) {
return NULL;
ret = g_new0(QCryptoBlockOpenOptions, 1);
ret->format = format;
v = qobject_input_visitor_new_keyval(QOBJECT(opts));
visit_start_struct(v, NULL, NULL, 0, &local_err);
if (local_err) {
goto out;
}
visit_type_QCryptoBlockOpenOptions(v, NULL, &ret, errp);
switch (format) {
case Q_CRYPTO_BLOCK_FORMAT_LUKS:
visit_type_QCryptoBlockOptionsLUKS_members(
v, &ret->u.luks, &local_err);
break;
case Q_CRYPTO_BLOCK_FORMAT_QCOW:
visit_type_QCryptoBlockOptionsQCow_members(
v, &ret->u.qcow, &local_err);
break;
default:
error_setg(&local_err, "Unsupported block format %d", format);
break;
}
if (!local_err) {
visit_check_struct(v, &local_err);
}
visit_end_struct(v, NULL);
out:
if (local_err) {
error_propagate(errp, local_err);
qapi_free_QCryptoBlockOpenOptions(ret);
ret = NULL;
}
visit_free(v);
return ret;
}
QCryptoBlockCreateOptions *
block_crypto_create_opts_init(QDict *opts, Error **errp)
block_crypto_create_opts_init(QCryptoBlockFormat format,
QDict *opts,
Error **errp)
{
Visitor *v;
QCryptoBlockCreateOptions *ret;
QCryptoBlockCreateOptions *ret = NULL;
Error *local_err = NULL;
v = qobject_input_visitor_new_flat_confused(opts, errp);
if (!v) {
return NULL;
ret = g_new0(QCryptoBlockCreateOptions, 1);
ret->format = format;
v = qobject_input_visitor_new_keyval(QOBJECT(opts));
visit_start_struct(v, NULL, NULL, 0, &local_err);
if (local_err) {
goto out;
}
visit_type_QCryptoBlockCreateOptions(v, NULL, &ret, errp);
switch (format) {
case Q_CRYPTO_BLOCK_FORMAT_LUKS:
visit_type_QCryptoBlockCreateOptionsLUKS_members(
v, &ret->u.luks, &local_err);
break;
case Q_CRYPTO_BLOCK_FORMAT_QCOW:
visit_type_QCryptoBlockOptionsQCow_members(
v, &ret->u.qcow, &local_err);
break;
default:
error_setg(&local_err, "Unsupported block format %d", format);
break;
}
if (!local_err) {
visit_check_struct(v, &local_err);
}
visit_end_struct(v, NULL);
out:
if (local_err) {
error_propagate(errp, local_err);
qapi_free_QCryptoBlockCreateOptions(ret);
ret = NULL;
}
visit_free(v);
return ret;
}
@@ -215,9 +281,8 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
}
cryptoopts = qemu_opts_to_qdict(opts, NULL);
qdict_put_str(cryptoopts, "format", QCryptoBlockFormat_str(format));
open_opts = block_crypto_open_opts_init(cryptoopts, errp);
open_opts = block_crypto_open_opts_init(format, cryptoopts, errp);
if (!open_opts) {
goto cleanup;
}
@@ -240,7 +305,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
ret = 0;
cleanup:
qobject_unref(cryptoopts);
QDECREF(cryptoopts);
qapi_free_QCryptoBlockOpenOptions(open_opts);
return ret;
}
@@ -286,9 +351,8 @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
return ret;
}
static int coroutine_fn
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
static int block_crypto_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
BlockCrypto *crypto = bs->opaque;
uint64_t payload_offset =
@@ -301,7 +365,7 @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset,
offset += payload_offset;
return bdrv_co_truncate(bs->file, offset, prealloc, errp);
return bdrv_truncate(bs->file, offset, prealloc, errp);
}
static void block_crypto_close(BlockDriverState *bs)
@@ -541,8 +605,8 @@ static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename,
&block_crypto_create_opts_luks,
true);
qdict_put_str(cryptoopts, "format", "luks");
create_opts = block_crypto_create_opts_init(cryptoopts, errp);
create_opts = block_crypto_create_opts_init(Q_CRYPTO_BLOCK_FORMAT_LUKS,
cryptoopts, errp);
if (!create_opts) {
ret = -EINVAL;
goto fail;
@@ -551,7 +615,7 @@ static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename,
/* Create protocol layer */
ret = bdrv_create_file(filename, opts, errp);
if (ret < 0) {
goto fail;
return ret;
}
bs = bdrv_open(filename, NULL, NULL,
@@ -571,7 +635,7 @@ static int coroutine_fn block_crypto_co_create_opts_luks(const char *filename,
fail:
bdrv_unref(bs);
qapi_free_QCryptoBlockCreateOptions(create_opts);
qobject_unref(cryptoopts);
QDECREF(cryptoopts);
return ret;
}
@@ -630,7 +694,7 @@ BlockDriver bdrv_crypto_luks = {
.bdrv_child_perm = bdrv_format_default_perms,
.bdrv_co_create = block_crypto_co_create_luks,
.bdrv_co_create_opts = block_crypto_co_create_opts_luks,
.bdrv_co_truncate = block_crypto_co_truncate,
.bdrv_truncate = block_crypto_truncate,
.create_opts = &block_crypto_create_opts_luks,
.bdrv_reopen_prepare = block_crypto_reopen_prepare,
+6 -2
View File
@@ -89,9 +89,13 @@
}
QCryptoBlockCreateOptions *
block_crypto_create_opts_init(QDict *opts, Error **errp);
block_crypto_create_opts_init(QCryptoBlockFormat format,
QDict *opts,
Error **errp);
QCryptoBlockOpenOptions *
block_crypto_open_opts_init(QDict *opts, Error **errp);
block_crypto_open_opts_init(QCryptoBlockFormat format,
QDict *opts,
Error **errp);
#endif /* BLOCK_CRYPTO_H__ */
+1 -1
View File
@@ -804,7 +804,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
}
/* Prior CURL 7.19.4 return value of 0 could mean that the file size is not
* know or the size is zero. From 7.19.4 CURL returns -1 if size is not
* known and zero if it is really zero-length file. */
* known and zero if it is realy zero-length file. */
#if LIBCURL_VERSION_NUM >= 0x071304
if (d < 0) {
pstrcpy(state->errmsg, CURL_ERROR_SIZE,
+67 -119
View File
@@ -97,6 +97,15 @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)
return NULL;
}
/* Called with BQL taken. */
void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
{
assert(!bdrv_dirty_bitmap_frozen(bitmap));
g_free(bitmap->name);
bitmap->name = NULL;
bitmap->persistent = false;
}
/* Called with BQL taken. */
BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
uint32_t granularity,
@@ -241,31 +250,57 @@ int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
return 0;
}
void bdrv_enable_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
{
assert(!bdrv_dirty_bitmap_frozen(bitmap));
bitmap->disabled = false;
}
/* Called with BQL taken. */
void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap)
{
assert(bitmap->mutex == bitmap->successor->mutex);
qemu_mutex_lock(bitmap->mutex);
bdrv_enable_dirty_bitmap_locked(bitmap->successor);
bdrv_enable_dirty_bitmap(bitmap->successor);
qemu_mutex_unlock(bitmap->mutex);
}
/* Called within bdrv_dirty_bitmap_lock..unlock and with BQL taken. */
static void bdrv_release_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap)
/* Called within bdrv_dirty_bitmap_lock..unlock */
static void bdrv_do_release_matching_dirty_bitmap_locked(
BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
bool (*cond)(BdrvDirtyBitmap *bitmap))
{
assert(!bitmap->active_iterators);
assert(!bdrv_dirty_bitmap_frozen(bitmap));
assert(!bitmap->meta);
QLIST_REMOVE(bitmap, list);
hbitmap_free(bitmap->bitmap);
g_free(bitmap->name);
g_free(bitmap);
BdrvDirtyBitmap *bm, *next;
QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
if ((!bitmap || bm == bitmap) && (!cond || cond(bm))) {
assert(!bm->active_iterators);
assert(!bdrv_dirty_bitmap_frozen(bm));
assert(!bm->meta);
QLIST_REMOVE(bm, list);
hbitmap_free(bm->bitmap);
g_free(bm->name);
g_free(bm);
if (bitmap) {
return;
}
}
}
if (bitmap) {
abort();
}
}
/* Called with BQL taken. */
static void bdrv_do_release_matching_dirty_bitmap(
BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
bool (*cond)(BdrvDirtyBitmap *bitmap))
{
bdrv_dirty_bitmaps_lock(bs);
bdrv_do_release_matching_dirty_bitmap_locked(bs, bitmap, cond);
bdrv_dirty_bitmaps_unlock(bs);
}
/* Called within bdrv_dirty_bitmap_lock..unlock */
static void bdrv_release_dirty_bitmap_locked(BlockDriverState *bs,
BdrvDirtyBitmap *bitmap)
{
bdrv_do_release_matching_dirty_bitmap_locked(bs, bitmap, NULL);
}
/**
@@ -318,7 +353,7 @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BlockDriverState *bs,
error_setg(errp, "Merging of parent and successor bitmap failed");
return NULL;
}
bdrv_release_dirty_bitmap_locked(successor);
bdrv_release_dirty_bitmap_locked(bs, successor);
parent->successor = NULL;
return parent;
@@ -356,12 +391,15 @@ void bdrv_dirty_bitmap_truncate(BlockDriverState *bs, int64_t bytes)
bdrv_dirty_bitmaps_unlock(bs);
}
static bool bdrv_dirty_bitmap_has_name(BdrvDirtyBitmap *bitmap)
{
return !!bdrv_dirty_bitmap_name(bitmap);
}
/* Called with BQL taken. */
void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
{
bdrv_dirty_bitmaps_lock(bs);
bdrv_release_dirty_bitmap_locked(bitmap);
bdrv_dirty_bitmaps_unlock(bs);
bdrv_do_release_matching_dirty_bitmap(bs, bitmap, NULL);
}
/**
@@ -372,15 +410,7 @@ void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)
*/
void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
{
BdrvDirtyBitmap *bm, *next;
bdrv_dirty_bitmaps_lock(bs);
QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
if (bdrv_dirty_bitmap_name(bm)) {
bdrv_release_dirty_bitmap_locked(bm);
}
}
bdrv_dirty_bitmaps_unlock(bs);
bdrv_do_release_matching_dirty_bitmap(bs, NULL, bdrv_dirty_bitmap_has_name);
}
/**
@@ -388,19 +418,11 @@ void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
* bdrv_inactivate_recurse()).
* There must not be any frozen bitmaps attached.
* This function does not remove persistent bitmaps from the storage.
* Called with BQL taken.
*/
void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
{
BdrvDirtyBitmap *bm, *next;
bdrv_dirty_bitmaps_lock(bs);
QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
if (bdrv_dirty_bitmap_get_persistance(bm)) {
bdrv_release_dirty_bitmap_locked(bm);
}
}
bdrv_dirty_bitmaps_unlock(bs);
bdrv_do_release_matching_dirty_bitmap(bs, NULL,
bdrv_dirty_bitmap_get_persistance);
}
/**
@@ -420,19 +442,18 @@ void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
}
}
/* Called with BQL taken. */
void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
{
bdrv_dirty_bitmap_lock(bitmap);
assert(!bdrv_dirty_bitmap_frozen(bitmap));
bitmap->disabled = true;
bdrv_dirty_bitmap_unlock(bitmap);
}
/* Called with BQL taken. */
void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
{
bdrv_dirty_bitmap_lock(bitmap);
bdrv_enable_dirty_bitmap_locked(bitmap);
bdrv_dirty_bitmap_unlock(bitmap);
assert(!bdrv_dirty_bitmap_frozen(bitmap));
bitmap->disabled = false;
}
BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
@@ -525,62 +546,7 @@ void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)
int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
{
return hbitmap_iter_next(&iter->hbi, true);
}
/**
* Return the next consecutively dirty area in the dirty bitmap
* belonging to the given iterator @iter.
*
* @max_offset: Maximum value that may be returned for
* *offset + *bytes
* @offset: Will contain the start offset of the next dirty area
* @bytes: Will contain the length of the next dirty area
*
* Returns: True if a dirty area could be found before max_offset
* (which means that *offset and *bytes then contain valid
* values), false otherwise.
*
* Note that @iter is never advanced if false is returned. If an area
* is found (which means that true is returned), it will be advanced
* past that area.
*/
bool bdrv_dirty_iter_next_area(BdrvDirtyBitmapIter *iter, uint64_t max_offset,
uint64_t *offset, int *bytes)
{
uint32_t granularity = bdrv_dirty_bitmap_granularity(iter->bitmap);
uint64_t gran_max_offset;
int64_t ret;
int size;
if (max_offset == iter->bitmap->size) {
/* If max_offset points to the image end, round it up by the
* bitmap granularity */
gran_max_offset = ROUND_UP(max_offset, granularity);
} else {
gran_max_offset = max_offset;
}
ret = hbitmap_iter_next(&iter->hbi, false);
if (ret < 0 || ret + granularity > gran_max_offset) {
return false;
}
*offset = ret;
size = 0;
assert(granularity <= INT_MAX);
do {
/* Advance iterator */
ret = hbitmap_iter_next(&iter->hbi, true);
size += granularity;
} while (ret + granularity <= gran_max_offset &&
hbitmap_iter_next(&iter->hbi, false) == ret + granularity &&
size <= INT_MAX - granularity);
*bytes = MIN(size, max_offset - *offset);
return true;
return hbitmap_iter_next(&iter->hbi);
}
/* Called within bdrv_dirty_bitmap_lock..unlock */
@@ -789,21 +755,3 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, uint64_t offset)
{
return hbitmap_next_zero(bitmap->bitmap, offset);
}
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
Error **errp)
{
/* only bitmaps from one bds are supported */
assert(dest->mutex == src->mutex);
qemu_mutex_lock(dest->mutex);
assert(bdrv_dirty_bitmap_enabled(dest));
assert(!bdrv_dirty_bitmap_readonly(dest));
if (!hbitmap_merge(dest->bitmap, src->bitmap)) {
error_setg(errp, "Bitmaps are incompatible and can't be merged");
}
qemu_mutex_unlock(dest->mutex);
}
+277 -654
View File
File diff suppressed because it is too large. Load diff
+22 -33
View File
@@ -162,7 +162,7 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
acb->aio_nbytes = count;
acb->aio_offset = offset;
trace_file_paio_submit(acb, opaque, offset, count, type);
trace_paio_submit(acb, opaque, offset, count, type);
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
}
@@ -251,11 +251,7 @@ static void raw_probe_alignment(BlockDriverState *bs, Error **errp)
&dg.Geometry.BytesPerSector,
&freeClusters, &totalClusters);
bs->bl.request_alignment = dg.Geometry.BytesPerSector;
return;
}
/* XXX Does Windows support AIO on less than 512-byte alignment? */
bs->bl.request_alignment = 512;
}
static void raw_parse_flags(int flags, bool use_aio, int *access_flags,
@@ -414,32 +410,32 @@ fail:
return ret;
}
static BlockAIOCB *raw_aio_preadv(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
BlockCompletionFunc *cb, void *opaque)
static BlockAIOCB *raw_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
BDRVRawState *s = bs->opaque;
if (s->aio) {
return win32_aio_submit(bs, s->aio, s->hfile, offset, bytes, qiov,
cb, opaque, QEMU_AIO_READ);
return win32_aio_submit(bs, s->aio, s->hfile, sector_num, qiov,
nb_sectors, cb, opaque, QEMU_AIO_READ);
} else {
return paio_submit(bs, s->hfile, offset, qiov, bytes,
return paio_submit(bs, s->hfile, sector_num << BDRV_SECTOR_BITS, qiov,
nb_sectors << BDRV_SECTOR_BITS,
cb, opaque, QEMU_AIO_READ);
}
}
static BlockAIOCB *raw_aio_pwritev(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
BlockCompletionFunc *cb, void *opaque)
static BlockAIOCB *raw_aio_writev(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
BDRVRawState *s = bs->opaque;
if (s->aio) {
return win32_aio_submit(bs, s->aio, s->hfile, offset, bytes, qiov,
cb, opaque, QEMU_AIO_WRITE);
return win32_aio_submit(bs, s->aio, s->hfile, sector_num, qiov,
nb_sectors, cb, opaque, QEMU_AIO_WRITE);
} else {
return paio_submit(bs, s->hfile, offset, qiov, bytes,
return paio_submit(bs, s->hfile, sector_num << BDRV_SECTOR_BITS, qiov,
nb_sectors << BDRV_SECTOR_BITS,
cb, opaque, QEMU_AIO_WRITE);
}
}
@@ -467,8 +463,8 @@ static void raw_close(BlockDriverState *bs)
}
}
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
static int raw_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
BDRVRawState *s = bs->opaque;
LONG low, high;
@@ -636,11 +632,11 @@ BlockDriver bdrv_file = {
.bdrv_co_create_opts = raw_co_create_opts,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_aio_preadv = raw_aio_preadv,
.bdrv_aio_pwritev = raw_aio_pwritev,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_co_truncate = raw_co_truncate,
.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
@@ -712,12 +708,6 @@ static void hdev_parse_filename(const char *filename, QDict *options,
bdrv_parse_filename_strip_prefix(filename, "host_device:", options);
}
static void hdev_refresh_limits(BlockDriverState *bs, Error **errp)
{
/* XXX Does Windows support AIO on less than 512-byte alignment? */
bs->bl.request_alignment = 512;
}
static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
@@ -803,10 +793,9 @@ static BlockDriver bdrv_host_device = {
.bdrv_probe_device = hdev_probe_device,
.bdrv_file_open = hdev_open,
.bdrv_close = raw_close,
.bdrv_refresh_limits = hdev_refresh_limits,
.bdrv_aio_preadv = raw_aio_preadv,
.bdrv_aio_pwritev = raw_aio_pwritev,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_detach_aio_context = raw_detach_aio_context,
+10 -15
View File
@@ -11,7 +11,6 @@
#include "qemu/osdep.h"
#include <glusterfs/api/glfs.h>
#include "block/block_int.h"
#include "block/qdict.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
@@ -651,7 +650,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
}
gsconf = NULL;
qobject_unref(backing_options);
QDECREF(backing_options);
backing_options = NULL;
g_free(str);
str = NULL;
@@ -664,7 +663,7 @@ out:
qapi_free_SocketAddress(gsconf);
qemu_opts_del(opts);
g_free(str);
qobject_unref(backing_options);
QDECREF(backing_options);
errno = EINVAL;
return -errno;
}
@@ -1177,10 +1176,8 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
return acb.ret;
}
static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
int64_t offset,
PreallocMode prealloc,
Error **errp)
static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
BDRVGlusterState *s = bs->opaque;
return qemu_gluster_do_truncate(s->fd, offset, prealloc, errp);
@@ -1197,10 +1194,8 @@ static coroutine_fn int qemu_gluster_co_readv(BlockDriverState *bs,
static coroutine_fn int qemu_gluster_co_writev(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors,
QEMUIOVector *qiov,
int flags)
QEMUIOVector *qiov)
{
assert(!flags);
return qemu_gluster_co_rw(bs, sector_num, nb_sectors, qiov, 1);
}
@@ -1326,7 +1321,7 @@ static int qemu_gluster_has_zero_init(BlockDriverState *bs)
* If @start is in a trailing hole or beyond EOF, return -ENXIO.
* If we can't find out, return a negative errno other than -ENXIO.
*
* (Shamefully copied from file-posix.c, only minuscule adaptions.)
* (Shamefully copied from file-posix.c, only miniscule adaptions.)
*/
static int find_allocation(BlockDriverState *bs, off_t start,
off_t *data, off_t *hole)
@@ -1501,7 +1496,7 @@ static BlockDriver bdrv_gluster = {
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
.bdrv_getlength = qemu_gluster_getlength,
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
.bdrv_co_truncate = qemu_gluster_co_truncate,
.bdrv_truncate = qemu_gluster_truncate,
.bdrv_co_readv = qemu_gluster_co_readv,
.bdrv_co_writev = qemu_gluster_co_writev,
.bdrv_co_flush_to_disk = qemu_gluster_co_flush_to_disk,
@@ -1530,7 +1525,7 @@ static BlockDriver bdrv_gluster_tcp = {
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
.bdrv_getlength = qemu_gluster_getlength,
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
.bdrv_co_truncate = qemu_gluster_co_truncate,
.bdrv_truncate = qemu_gluster_truncate,
.bdrv_co_readv = qemu_gluster_co_readv,
.bdrv_co_writev = qemu_gluster_co_writev,
.bdrv_co_flush_to_disk = qemu_gluster_co_flush_to_disk,
@@ -1559,7 +1554,7 @@ static BlockDriver bdrv_gluster_unix = {
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
.bdrv_getlength = qemu_gluster_getlength,
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
.bdrv_co_truncate = qemu_gluster_co_truncate,
.bdrv_truncate = qemu_gluster_truncate,
.bdrv_co_readv = qemu_gluster_co_readv,
.bdrv_co_writev = qemu_gluster_co_writev,
.bdrv_co_flush_to_disk = qemu_gluster_co_flush_to_disk,
@@ -1594,7 +1589,7 @@ static BlockDriver bdrv_gluster_rdma = {
.bdrv_co_create_opts = qemu_gluster_co_create_opts,
.bdrv_getlength = qemu_gluster_getlength,
.bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size,
.bdrv_co_truncate = qemu_gluster_co_truncate,
.bdrv_truncate = qemu_gluster_truncate,
.bdrv_co_readv = qemu_gluster_co_readv,
.bdrv_co_writev = qemu_gluster_co_writev,
.bdrv_co_flush_to_disk = qemu_gluster_co_flush_to_disk,
+237 -649
View File
File diff suppressed because it is too large. Load diff
+67 -295
View File
@@ -33,7 +33,6 @@
#include "qemu/bitops.h"
#include "qemu/bitmap.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "scsi/constants.h"
#include "qemu/iov.h"
#include "qemu/option.h"
@@ -44,7 +43,6 @@
#include "qapi/qmp/qstring.h"
#include "crypto/secret.h"
#include "scsi/utils.h"
#include "trace.h"
/* Conflict between scsi/utils.h and libiscsi! :( */
#define SCSI_XFER_NONE ISCSI_XFER_NONE
@@ -70,7 +68,6 @@ typedef struct IscsiLun {
QemuMutex mutex;
struct scsi_inquiry_logical_block_provisioning lbp;
struct scsi_inquiry_block_limits bl;
struct scsi_inquiry_device_designator *dd;
unsigned char *zeroblock;
/* The allocmap tracks which clusters (pages) on the iSCSI target are
* allocated and which are not. In case a target returns zeros for
@@ -558,20 +555,9 @@ static inline bool iscsi_allocmap_is_valid(IscsiLun *iscsilun,
offset / iscsilun->cluster_size) == size);
}
static void coroutine_fn iscsi_co_wait_for_task(IscsiTask *iTask,
IscsiLun *iscsilun)
{
while (!iTask->complete) {
iscsi_set_events(iscsilun);
qemu_mutex_unlock(&iscsilun->mutex);
qemu_coroutine_yield();
qemu_mutex_lock(&iscsilun->mutex);
}
}
static int coroutine_fn
iscsi_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *iov, int flags)
iscsi_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *iov, int flags)
{
IscsiLun *iscsilun = bs->opaque;
struct IscsiTask iTask;
@@ -630,7 +616,12 @@ retry:
scsi_task_set_iov_out(iTask.task, (struct scsi_iovec *) iov->iov,
iov->niov);
#endif
iscsi_co_wait_for_task(&iTask, iscsilun);
while (!iTask.complete) {
iscsi_set_events(iscsilun);
qemu_mutex_unlock(&iscsilun->mutex);
qemu_coroutine_yield();
qemu_mutex_lock(&iscsilun->mutex);
}
if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task);
@@ -701,7 +692,13 @@ retry:
ret = -ENOMEM;
goto out_unlock;
}
iscsi_co_wait_for_task(&iTask, iscsilun);
while (!iTask.complete) {
iscsi_set_events(iscsilun);
qemu_mutex_unlock(&iscsilun->mutex);
qemu_coroutine_yield();
qemu_mutex_lock(&iscsilun->mutex);
}
if (iTask.do_retry) {
if (iTask.task != NULL) {
@@ -865,8 +862,13 @@ retry:
#if LIBISCSI_API_VERSION < (20160603)
scsi_task_set_iov_in(iTask.task, (struct scsi_iovec *) iov->iov, iov->niov);
#endif
while (!iTask.complete) {
iscsi_set_events(iscsilun);
qemu_mutex_unlock(&iscsilun->mutex);
qemu_coroutine_yield();
qemu_mutex_lock(&iscsilun->mutex);
}
iscsi_co_wait_for_task(&iTask, iscsilun);
if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task);
iTask.task = NULL;
@@ -903,7 +905,12 @@ retry:
return -ENOMEM;
}
iscsi_co_wait_for_task(&iTask, iscsilun);
while (!iTask.complete) {
iscsi_set_events(iscsilun);
qemu_mutex_unlock(&iscsilun->mutex);
qemu_coroutine_yield();
qemu_mutex_lock(&iscsilun->mutex);
}
if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task);
@@ -1135,7 +1142,12 @@ retry:
goto out_unlock;
}
iscsi_co_wait_for_task(&iTask, iscsilun);
while (!iTask.complete) {
iscsi_set_events(iscsilun);
qemu_mutex_unlock(&iscsilun->mutex);
qemu_coroutine_yield();
qemu_mutex_lock(&iscsilun->mutex);
}
if (iTask.task != NULL) {
scsi_free_scsi_task(iTask.task);
@@ -1231,7 +1243,12 @@ retry:
return -ENOMEM;
}
iscsi_co_wait_for_task(&iTask, iscsilun);
while (!iTask.complete) {
iscsi_set_events(iscsilun);
qemu_mutex_unlock(&iscsilun->mutex);
qemu_coroutine_yield();
qemu_mutex_lock(&iscsilun->mutex);
}
if (iTask.status == SCSI_STATUS_CHECK_CONDITION &&
iTask.task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST &&
@@ -1715,34 +1732,14 @@ static QemuOptsList runtime_opts = {
.name = "timeout",
.type = QEMU_OPT_NUMBER,
},
{
.name = "filename",
.type = QEMU_OPT_STRING,
},
{ /* end of list */ }
},
};
static void iscsi_save_designator(IscsiLun *lun,
struct scsi_inquiry_device_identification *inq_di)
{
struct scsi_inquiry_device_designator *desig, *copy = NULL;
for (desig = inq_di->designators; desig; desig = desig->next) {
if (desig->association ||
desig->designator_type > SCSI_DESIGNATOR_TYPE_NAA) {
continue;
}
/* NAA works better than T10 vendor ID based designator. */
if (!copy || copy->designator_type < desig->designator_type) {
copy = desig;
}
}
if (copy) {
lun->dd = g_new(struct scsi_inquiry_device_designator, 1);
*lun->dd = *copy;
lun->dd->next = NULL;
lun->dd->designator = g_malloc(copy->designator_length);
memcpy(lun->dd->designator, copy->designator, copy->designator_length);
}
}
static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
@@ -1754,12 +1751,27 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
char *initiator_name = NULL;
QemuOpts *opts;
Error *local_err = NULL;
const char *transport_name, *portal, *target;
const char *transport_name, *portal, *target, *filename;
#if LIBISCSI_API_VERSION >= (20160603)
enum iscsi_transport_type transport;
#endif
int i, ret = 0, timeout = 0, lun;
/* If we are given a filename, parse the filename, with precedence given to
* filename encoded options */
filename = qdict_get_try_str(options, "filename");
if (filename) {
warn_report("'filename' option specified. "
"This is an unsupported option, and may be deprecated "
"in the future");
iscsi_parse_filename(filename, options, &local_err);
if (local_err) {
ret = -EINVAL;
error_propagate(errp, local_err);
goto exit;
}
}
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
@@ -1910,7 +1922,6 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
struct scsi_task *inq_task;
struct scsi_inquiry_logical_block_provisioning *inq_lbp;
struct scsi_inquiry_block_limits *inq_bl;
struct scsi_inquiry_device_identification *inq_di;
switch (inq_vpd->pages[i]) {
case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
@@ -1936,17 +1947,6 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
sizeof(struct scsi_inquiry_block_limits));
scsi_free_scsi_task(inq_task);
break;
case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION:
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION,
(void **) &inq_di, errp);
if (inq_task == NULL) {
ret = -EINVAL;
goto out;
}
iscsi_save_designator(iscsilun, inq_di);
scsi_free_scsi_task(inq_task);
break;
default:
break;
}
@@ -1989,7 +1989,7 @@ out:
}
memset(iscsilun, 0, sizeof(IscsiLun));
}
exit:
return ret;
}
@@ -2003,10 +2003,6 @@ static void iscsi_close(BlockDriverState *bs)
iscsi_logout_sync(iscsi);
}
iscsi_destroy_context(iscsi);
if (iscsilun->dd) {
g_free(iscsilun->dd->designator);
g_free(iscsilun->dd);
}
g_free(iscsilun->zeroblock);
iscsi_allocmap_free(iscsilun);
qemu_mutex_destroy(&iscsilun->mutex);
@@ -2086,8 +2082,8 @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
}
}
static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
static int iscsi_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
IscsiLun *iscsilun = bs->opaque;
Error *local_err = NULL;
@@ -2147,7 +2143,7 @@ static int coroutine_fn iscsi_co_create_opts(const char *filename, QemuOpts *opt
} else {
ret = iscsi_open(bs, bs_options, 0, NULL);
}
qobject_unref(bs_options);
QDECREF(bs_options);
if (ret != 0) {
goto out;
@@ -2188,226 +2184,6 @@ static void coroutine_fn iscsi_co_invalidate_cache(BlockDriverState *bs,
iscsi_allocmap_invalidate(iscsilun);
}
static int coroutine_fn iscsi_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src,
uint64_t src_offset,
BdrvChild *dst,
uint64_t dst_offset,
uint64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags);
}
static struct scsi_task *iscsi_xcopy_task(int param_len)
{
struct scsi_task *task;
task = g_new0(struct scsi_task, 1);
task->cdb[0] = EXTENDED_COPY;
task->cdb[10] = (param_len >> 24) & 0xFF;
task->cdb[11] = (param_len >> 16) & 0xFF;
task->cdb[12] = (param_len >> 8) & 0xFF;
task->cdb[13] = param_len & 0xFF;
task->cdb_size = 16;
task->xfer_dir = SCSI_XFER_WRITE;
task->expxferlen = param_len;
return task;
}
static void iscsi_populate_target_desc(unsigned char *desc, IscsiLun *lun)
{
struct scsi_inquiry_device_designator *dd = lun->dd;
memset(desc, 0, 32);
desc[0] = 0xE4; /* IDENT_DESCR_TGT_DESCR */
desc[4] = dd->code_set;
desc[5] = (dd->designator_type & 0xF)
| ((dd->association & 3) << 4);
desc[7] = dd->designator_length;
memcpy(desc + 8, dd->designator, MIN(dd->designator_length, 20));
desc[28] = 0;
desc[29] = (lun->block_size >> 16) & 0xFF;
desc[30] = (lun->block_size >> 8) & 0xFF;
desc[31] = lun->block_size & 0xFF;
}
static void iscsi_xcopy_desc_hdr(uint8_t *hdr, int dc, int cat, int src_index,
int dst_index)
{
hdr[0] = 0x02; /* BLK_TO_BLK_SEG_DESCR */
hdr[1] = ((dc << 1) | cat) & 0xFF;
hdr[2] = (XCOPY_BLK2BLK_SEG_DESC_SIZE >> 8) & 0xFF;
/* don't account for the first 4 bytes in descriptor header*/
hdr[3] = (XCOPY_BLK2BLK_SEG_DESC_SIZE - 4 /* SEG_DESC_SRC_INDEX_OFFSET */) & 0xFF;
hdr[4] = (src_index >> 8) & 0xFF;
hdr[5] = src_index & 0xFF;
hdr[6] = (dst_index >> 8) & 0xFF;
hdr[7] = dst_index & 0xFF;
}
static void iscsi_xcopy_populate_desc(uint8_t *desc, int dc, int cat,
int src_index, int dst_index, int num_blks,
uint64_t src_lba, uint64_t dst_lba)
{
iscsi_xcopy_desc_hdr(desc, dc, cat, src_index, dst_index);
/* The caller should verify the request size */
assert(num_blks < 65536);
desc[10] = (num_blks >> 8) & 0xFF;
desc[11] = num_blks & 0xFF;
desc[12] = (src_lba >> 56) & 0xFF;
desc[13] = (src_lba >> 48) & 0xFF;
desc[14] = (src_lba >> 40) & 0xFF;
desc[15] = (src_lba >> 32) & 0xFF;
desc[16] = (src_lba >> 24) & 0xFF;
desc[17] = (src_lba >> 16) & 0xFF;
desc[18] = (src_lba >> 8) & 0xFF;
desc[19] = src_lba & 0xFF;
desc[20] = (dst_lba >> 56) & 0xFF;
desc[21] = (dst_lba >> 48) & 0xFF;
desc[22] = (dst_lba >> 40) & 0xFF;
desc[23] = (dst_lba >> 32) & 0xFF;
desc[24] = (dst_lba >> 24) & 0xFF;
desc[25] = (dst_lba >> 16) & 0xFF;
desc[26] = (dst_lba >> 8) & 0xFF;
desc[27] = dst_lba & 0xFF;
}
static void iscsi_xcopy_populate_header(unsigned char *buf, int list_id, int str,
int list_id_usage, int prio,
int tgt_desc_len,
int seg_desc_len, int inline_data_len)
{
buf[0] = list_id;
buf[1] = ((str & 1) << 5) | ((list_id_usage & 3) << 3) | (prio & 7);
buf[2] = (tgt_desc_len >> 8) & 0xFF;
buf[3] = tgt_desc_len & 0xFF;
buf[8] = (seg_desc_len >> 24) & 0xFF;
buf[9] = (seg_desc_len >> 16) & 0xFF;
buf[10] = (seg_desc_len >> 8) & 0xFF;
buf[11] = seg_desc_len & 0xFF;
buf[12] = (inline_data_len >> 24) & 0xFF;
buf[13] = (inline_data_len >> 16) & 0xFF;
buf[14] = (inline_data_len >> 8) & 0xFF;
buf[15] = inline_data_len & 0xFF;
}
static void iscsi_xcopy_data(struct iscsi_data *data,
IscsiLun *src, int64_t src_lba,
IscsiLun *dst, int64_t dst_lba,
uint16_t num_blocks)
{
uint8_t *buf;
const int src_offset = XCOPY_DESC_OFFSET;
const int dst_offset = XCOPY_DESC_OFFSET + IDENT_DESCR_TGT_DESCR_SIZE;
const int seg_offset = dst_offset + IDENT_DESCR_TGT_DESCR_SIZE;
data->size = XCOPY_DESC_OFFSET +
IDENT_DESCR_TGT_DESCR_SIZE * 2 +
XCOPY_BLK2BLK_SEG_DESC_SIZE;
data->data = g_malloc0(data->size);
buf = data->data;
/* Initialise the parameter list header */
iscsi_xcopy_populate_header(buf, 1, 0, 2 /* LIST_ID_USAGE_DISCARD */,
0, 2 * IDENT_DESCR_TGT_DESCR_SIZE,
XCOPY_BLK2BLK_SEG_DESC_SIZE,
0);
/* Initialise CSCD list with one src + one dst descriptor */
iscsi_populate_target_desc(&buf[src_offset], src);
iscsi_populate_target_desc(&buf[dst_offset], dst);
/* Initialise one segment descriptor */
iscsi_xcopy_populate_desc(&buf[seg_offset], 0, 0, 0, 1, num_blocks,
src_lba, dst_lba);
}
static int coroutine_fn iscsi_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src,
uint64_t src_offset,
BdrvChild *dst,
uint64_t dst_offset,
uint64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
IscsiLun *dst_lun = dst->bs->opaque;
IscsiLun *src_lun;
struct IscsiTask iscsi_task;
struct iscsi_data data;
int r = 0;
int block_size;
if (src->bs->drv->bdrv_co_copy_range_to != iscsi_co_copy_range_to) {
return -ENOTSUP;
}
src_lun = src->bs->opaque;
if (!src_lun->dd || !dst_lun->dd) {
return -ENOTSUP;
}
if (!is_byte_request_lun_aligned(dst_offset, bytes, dst_lun)) {
return -ENOTSUP;
}
if (!is_byte_request_lun_aligned(src_offset, bytes, src_lun)) {
return -ENOTSUP;
}
if (dst_lun->block_size != src_lun->block_size ||
!dst_lun->block_size) {
return -ENOTSUP;
}
block_size = dst_lun->block_size;
if (bytes / block_size > 65535) {
return -ENOTSUP;
}
iscsi_xcopy_data(&data,
src_lun, src_offset / block_size,
dst_lun, dst_offset / block_size,
bytes / block_size);
iscsi_co_init_iscsitask(dst_lun, &iscsi_task);
qemu_mutex_lock(&dst_lun->mutex);
iscsi_task.task = iscsi_xcopy_task(data.size);
retry:
if (iscsi_scsi_command_async(dst_lun->iscsi, dst_lun->lun,
iscsi_task.task, iscsi_co_generic_cb,
&data,
&iscsi_task) != 0) {
r = -EIO;
goto out_unlock;
}
iscsi_co_wait_for_task(&iscsi_task, dst_lun);
if (iscsi_task.do_retry) {
iscsi_task.complete = 0;
goto retry;
}
if (iscsi_task.status != SCSI_STATUS_GOOD) {
r = iscsi_task.err_code;
goto out_unlock;
}
out_unlock:
trace_iscsi_xcopy(src_lun, src_offset, dst_lun, dst_offset, bytes, r);
g_free(iscsi_task.task);
qemu_mutex_unlock(&dst_lun->mutex);
g_free(iscsi_task.err_str);
return r;
}
static QemuOptsList iscsi_create_opts = {
.name = "iscsi-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(iscsi_create_opts.head),
@@ -2437,16 +2213,14 @@ static BlockDriver bdrv_iscsi = {
.bdrv_getlength = iscsi_getlength,
.bdrv_get_info = iscsi_get_info,
.bdrv_co_truncate = iscsi_co_truncate,
.bdrv_truncate = iscsi_truncate,
.bdrv_refresh_limits = iscsi_refresh_limits,
.bdrv_co_block_status = iscsi_co_block_status,
.bdrv_co_pdiscard = iscsi_co_pdiscard,
.bdrv_co_copy_range_from = iscsi_co_copy_range_from,
.bdrv_co_copy_range_to = iscsi_co_copy_range_to,
.bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes,
.bdrv_co_readv = iscsi_co_readv,
.bdrv_co_writev = iscsi_co_writev,
.bdrv_co_writev_flags = iscsi_co_writev_flags,
.bdrv_co_flush_to_disk = iscsi_co_flush,
#ifdef __linux__
@@ -2474,16 +2248,14 @@ static BlockDriver bdrv_iser = {
.bdrv_getlength = iscsi_getlength,
.bdrv_get_info = iscsi_get_info,
.bdrv_co_truncate = iscsi_co_truncate,
.bdrv_truncate = iscsi_truncate,
.bdrv_refresh_limits = iscsi_refresh_limits,
.bdrv_co_block_status = iscsi_co_block_status,
.bdrv_co_pdiscard = iscsi_co_pdiscard,
.bdrv_co_copy_range_from = iscsi_co_copy_range_from,
.bdrv_co_copy_range_to = iscsi_co_copy_range_to,
.bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes,
.bdrv_co_readv = iscsi_co_readv,
.bdrv_co_writev = iscsi_co_writev,
.bdrv_co_writev_flags = iscsi_co_writev_flags,
.bdrv_co_flush_to_disk = iscsi_co_flush,
#ifdef __linux__
+3 -9
View File
@@ -15,7 +15,6 @@
#include "block/raw-aio.h"
#include "qemu/event_notifier.h"
#include "qemu/coroutine.h"
#include "qapi/error.h"
#include <libaio.h>
@@ -471,21 +470,16 @@ void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context)
qemu_laio_poll_cb);
}
LinuxAioState *laio_init(Error **errp)
LinuxAioState *laio_init(void)
{
int rc;
LinuxAioState *s;
s = g_malloc0(sizeof(*s));
rc = event_notifier_init(&s->e, false);
if (rc < 0) {
error_setg_errno(errp, -rc, "failed to to initialize event notifier");
if (event_notifier_init(&s->e, false) < 0) {
goto out_free_state;
}
rc = io_setup(MAX_EVENTS, &s->ctx);
if (rc < 0) {
error_setg_errno(errp, -rc, "failed to create linux AIO context");
if (io_setup(MAX_EVENTS, &s->ctx) != 0) {
goto out_close_efd;
}
+197 -567
View File
File diff suppressed because it is too large. Load diff
-3
View File
@@ -970,7 +970,6 @@ int nbd_client_init(BlockDriverState *bs,
const char *export,
QCryptoTLSCreds *tlscreds,
const char *hostname,
const char *x_dirty_bitmap,
Error **errp)
{
NBDClientSession *client = nbd_get_client_session(bs);
@@ -983,11 +982,9 @@ int nbd_client_init(BlockDriverState *bs,
client->info.request_sizes = true;
client->info.structured_reply = true;
client->info.base_allocation = true;
client->info.x_dirty_bitmap = g_strdup(x_dirty_bitmap);
ret = nbd_receive_negotiate(QIO_CHANNEL(sioc), export,
tlscreds, hostname,
&client->ioc, &client->info, errp);
g_free(client->info.x_dirty_bitmap);
if (ret < 0) {
logout("Failed to negotiate with the NBD server\n");
return ret;
-1
View File
@@ -45,7 +45,6 @@ int nbd_client_init(BlockDriverState *bs,
const char *export_name,
QCryptoTLSCreds *tlscreds,
const char *hostname,
const char *x_dirty_bitmap,
Error **errp);
void nbd_client_close(BlockDriverState *bs);
+18 -14
View File
@@ -27,8 +27,7 @@
*/
#include "qemu/osdep.h"
#include "nbd-client.h"
#include "block/qdict.h"
#include "block/nbd-client.h"
#include "qapi/error.h"
#include "qemu/uri.h"
#include "block/block_int.h"
@@ -109,7 +108,7 @@ static int nbd_parse_uri(const char *filename, QDict *options)
/* strip braces from literal IPv6 address */
if (uri->server[0] == '[') {
host = qstring_from_substr(uri->server, 1,
strlen(uri->server) - 1);
strlen(uri->server) - 2);
} else {
host = qstring_from_str(uri->server);
}
@@ -263,6 +262,7 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options,
{
SocketAddress *saddr = NULL;
QDict *addr = NULL;
QObject *crumpled_addr = NULL;
Visitor *iv = NULL;
Error *local_err = NULL;
@@ -272,11 +272,20 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options,
goto done;
}
iv = qobject_input_visitor_new_flat_confused(addr, errp);
if (!iv) {
crumpled_addr = qdict_crumple(addr, errp);
if (!crumpled_addr) {
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);
if (local_err) {
error_propagate(errp, local_err);
@@ -284,7 +293,8 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options,
}
done:
qobject_unref(addr);
QDECREF(addr);
qobject_decref(crumpled_addr);
visit_free(iv);
return saddr;
}
@@ -378,12 +388,6 @@ static QemuOptsList nbd_runtime_opts = {
.type = QEMU_OPT_STRING,
.help = "ID of the TLS credentials to use",
},
{
.name = "x-dirty-bitmap",
.type = QEMU_OPT_STRING,
.help = "experimental: expose named dirty bitmap in place of "
"block status",
},
{ /* end of list */ }
},
};
@@ -444,8 +448,8 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
}
/* NBD handshake */
ret = nbd_client_init(bs, sioc, s->export, tlscreds, hostname,
qemu_opt_get(opts, "x-dirty-bitmap"), errp);
ret = nbd_client_init(bs, sioc, s->export,
tlscreds, hostname, errp);
error:
if (sioc) {
object_unref(OBJECT(sioc));
+9 -9
View File
@@ -29,7 +29,6 @@
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "trace.h"
#include "qemu/iov.h"
#include "qemu/option.h"
@@ -556,20 +555,22 @@ static BlockdevOptionsNfs *nfs_options_qdict_to_qapi(QDict *options,
Error **errp)
{
BlockdevOptionsNfs *opts = NULL;
QObject *crumpled = NULL;
Visitor *v;
const QDictEntry *e;
Error *local_err = NULL;
v = qobject_input_visitor_new_flat_confused(options, errp);
if (!v) {
crumpled = qdict_crumple(options, errp);
if (crumpled == NULL) {
return NULL;
}
v = qobject_input_visitor_new_keyval(crumpled);
visit_type_BlockdevOptionsNfs(v, NULL, &opts, &local_err);
visit_free(v);
qobject_decref(crumpled);
if (local_err) {
error_propagate(errp, local_err);
return NULL;
}
@@ -689,7 +690,7 @@ static int coroutine_fn nfs_file_co_create_opts(const char *url, QemuOpts *opts,
ret = 0;
out:
qobject_unref(options);
QDECREF(options);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
@@ -743,9 +744,8 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
}
static int coroutine_fn
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
static int nfs_file_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
NFSClient *client = bs->opaque;
int ret;
@@ -874,7 +874,7 @@ static BlockDriver bdrv_nfs = {
.bdrv_has_zero_init = nfs_has_zero_init,
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
.bdrv_co_truncate = nfs_file_co_truncate,
.bdrv_truncate = nfs_file_truncate,
.bdrv_file_open = nfs_file_open,
.bdrv_close = nfs_file_close,
+24 -24
View File
@@ -93,7 +93,6 @@ static int null_file_open(BlockDriverState *bs, QDict *options, int flags,
}
s->read_zeroes = qemu_opt_get_bool(opts, NULL_OPT_ZEROES, false);
qemu_opts_del(opts);
bs->supported_write_flags = BDRV_REQ_FUA;
return ret;
}
@@ -117,22 +116,22 @@ static coroutine_fn int null_co_common(BlockDriverState *bs)
return 0;
}
static coroutine_fn int null_co_preadv(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags)
static coroutine_fn int null_co_readv(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
{
BDRVNullState *s = bs->opaque;
if (s->read_zeroes) {
qemu_iovec_memset(qiov, 0, 0, bytes);
qemu_iovec_memset(qiov, 0, 0, nb_sectors * BDRV_SECTOR_SIZE);
}
return null_co_common(bs);
}
static coroutine_fn int null_co_pwritev(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags)
static coroutine_fn int null_co_writev(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
{
return null_co_common(bs);
}
@@ -187,26 +186,26 @@ static inline BlockAIOCB *null_aio_common(BlockDriverState *bs,
return &acb->common;
}
static BlockAIOCB *null_aio_preadv(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
BlockCompletionFunc *cb,
void *opaque)
static BlockAIOCB *null_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov,
int nb_sectors,
BlockCompletionFunc *cb,
void *opaque)
{
BDRVNullState *s = bs->opaque;
if (s->read_zeroes) {
qemu_iovec_memset(qiov, 0, 0, bytes);
qemu_iovec_memset(qiov, 0, 0, nb_sectors * BDRV_SECTOR_SIZE);
}
return null_aio_common(bs, cb, opaque);
}
static BlockAIOCB *null_aio_pwritev(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
BlockCompletionFunc *cb,
void *opaque)
static BlockAIOCB *null_aio_writev(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov,
int nb_sectors,
BlockCompletionFunc *cb,
void *opaque)
{
return null_aio_common(bs, cb, opaque);
}
@@ -245,6 +244,7 @@ static int coroutine_fn null_co_block_status(BlockDriverState *bs,
static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
{
QINCREF(opts);
qdict_del(opts, "filename");
if (!qdict_size(opts)) {
@@ -253,7 +253,7 @@ static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
}
qdict_put_str(opts, "driver", bs->drv->format_name);
bs->full_open_options = qobject_ref(opts);
bs->full_open_options = opts;
}
static BlockDriver bdrv_null_co = {
@@ -266,8 +266,8 @@ static BlockDriver bdrv_null_co = {
.bdrv_close = null_close,
.bdrv_getlength = null_getlength,
.bdrv_co_preadv = null_co_preadv,
.bdrv_co_pwritev = null_co_pwritev,
.bdrv_co_readv = null_co_readv,
.bdrv_co_writev = null_co_writev,
.bdrv_co_flush_to_disk = null_co_flush,
.bdrv_reopen_prepare = null_reopen_prepare,
@@ -286,8 +286,8 @@ static BlockDriver bdrv_null_aio = {
.bdrv_close = null_close,
.bdrv_getlength = null_getlength,
.bdrv_aio_preadv = null_aio_preadv,
.bdrv_aio_pwritev = null_aio_pwritev,
.bdrv_aio_readv = null_aio_readv,
.bdrv_aio_writev = null_aio_writev,
.bdrv_aio_flush = null_aio_flush,
.bdrv_reopen_prepare = null_reopen_prepare,
+2 -1
View File
@@ -1073,6 +1073,7 @@ static int nvme_reopen_prepare(BDRVReopenState *reopen_state,
static void nvme_refresh_filename(BlockDriverState *bs, QDict *opts)
{
QINCREF(opts);
qdict_del(opts, "filename");
if (!qdict_size(opts)) {
@@ -1081,7 +1082,7 @@ static void nvme_refresh_filename(BlockDriverState *bs, QDict *opts)
}
qdict_put_str(opts, "driver", bs->drv->format_name);
bs->full_open_options = qobject_ref(opts);
bs->full_open_options = opts;
}
static void nvme_refresh_limits(BlockDriverState *bs, Error **errp)
+15 -18
View File
@@ -31,7 +31,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
@@ -227,15 +226,14 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
};
qemu_iovec_init_external(&qiov, &iov, 1);
ret = bdrv_co_preadv(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE,
nb_cow_bytes, &qiov, 0);
ret = bdrv_co_readv(bs->backing, idx * s->tracks, nb_cow_sectors,
&qiov);
if (ret < 0) {
qemu_vfree(iov.iov_base);
return ret;
}
ret = bdrv_co_pwritev(bs->file, s->data_end * BDRV_SECTOR_SIZE,
nb_cow_bytes, &qiov, 0);
ret = bdrv_co_writev(bs->file, s->data_end, nb_cow_sectors, &qiov);
qemu_vfree(iov.iov_base);
if (ret < 0) {
return ret;
@@ -313,15 +311,13 @@ static int coroutine_fn parallels_co_block_status(BlockDriverState *bs,
}
static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags)
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
{
BDRVParallelsState *s = bs->opaque;
uint64_t bytes_done = 0;
QEMUIOVector hd_qiov;
int ret = 0;
assert(!flags);
qemu_iovec_init(&hd_qiov, qiov->niov);
while (nb_sectors > 0) {
@@ -341,8 +337,7 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
qemu_iovec_reset(&hd_qiov);
qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
ret = bdrv_co_pwritev(bs->file, position * BDRV_SECTOR_SIZE, nbytes,
&hd_qiov, 0);
ret = bdrv_co_writev(bs->file, position, n, &hd_qiov);
if (ret < 0) {
break;
}
@@ -381,8 +376,7 @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
if (position < 0) {
if (bs->backing) {
ret = bdrv_co_preadv(bs->backing, sector_num * BDRV_SECTOR_SIZE,
nbytes, &hd_qiov, 0);
ret = bdrv_co_readv(bs->backing, sector_num, n, &hd_qiov);
if (ret < 0) {
break;
}
@@ -390,8 +384,7 @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
qemu_iovec_memset(&hd_qiov, 0, 0, nbytes);
}
} else {
ret = bdrv_co_preadv(bs->file, position * BDRV_SECTOR_SIZE, nbytes,
&hd_qiov, 0);
ret = bdrv_co_readv(bs->file, position, n, &hd_qiov);
if (ret < 0) {
break;
}
@@ -620,7 +613,8 @@ static int coroutine_fn parallels_co_create_opts(const char *filename,
BlockdevCreateOptions *create_options = NULL;
Error *local_err = NULL;
BlockDriverState *bs = NULL;
QDict *qdict;
QDict *qdict = NULL;
QObject *qobj;
Visitor *v;
int ret;
@@ -656,12 +650,15 @@ static int coroutine_fn parallels_co_create_opts(const char *filename,
qdict_put_str(qdict, "driver", "parallels");
qdict_put_str(qdict, "file", bs->node_name);
v = qobject_input_visitor_new_flat_confused(qdict, errp);
if (!v) {
qobj = qdict_crumple(qdict, errp);
QDECREF(qdict);
qdict = qobject_to(QDict, qobj);
if (qdict == NULL) {
ret = -EINVAL;
goto done;
}
v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
visit_free(v);
@@ -685,7 +682,7 @@ static int coroutine_fn parallels_co_create_opts(const char *filename,
ret = 0;
done:
qobject_unref(qdict);
QDECREF(qdict);
bdrv_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
+2 -16
View File
@@ -593,29 +593,15 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
p_next = &info->next;
}
} else {
for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
BlockStatsList *info = g_malloc0(sizeof(*info));
AioContext *ctx = blk_get_aio_context(blk);
BlockStats *s;
char *qdev;
if (!*blk_name(blk) && !blk_get_attached_dev(blk)) {
continue;
}
aio_context_acquire(ctx);
s = bdrv_query_bds_stats(blk_bs(blk), true);
s->has_device = true;
s->device = g_strdup(blk_name(blk));
qdev = blk_get_attached_dev_id(blk);
if (qdev && *qdev) {
s->has_qdev = true;
s->qdev = qdev;
} else {
g_free(qdev);
}
bdrv_query_blk_stats(s->stats, blk);
aio_context_release(ctx);
@@ -787,7 +773,7 @@ void bdrv_image_info_specific_dump(fprintf_function func_fprintf, void *f,
visit_complete(v, &obj);
data = qdict_get(qobject_to(QDict, obj), "data");
dump_qobject(func_fprintf, f, 1, data);
qobject_unref(obj);
qobject_decref(obj);
visit_free(v);
}
+77 -77
View File
@@ -26,7 +26,6 @@
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
@@ -38,7 +37,7 @@
#include "qapi/qapi-visit-block-core.h"
#include "crypto/block.h"
#include "migration/blocker.h"
#include "crypto.h"
#include "block/crypto.h"
/**************************************************************/
/* QEMU COW block driver with compression and encryption support */
@@ -70,6 +69,7 @@ typedef struct QCowHeader {
typedef struct BDRVQcowState {
int cluster_bits;
int cluster_size;
int cluster_sectors;
int l2_bits;
int l2_size;
unsigned int l1_size;
@@ -202,8 +202,9 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
ret = -EINVAL;
goto fail;
}
qdict_put_str(encryptopts, "format", "qcow");
crypto_opts = block_crypto_open_opts_init(encryptopts, errp);
qdict_del(encryptopts, "format");
crypto_opts = block_crypto_open_opts_init(
Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp);
if (!crypto_opts) {
ret = -EINVAL;
goto fail;
@@ -234,6 +235,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
}
s->cluster_bits = header.cluster_bits;
s->cluster_size = 1 << s->cluster_bits;
s->cluster_sectors = 1 << (s->cluster_bits - 9);
s->l2_bits = header.l2_bits;
s->l2_size = 1 << s->l2_bits;
bs->total_sectors = header.size / 512;
@@ -313,7 +315,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
qobject_unref(encryptopts);
QDECREF(encryptopts);
qapi_free_QCryptoBlockOpenOptions(crypto_opts);
qemu_co_mutex_init(&s->lock);
return 0;
@@ -324,7 +326,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
g_free(s->cluster_cache);
g_free(s->cluster_data);
qcrypto_block_free(s->crypto);
qobject_unref(encryptopts);
QDECREF(encryptopts);
qapi_free_QCryptoBlockOpenOptions(crypto_opts);
return ret;
}
@@ -343,8 +345,8 @@ static int qcow_reopen_prepare(BDRVReopenState *state,
*
* 0 to not allocate.
*
* 1 to allocate a normal cluster (for sector-aligned byte offsets 'n_start'
* to 'n_end' within the cluster)
* 1 to allocate a normal cluster (for sector indexes 'n_start' to
* 'n_end')
*
* 2 to allocate a compressed cluster of size
* 'compressed_size'. 'compressed_size' must be > 0 and <
@@ -438,10 +440,9 @@ static int get_cluster_offset(BlockDriverState *bs,
if (!allocate)
return 0;
BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC);
assert(QEMU_IS_ALIGNED(n_start | n_end, BDRV_SECTOR_SIZE));
/* allocate a new cluster */
if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
(n_end - n_start) < s->cluster_size) {
(n_end - n_start) < s->cluster_sectors) {
/* if the cluster is already compressed, we must
decompress it in the case it is not completely
overwritten */
@@ -479,15 +480,16 @@ static int get_cluster_offset(BlockDriverState *bs,
/* if encrypted, we must initialize the cluster
content which won't be written */
if (bs->encrypted &&
(n_end - n_start) < s->cluster_size) {
uint64_t start_offset;
(n_end - n_start) < s->cluster_sectors) {
uint64_t start_sect;
assert(s->crypto);
start_offset = offset & ~(s->cluster_size - 1);
for (i = 0; i < s->cluster_size; i += BDRV_SECTOR_SIZE) {
start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
for(i = 0; i < s->cluster_sectors; i++) {
if (i < n_start || i >= n_end) {
memset(s->cluster_data, 0x00, BDRV_SECTOR_SIZE);
memset(s->cluster_data, 0x00, 512);
if (qcrypto_block_encrypt(s->crypto,
start_offset + i,
(start_sect + i) *
BDRV_SECTOR_SIZE,
s->cluster_data,
BDRV_SECTOR_SIZE,
NULL) < 0) {
@@ -495,9 +497,8 @@ static int get_cluster_offset(BlockDriverState *bs,
}
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
ret = bdrv_pwrite(bs->file,
cluster_offset + i,
s->cluster_data,
BDRV_SECTOR_SIZE);
cluster_offset + i * 512,
s->cluster_data, 512);
if (ret < 0) {
return ret;
}
@@ -611,21 +612,11 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
return 0;
}
static void qcow_refresh_limits(BlockDriverState *bs, Error **errp)
{
/* At least encrypted images require 512-byte alignment. Apply the
* limit universally, rather than just on encrypted images, as
* it's easier to let the block layer handle rounding than to
* audit this code further. */
bs->bl.request_alignment = BDRV_SECTOR_SIZE;
}
static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, QEMUIOVector *qiov,
int flags)
static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov)
{
BDRVQcowState *s = bs->opaque;
int offset_in_cluster;
int index_in_cluster;
int ret = 0, n;
uint64_t cluster_offset;
struct iovec hd_iov;
@@ -633,7 +624,6 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
uint8_t *buf;
void *orig_buf;
assert(!flags);
if (qiov->niov > 1) {
buf = orig_buf = qemu_try_blockalign(bs, qiov->size);
if (buf == NULL) {
@@ -646,35 +636,36 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
qemu_co_mutex_lock(&s->lock);
while (bytes != 0) {
while (nb_sectors != 0) {
/* prepare next request */
ret = get_cluster_offset(bs, offset, 0, 0, 0, 0, &cluster_offset);
ret = get_cluster_offset(bs, sector_num << 9,
0, 0, 0, 0, &cluster_offset);
if (ret < 0) {
break;
}
offset_in_cluster = offset & (s->cluster_size - 1);
n = s->cluster_size - offset_in_cluster;
if (n > bytes) {
n = bytes;
index_in_cluster = sector_num & (s->cluster_sectors - 1);
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors) {
n = nb_sectors;
}
if (!cluster_offset) {
if (bs->backing) {
/* read from the base image */
hd_iov.iov_base = (void *)buf;
hd_iov.iov_len = n;
hd_iov.iov_len = n * 512;
qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
qemu_co_mutex_unlock(&s->lock);
/* qcow2 emits this on bs->file instead of bs->backing */
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
ret = bdrv_co_preadv(bs->backing, offset, n, &hd_qiov, 0);
ret = bdrv_co_readv(bs->backing, sector_num, n, &hd_qiov);
qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
break;
}
} else {
/* Note: in this case, no need to wait */
memset(buf, 0, n);
memset(buf, 0, 512 * n);
}
} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
/* add AIO support for compressed blocks ? */
@@ -682,19 +673,21 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
ret = -EIO;
break;
}
memcpy(buf, s->cluster_cache + offset_in_cluster, n);
memcpy(buf,
s->cluster_cache + index_in_cluster * 512, 512 * n);
} else {
if ((cluster_offset & 511) != 0) {
ret = -EIO;
break;
}
hd_iov.iov_base = (void *)buf;
hd_iov.iov_len = n;
hd_iov.iov_len = n * 512;
qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
qemu_co_mutex_unlock(&s->lock);
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
ret = bdrv_co_preadv(bs->file, cluster_offset + offset_in_cluster,
n, &hd_qiov, 0);
ret = bdrv_co_readv(bs->file,
(cluster_offset >> 9) + index_in_cluster,
n, &hd_qiov);
qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
break;
@@ -702,7 +695,8 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
if (bs->encrypted) {
assert(s->crypto);
if (qcrypto_block_decrypt(s->crypto,
offset, buf, n, NULL) < 0) {
sector_num * BDRV_SECTOR_SIZE, buf,
n * BDRV_SECTOR_SIZE, NULL) < 0) {
ret = -EIO;
break;
}
@@ -710,9 +704,9 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
}
ret = 0;
bytes -= n;
offset += n;
buf += n;
nb_sectors -= n;
sector_num += n;
buf += n * 512;
}
qemu_co_mutex_unlock(&s->lock);
@@ -725,12 +719,11 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
return ret;
}
static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, QEMUIOVector *qiov,
int flags)
static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov)
{
BDRVQcowState *s = bs->opaque;
int offset_in_cluster;
int index_in_cluster;
uint64_t cluster_offset;
int ret = 0, n;
struct iovec hd_iov;
@@ -738,7 +731,6 @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
uint8_t *buf;
void *orig_buf;
assert(!flags);
s->cluster_cache_offset = -1; /* disable compressed cache */
/* We must always copy the iov when encrypting, so we
@@ -756,14 +748,16 @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
qemu_co_mutex_lock(&s->lock);
while (bytes != 0) {
offset_in_cluster = offset & (s->cluster_size - 1);
n = s->cluster_size - offset_in_cluster;
if (n > bytes) {
n = bytes;
while (nb_sectors != 0) {
index_in_cluster = sector_num & (s->cluster_sectors - 1);
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors) {
n = nb_sectors;
}
ret = get_cluster_offset(bs, offset, 1, 0, offset_in_cluster,
offset_in_cluster + n, &cluster_offset);
ret = get_cluster_offset(bs, sector_num << 9, 1, 0,
index_in_cluster,
index_in_cluster + n, &cluster_offset);
if (ret < 0) {
break;
}
@@ -773,28 +767,30 @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
}
if (bs->encrypted) {
assert(s->crypto);
if (qcrypto_block_encrypt(s->crypto, offset, buf, n, NULL) < 0) {
if (qcrypto_block_encrypt(s->crypto, sector_num * BDRV_SECTOR_SIZE,
buf, n * BDRV_SECTOR_SIZE, NULL) < 0) {
ret = -EIO;
break;
}
}
hd_iov.iov_base = (void *)buf;
hd_iov.iov_len = n;
hd_iov.iov_len = n * 512;
qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
qemu_co_mutex_unlock(&s->lock);
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
n, &hd_qiov, 0);
ret = bdrv_co_writev(bs->file,
(cluster_offset >> 9) + index_in_cluster,
n, &hd_qiov);
qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
break;
}
ret = 0;
bytes -= n;
offset += n;
buf += n;
nb_sectors -= n;
sector_num += n;
buf += n * 512;
}
qemu_co_mutex_unlock(&s->lock);
@@ -948,7 +944,8 @@ static int coroutine_fn qcow_co_create_opts(const char *filename,
{
BlockdevCreateOptions *create_options = NULL;
BlockDriverState *bs = NULL;
QDict *qdict;
QDict *qdict = NULL;
QObject *qobj;
Visitor *v;
const char *val;
Error *local_err = NULL;
@@ -998,12 +995,15 @@ static int coroutine_fn qcow_co_create_opts(const char *filename,
qdict_put_str(qdict, "driver", "qcow");
qdict_put_str(qdict, "file", bs->node_name);
v = qobject_input_visitor_new_flat_confused(qdict, errp);
if (!v) {
qobj = qdict_crumple(qdict, errp);
QDECREF(qdict);
qdict = qobject_to(QDict, qobj);
if (qdict == NULL) {
ret = -EINVAL;
goto fail;
}
v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
visit_free(v);
@@ -1026,7 +1026,7 @@ static int coroutine_fn qcow_co_create_opts(const char *filename,
ret = 0;
fail:
qobject_unref(qdict);
QDECREF(qdict);
bdrv_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
@@ -1110,7 +1110,8 @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
/* could not compress: write normal cluster */
ret = qcow_co_pwritev(bs, offset, bytes, qiov, 0);
ret = qcow_co_writev(bs, offset >> BDRV_SECTOR_BITS,
bytes >> BDRV_SECTOR_BITS, qiov);
if (ret < 0) {
goto fail;
}
@@ -1195,10 +1196,9 @@ static BlockDriver bdrv_qcow = {
.bdrv_co_create_opts = qcow_co_create_opts,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.supports_backing = true,
.bdrv_refresh_limits = qcow_refresh_limits,
.bdrv_co_preadv = qcow_co_preadv,
.bdrv_co_pwritev = qcow_co_pwritev,
.bdrv_co_readv = qcow_co_readv,
.bdrv_co_writev = qcow_co_writev,
.bdrv_co_block_status = qcow_co_block_status,
.bdrv_make_empty = qcow_make_empty,
+3 -7
View File
@@ -30,7 +30,7 @@
#include "qemu/cutils.h"
#include "block/block_int.h"
#include "qcow2.h"
#include "block/qcow2.h"
/* NOTICE: BME here means Bitmaps Extension and used as a namespace for
* _internal_ constants. Please do not use this _internal_ abbreviation for
@@ -254,6 +254,7 @@ static int free_bitmap_clusters(BlockDriverState *bs, Qcow2BitmapTable *tb)
ret = bitmap_table_load(bs, tb, &bitmap_table);
if (ret < 0) {
assert(bitmap_table == NULL);
return ret;
}
@@ -775,12 +776,7 @@ static int bitmap_list_store(BlockDriverState *bs, Qcow2BitmapList *bm_list,
}
}
/* Actually, even in in-place case ignoring QCOW2_OL_BITMAP_DIRECTORY is not
* necessary, because we drop QCOW2_AUTOCLEAR_BITMAPS when updating bitmap
* directory in-place (actually, turn-off the extension), which is checked
* in qcow2_check_metadata_overlap() */
ret = qcow2_pre_write_overlap_check(
bs, in_place ? QCOW2_OL_BITMAP_DIRECTORY : 0, dir_offset, dir_size);
ret = qcow2_pre_write_overlap_check(bs, 0, dir_offset, dir_size);
if (ret < 0) {
goto fail;
}
+1 -12
View File
@@ -28,7 +28,7 @@
#include "qapi/error.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qcow2.h"
#include "block/qcow2.h"
#include "qemu/bswap.h"
#include "trace.h"
@@ -994,17 +994,6 @@ err:
return ret;
}
/**
* Frees the allocated clusters because the request failed and they won't
* actually be linked.
*/
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
{
BDRVQcow2State *s = bs->opaque;
qcow2_free_clusters(bs, m->alloc_offset, m->nb_clusters << s->cluster_bits,
QCOW2_DISCARD_NEVER);
}
/*
* Returns the number of contiguous clusters that can be used for an allocating
* write, but require COW to be performed (this includes yet unallocated space,
+12 -31
View File
@@ -26,7 +26,7 @@
#include "qapi/error.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include "qcow2.h"
#include "block/qcow2.h"
#include "qemu/range.h"
#include "qemu/bswap.h"
#include "qemu/cutils.h"
@@ -734,7 +734,7 @@ void qcow2_process_discards(BlockDriverState *bs, int ret)
/* Discard is optional, ignore the return value */
if (ret >= 0) {
bdrv_pdiscard(bs->file, d->offset, d->bytes);
bdrv_pdiscard(bs->file->bs, d->offset, d->bytes);
}
g_free(d);
@@ -1577,9 +1577,9 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
case QCOW2_CLUSTER_COMPRESSED:
/* Compressed clusters don't have QCOW_OFLAG_COPIED */
if (l2_entry & QCOW_OFLAG_COPIED) {
fprintf(stderr, "ERROR: coffset=0x%" PRIx64 ": "
fprintf(stderr, "ERROR: cluster %" PRId64 ": "
"copied flag must never be set for compressed "
"clusters\n", l2_entry & s->cluster_offset_mask);
"clusters\n", l2_entry >> s->cluster_bits);
l2_entry &= ~QCOW_OFLAG_COPIED;
res->corruptions++;
}
@@ -1799,19 +1799,6 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
int ret;
uint64_t refcount;
int i, j;
bool repair;
if (fix & BDRV_FIX_ERRORS) {
/* Always repair */
repair = true;
} else if (fix & BDRV_FIX_LEAKS) {
/* Repair only if that seems safe: This function is always
* called after the refcounts have been fixed, so the refcount
* is accurate if that repair was successful */
repair = !res->check_errors && !res->corruptions && !res->leaks;
} else {
repair = false;
}
for (i = 0; i < s->l1_size; i++) {
uint64_t l1_entry = s->l1_table[i];
@@ -1831,8 +1818,10 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) {
fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d "
"l1_entry=%" PRIx64 " refcount=%" PRIu64 "\n",
repair ? "Repairing" : "ERROR", i, l1_entry, refcount);
if (repair) {
fix & BDRV_FIX_ERRORS ? "Repairing" :
"ERROR",
i, l1_entry, refcount);
if (fix & BDRV_FIX_ERRORS) {
s->l1_table[i] = refcount == 1
? l1_entry | QCOW_OFLAG_COPIED
: l1_entry & ~QCOW_OFLAG_COPIED;
@@ -1873,8 +1862,10 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
fprintf(stderr, "%s OFLAG_COPIED data cluster: "
"l2_entry=%" PRIx64 " refcount=%" PRIu64 "\n",
repair ? "Repairing" : "ERROR", l2_entry, refcount);
if (repair) {
fix & BDRV_FIX_ERRORS ? "Repairing" :
"ERROR",
l2_entry, refcount);
if (fix & BDRV_FIX_ERRORS) {
l2_table[j] = cpu_to_be64(refcount == 1
? l2_entry | QCOW_OFLAG_COPIED
: l2_entry & ~QCOW_OFLAG_COPIED);
@@ -2705,16 +2696,6 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
}
}
if ((chk & QCOW2_OL_BITMAP_DIRECTORY) &&
(s->autoclear_features & QCOW2_AUTOCLEAR_BITMAPS))
{
if (overlaps_with(s->bitmap_directory_offset,
s->bitmap_directory_size))
{
return QCOW2_OL_BITMAP_DIRECTORY;
}
}
return 0;
}
+1 -1
View File
@@ -25,7 +25,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "qcow2.h"
#include "block/qcow2.h"
#include "qemu/bswap.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"
+200 -450
View File
File diff suppressed because it is too large. Load diff
+23 -26
View File
@@ -77,6 +77,10 @@
#define DEFAULT_L2_CACHE_CLUSTERS 8 /* clusters */
#define DEFAULT_L2_CACHE_BYTE_SIZE 1048576 /* bytes */
/* The refblock cache needs only a fourth of the L2 cache size to cover as many
* clusters */
#define DEFAULT_L2_REFCOUNT_SIZE_RATIO 4
#define DEFAULT_CLUSTER_SIZE 65536
@@ -94,7 +98,6 @@
#define QCOW2_OPT_OVERLAP_SNAPSHOT_TABLE "overlap-check.snapshot-table"
#define QCOW2_OPT_OVERLAP_INACTIVE_L1 "overlap-check.inactive-l1"
#define QCOW2_OPT_OVERLAP_INACTIVE_L2 "overlap-check.inactive-l2"
#define QCOW2_OPT_OVERLAP_BITMAP_DIRECTORY "overlap-check.bitmap-directory"
#define QCOW2_OPT_CACHE_SIZE "cache-size"
#define QCOW2_OPT_L2_CACHE_SIZE "l2-cache-size"
#define QCOW2_OPT_L2_CACHE_ENTRY_SIZE "l2-cache-entry-size"
@@ -327,9 +330,6 @@ typedef struct BDRVQcow2State {
* override) */
char *image_backing_file;
char *image_backing_format;
CoQueue compress_wait_queue;
int nb_compress_threads;
} BDRVQcow2State;
typedef struct Qcow2COWRegion {
@@ -401,36 +401,34 @@ typedef enum QCow2ClusterType {
} QCow2ClusterType;
typedef enum QCow2MetadataOverlap {
QCOW2_OL_MAIN_HEADER_BITNR = 0,
QCOW2_OL_ACTIVE_L1_BITNR = 1,
QCOW2_OL_ACTIVE_L2_BITNR = 2,
QCOW2_OL_REFCOUNT_TABLE_BITNR = 3,
QCOW2_OL_REFCOUNT_BLOCK_BITNR = 4,
QCOW2_OL_SNAPSHOT_TABLE_BITNR = 5,
QCOW2_OL_INACTIVE_L1_BITNR = 6,
QCOW2_OL_INACTIVE_L2_BITNR = 7,
QCOW2_OL_BITMAP_DIRECTORY_BITNR = 8,
QCOW2_OL_MAIN_HEADER_BITNR = 0,
QCOW2_OL_ACTIVE_L1_BITNR = 1,
QCOW2_OL_ACTIVE_L2_BITNR = 2,
QCOW2_OL_REFCOUNT_TABLE_BITNR = 3,
QCOW2_OL_REFCOUNT_BLOCK_BITNR = 4,
QCOW2_OL_SNAPSHOT_TABLE_BITNR = 5,
QCOW2_OL_INACTIVE_L1_BITNR = 6,
QCOW2_OL_INACTIVE_L2_BITNR = 7,
QCOW2_OL_MAX_BITNR = 9,
QCOW2_OL_MAX_BITNR = 8,
QCOW2_OL_NONE = 0,
QCOW2_OL_MAIN_HEADER = (1 << QCOW2_OL_MAIN_HEADER_BITNR),
QCOW2_OL_ACTIVE_L1 = (1 << QCOW2_OL_ACTIVE_L1_BITNR),
QCOW2_OL_ACTIVE_L2 = (1 << QCOW2_OL_ACTIVE_L2_BITNR),
QCOW2_OL_REFCOUNT_TABLE = (1 << QCOW2_OL_REFCOUNT_TABLE_BITNR),
QCOW2_OL_REFCOUNT_BLOCK = (1 << QCOW2_OL_REFCOUNT_BLOCK_BITNR),
QCOW2_OL_SNAPSHOT_TABLE = (1 << QCOW2_OL_SNAPSHOT_TABLE_BITNR),
QCOW2_OL_INACTIVE_L1 = (1 << QCOW2_OL_INACTIVE_L1_BITNR),
QCOW2_OL_NONE = 0,
QCOW2_OL_MAIN_HEADER = (1 << QCOW2_OL_MAIN_HEADER_BITNR),
QCOW2_OL_ACTIVE_L1 = (1 << QCOW2_OL_ACTIVE_L1_BITNR),
QCOW2_OL_ACTIVE_L2 = (1 << QCOW2_OL_ACTIVE_L2_BITNR),
QCOW2_OL_REFCOUNT_TABLE = (1 << QCOW2_OL_REFCOUNT_TABLE_BITNR),
QCOW2_OL_REFCOUNT_BLOCK = (1 << QCOW2_OL_REFCOUNT_BLOCK_BITNR),
QCOW2_OL_SNAPSHOT_TABLE = (1 << QCOW2_OL_SNAPSHOT_TABLE_BITNR),
QCOW2_OL_INACTIVE_L1 = (1 << QCOW2_OL_INACTIVE_L1_BITNR),
/* NOTE: Checking overlaps with inactive L2 tables will result in bdrv
* reads. */
QCOW2_OL_INACTIVE_L2 = (1 << QCOW2_OL_INACTIVE_L2_BITNR),
QCOW2_OL_BITMAP_DIRECTORY = (1 << QCOW2_OL_BITMAP_DIRECTORY_BITNR),
QCOW2_OL_INACTIVE_L2 = (1 << QCOW2_OL_INACTIVE_L2_BITNR),
} QCow2MetadataOverlap;
/* Perform all overlap checks which can be done in constant time */
#define QCOW2_OL_CONSTANT \
(QCOW2_OL_MAIN_HEADER | QCOW2_OL_ACTIVE_L1 | QCOW2_OL_REFCOUNT_TABLE | \
QCOW2_OL_SNAPSHOT_TABLE | QCOW2_OL_BITMAP_DIRECTORY)
QCOW2_OL_SNAPSHOT_TABLE)
/* Perform all overlap checks which don't require disk access */
#define QCOW2_OL_CACHED \
@@ -620,7 +618,6 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
int compressed_size);
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, enum qcow2_discard_type type,
bool full_discard);
+12 -12
View File
@@ -13,7 +13,6 @@
*/
#include "qemu/osdep.h"
#include "block/qdict.h"
#include "qapi/error.h"
#include "qemu/timer.h"
#include "qemu/bswap.h"
@@ -722,7 +721,8 @@ static int coroutine_fn bdrv_qed_co_create_opts(const char *filename,
Error **errp)
{
BlockdevCreateOptions *create_options = NULL;
QDict *qdict;
QDict *qdict = NULL;
QObject *qobj;
Visitor *v;
BlockDriverState *bs = NULL;
Error *local_err = NULL;
@@ -762,12 +762,15 @@ static int coroutine_fn bdrv_qed_co_create_opts(const char *filename,
qdict_put_str(qdict, "driver", "qed");
qdict_put_str(qdict, "file", bs->node_name);
v = qobject_input_visitor_new_flat_confused(qdict, errp);
if (!v) {
qobj = qdict_crumple(qdict, errp);
QDECREF(qdict);
qdict = qobject_to(QDict, qobj);
if (qdict == NULL) {
ret = -EINVAL;
goto fail;
}
v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
visit_free(v);
@@ -786,7 +789,7 @@ static int coroutine_fn bdrv_qed_co_create_opts(const char *filename,
ret = bdrv_qed_co_create(create_options, errp);
fail:
qobject_unref(qdict);
QDECREF(qdict);
bdrv_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
@@ -1434,9 +1437,8 @@ static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs,
static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs,
int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags)
QEMUIOVector *qiov)
{
assert(!flags);
return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
}
@@ -1467,10 +1469,8 @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
QED_AIOCB_WRITE | QED_AIOCB_ZERO);
}
static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
int64_t offset,
PreallocMode prealloc,
Error **errp)
static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
BDRVQEDState *s = bs->opaque;
uint64_t old_image_size;
@@ -1680,7 +1680,7 @@ static BlockDriver bdrv_qed = {
.bdrv_co_readv = bdrv_qed_co_readv,
.bdrv_co_writev = bdrv_qed_co_writev,
.bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes,
.bdrv_co_truncate = bdrv_qed_co_truncate,
.bdrv_truncate = bdrv_qed_truncate,
.bdrv_getlength = bdrv_qed_getlength,
.bdrv_get_info = bdrv_qed_get_info,
.bdrv_refresh_limits = bdrv_qed_refresh_limits,
+12 -18
View File
@@ -17,7 +17,6 @@
#include "qemu/cutils.h"
#include "qemu/option.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "qapi/error.h"
#include "qapi/qapi-events-block.h"
#include "qapi/qmp/qdict.h"
@@ -116,7 +115,6 @@ struct QuorumAIOCB {
/* Request metadata */
uint64_t offset;
uint64_t bytes;
int flags;
QEMUIOVector *qiov; /* calling IOV */
@@ -159,8 +157,7 @@ static bool quorum_64bits_compare(QuorumVoteValue *a, QuorumVoteValue *b)
static QuorumAIOCB *quorum_aio_get(BlockDriverState *bs,
QEMUIOVector *qiov,
uint64_t offset,
uint64_t bytes,
int flags)
uint64_t bytes)
{
BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = g_new(QuorumAIOCB, 1);
@@ -171,7 +168,6 @@ static QuorumAIOCB *quorum_aio_get(BlockDriverState *bs,
.bs = bs,
.offset = offset,
.bytes = bytes,
.flags = flags,
.qiov = qiov,
.votes.compare = quorum_sha256_compare,
.votes.vote_list = QLIST_HEAD_INITIALIZER(acb.votes.vote_list),
@@ -275,11 +271,9 @@ static void quorum_rewrite_entry(void *opaque)
BDRVQuorumState *s = acb->bs->opaque;
/* Ignore any errors, it's just a correction attempt for already
* corrupted data.
* Mask out BDRV_REQ_WRITE_UNCHANGED because this overwrites the
* area with different data from the other children. */
* corrupted data. */
bdrv_co_pwritev(s->children[co->idx], acb->offset, acb->bytes,
acb->qiov, acb->flags & ~BDRV_REQ_WRITE_UNCHANGED);
acb->qiov, 0);
/* Wake up the caller after the last rewrite */
acb->rewrite_count--;
@@ -614,7 +608,7 @@ static void read_quorum_children_entry(void *opaque)
static int read_quorum_children(QuorumAIOCB *acb)
{
BDRVQuorumState *s = acb->bs->opaque;
int i;
int i, ret;
acb->children_read = s->num_children;
for (i = 0; i < s->num_children; i++) {
@@ -649,7 +643,9 @@ static int read_quorum_children(QuorumAIOCB *acb)
qemu_coroutine_yield();
}
return acb->vote_ret;
ret = acb->vote_ret;
return ret;
}
static int read_fifo_child(QuorumAIOCB *acb)
@@ -677,7 +673,7 @@ static int quorum_co_preadv(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, QEMUIOVector *qiov, int flags)
{
BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes);
int ret;
acb->is_read = true;
@@ -703,7 +699,7 @@ static void write_quorum_entry(void *opaque)
sacb->bs = s->children[i]->bs;
sacb->ret = bdrv_co_pwritev(s->children[i], acb->offset, acb->bytes,
acb->qiov, acb->flags);
acb->qiov, 0);
if (sacb->ret == 0) {
acb->success_count++;
} else {
@@ -723,7 +719,7 @@ static int quorum_co_pwritev(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, QEMUIOVector *qiov, int flags)
{
BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes);
int i, ret;
for (i = 0; i < s->num_children; i++) {
@@ -965,8 +961,6 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
}
s->next_child_index = s->num_children;
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED;
g_free(opened);
goto exit;
@@ -1088,8 +1082,8 @@ static void quorum_refresh_filename(BlockDriverState *bs, QDict *options)
children = qlist_new();
for (i = 0; i < s->num_children; i++) {
qlist_append(children,
qobject_ref(s->children[i]->bs->full_open_options));
QINCREF(s->children[i]->bs->full_open_options);
qlist_append(children, s->children[i]->bs->full_open_options);
}
opts = qdict_new();
+10 -51
View File
@@ -177,7 +177,7 @@ static inline int raw_adjust_offset(BlockDriverState *bs, uint64_t *offset,
/* There's not enough space for the write, or the read request is
* out-of-range. Don't read/write anything to prevent leaking out of
* the size specified in options. */
return is_write ? -ENOSPC : -EINVAL;
return is_write ? -ENOSPC : -EINVAL;;
}
if (*offset > INT64_MAX - s->offset) {
@@ -297,7 +297,7 @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
if (ret) {
return ret;
}
return bdrv_co_pdiscard(bs->file, offset, bytes);
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
}
static int64_t raw_getlength(BlockDriverState *bs)
@@ -366,8 +366,8 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
}
}
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
static int raw_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
BDRVRawState *s = bs->opaque;
@@ -383,7 +383,7 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
s->size = offset;
offset += s->offset;
return bdrv_co_truncate(bs->file, offset, prealloc, errp);
return bdrv_truncate(bs->file, offset, prealloc, errp);
}
static void raw_eject(BlockDriverState *bs, bool eject_flag)
@@ -429,11 +429,10 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
}
bs->sg = bs->file->bs->sg;
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
bs->file->bs->supported_zero_flags);
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;
if (bs->probed && !bdrv_is_read_only(bs)) {
fprintf(stderr,
@@ -497,44 +496,6 @@ static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
return bdrv_probe_geometry(bs->file->bs, geo);
}
static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src,
uint64_t src_offset,
BdrvChild *dst,
uint64_t dst_offset,
uint64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
int ret;
ret = raw_adjust_offset(bs, &src_offset, bytes, false);
if (ret) {
return ret;
}
return bdrv_co_copy_range_from(bs->file, src_offset, dst, dst_offset,
bytes, read_flags, write_flags);
}
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src,
uint64_t src_offset,
BdrvChild *dst,
uint64_t dst_offset,
uint64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags)
{
int ret;
ret = raw_adjust_offset(bs, &dst_offset, bytes, true);
if (ret) {
return ret;
}
return bdrv_co_copy_range_to(src, src_offset, bs->file, dst_offset, bytes,
read_flags, write_flags);
}
BlockDriver bdrv_raw = {
.format_name = "raw",
.instance_size = sizeof(BDRVRawState),
@@ -551,9 +512,7 @@ BlockDriver bdrv_raw = {
.bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes,
.bdrv_co_pdiscard = &raw_co_pdiscard,
.bdrv_co_block_status = &raw_co_block_status,
.bdrv_co_copy_range_from = &raw_co_copy_range_from,
.bdrv_co_copy_range_to = &raw_co_copy_range_to,
.bdrv_co_truncate = &raw_co_truncate,
.bdrv_truncate = &raw_truncate,
.bdrv_getlength = &raw_getlength,
.has_variable_length = true,
.bdrv_measure = &raw_measure,
+63 -82
View File
@@ -18,7 +18,6 @@
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "crypto/secret.h"
#include "qemu/cutils.h"
#include "qapi/qmp/qstring.h"
@@ -227,57 +226,27 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
done:
g_free(buf);
qobject_unref(keypairs);
QDECREF(keypairs);
return;
}
static void qemu_rbd_refresh_limits(BlockDriverState *bs, Error **errp)
{
/* XXX Does RBD support AIO on less than 512-byte alignment? */
bs->bl.request_alignment = 512;
}
static int qemu_rbd_set_auth(rados_t cluster, BlockdevOptionsRbd *opts,
static int qemu_rbd_set_auth(rados_t cluster, const char *secretid,
Error **errp)
{
char *key, *acr;
int r;
GString *accu;
RbdAuthModeList *auth;
if (opts->key_secret) {
key = qcrypto_secret_lookup_as_base64(opts->key_secret, errp);
if (!key) {
return -EIO;
}
r = rados_conf_set(cluster, "key", key);
g_free(key);
if (r < 0) {
error_setg_errno(errp, -r, "Could not set 'key'");
return r;
}
if (secretid == 0) {
return 0;
}
if (opts->has_auth_client_required) {
accu = g_string_new("");
for (auth = opts->auth_client_required; auth; auth = auth->next) {
if (accu->str[0]) {
g_string_append_c(accu, ';');
}
g_string_append(accu, RbdAuthMode_str(auth->value));
}
acr = g_string_free(accu, FALSE);
r = rados_conf_set(cluster, "auth_client_required", acr);
g_free(acr);
if (r < 0) {
error_setg_errno(errp, -r,
"Could not set 'auth_client_required'");
return r;
}
gchar *secret = qcrypto_secret_lookup_as_base64(secretid,
errp);
if (!secret) {
return -1;
}
rados_conf_set(cluster, "key", secret);
g_free(secret);
return 0;
}
@@ -306,17 +275,17 @@ static int qemu_rbd_set_keypairs(rados_t cluster, const char *keypairs_json,
key = qstring_get_str(name);
ret = rados_conf_set(cluster, key, qstring_get_str(value));
qobject_unref(value);
QDECREF(value);
if (ret < 0) {
error_setg_errno(errp, -ret, "invalid conf option %s", key);
qobject_unref(name);
QDECREF(name);
ret = -EINVAL;
break;
}
qobject_unref(name);
QDECREF(name);
}
qobject_unref(keypairs);
QDECREF(keypairs);
return ret;
}
@@ -368,7 +337,9 @@ static QemuOptsList runtime_opts = {
},
};
/* FIXME Deprecate and remove keypairs or make it available in QMP. */
/* FIXME Deprecate and remove keypairs or make it available in QMP.
* password_secret should eventually be configurable in opts->location. Support
* for it in .bdrv_open will make it work here as well. */
static int qemu_rbd_do_create(BlockdevCreateOptions *options,
const char *keypairs, const char *password_secret,
Error **errp)
@@ -478,7 +449,7 @@ static int coroutine_fn qemu_rbd_co_create_opts(const char *filename,
}
exit:
qobject_unref(options);
QDECREF(options);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
@@ -574,16 +545,6 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
Error *local_err = NULL;
int r;
if (secretid) {
if (opts->key_secret) {
error_setg(errp,
"Legacy 'password-secret' clashes with 'key-secret'");
return -EINVAL;
}
opts->key_secret = g_strdup(secretid);
opts->has_key_secret = true;
}
mon_host = qemu_rbd_mon_host(opts, &local_err);
if (local_err) {
error_propagate(errp, local_err);
@@ -616,8 +577,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
}
}
r = qemu_rbd_set_auth(*cluster, opts, errp);
if (r < 0) {
if (qemu_rbd_set_auth(*cluster, secretid, errp) < 0) {
r = -EIO;
goto failed_shutdown;
}
@@ -661,11 +622,28 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
BDRVRBDState *s = bs->opaque;
BlockdevOptionsRbd *opts = NULL;
Visitor *v;
QObject *crumpled = NULL;
const QDictEntry *e;
Error *local_err = NULL;
const char *filename;
char *keypairs, *secretid;
int r;
/* If we are given a filename, parse the filename, with precedence given to
* filename encoded options */
filename = qdict_get_try_str(options, "filename");
if (filename) {
warn_report("'filename' option specified. "
"This is an unsupported option, and may be deprecated "
"in the future");
qemu_rbd_parse_filename(filename, options, &local_err);
qdict_del(options, "filename");
if (local_err) {
error_propagate(errp, local_err);
return -EINVAL;
}
}
keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs"));
if (keypairs) {
qdict_del(options, "=keyvalue-pairs");
@@ -677,14 +655,16 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
}
/* Convert the remaining options into a QAPI object */
v = qobject_input_visitor_new_flat_confused(options, errp);
if (!v) {
crumpled = qdict_crumple(options, errp);
if (crumpled == NULL) {
r = -EINVAL;
goto out;
}
v = qobject_input_visitor_new_keyval(crumpled);
visit_type_BlockdevOptionsRbd(v, NULL, &opts, &local_err);
visit_free(v);
qobject_decref(crumpled);
if (local_err) {
error_propagate(errp, local_err);
@@ -919,23 +899,27 @@ failed:
return NULL;
}
static BlockAIOCB *qemu_rbd_aio_preadv(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
BlockCompletionFunc *cb,
void *opaque)
static BlockAIOCB *qemu_rbd_aio_readv(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
int nb_sectors,
BlockCompletionFunc *cb,
void *opaque)
{
return rbd_start_aio(bs, offset, qiov, bytes, cb, opaque,
return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
(int64_t) nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
RBD_AIO_READ);
}
static BlockAIOCB *qemu_rbd_aio_pwritev(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
BlockCompletionFunc *cb,
void *opaque)
static BlockAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
int nb_sectors,
BlockCompletionFunc *cb,
void *opaque)
{
return rbd_start_aio(bs, offset, qiov, bytes, cb, opaque,
return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
(int64_t) nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
RBD_AIO_WRITE);
}
@@ -990,10 +974,8 @@ static int64_t qemu_rbd_getlength(BlockDriverState *bs)
return info.size;
}
static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
int64_t offset,
PreallocMode prealloc,
Error **errp)
static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
BDRVRBDState *s = bs->opaque;
int r;
@@ -1176,7 +1158,6 @@ static BlockDriver bdrv_rbd = {
.format_name = "rbd",
.instance_size = sizeof(BDRVRBDState),
.bdrv_parse_filename = qemu_rbd_parse_filename,
.bdrv_refresh_limits = qemu_rbd_refresh_limits,
.bdrv_file_open = qemu_rbd_open,
.bdrv_close = qemu_rbd_close,
.bdrv_reopen_prepare = qemu_rbd_reopen_prepare,
@@ -1186,11 +1167,11 @@ static BlockDriver bdrv_rbd = {
.bdrv_get_info = qemu_rbd_getinfo,
.create_opts = &qemu_rbd_create_opts,
.bdrv_getlength = qemu_rbd_getlength,
.bdrv_co_truncate = qemu_rbd_co_truncate,
.bdrv_truncate = qemu_rbd_truncate,
.protocol_name = "rbd",
.bdrv_aio_preadv = qemu_rbd_aio_preadv,
.bdrv_aio_pwritev = qemu_rbd_aio_pwritev,
.bdrv_aio_readv = qemu_rbd_aio_readv,
.bdrv_aio_writev = qemu_rbd_aio_writev,
#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
.bdrv_aio_flush = qemu_rbd_aio_flush,
+12 -16
View File
@@ -145,7 +145,7 @@ static void replication_close(BlockDriverState *bs)
replication_stop(s->rs, false, NULL);
}
if (s->stage == BLOCK_REPLICATION_FAILOVER) {
job_cancel_sync(&s->active_disk->bs->job->job);
block_job_cancel_sync(s->active_disk->bs->job);
}
if (s->mode == REPLICATION_MODE_SECONDARY) {
@@ -246,14 +246,13 @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs,
backup_cow_request_begin(&req, child->bs->job,
sector_num * BDRV_SECTOR_SIZE,
remaining_bytes);
ret = bdrv_co_preadv(bs->file, sector_num * BDRV_SECTOR_SIZE,
remaining_bytes, qiov, 0);
ret = bdrv_co_readv(bs->file, sector_num, remaining_sectors,
qiov);
backup_cow_request_end(&req);
goto out;
}
ret = bdrv_co_preadv(bs->file, sector_num * BDRV_SECTOR_SIZE,
remaining_sectors * BDRV_SECTOR_SIZE, qiov, 0);
ret = bdrv_co_readv(bs->file, sector_num, remaining_sectors, qiov);
out:
return replication_return_value(s, ret);
}
@@ -261,8 +260,7 @@ out:
static coroutine_fn int replication_co_writev(BlockDriverState *bs,
int64_t sector_num,
int remaining_sectors,
QEMUIOVector *qiov,
int flags)
QEMUIOVector *qiov)
{
BDRVReplicationState *s = bs->opaque;
QEMUIOVector hd_qiov;
@@ -273,15 +271,14 @@ static coroutine_fn int replication_co_writev(BlockDriverState *bs,
int ret;
int64_t n;
assert(!flags);
ret = replication_get_io_status(s);
if (ret < 0) {
goto out;
}
if (ret == 0) {
ret = bdrv_co_pwritev(top, sector_num * BDRV_SECTOR_SIZE,
remaining_sectors * BDRV_SECTOR_SIZE, qiov, 0);
ret = bdrv_co_writev(top, sector_num,
remaining_sectors, qiov);
return replication_return_value(s, ret);
}
@@ -307,8 +304,7 @@ static coroutine_fn int replication_co_writev(BlockDriverState *bs,
qemu_iovec_concat(&hd_qiov, qiov, bytes_done, count);
target = ret ? top : base;
ret = bdrv_co_pwritev(target, sector_num * BDRV_SECTOR_SIZE,
n * BDRV_SECTOR_SIZE, &hd_qiov, 0);
ret = bdrv_co_writev(target, sector_num, n, &hd_qiov);
if (ret < 0) {
goto out1;
}
@@ -570,7 +566,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
job = backup_job_create(NULL, s->secondary_disk->bs, s->hidden_disk->bs,
0, MIRROR_SYNC_MODE_NONE, NULL, false,
BLOCKDEV_ON_ERROR_REPORT,
BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL,
BLOCKDEV_ON_ERROR_REPORT, BLOCK_JOB_INTERNAL,
backup_job_completed, bs, NULL, &local_err);
if (local_err) {
error_propagate(errp, local_err);
@@ -578,7 +574,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
aio_context_release(aio_context);
return;
}
job_start(&job->job);
block_job_start(job);
break;
default:
aio_context_release(aio_context);
@@ -683,7 +679,7 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
* disk, secondary disk in backup_job_completed().
*/
if (s->secondary_disk->bs->job) {
job_cancel_sync(&s->secondary_disk->bs->job->job);
block_job_cancel_sync(s->secondary_disk->bs->job);
}
if (!failover) {
@@ -695,7 +691,7 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
s->stage = BLOCK_REPLICATION_FAILOVER;
commit_active_start(NULL, s->active_disk->bs, s->secondary_disk->bs,
JOB_INTERNAL, 0, BLOCKDEV_ON_ERROR_REPORT,
BLOCK_JOB_INTERNAL, 0, BLOCKDEV_ON_ERROR_REPORT,
NULL, replication_done, bs, true, errp);
break;
default:
+46 -37
View File
@@ -24,7 +24,6 @@
#include "qemu/option.h"
#include "qemu/sockets.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "qemu/bitops.h"
#include "qemu/cutils.h"
@@ -539,17 +538,27 @@ static void sd_aio_setup(SheepdogAIOCB *acb, BDRVSheepdogState *s,
static SocketAddress *sd_server_config(QDict *options, Error **errp)
{
QDict *server = NULL;
QObject *crumpled_server = NULL;
Visitor *iv = NULL;
SocketAddress *saddr = NULL;
Error *local_err = NULL;
qdict_extract_subqdict(options, &server, "server.");
iv = qobject_input_visitor_new_flat_confused(server, errp);
if (!iv) {
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_SocketAddress(iv, NULL, &saddr, &local_err);
if (local_err) {
error_propagate(errp, local_err);
@@ -558,7 +567,8 @@ static SocketAddress *sd_server_config(QDict *options, Error **errp)
done:
visit_free(iv);
qobject_unref(server);
qobject_decref(crumpled_server);
QDECREF(server);
return saddr;
}
@@ -1849,7 +1859,9 @@ out:
error_setg_errno(errp, -ret, "Can't pre-allocate");
}
out_with_err_set:
blk_unref(blk);
if (blk) {
blk_unref(blk);
}
g_free(buf);
return ret;
@@ -1871,7 +1883,7 @@ static int sd_create_prealloc(BlockdevOptionsSheepdog *location, int64_t size,
if (local_err) {
error_propagate(errp, local_err);
qobject_unref(obj);
qobject_decref(obj);
return -EINVAL;
}
@@ -1889,7 +1901,7 @@ static int sd_create_prealloc(BlockdevOptionsSheepdog *location, int64_t size,
ret = sd_prealloc(bs, 0, size, errp);
fail:
bdrv_unref(bs);
qobject_unref(qdict);
QDECREF(qdict);
return ret;
}
@@ -1975,7 +1987,6 @@ static SheepdogRedundancy *parse_redundancy_str(const char *opt)
} else {
ret = qemu_strtol(n2, NULL, 10, &parity);
if (ret < 0) {
g_free(redundancy);
return NULL;
}
@@ -2170,8 +2181,9 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts,
{
BlockdevCreateOptions *create_options = NULL;
QDict *qdict, *location_qdict;
QObject *crumpled;
Visitor *v;
char *redundancy;
const char *redundancy;
Error *local_err = NULL;
int ret;
@@ -2205,14 +2217,16 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts,
}
/* Get the QAPI object */
v = qobject_input_visitor_new_flat_confused(qdict, errp);
if (!v) {
crumpled = qdict_crumple(qdict, errp);
if (crumpled == NULL) {
ret = -EINVAL;
goto fail;
}
v = qobject_input_visitor_new_keyval(crumpled);
visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
visit_free(v);
qobject_decref(crumpled);
if (local_err) {
error_propagate(errp, local_err);
@@ -2238,8 +2252,7 @@ static int coroutine_fn sd_co_create_opts(const char *filename, QemuOpts *opts,
ret = sd_co_create(create_options, errp);
fail:
qapi_free_BlockdevCreateOptions(create_options);
qobject_unref(qdict);
g_free(redundancy);
QDECREF(qdict);
return ret;
}
@@ -2292,8 +2305,8 @@ static int64_t sd_getlength(BlockDriverState *bs)
return s->inode.vdi_size;
}
static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
static int sd_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
BDRVSheepdogState *s = bs->opaque;
int ret, fd;
@@ -2322,7 +2335,7 @@ static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
}
/* we don't need to update entire object */
datalen = SD_INODE_HEADER_SIZE;
datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
s->inode.vdi_size = offset;
ret = write_object(fd, s->bs, (char *)&s->inode,
vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies,
@@ -2599,17 +2612,15 @@ static void sd_aio_complete(SheepdogAIOCB *acb)
}
static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov,
int flags)
int nb_sectors, QEMUIOVector *qiov)
{
SheepdogAIOCB acb;
int ret;
int64_t offset = (sector_num + nb_sectors) * BDRV_SECTOR_SIZE;
BDRVSheepdogState *s = bs->opaque;
assert(!flags);
if (offset > s->inode.vdi_size) {
ret = sd_co_truncate(bs, offset, PREALLOC_MODE_OFF, NULL);
ret = sd_truncate(bs, offset, PREALLOC_MODE_OFF, NULL);
if (ret < 0) {
return ret;
}
@@ -2690,7 +2701,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
*/
strncpy(s->inode.tag, sn_info->name, sizeof(s->inode.tag));
/* we don't need to update entire object */
datalen = SD_INODE_HEADER_SIZE;
datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
inode = g_malloc(datalen);
/* refresh inode. */
@@ -2925,14 +2936,13 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
QEMUSnapshotInfo *sn_tab = NULL;
unsigned wlen, rlen;
int found = 0;
SheepdogInode *inode;
static SheepdogInode inode;
unsigned long *vdi_inuse;
unsigned int start_nr;
uint64_t hval;
uint32_t vid;
vdi_inuse = g_malloc(max);
inode = g_malloc(SD_INODE_HEADER_SIZE);
fd = connect_to_sdog(s, &local_err);
if (fd < 0) {
@@ -2975,26 +2985,26 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
}
/* we don't need to read entire object */
ret = read_object(fd, s->bs, (char *)inode,
ret = read_object(fd, s->bs, (char *)&inode,
vid_to_vdi_oid(vid),
0, SD_INODE_HEADER_SIZE, 0,
0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,
s->cache_flags);
if (ret) {
continue;
}
if (!strcmp(inode->name, s->name) && is_snapshot(inode)) {
sn_tab[found].date_sec = inode->snap_ctime >> 32;
sn_tab[found].date_nsec = inode->snap_ctime & 0xffffffff;
sn_tab[found].vm_state_size = inode->vm_state_size;
sn_tab[found].vm_clock_nsec = inode->vm_clock_nsec;
if (!strcmp(inode.name, s->name) && is_snapshot(&inode)) {
sn_tab[found].date_sec = inode.snap_ctime >> 32;
sn_tab[found].date_nsec = inode.snap_ctime & 0xffffffff;
sn_tab[found].vm_state_size = inode.vm_state_size;
sn_tab[found].vm_clock_nsec = inode.vm_clock_nsec;
snprintf(sn_tab[found].id_str, sizeof(sn_tab[found].id_str),
"%" PRIu32, inode->snap_id);
"%" PRIu32, inode.snap_id);
pstrcpy(sn_tab[found].name,
MIN(sizeof(sn_tab[found].name), sizeof(inode->tag)),
inode->tag);
MIN(sizeof(sn_tab[found].name), sizeof(inode.tag)),
inode.tag);
found++;
}
}
@@ -3004,7 +3014,6 @@ out:
*psn_tab = sn_tab;
g_free(vdi_inuse);
g_free(inode);
if (ret < 0) {
return ret;
@@ -3231,7 +3240,7 @@ static BlockDriver bdrv_sheepdog = {
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_getlength = sd_getlength,
.bdrv_get_allocated_file_size = sd_get_allocated_file_size,
.bdrv_co_truncate = sd_co_truncate,
.bdrv_truncate = sd_truncate,
.bdrv_co_readv = sd_co_readv,
.bdrv_co_writev = sd_co_writev,
@@ -3268,7 +3277,7 @@ static BlockDriver bdrv_sheepdog_tcp = {
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_getlength = sd_getlength,
.bdrv_get_allocated_file_size = sd_get_allocated_file_size,
.bdrv_co_truncate = sd_co_truncate,
.bdrv_truncate = sd_truncate,
.bdrv_co_readv = sd_co_readv,
.bdrv_co_writev = sd_co_writev,
@@ -3305,7 +3314,7 @@ static BlockDriver bdrv_sheepdog_unix = {
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_getlength = sd_getlength,
.bdrv_get_allocated_file_size = sd_get_allocated_file_size,
.bdrv_co_truncate = sd_co_truncate,
.bdrv_truncate = sd_truncate,
.bdrv_co_readv = sd_co_readv,
.bdrv_co_writev = sd_co_writev,
+2 -3
View File
@@ -25,7 +25,6 @@
#include "qemu/osdep.h"
#include "block/snapshot.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
@@ -215,7 +214,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
bdrv_ref(file);
qdict_extract_subqdict(options, &file_options, "file.");
qobject_unref(file_options);
QDECREF(file_options);
qdict_put_str(options, "file", bdrv_get_node_name(file));
drv->bdrv_close(bs);
@@ -224,7 +223,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
ret = bdrv_snapshot_goto(file, snapshot_id, errp);
open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err);
qobject_unref(options);
QDECREF(options);
if (open_ret < 0) {
bdrv_unref(file);
bs->drv = NULL;
+18 -10
View File
@@ -28,7 +28,6 @@
#include <libssh2_sftp.h>
#include "block/block_int.h"
#include "block/qdict.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
@@ -606,6 +605,7 @@ static BlockdevOptionsSsh *ssh_parse_options(QDict *options, Error **errp)
BlockdevOptionsSsh *result = NULL;
QemuOpts *opts = NULL;
Error *local_err = NULL;
QObject *crumpled;
const QDictEntry *e;
Visitor *v;
@@ -622,13 +622,23 @@ static BlockdevOptionsSsh *ssh_parse_options(QDict *options, Error **errp)
}
/* Create the QAPI object */
v = qobject_input_visitor_new_flat_confused(options, errp);
if (!v) {
crumpled = qdict_crumple(options, errp);
if (crumpled == NULL) {
goto fail;
}
/*
* 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.
*/
v = qobject_input_visitor_new(crumpled);
visit_type_BlockdevOptionsSsh(v, NULL, &result, &local_err);
visit_free(v);
qobject_decref(crumpled);
if (local_err) {
error_propagate(errp, local_err);
@@ -907,7 +917,7 @@ static int coroutine_fn ssh_co_create_opts(const char *filename, QemuOpts *opts,
ret = ssh_co_create(create_options, errp);
out:
qobject_unref(uri_options);
QDECREF(uri_options);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
}
@@ -1154,13 +1164,11 @@ static int ssh_write(BDRVSSHState *s, BlockDriverState *bs,
static coroutine_fn int ssh_co_writev(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov,
int flags)
int nb_sectors, QEMUIOVector *qiov)
{
BDRVSSHState *s = bs->opaque;
int ret;
assert(!flags);
qemu_co_mutex_lock(&s->lock);
ret = ssh_write(s, bs, sector_num * BDRV_SECTOR_SIZE,
nb_sectors * BDRV_SECTOR_SIZE, qiov);
@@ -1243,8 +1251,8 @@ static int64_t ssh_getlength(BlockDriverState *bs)
return length;
}
static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
static int ssh_truncate(BlockDriverState *bs, int64_t offset,
PreallocMode prealloc, Error **errp)
{
BDRVSSHState *s = bs->opaque;
@@ -1279,7 +1287,7 @@ static BlockDriver bdrv_ssh = {
.bdrv_co_readv = ssh_co_readv,
.bdrv_co_writev = ssh_co_writev,
.bdrv_getlength = ssh_getlength,
.bdrv_co_truncate = ssh_co_truncate,
.bdrv_truncate = ssh_truncate,
.bdrv_co_flush_to_disk = ssh_co_flush,
.create_opts = &ssh_create_opts,
};
+38 -30
View File
@@ -29,8 +29,11 @@ enum {
STREAM_BUFFER_SIZE = 512 * 1024, /* in bytes */
};
#define SLICE_TIME 100000000ULL /* ns */
typedef struct StreamBlockJob {
BlockJob common;
RateLimit limit;
BlockDriverState *base;
BlockdevOnError on_error;
char *backing_file_str;
@@ -58,16 +61,16 @@ typedef struct {
int ret;
} StreamCompleteData;
static void stream_complete(Job *job, void *opaque)
static void stream_complete(BlockJob *job, void *opaque)
{
StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
BlockJob *bjob = &s->common;
StreamBlockJob *s = container_of(job, StreamBlockJob, common);
StreamCompleteData *data = opaque;
BlockDriverState *bs = blk_bs(bjob->blk);
BlockDriverState *bs = blk_bs(job->blk);
BlockDriverState *base = s->base;
Error *local_err = NULL;
if (!job_is_cancelled(job) && bs->backing && data->ret == 0) {
if (!block_job_is_cancelled(&s->common) && bs->backing &&
data->ret == 0) {
const char *base_id = NULL, *base_fmt = NULL;
if (base) {
base_id = s->backing_file_str;
@@ -88,12 +91,12 @@ out:
/* Reopen the image back in read-only mode if necessary */
if (s->bs_flags != bdrv_get_flags(bs)) {
/* Give up write permissions before making it read-only */
blk_set_perm(bjob->blk, 0, BLK_PERM_ALL, &error_abort);
blk_set_perm(job->blk, 0, BLK_PERM_ALL, &error_abort);
bdrv_reopen(bs, s->bs_flags, NULL);
}
g_free(s->backing_file_str);
job_completed(job, data->ret, NULL);
block_job_completed(&s->common, data->ret);
g_free(data);
}
@@ -104,7 +107,6 @@ static void coroutine_fn stream_run(void *opaque)
BlockBackend *blk = s->common.blk;
BlockDriverState *bs = blk_bs(blk);
BlockDriverState *base = s->base;
int64_t len;
int64_t offset = 0;
uint64_t delay_ns = 0;
int error = 0;
@@ -116,12 +118,11 @@ static void coroutine_fn stream_run(void *opaque)
goto out;
}
len = bdrv_getlength(bs);
if (len < 0) {
ret = len;
s->common.len = bdrv_getlength(bs);
if (s->common.len < 0) {
ret = s->common.len;
goto out;
}
job_progress_set_remaining(&s->common.job, len);
buf = qemu_blockalign(bs, STREAM_BUFFER_SIZE);
@@ -134,14 +135,14 @@ static void coroutine_fn stream_run(void *opaque)
bdrv_enable_copy_on_read(bs);
}
for ( ; offset < len; offset += n) {
for ( ; offset < s->common.len; offset += n) {
bool copy;
/* Note that even when no rate limit is applied we need to yield
* with no pending I/O here so that bdrv_drain_all() returns.
*/
job_sleep_ns(&s->common.job, delay_ns);
if (job_is_cancelled(&s->common.job)) {
block_job_sleep_ns(&s->common, delay_ns);
if (block_job_is_cancelled(&s->common)) {
break;
}
@@ -158,7 +159,7 @@ static void coroutine_fn stream_run(void *opaque)
/* Finish early if end of backing file has been reached */
if (ret == 0 && n == 0) {
n = len - offset;
n = s->common.len - offset;
}
copy = (ret == 1);
@@ -184,9 +185,9 @@ static void coroutine_fn stream_run(void *opaque)
ret = 0;
/* Publish progress */
job_progress_update(&s->common.job, n);
if (copy) {
delay_ns = block_job_ratelimit_get_delay(&s->common, n);
s->common.offset += n;
if (copy && s->common.speed) {
delay_ns = ratelimit_calculate_delay(&s->limit, n);
} else {
delay_ns = 0;
}
@@ -205,18 +206,25 @@ out:
/* Modify backing chain and close BDSes in main loop */
data = g_malloc(sizeof(*data));
data->ret = ret;
job_defer_to_main_loop(&s->common.job, stream_complete, data);
block_job_defer_to_main_loop(&s->common, stream_complete, data);
}
static void stream_set_speed(BlockJob *job, int64_t speed, Error **errp)
{
StreamBlockJob *s = container_of(job, StreamBlockJob, common);
if (speed < 0) {
error_setg(errp, QERR_INVALID_PARAMETER, "speed");
return;
}
ratelimit_set_speed(&s->limit, speed, SLICE_TIME);
}
static const BlockJobDriver stream_job_driver = {
.job_driver = {
.instance_size = sizeof(StreamBlockJob),
.job_type = JOB_TYPE_STREAM,
.free = block_job_free,
.start = stream_run,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
},
.instance_size = sizeof(StreamBlockJob),
.job_type = BLOCK_JOB_TYPE_STREAM,
.set_speed = stream_set_speed,
.start = stream_run,
};
void stream_start(const char *job_id, BlockDriverState *bs,
@@ -243,7 +251,7 @@ void stream_start(const char *job_id, BlockDriverState *bs,
BLK_PERM_GRAPH_MOD,
BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
BLK_PERM_WRITE,
speed, JOB_DEFAULT, NULL, NULL, errp);
speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);
if (!s) {
goto fail;
}
@@ -264,7 +272,7 @@ void stream_start(const char *job_id, BlockDriverState *bs,
s->on_error = on_error;
trace_stream_start(bs, base, s);
job_start(&s->common.job);
block_job_start(&s->common);
return;
fail:
-4
View File
@@ -564,10 +564,6 @@ void throttle_group_unregister_tgm(ThrottleGroupMember *tgm)
qemu_mutex_lock(&tg->lock);
for (i = 0; i < 2; i++) {
if (timer_pending(tgm->throttle_timers.timers[i])) {
tg->any_timer_armed[i] = false;
schedule_next_request(tgm, i);
}
if (tg->tokens[i] == tgm) {
token = throttle_group_next_tgm(tgm);
/* Take care of the case where this is the last tgm in the group */
+3 -5
View File
@@ -85,10 +85,8 @@ static int throttle_open(BlockDriverState *bs, QDict *options,
if (!bs->file) {
return -EINVAL;
}
bs->supported_write_flags = bs->file->bs->supported_write_flags |
BDRV_REQ_WRITE_UNCHANGED;
bs->supported_zero_flags = bs->file->bs->supported_zero_flags |
BDRV_REQ_WRITE_UNCHANGED;
bs->supported_write_flags = bs->file->bs->supported_write_flags;
bs->supported_zero_flags = bs->file->bs->supported_zero_flags;
ret = throttle_parse_options(options, &group, errp);
if (ret == 0) {
@@ -149,7 +147,7 @@ static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
ThrottleGroupMember *tgm = bs->opaque;
throttle_group_co_io_limits_intercept(tgm, bytes, true);
return bdrv_co_pdiscard(bs->file, offset, bytes);
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
}
static int throttle_co_flush(BlockDriverState *bs)
+7 -9
View File
@@ -4,6 +4,11 @@
bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags 0x%x format_name \"%s\""
bdrv_lock_medium(void *bs, bool locked) "bs %p locked %d"
# blockjob.c
block_job_completed(void *job, int ret, int jret) "job %p ret %d corrected ret %d"
block_job_state_transition(void *job, int ret, const char *legal, const char *s0, const char *s1) "job %p (ret: %d) attempting %s transition (%s-->%s)"
block_job_apply_verb(void *job, const char *state, const char *verb, const char *legal) "job %p in state %s; applying verb %s (%s)"
# block/block-backend.c
blk_co_preadv(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
blk_co_pwritev(void *blk, void *bs, int64_t offset, unsigned int bytes, int flags) "blk %p bs %p offset %"PRId64" bytes %u flags 0x%x"
@@ -15,8 +20,6 @@ bdrv_co_preadv(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs
bdrv_co_pwritev(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x"
bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags 0x%x"
bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64
bdrv_co_copy_range_from(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x"
bdrv_co_copy_range_to(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x"
# block/stream.c
stream_one_iteration(void *s, int64_t offset, uint64_t bytes, int is_allocated) "s %p offset %" PRId64 " bytes %" PRIu64 " is_allocated %d"
@@ -44,7 +47,6 @@ backup_do_cow_skip(void *job, int64_t start) "job %p start %"PRId64
backup_do_cow_process(void *job, int64_t start) "job %p start %"PRId64
backup_do_cow_read_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
backup_do_cow_write_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
backup_do_cow_copy_range_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d"
# blockdev.c
qmp_block_job_cancel(void *job) "job %p"
@@ -57,9 +59,8 @@ qmp_block_stream(void *bs, void *job) "bs %p job %p"
# block/file-win32.c
# block/file-posix.c
file_paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
file_paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
file_copy_file_range(void *bs, int src, int64_t src_off, int dst, int64_t dst_off, int64_t bytes, int flags, int64_t ret) "bs %p src_fd %d offset %"PRIu64" dst_fd %d offset %"PRIu64" bytes %"PRIu64" flags %d ret %"PRId64
paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
# block/qcow2.c
qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset 0x%" PRIx64 " bytes %d"
@@ -153,6 +154,3 @@ nvme_free_req_queue_wait(void *q) "q %p"
nvme_cmd_map_qiov(void *s, void *cmd, void *req, void *qiov, int entries) "s %p cmd %p req %p qiov %p entries %d"
nvme_cmd_map_qiov_pages(void *s, int i, uint64_t page) "s %p page[%d] 0x%"PRIx64
nvme_cmd_map_qiov_iov(void *s, int i, void *page, int pages) "s %p iov[%d] %p pages %d"
# block/iscsi.c
iscsi_xcopy(void *src_lun, uint64_t src_off, void *dst_lun, uint64_t dst_off, uint64_t bytes, int ret) "src_lun %p offset %"PRIu64" dst_lun %p offset %"PRIu64" bytes %"PRIu64" ret %d"
+7 -11
View File
@@ -50,12 +50,11 @@
*/
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-visit-block-core.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
@@ -84,6 +83,9 @@
/* Command line option for static images. */
#define BLOCK_OPT_STATIC "static"
#define KiB 1024
#define MiB (KiB * KiB)
#define SECTOR_SIZE 512
#define DEFAULT_CLUSTER_SIZE (1 * MiB)
@@ -432,8 +434,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
} else if (header.block_size != DEFAULT_CLUSTER_SIZE) {
error_setg(errp, "unsupported VDI image (block size %" PRIu32
" is not %" PRIu64 ")",
header.block_size, DEFAULT_CLUSTER_SIZE);
" is not %u)", header.block_size, DEFAULT_CLUSTER_SIZE);
ret = -ENOTSUP;
goto fail;
} else if (header.disk_size >
@@ -864,7 +865,6 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
}
}
ret = 0;
exit:
blk_unref(blk);
bdrv_unref(bs_file);
@@ -933,11 +933,7 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
}
/* Get the QAPI object */
v = qobject_input_visitor_new_flat_confused(qdict, errp);
if (!v) {
ret = -EINVAL;
goto done;
}
v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
visit_free(v);
@@ -955,7 +951,7 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
/* Create the vdi image (format layer) */
ret = vdi_co_do_create(create_options, block_size, errp);
done:
qobject_unref(qdict);
QDECREF(qdict);
qapi_free_BlockdevCreateOptions(create_options);
bdrv_unref(bs_file);
return ret;
+1 -1
View File
@@ -19,7 +19,7 @@
#include "qemu-common.h"
#include "block/block_int.h"
#include "qemu/bswap.h"
#include "vhdx.h"
#include "block/vhdx.h"
/*
* All the VHDX formats on disk are little endian - the following
+1 -1
View File
@@ -24,7 +24,7 @@
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/bswap.h"
#include "vhdx.h"
#include "block/vhdx.h"
typedef struct VHDXLogSequence {
+18 -17
View File
@@ -18,13 +18,12 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/crc32c.h"
#include "qemu/bswap.h"
#include "vhdx.h"
#include "block/vhdx.h"
#include "migration/blocker.h"
#include "qemu/uuid.h"
#include "qapi/qmp/qdict.h"
@@ -185,7 +184,7 @@ uint32_t vhdx_checksum_calc(uint32_t crc, uint8_t *buf, size_t size,
/* Validates the checksum of the buffer, with an in-place CRC.
*
* Zero is substituted during crc calculation for the original crc field,
* and the crc field is restored afterwards. But the buffer will be modified
* and the crc field is restored afterwards. But the buffer will be modifed
* during the calculation, so this may not be not suitable for multi-threaded
* use.
*
@@ -1127,9 +1126,9 @@ static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
break;
case PAYLOAD_BLOCK_FULLY_PRESENT:
qemu_co_mutex_unlock(&s->lock);
ret = bdrv_co_preadv(bs->file, sinfo.file_offset,
sinfo.sectors_avail * BDRV_SECTOR_SIZE,
&hd_qiov, 0);
ret = bdrv_co_readv(bs->file,
sinfo.file_offset >> BDRV_SECTOR_BITS,
sinfo.sectors_avail, &hd_qiov);
qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
goto exit;
@@ -1227,8 +1226,7 @@ int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s)
}
static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov,
int flags)
int nb_sectors, QEMUIOVector *qiov)
{
int ret = -ENOTSUP;
BDRVVHDXState *s = bs->opaque;
@@ -1244,7 +1242,6 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
uint64_t bat_prior_offset = 0;
bool bat_update = false;
assert(!flags);
qemu_iovec_init(&hd_qiov, qiov->niov);
qemu_co_mutex_lock(&s->lock);
@@ -1349,9 +1346,9 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
}
/* block exists, so we can just overwrite it */
qemu_co_mutex_unlock(&s->lock);
ret = bdrv_co_pwritev(bs->file, sinfo.file_offset,
sectors_to_write * BDRV_SECTOR_SIZE,
&hd_qiov, 0);
ret = bdrv_co_writev(bs->file,
sinfo.file_offset >> BDRV_SECTOR_BITS,
sectors_to_write, &hd_qiov);
qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
goto error_bat_restore;
@@ -1952,7 +1949,7 @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
goto delete_and_exit;
}
ret = 0;
delete_and_exit:
blk_unref(blk);
bdrv_unref(bs);
@@ -1965,7 +1962,8 @@ static int coroutine_fn vhdx_co_create_opts(const char *filename,
Error **errp)
{
BlockdevCreateOptions *create_options = NULL;
QDict *qdict;
QDict *qdict = NULL;
QObject *qobj;
Visitor *v;
BlockDriverState *bs = NULL;
Error *local_err = NULL;
@@ -2004,12 +2002,15 @@ static int coroutine_fn vhdx_co_create_opts(const char *filename,
qdict_put_str(qdict, "driver", "vhdx");
qdict_put_str(qdict, "file", bs->node_name);
v = qobject_input_visitor_new_flat_confused(qdict, errp);
if (!v) {
qobj = qdict_crumple(qdict, errp);
QDECREF(qdict);
qdict = qobject_to(QDict, qobj);
if (qdict == NULL) {
ret = -EINVAL;
goto fail;
}
v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
visit_free(v);
@@ -2048,7 +2049,7 @@ static int coroutine_fn vhdx_co_create_opts(const char *filename,
ret = vhdx_co_create(create_options, errp);
fail:
qobject_unref(qdict);
QDECREF(qdict);
bdrv_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
-6
View File
@@ -333,12 +333,6 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
if (!s->cid_checked && bs->backing) {
BlockDriverState *p_bs = bs->backing->bs;
if (strcmp(p_bs->drv->format_name, "vmdk")) {
/* Backing file is not in vmdk format, so it does not have
* a CID, which makes the overlay's parent CID invalid */
return 0;
}
if (vmdk_read_cid(p_bs, 0, &cur_pcid) != 0) {
/* read failure: report as not valid */
return 0;
+8 -5
View File
@@ -26,7 +26,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "qemu/module.h"
#include "qemu/option.h"
@@ -1081,7 +1080,8 @@ static int coroutine_fn vpc_co_create_opts(const char *filename,
QemuOpts *opts, Error **errp)
{
BlockdevCreateOptions *create_options = NULL;
QDict *qdict;
QDict *qdict = NULL;
QObject *qobj;
Visitor *v;
BlockDriverState *bs = NULL;
Error *local_err = NULL;
@@ -1118,12 +1118,15 @@ static int coroutine_fn vpc_co_create_opts(const char *filename,
qdict_put_str(qdict, "driver", "vpc");
qdict_put_str(qdict, "file", bs->node_name);
v = qobject_input_visitor_new_flat_confused(qdict, errp);
if (!v) {
qobj = qdict_crumple(qdict, errp);
QDECREF(qdict);
qdict = qobject_to(QDict, qobj);
if (qdict == NULL) {
ret = -EINVAL;
goto fail;
}
v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err);
visit_free(v);
@@ -1154,7 +1157,7 @@ static int coroutine_fn vpc_co_create_opts(const char *filename,
ret = vpc_co_create(create_options, errp);
fail:
qobject_unref(qdict);
QDECREF(qdict);
bdrv_unref(bs);
qapi_free_BlockdevCreateOptions(create_options);
return ret;
+3 -5
View File
@@ -27,7 +27,6 @@
#include <dirent.h>
#include "qapi/error.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/bswap.h"
@@ -1245,8 +1244,8 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
s->fat2 = NULL;
s->downcase_short_names = 1;
DLOG(fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
dirname, cyls, heads, secs));
fprintf(stderr, "vvfat %s chs %d,%d,%d\n",
dirname, cyls, heads, secs);
s->sector_count = cyls * heads * secs - s->offset_to_bootsector;
@@ -3134,7 +3133,6 @@ static void vvfat_qcow_options(int *child_flags, QDict *child_options,
}
static const BdrvChildRole child_vvfat_qcow = {
.parent_is_bds = true,
.inherit_options = vvfat_qcow_options,
};
@@ -3181,7 +3179,7 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
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);
qobject_unref(options);
QDECREF(options);
if (!s->qcow) {
ret = -EINVAL;
goto err;
+22 -24
View File
@@ -12,7 +12,6 @@
#include <qnio/qnio_api.h>
#include <sys/param.h>
#include "block/block_int.h"
#include "block/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
@@ -217,12 +216,6 @@ static void vxhs_parse_filename(const char *filename, QDict *options,
}
}
static void vxhs_refresh_limits(BlockDriverState *bs, Error **errp)
{
/* XXX Does VXHS support AIO on less than 512-byte alignment? */
bs->bl.request_alignment = 512;
}
static int vxhs_init_and_ref(void)
{
if (vxhs_ref++ == 0) {
@@ -403,7 +396,7 @@ static int vxhs_open(BlockDriverState *bs, QDict *options,
out:
g_free(of_vsa_addr);
qobject_unref(backing_options);
QDECREF(backing_options);
qemu_opts_del(tcp_opts);
qemu_opts_del(opts);
g_free(cacert);
@@ -431,17 +424,21 @@ static const AIOCBInfo vxhs_aiocb_info = {
* and is passed to QNIO. When QNIO completes the work,
* it will be passed back through the callback.
*/
static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, uint64_t offset,
QEMUIOVector *qiov, uint64_t size,
static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, int64_t sector_num,
QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque,
VDISKAIOCmd iodir)
{
VXHSAIOCB *acb = NULL;
BDRVVXHSState *s = bs->opaque;
size_t size;
uint64_t offset;
int iio_flags = 0;
int ret = 0;
void *dev_handle = s->vdisk_hostinfo.dev_handle;
offset = sector_num * BDRV_SECTOR_SIZE;
size = nb_sectors * BDRV_SECTOR_SIZE;
acb = qemu_aio_get(&vxhs_aiocb_info, bs, cb, opaque);
/*
@@ -454,11 +451,11 @@ static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, uint64_t offset,
switch (iodir) {
case VDISK_AIO_WRITE:
ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
offset, size, iio_flags);
offset, (uint64_t)size, iio_flags);
break;
case VDISK_AIO_READ:
ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
offset, size, iio_flags);
offset, (uint64_t)size, iio_flags);
break;
default:
trace_vxhs_aio_rw_invalid(iodir);
@@ -477,20 +474,22 @@ errout:
return NULL;
}
static BlockAIOCB *vxhs_aio_preadv(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
static BlockAIOCB *vxhs_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov,
int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
return vxhs_aio_rw(bs, offset, qiov, bytes, cb, opaque, VDISK_AIO_READ);
return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
opaque, VDISK_AIO_READ);
}
static BlockAIOCB *vxhs_aio_pwritev(BlockDriverState *bs,
uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags,
BlockCompletionFunc *cb, void *opaque)
static BlockAIOCB *vxhs_aio_writev(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov,
int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
return vxhs_aio_rw(bs, offset, qiov, bytes, cb, opaque, VDISK_AIO_WRITE);
return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors,
cb, opaque, VDISK_AIO_WRITE);
}
static void vxhs_close(BlockDriverState *bs)
@@ -562,11 +561,10 @@ static BlockDriver bdrv_vxhs = {
.instance_size = sizeof(BDRVVXHSState),
.bdrv_file_open = vxhs_open,
.bdrv_parse_filename = vxhs_parse_filename,
.bdrv_refresh_limits = vxhs_refresh_limits,
.bdrv_close = vxhs_close,
.bdrv_getlength = vxhs_getlength,
.bdrv_aio_preadv = vxhs_aio_preadv,
.bdrv_aio_pwritev = vxhs_aio_pwritev,
.bdrv_aio_readv = vxhs_aio_readv,
.bdrv_aio_writev = vxhs_aio_writev,
};
static void bdrv_vxhs_init(void)
+3 -2
View File
@@ -112,14 +112,15 @@ static const AIOCBInfo win32_aiocb_info = {
BlockAIOCB *win32_aio_submit(BlockDriverState *bs,
QEMUWin32AIOState *aio, HANDLE hfile,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque, int type)
{
struct QEMUWin32AIOCB *waiocb;
uint64_t offset = sector_num * 512;
DWORD rc;
waiocb = qemu_aio_get(&win32_aiocb_info, bs, cb, opaque);
waiocb->nbytes = bytes;
waiocb->nbytes = nb_sectors * 512;
waiocb->qiov = qiov;
waiocb->is_read = (type == QEMU_AIO_READ);
-23
View File
@@ -220,26 +220,3 @@ void qmp_nbd_server_stop(Error **errp)
nbd_server_free(nbd_server);
nbd_server = NULL;
}
void qmp_x_nbd_server_add_bitmap(const char *name, const char *bitmap,
bool has_bitmap_export_name,
const char *bitmap_export_name,
Error **errp)
{
NBDExport *exp;
if (!nbd_server) {
error_setg(errp, "NBD server not running");
return;
}
exp = nbd_export_find(name);
if (exp == NULL) {
error_setg(errp, "Export '%s' is not found", name);
return;
}
nbd_export_bitmap(exp, bitmap,
has_bitmap_export_name ? bitmap_export_name : bitmap,
errp);
}
+46 -216
View File
@@ -35,7 +35,6 @@
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
#include "block/blockjob.h"
#include "block/qdict.h"
#include "block/throttle-groups.h"
#include "monitor/monitor.h"
#include "qemu/error-report.h"
@@ -151,7 +150,7 @@ void blockdev_mark_auto_del(BlockBackend *blk)
aio_context_acquire(aio_context);
if (bs->job) {
job_cancel(&bs->job->job, false);
block_job_cancel(bs->job, false);
}
aio_context_release(aio_context);
@@ -577,7 +576,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
blk_rs->read_only = read_only;
blk_rs->detect_zeroes = detect_zeroes;
qobject_unref(bs_opts);
QDECREF(bs_opts);
} else {
if (file && !*file) {
file = NULL;
@@ -633,16 +632,16 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
err_no_bs_opts:
qemu_opts_del(opts);
qobject_unref(interval_dict);
qobject_unref(interval_list);
QDECREF(interval_dict);
QDECREF(interval_list);
return blk;
early_err:
qemu_opts_del(opts);
qobject_unref(interval_dict);
qobject_unref(interval_list);
QDECREF(interval_dict);
QDECREF(interval_list);
err_no_opts:
qobject_unref(bs_opts);
QDECREF(bs_opts);
return NULL;
}
@@ -1131,7 +1130,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
fail:
qemu_opts_del(legacy_opts);
qobject_unref(bs_opts);
QDECREF(bs_opts);
return dinfo;
}
@@ -1447,7 +1446,7 @@ typedef struct BlkActionOps {
struct BlkActionState {
TransactionAction *action;
const BlkActionOps *ops;
JobTxn *block_job_txn;
BlockJobTxn *block_job_txn;
TransactionProperties *txn_props;
QSIMPLEQ_ENTRY(BlkActionState) entry;
};
@@ -1865,7 +1864,7 @@ typedef struct DriveBackupState {
BlockJob *job;
} DriveBackupState;
static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
Error **errp);
static void drive_backup_prepare(BlkActionState *common, Error **errp)
@@ -1911,7 +1910,7 @@ static void drive_backup_commit(BlkActionState *common)
aio_context_acquire(aio_context);
assert(state->job);
job_start(&state->job->job);
block_job_start(state->job);
aio_context_release(aio_context);
}
@@ -1926,7 +1925,7 @@ static void drive_backup_abort(BlkActionState *common)
aio_context = bdrv_get_aio_context(state->bs);
aio_context_acquire(aio_context);
job_cancel_sync(&state->job->job);
block_job_cancel_sync(state->job);
aio_context_release(aio_context);
}
@@ -1955,7 +1954,7 @@ typedef struct BlockdevBackupState {
BlockJob *job;
} BlockdevBackupState;
static BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
static BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
Error **errp);
static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
@@ -1969,7 +1968,7 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
backup = common->action->u.blockdev_backup.data;
bs = bdrv_lookup_bs(backup->device, backup->device, errp);
bs = qmp_get_root_bs(backup->device, errp);
if (!bs) {
return;
}
@@ -2009,7 +2008,7 @@ static void blockdev_backup_commit(BlkActionState *common)
aio_context_acquire(aio_context);
assert(state->job);
job_start(&state->job->job);
block_job_start(state->job);
aio_context_release(aio_context);
}
@@ -2024,7 +2023,7 @@ static void blockdev_backup_abort(BlkActionState *common)
aio_context = bdrv_get_aio_context(state->bs);
aio_context_acquire(aio_context);
job_cancel_sync(&state->job->job);
block_job_cancel_sync(state->job);
aio_context_release(aio_context);
}
@@ -2053,7 +2052,6 @@ typedef struct BlockDirtyBitmapState {
BlockDriverState *bs;
HBitmap *backup;
bool prepared;
bool was_enabled;
} BlockDirtyBitmapState;
static void block_dirty_bitmap_add_prepare(BlkActionState *common,
@@ -2074,7 +2072,6 @@ static void block_dirty_bitmap_add_prepare(BlkActionState *common,
action->has_granularity, action->granularity,
action->has_persistent, action->persistent,
action->has_autoload, action->autoload,
action->has_x_disabled, action->x_disabled,
&local_err);
if (!local_err) {
@@ -2154,74 +2151,6 @@ static void block_dirty_bitmap_clear_commit(BlkActionState *common)
hbitmap_free(state->backup);
}
static void block_dirty_bitmap_enable_prepare(BlkActionState *common,
Error **errp)
{
BlockDirtyBitmap *action;
BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
common, common);
if (action_check_completion_mode(common, errp) < 0) {
return;
}
action = common->action->u.x_block_dirty_bitmap_enable.data;
state->bitmap = block_dirty_bitmap_lookup(action->node,
action->name,
NULL,
errp);
if (!state->bitmap) {
return;
}
state->was_enabled = bdrv_dirty_bitmap_enabled(state->bitmap);
bdrv_enable_dirty_bitmap(state->bitmap);
}
static void block_dirty_bitmap_enable_abort(BlkActionState *common)
{
BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
common, common);
if (!state->was_enabled) {
bdrv_disable_dirty_bitmap(state->bitmap);
}
}
static void block_dirty_bitmap_disable_prepare(BlkActionState *common,
Error **errp)
{
BlockDirtyBitmap *action;
BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
common, common);
if (action_check_completion_mode(common, errp) < 0) {
return;
}
action = common->action->u.x_block_dirty_bitmap_disable.data;
state->bitmap = block_dirty_bitmap_lookup(action->node,
action->name,
NULL,
errp);
if (!state->bitmap) {
return;
}
state->was_enabled = bdrv_dirty_bitmap_enabled(state->bitmap);
bdrv_disable_dirty_bitmap(state->bitmap);
}
static void block_dirty_bitmap_disable_abort(BlkActionState *common)
{
BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
common, common);
if (state->was_enabled) {
bdrv_enable_dirty_bitmap(state->bitmap);
}
}
static void abort_prepare(BlkActionState *common, Error **errp)
{
error_setg(errp, "Transaction aborted using Abort action");
@@ -2282,17 +2211,7 @@ static const BlkActionOps actions[] = {
.prepare = block_dirty_bitmap_clear_prepare,
.commit = block_dirty_bitmap_clear_commit,
.abort = block_dirty_bitmap_clear_abort,
},
[TRANSACTION_ACTION_KIND_X_BLOCK_DIRTY_BITMAP_ENABLE] = {
.instance_size = sizeof(BlockDirtyBitmapState),
.prepare = block_dirty_bitmap_enable_prepare,
.abort = block_dirty_bitmap_enable_abort,
},
[TRANSACTION_ACTION_KIND_X_BLOCK_DIRTY_BITMAP_DISABLE] = {
.instance_size = sizeof(BlockDirtyBitmapState),
.prepare = block_dirty_bitmap_disable_prepare,
.abort = block_dirty_bitmap_disable_abort,
}
}
};
/**
@@ -2324,7 +2243,7 @@ void qmp_transaction(TransactionActionList *dev_list,
Error **errp)
{
TransactionActionList *dev_entry = dev_list;
JobTxn *block_job_txn = NULL;
BlockJobTxn *block_job_txn = NULL;
BlkActionState *state, *next;
Error *local_err = NULL;
@@ -2332,11 +2251,11 @@ void qmp_transaction(TransactionActionList *dev_list,
QSIMPLEQ_INIT(&snap_bdrv_states);
/* Does this transaction get canceled as a group on failure?
* If not, we don't really need to make a JobTxn.
* If not, we don't really need to make a BlockJobTxn.
*/
props = get_transaction_properties(props);
if (props->completion_mode != ACTION_COMPLETION_MODE_INDIVIDUAL) {
block_job_txn = job_txn_new();
block_job_txn = block_job_txn_new();
}
/* drain all i/o before any operations */
@@ -2395,7 +2314,7 @@ exit:
if (!has_props) {
qapi_free_TransactionProperties(props);
}
job_txn_unref(block_job_txn);
block_job_txn_unref(block_job_txn);
}
void qmp_eject(bool has_device, const char *device,
@@ -2882,7 +2801,6 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
bool has_granularity, uint32_t granularity,
bool has_persistent, bool persistent,
bool has_autoload, bool autoload,
bool has_disabled, bool disabled,
Error **errp)
{
BlockDriverState *bs;
@@ -2917,10 +2835,6 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
warn_report("Autoload option is deprecated and its value is ignored");
}
if (!has_disabled) {
disabled = false;
}
if (persistent &&
!bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
{
@@ -2932,10 +2846,6 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
return;
}
if (disabled) {
bdrv_disable_dirty_bitmap(bitmap);
}
bdrv_dirty_bitmap_set_persistance(bitmap, persistent);
}
@@ -2971,6 +2881,7 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
}
}
bdrv_dirty_bitmap_make_anon(bitmap);
bdrv_release_dirty_bitmap(bs, bitmap);
}
@@ -3012,78 +2923,6 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
bdrv_clear_dirty_bitmap(bitmap, NULL);
}
void qmp_x_block_dirty_bitmap_enable(const char *node, const char *name,
Error **errp)
{
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
if (!bitmap) {
return;
}
if (bdrv_dirty_bitmap_frozen(bitmap)) {
error_setg(errp,
"Bitmap '%s' is currently frozen and cannot be enabled",
name);
return;
}
bdrv_enable_dirty_bitmap(bitmap);
}
void qmp_x_block_dirty_bitmap_disable(const char *node, const char *name,
Error **errp)
{
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
if (!bitmap) {
return;
}
if (bdrv_dirty_bitmap_frozen(bitmap)) {
error_setg(errp,
"Bitmap '%s' is currently frozen and cannot be disabled",
name);
return;
}
bdrv_disable_dirty_bitmap(bitmap);
}
void qmp_x_block_dirty_bitmap_merge(const char *node, const char *dst_name,
const char *src_name, Error **errp)
{
BlockDriverState *bs;
BdrvDirtyBitmap *dst, *src;
dst = block_dirty_bitmap_lookup(node, dst_name, &bs, errp);
if (!dst) {
return;
}
if (bdrv_dirty_bitmap_frozen(dst)) {
error_setg(errp, "Bitmap '%s' is frozen and cannot be modified",
dst_name);
return;
} else if (bdrv_dirty_bitmap_readonly(dst)) {
error_setg(errp, "Bitmap '%s' is readonly and cannot be modified",
dst_name);
return;
}
src = bdrv_find_dirty_bitmap(bs, src_name);
if (!src) {
error_setg(errp, "Dirty bitmap '%s' not found", src_name);
return;
}
bdrv_merge_dirty_bitmap(dst, src, errp);
}
BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
const char *name,
Error **errp)
@@ -3405,7 +3244,7 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
goto out;
}
commit_active_start(has_job_id ? job_id : NULL, bs, base_bs,
JOB_DEFAULT, speed, on_error,
BLOCK_JOB_DEFAULT, speed, on_error,
filter_node_name, NULL, NULL, false, &local_err);
} else {
BlockDriverState *overlay_bs = bdrv_find_overlay(bs, top_bs);
@@ -3425,7 +3264,7 @@ out:
aio_context_release(aio_context);
}
static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn,
Error **errp)
{
BlockDriverState *bs;
@@ -3436,7 +3275,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
AioContext *aio_context;
QDict *options = NULL;
Error *local_err = NULL;
int flags, job_flags = JOB_DEFAULT;
int flags, job_flags = BLOCK_JOB_DEFAULT;
int64_t size;
bool set_backing_hd = false;
@@ -3559,10 +3398,10 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
}
}
if (!backup->auto_finalize) {
job_flags |= JOB_MANUAL_FINALIZE;
job_flags |= BLOCK_JOB_MANUAL_FINALIZE;
}
if (!backup->auto_dismiss) {
job_flags |= JOB_MANUAL_DISMISS;
job_flags |= BLOCK_JOB_MANUAL_DISMISS;
}
job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
@@ -3586,7 +3425,7 @@ void qmp_drive_backup(DriveBackup *arg, Error **errp)
BlockJob *job;
job = do_drive_backup(arg, NULL, errp);
if (job) {
job_start(&job->job);
block_job_start(job);
}
}
@@ -3595,7 +3434,7 @@ BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
return bdrv_named_nodes_list(errp);
}
BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
BlockJob *do_blockdev_backup(BlockdevBackup *backup, BlockJobTxn *txn,
Error **errp)
{
BlockDriverState *bs;
@@ -3603,7 +3442,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
Error *local_err = NULL;
AioContext *aio_context;
BlockJob *job = NULL;
int job_flags = JOB_DEFAULT;
int job_flags = BLOCK_JOB_DEFAULT;
if (!backup->has_speed) {
backup->speed = 0;
@@ -3627,7 +3466,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
backup->compress = false;
}
bs = bdrv_lookup_bs(backup->device, backup->device, errp);
bs = qmp_get_root_bs(backup->device, errp);
if (!bs) {
return NULL;
}
@@ -3652,10 +3491,10 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
}
}
if (!backup->auto_finalize) {
job_flags |= JOB_MANUAL_FINALIZE;
job_flags |= BLOCK_JOB_MANUAL_FINALIZE;
}
if (!backup->auto_dismiss) {
job_flags |= JOB_MANUAL_DISMISS;
job_flags |= BLOCK_JOB_MANUAL_DISMISS;
}
job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
backup->sync, NULL, backup->compress,
@@ -3674,7 +3513,7 @@ void qmp_blockdev_backup(BlockdevBackup *arg, Error **errp)
BlockJob *job;
job = do_blockdev_backup(arg, NULL, errp);
if (job) {
job_start(&job->job);
block_job_start(job);
}
}
@@ -3696,7 +3535,6 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
bool has_unmap, bool unmap,
bool has_filter_node_name,
const char *filter_node_name,
bool has_copy_mode, MirrorCopyMode copy_mode,
Error **errp)
{
@@ -3721,9 +3559,6 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
if (!has_filter_node_name) {
filter_node_name = NULL;
}
if (!has_copy_mode) {
copy_mode = MIRROR_COPY_MODE_BACKGROUND;
}
if (granularity != 0 && (granularity < 512 || granularity > 1048576 * 64)) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "granularity",
@@ -3754,7 +3589,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
has_replaces ? replaces : NULL,
speed, granularity, buf_size, sync, backing_mode,
on_source_error, on_target_error, unmap, filter_node_name,
copy_mode, errp);
errp);
}
void qmp_drive_mirror(DriveMirror *arg, Error **errp)
@@ -3900,7 +3735,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
arg->has_on_target_error, arg->on_target_error,
arg->has_unmap, arg->unmap,
false, NULL,
arg->has_copy_mode, arg->copy_mode,
&local_err);
bdrv_unref(target_bs);
error_propagate(errp, local_err);
@@ -3921,7 +3755,6 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
BlockdevOnError on_target_error,
bool has_filter_node_name,
const char *filter_node_name,
bool has_copy_mode, MirrorCopyMode copy_mode,
Error **errp)
{
BlockDriverState *bs;
@@ -3954,7 +3787,6 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id,
has_on_target_error, on_target_error,
true, true,
has_filter_node_name, filter_node_name,
has_copy_mode, copy_mode,
&local_err);
error_propagate(errp, local_err);
@@ -4012,14 +3844,14 @@ void qmp_block_job_cancel(const char *device,
force = false;
}
if (job_user_paused(&job->job) && !force) {
if (block_job_user_paused(job) && !force) {
error_setg(errp, "The block job for device '%s' is currently paused",
device);
goto out;
}
trace_qmp_block_job_cancel(job);
job_user_cancel(&job->job, force, errp);
block_job_user_cancel(job, force, errp);
out:
aio_context_release(aio_context);
}
@@ -4034,7 +3866,7 @@ void qmp_block_job_pause(const char *device, Error **errp)
}
trace_qmp_block_job_pause(job);
job_user_pause(&job->job, errp);
block_job_user_pause(job, errp);
aio_context_release(aio_context);
}
@@ -4048,7 +3880,7 @@ void qmp_block_job_resume(const char *device, Error **errp)
}
trace_qmp_block_job_resume(job);
job_user_resume(&job->job, errp);
block_job_user_resume(job, errp);
aio_context_release(aio_context);
}
@@ -4062,7 +3894,7 @@ void qmp_block_job_complete(const char *device, Error **errp)
}
trace_qmp_block_job_complete(job);
job_complete(&job->job, errp);
block_job_complete(job, errp);
aio_context_release(aio_context);
}
@@ -4076,23 +3908,21 @@ void qmp_block_job_finalize(const char *id, Error **errp)
}
trace_qmp_block_job_finalize(job);
job_finalize(&job->job, errp);
block_job_finalize(job, errp);
aio_context_release(aio_context);
}
void qmp_block_job_dismiss(const char *id, Error **errp)
{
AioContext *aio_context;
BlockJob *bjob = find_block_job(id, &aio_context, errp);
Job *job;
BlockJob *job = find_block_job(id, &aio_context, errp);
if (!bjob) {
if (!job) {
return;
}
trace_qmp_block_job_dismiss(bjob);
job = &bjob->job;
job_dismiss(&job, errp);
trace_qmp_block_job_dismiss(job);
block_job_dismiss(&job, errp);
aio_context_release(aio_context);
}
@@ -4192,7 +4022,7 @@ void hmp_drive_add_node(Monitor *mon, const char *optstr)
qdict = qemu_opts_to_qdict(opts, NULL);
if (!qdict_get_try_str(qdict, "node-name")) {
qobject_unref(qdict);
QDECREF(qdict);
error_report("'node-name' needs to be specified");
goto out;
}
+956 -184
View File
File diff suppressed because it is too large. Load diff
+5 -7
View File
@@ -17,7 +17,6 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu-version.h"
#include <machine/trap.h>
@@ -796,9 +795,9 @@ int main(int argc, char **argv)
if (x86_stack_size <= 0)
usage();
if (*r == 'M')
x86_stack_size *= MiB;
x86_stack_size *= 1024 * 1024;
else if (*r == 'k' || *r == 'K')
x86_stack_size *= KiB;
x86_stack_size *= 1024;
} else if (!strcmp(r, "L")) {
interp_prefix = argv[optind++];
} else if (!strcmp(r, "p")) {
@@ -899,10 +898,9 @@ int main(int argc, char **argv)
cpu_model = "any";
#endif
}
/* init tcg before creating CPUs and to get qemu_host_page_size */
tcg_exec_init(0);
/* NOTE: we need to init the CPU at this stage to get
qemu_host_page_size */
cpu_type = parse_cpu_model(cpu_model);
cpu = cpu_create(cpu_type);
env = cpu->env_ptr;
@@ -919,7 +917,7 @@ int main(int argc, char **argv)
envlist_free(envlist);
/*
* Now that page sizes are configured in tcg_exec_init() we can do
* Now that page sizes are configured in cpu_init() we can do
* proper page alignment for guest_base.
*/
guest_base = HOST_PAGE_ALIGN(guest_base);
-1
View File
@@ -21,7 +21,6 @@
#include "qemu.h"
#include "qemu-common.h"
#include "bsd-mman.h"
#include "exec/exec-all.h"
//#define DEBUG_MMAP
+1
View File
@@ -19,6 +19,7 @@
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
#undef DEBUG_REMAP
+2 -3
View File
@@ -139,7 +139,7 @@ static void tty_serial_init(int fd, int speed,
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
| INLCR | IGNCR | ICRNL | IXON);
tty.c_oflag &= ~OPOST;
tty.c_oflag |= OPOST;
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
tty.c_cflag &= ~(CSIZE | PARENB | PARODD | CRTSCTS | CSTOPB);
switch (data_bits) {
@@ -265,8 +265,7 @@ static void qmp_chardev_open_serial(Chardev *chr,
ChardevHostdev *serial = backend->u.serial.data;
int fd;
fd = qmp_chardev_open_file_source(serial->device, O_RDWR | O_NONBLOCK,
errp);
fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
if (fd < 0) {
return;
}
+2 -5
View File
@@ -134,11 +134,8 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
s->write_msgfds,
s->write_msgfds_num);
/* free the written msgfds in any cases
* other than ret < 0 && errno == EAGAIN
*/
if (!(ret < 0 && EAGAIN == errno)
&& s->write_msgfds_num) {
/* free the written msgfds, no matter what */
if (s->write_msgfds_num) {
g_free(s->write_msgfds);
s->write_msgfds = 0;
s->write_msgfds_num = 0;
+2 -4
View File
@@ -46,10 +46,8 @@ static bool stdio_echo_state;
static void term_exit(void)
{
if (stdio_in_use) {
tcsetattr(0, TCSANOW, &oldtty);
fcntl(0, F_SETFL, old_fd0_flags);
}
tcsetattr(0, TCSANOW, &oldtty);
fcntl(0, F_SETFL, old_fd0_flags);
}
static void qemu_chr_set_echo_stdio(Chardev *chr, bool echo)
Vendored
+41 -269
View File
@@ -60,11 +60,6 @@ do_compiler() {
# is compiler binary to execute.
local compiler="$1"
shift
if test -n "$BASH_VERSION"; then eval '
echo >>config.log "
funcs: ${FUNCNAME[*]}
lines: ${BASH_LINENO[*]}"
'; fi
echo $compiler "$@" >> config.log
$compiler "$@" >> config.log 2>&1 || return $?
# Test passed. If this is an --enable-werror build, rerun
@@ -289,6 +284,7 @@ libs_softmmu=""
libs_tools=""
audio_pt_int=""
audio_win_int=""
cc_i386=i386-pc-linux-gnu-gcc
libs_qga=""
debug_info="yes"
stack_protector=""
@@ -300,24 +296,6 @@ then
else
git_update=no
git_submodules=""
if ! test -f "$source_path/ui/keycodemapdb/README"
then
echo
echo "ERROR: missing file $source_path/ui/keycodemapdb/README"
echo
echo "This is not a GIT checkout but module content appears to"
echo "be missing. Do not use 'git archive' or GitHub download links"
echo "to acquire QEMU source archives. Non-GIT builds are only"
echo "supported with source archives linked from:"
echo
echo " https://www.qemu.org/download/"
echo
echo "Developers working with GIT can use scripts/archive-source.sh"
echo "if they need to create valid source archives."
echo
exit 1
fi
fi
git="git"
@@ -473,21 +451,6 @@ jemalloc="no"
replication="yes"
vxhs=""
libxml2=""
docker="no"
debug_mutex="no"
# cross compilers defaults, can be overridden with --cross-cc-ARCH
cross_cc_aarch64="aarch64-linux-gnu-gcc"
cross_cc_aarch64_be="$cross_cc_aarch64"
cross_cc_cflags_aarch64_be="-mbig-endian"
cross_cc_arm="arm-linux-gnueabihf-gcc"
cross_cc_cflags_armeb="-mbig-endian"
cross_cc_i386="i386-pc-linux-gnu-gcc"
cross_cc_cflags_i386=""
cross_cc_powerpc="powerpc-linux-gnu-gcc"
cross_cc_powerpc="powerpc-linux-gnu-gcc"
enabled_cross_compilers=""
supported_cpu="no"
supported_os="no"
@@ -519,14 +482,6 @@ for opt do
;;
--disable-debug-info) debug_info="no"
;;
--cross-cc-*[!a-zA-Z0-9_-]*=*) error_exit "Passed bad --cross-cc-FOO option"
;;
--cross-cc-cflags-*) cc_arch=${opt#--cross-cc-flags-}; cc_arch=${cc_arch%%=*}
eval "cross_cc_cflags_${cc_arch}=\$optarg"
;;
--cross-cc-*) cc_arch=${opt#--cross-cc-}; cc_arch=${cc_arch%%=*}
eval "cross_cc_${cc_arch}=\$optarg"
;;
esac
done
# OS specific
@@ -715,37 +670,30 @@ case "$cpu" in
ppc|ppc64|s390|s390x|sparc64|x32)
cpu="$cpu"
supported_cpu="yes"
eval "cross_cc_${cpu}=\$host_cc"
;;
i386|i486|i586|i686|i86pc|BePC)
cpu="i386"
supported_cpu="yes"
cross_cc_i386=$host_cc
;;
x86_64|amd64)
cpu="x86_64"
supported_cpu="yes"
cross_cc_x86_64=$host_cc
;;
armv*b|armv*l|arm)
cpu="arm"
supported_cpu="yes"
cross_cc_arm=$host_cc
;;
aarch64)
cpu="aarch64"
supported_cpu="yes"
cross_cc_aarch64=$host_cc
;;
mips*)
cpu="mips"
supported_cpu="yes"
cross_cc_mips=$host_cc
;;
sparc|sun4[cdmuv])
cpu="sparc"
supported_cpu="yes"
cross_cc_sparc=$host_cc
;;
*)
# This will result in either an error or falling back to TCI later
@@ -963,8 +911,6 @@ for opt do
;;
--disable-debug-info)
;;
--cross-cc-*)
;;
--enable-modules)
modules="yes"
;;
@@ -1060,7 +1006,6 @@ for opt do
--enable-debug)
# Enable debugging options that aren't excessively noisy
debug_tcg="yes"
debug_mutex="yes"
debug="yes"
strip_opt="no"
fortify_source="no"
@@ -1431,10 +1376,6 @@ for opt do
;;
--disable-git-update) git_update=no
;;
--enable-debug-mutex) debug_mutex=yes
;;
--disable-debug-mutex) debug_mutex=no
;;
*)
echo "ERROR: unknown option $opt"
echo "Try '$0 --help' for more information"
@@ -1455,44 +1396,31 @@ case "$cpu" in
ppc)
CPU_CFLAGS="-m32"
LDFLAGS="-m32 $LDFLAGS"
cross_cc_powerpc=$cc
cross_cc_cflags_powerpc=$CPU_CFLAGS
;;
ppc64)
CPU_CFLAGS="-m64"
LDFLAGS="-m64 $LDFLAGS"
cross_cc_ppc64=$cc
cross_cc_cflags_ppc64=$CPU_CFLAGS
;;
sparc)
CPU_CFLAGS="-m32 -mv8plus -mcpu=ultrasparc"
LDFLAGS="-m32 -mv8plus $LDFLAGS"
cross_cc_sparc=$cc
cross_cc_cflags_sparc=$CPU_CFLAGS
;;
sparc64)
CPU_CFLAGS="-m64 -mcpu=ultrasparc"
LDFLAGS="-m64 $LDFLAGS"
cross_cc_sparc64=$cc
cross_cc_cflags_sparc64=$CPU_CFLAGS
;;
s390)
CPU_CFLAGS="-m31"
LDFLAGS="-m31 $LDFLAGS"
cross_cc_s390=$cc
cross_cc_cflags_s390=$CPU_CFLAGS
;;
s390x)
CPU_CFLAGS="-m64"
LDFLAGS="-m64 $LDFLAGS"
cross_cc_s390x=$cc
cross_cc_cflags_s390x=$CPU_CFLAGS
;;
i386)
CPU_CFLAGS="-m32"
LDFLAGS="-m32 $LDFLAGS"
cross_cc_i386=$cc
cross_cc_cflags_i386=$CPU_CFLAGS
cc_i386='$(CC) -m32'
;;
x86_64)
# ??? Only extremely old AMD cpus do not have cmpxchg16b.
@@ -1500,14 +1428,12 @@ case "$cpu" in
# runtime and generate the fallback to serial emulation.
CPU_CFLAGS="-m64 -mcx16"
LDFLAGS="-m64 $LDFLAGS"
cross_cc_x86_64=$cc
cross_cc_cflags_x86_64=$CPU_CFLAGS
cc_i386='$(CC) -m32'
;;
x32)
CPU_CFLAGS="-mx32"
LDFLAGS="-mx32 $LDFLAGS"
cross_cc_i386=$cc
cross_cc_cflags_i386=$CPU_CFLAGS
cc_i386='$(CC) -m32'
;;
# No special flags required for other host CPUs
esac
@@ -1569,8 +1495,6 @@ Advanced options (experts only):
--extra-cflags=CFLAGS append extra C compiler flags QEMU_CFLAGS
--extra-cxxflags=CXXFLAGS append extra C++ compiler flags QEMU_CXXFLAGS
--extra-ldflags=LDFLAGS append extra linker flags LDFLAGS
--cross-cc-ARCH=CC use compiler when building ARCH guest test cases
--cross-cc-flags-ARCH= use compiler flags when building ARCH guest tests
--make=MAKE use specified make [$make]
--install=INSTALL use specified install [$install]
--python=PYTHON use specified python [$python]
@@ -1659,7 +1583,7 @@ disabled with --disable-FEATURE, default is enabled if available:
virtfs VirtFS
mpath Multipath persistent reservation passthrough
xen xen backend driver support
xen-pci-passthrough PCI passthrough support for Xen
xen-pci-passthrough
brlapi BrlAPI (Braile)
curl curl connectivity
membarrier membarrier system call (for Linux 4.14+ or Windows)
@@ -1709,7 +1633,6 @@ disabled with --disable-FEATURE, default is enabled if available:
crypto-afalg Linux AF_ALG crypto backend driver
vhost-user vhost-user support
capstone capstone disassembler support
debug-mutex mutex debugging support
NOTE: The object files are built at the place where configure is launched
EOF
@@ -1722,8 +1645,8 @@ fi
# Note that if the Python conditional here evaluates True we will exit
# with status 1 which is a shell 'false' value.
if ! $python -c 'import sys; sys.exit(sys.version_info < (2,7))'; then
error_exit "Cannot use '$python', Python 2 >= 2.7 or Python 3 is required." \
if ! $python -c 'import sys; sys.exit(sys.version_info < (2,6))'; then
error_exit "Cannot use '$python', Python 2 >= 2.6 or Python 3 is required." \
"Use --python=/path/to/python to specify a supported Python."
fi
@@ -2268,9 +2191,6 @@ if test "$xen" != "no" ; then
xen=yes
xen_pc="xencontrol xenstore xenguest xenforeignmemory xengnttab"
xen_pc="$xen_pc xenevtchn xendevicemodel"
if $pkg_config --exists xentoolcore; then
xen_pc="$xen_pc xentoolcore"
fi
QEMU_CFLAGS="$QEMU_CFLAGS $($pkg_config --cflags $xen_pc)"
libs_softmmu="$($pkg_config --libs $xen_pc) $libs_softmmu"
LDFLAGS="$($pkg_config --libs $xen_pc) $LDFLAGS"
@@ -2300,46 +2220,20 @@ EOF
# Xen unstable
elif
cat > $TMPC <<EOF &&
#undef XC_WANT_COMPAT_DEVICEMODEL_API
#define __XEN_TOOLS__
#include <xendevicemodel.h>
#include <xenforeignmemory.h>
int main(void) {
xendevicemodel_handle *xd;
xenforeignmemory_handle *xfmem;
xd = xendevicemodel_open(0, 0);
xendevicemodel_pin_memory_cacheattr(xd, 0, 0, 0, 0);
xfmem = xenforeignmemory_open(0, 0);
xenforeignmemory_map_resource(xfmem, 0, 0, 0, 0, 0, NULL, 0, 0);
return 0;
}
EOF
compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs -lxentoolcore"
then
xen_stable_libs="-lxendevicemodel $xen_stable_libs -lxentoolcore"
xen_ctrl_version=41100
xen=yes
elif
cat > $TMPC <<EOF &&
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
#include <xenforeignmemory.h>
#include <xentoolcore.h>
int main(void) {
xenforeignmemory_handle *xfmem;
xfmem = xenforeignmemory_open(0, 0);
xenforeignmemory_map2(xfmem, 0, 0, 0, 0, 0, 0, 0);
xentoolcore_restrict_all(0);
return 0;
}
EOF
compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs -lxentoolcore"
compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs"
then
xen_stable_libs="-lxendevicemodel $xen_stable_libs -lxentoolcore"
xen_stable_libs="-lxendevicemodel $xen_stable_libs"
xen_ctrl_version=41000
xen=yes
elif
@@ -2601,7 +2495,20 @@ fi
##########################################
# Windows Hypervisor Platform accelerator (WHPX) check
if test "$whpx" != "no" ; then
if check_include "WinHvPlatform.h" && check_include "WinHvEmulation.h"; then
cat > $TMPC << EOF
#include <windows.h>
#include <WinHvPlatform.h>
#include <WinHvEmulation.h>
int main(void) {
WHV_CAPABILITY whpx_cap;
UINT32 writtenSize;
WHvGetCapability(WHvCapabilityCodeFeatures, &whpx_cap, sizeof(whpx_cap),
&writtenSize);
return 0;
}
EOF
if compile_prog "" "-lWinHvPlatform -lWinHvEmulation" ; then
libs_softmmu="$libs_softmmu -lWinHvPlatform -lWinHvEmulation"
whpx="yes"
else
if test "$whpx" = "yes"; then
@@ -3458,7 +3365,11 @@ fi
##########################################
# glib support probe
glib_req_ver=2.40
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-export-2.0"
@@ -3849,22 +3760,22 @@ int main(void) { fdt_first_subnode(0, 0); return 0; }
EOF
if compile_prog "" "$fdt_libs" ; then
# system DTC is good - use it
fdt=system
fdt=yes
else
# have GIT checkout, so activate dtc submodule
if test -e "${source_path}/.git" ; then
git_submodules="${git_submodules} dtc"
fi
if test -d "${source_path}/dtc/libfdt" || test -e "${source_path}/.git" ; then
fdt=git
fdt=yes
dtc_internal="yes"
mkdir -p dtc
if [ "$pwd_is_source_path" != "y" ] ; then
symlink "$source_path/dtc/Makefile" "dtc/Makefile"
symlink "$source_path/dtc/scripts" "dtc/scripts"
fi
fdt_cflags="-I\$(SRC_PATH)/dtc/libfdt"
fdt_ldflags="-L\$(BUILD_DIR)/dtc/libfdt"
fdt_libs="$fdt_libs"
fdt_libs="-L\$(BUILD_DIR)/dtc/libfdt $fdt_libs"
elif test "$fdt" = "yes" ; then
# Not a git build & no libfdt found, prompt for system install
error_exit "DTC (libfdt) version >= 1.4.2 not present." \
@@ -3883,7 +3794,7 @@ libs_softmmu="$libs_softmmu $fdt_libs"
# opengl probe (for sdl2, gtk, milkymist-tmu2)
if test "$opengl" != "no" ; then
opengl_pkgs="epoxy gbm"
opengl_pkgs="epoxy libdrm gbm"
if $pkg_config $opengl_pkgs; then
opengl_cflags="$($pkg_config --cflags $opengl_pkgs)"
opengl_libs="$($pkg_config --libs $opengl_pkgs)"
@@ -4540,7 +4451,7 @@ fi
# check for smartcard support
if test "$smartcard" != "no"; then
if $pkg_config --atleast-version=2.5.1 libcacard; then
if $pkg_config libcacard; then
libcacard_cflags=$($pkg_config --cflags libcacard)
libcacard_libs=$($pkg_config --libs libcacard)
smartcard="yes"
@@ -4666,7 +4577,6 @@ int main(void) { virgl_renderer_poll(); return 0; }
EOF
virgl_cflags=$($pkg_config --cflags virglrenderer 2>/dev/null)
virgl_libs=$($pkg_config --libs virglrenderer 2>/dev/null)
virgl_version=$($pkg_config --modversion virglrenderer 2>/dev/null)
if $pkg_config virglrenderer >/dev/null 2>&1 && \
compile_prog "$virgl_cflags" "$virgl_libs" ; then
virglrenderer="yes"
@@ -4814,21 +4724,6 @@ if compile_prog "" "" ; then
sem_timedwait=yes
fi
##########################################
# check if we have strchrnul
strchrnul=no
cat > $TMPC << EOF
#include <string.h>
int main(void);
// Use a haystack that the compiler shouldn't be able to constant fold
char *haystack = (char*)&main;
int main(void) { return strchrnul(haystack, 'x') != &haystack[6]; }
EOF
if compile_prog "" "" ; then
strchrnul=yes
fi
##########################################
# check if trace backend exists
@@ -5254,20 +5149,6 @@ if test "$fortify_source" != "no"; then
fi
fi
###############################################
# Check if copy_file_range is provided by glibc
have_copy_file_range=no
cat > $TMPC << EOF
#include <unistd.h>
int main(void) {
copy_file_range(0, NULL, 0, NULL, 0, 0);
return 0;
}
EOF
if compile_prog "" "" ; then
have_copy_file_range=yes
fi
##########################################
# check if struct fsxattr is available via linux/fs.h
@@ -5534,17 +5415,6 @@ EOF
fi
fi
##########################################
# Docker and cross-compiler support
#
# This is specifically for building test
# cases for foreign architectures, not
# cross-compiling QEMU itself.
if has "docker"; then
docker=$($python $source_path/tests/docker/docker.py probe)
fi
##########################################
# End of CC checks
# After here, no more $cc or $ld runs
@@ -5847,7 +5717,6 @@ echo_version() {
# prepend pixman and ftd flags after all config tests are done
QEMU_CFLAGS="$pixman_cflags $fdt_cflags $QEMU_CFLAGS"
QEMU_LDFLAGS="$fdt_ldflags $QEMU_LDFLAGS"
libs_softmmu="$pixman_libs $libs_softmmu"
echo "Install prefix $prefix"
@@ -5878,7 +5747,6 @@ echo "ARFLAGS $ARFLAGS"
echo "CFLAGS $CFLAGS"
echo "QEMU_CFLAGS $QEMU_CFLAGS"
echo "LDFLAGS $LDFLAGS"
echo "QEMU_LDFLAGS $QEMU_LDFLAGS"
echo "make $make"
echo "install $install"
echo "python $python"
@@ -5910,7 +5778,7 @@ echo "nettle $nettle $(echo_version $nettle $nettle_version)"
echo "nettle kdf $nettle_kdf"
echo "libtasn1 $tasn1"
echo "curses support $curses"
echo "virgl support $virglrenderer $(echo_version $virglrenderer $virgl_version)"
echo "virgl support $virglrenderer"
echo "curl support $curl"
echo "mingw32 support $mingw32"
echo "Audio drivers $audio_drv_list"
@@ -5987,7 +5855,6 @@ echo "seccomp support $seccomp"
echo "coroutine backend $coroutine"
echo "coroutine pool $coroutine_pool"
echo "debug stack usage $debug_stack_usage"
echo "mutex debugging $debug_mutex"
echo "crypto afalg $crypto_afalg"
echo "GlusterFS support $glusterfs"
echo "gcov $gcov_tool"
@@ -6009,7 +5876,6 @@ echo "avx2 optimization $avx2_opt"
echo "replication support $replication"
echo "VxHS block device $vxhs"
echo "capstone $capstone"
echo "docker $docker"
if test "$sdl_too_old" = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -6313,9 +6179,6 @@ fi
if test "$sem_timedwait" = "yes" ; then
echo "CONFIG_SEM_TIMEDWAIT=y" >> $config_host_mak
fi
if test "$strchrnul" = "yes" ; then
echo "HAVE_STRCHRNUL=y" >> $config_host_mak
fi
if test "$byteswap_h" = "yes" ; then
echo "CONFIG_BYTESWAP_H=y" >> $config_host_mak
fi
@@ -6387,9 +6250,6 @@ fi
if test "$have_fsxattr" = "yes" ; then
echo "HAVE_FSXATTR=y" >> $config_host_mak
fi
if test "$have_copy_file_range" = "yes" ; then
echo "HAVE_COPY_FILE_RANGE=y" >> $config_host_mak
fi
if test "$vte" = "yes" ; then
echo "CONFIG_VTE=y" >> $config_host_mak
echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak
@@ -6446,7 +6306,7 @@ fi
if test "$preadv" = "yes" ; then
echo "CONFIG_PREADV=y" >> $config_host_mak
fi
if test "$fdt" != "no" ; then
if test "$fdt" = "yes" ; then
echo "CONFIG_FDT=y" >> $config_host_mak
fi
if test "$membarrier" = "yes" ; then
@@ -6744,9 +6604,6 @@ fi
if test "$capstone" != "no" ; then
echo "CONFIG_CAPSTONE=y" >> $config_host_mak
fi
if test "$debug_mutex" = "yes" ; then
echo "CONFIG_DEBUG_MUTEX=y" >> $config_host_mak
fi
# Hold two types of flag:
# CONFIG_THREAD_SETNAME_BYTHREAD - we've got a way of setting the name on
@@ -6791,6 +6648,7 @@ echo "CC=$cc" >> $config_host_mak
if $iasl -h > /dev/null 2>&1; then
echo "IASL=$iasl" >> $config_host_mak
fi
echo "CC_I386=$cc_i386" >> $config_host_mak
echo "HOST_CC=$host_cc" >> $config_host_mak
echo "CXX=$cxx" >> $config_host_mak
echo "OBJCC=$objcc" >> $config_host_mak
@@ -6823,7 +6681,6 @@ else
fi
echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
echo "LD_REL_FLAGS=$LD_REL_FLAGS" >> $config_host_mak
echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
echo "LIBS+=$LIBS" >> $config_host_mak
@@ -6842,10 +6699,6 @@ if test "$gcov" = "yes" ; then
echo "GCOV=$gcov_tool" >> $config_host_mak
fi
if test "$docker" != "no"; then
echo "HAVE_USER_DOCKER=y" >> $config_host_mak
fi
# use included Linux headers
if test "$linux" = "yes" ; then
mkdir -p linux-headers
@@ -6909,10 +6762,6 @@ case "$target" in
;;
esac
target_compiler=""
target_compiler_static=""
target_compiler_cflags=""
mkdir -p $target_dir
echo "# Automatically generated by configure - do not modify" > $config_target_mak
@@ -6928,25 +6777,19 @@ TARGET_ABI_DIR=""
case "$target_name" in
i386)
gdb_xml_files="i386-32bit.xml i386-32bit-core.xml i386-32bit-sse.xml"
target_compiler=$cross_cc_i386
target_compiler_cflags=$cross_cc_ccflags_i386
;;
x86_64)
TARGET_BASE_ARCH=i386
gdb_xml_files="i386-64bit.xml i386-64bit-core.xml i386-64bit-sse.xml"
target_compiler=$cross_cc_x86_64
;;
alpha)
mttcg="yes"
target_compiler=$cross_cc_alpha
;;
arm|armeb)
TARGET_ARCH=arm
bflt="yes"
mttcg="yes"
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
target_compiler=$cross_cc_arm
eval "target_compiler_cflags=\$cross_cc_cflags_${target_name}"
;;
aarch64|aarch64_be)
TARGET_ARCH=aarch64
@@ -6954,75 +6797,58 @@ case "$target_name" in
bflt="yes"
mttcg="yes"
gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
target_compiler=$cross_cc_aarch64
eval "target_compiler_cflags=\$cross_cc_cflags_${target_name}"
;;
cris)
target_compiler=$cross_cc_cris
;;
hppa)
mttcg="yes"
target_compiler=$cross_cc_hppa
;;
lm32)
target_compiler=$cross_cc_lm32
;;
m68k)
bflt="yes"
gdb_xml_files="cf-core.xml cf-fp.xml m68k-fp.xml"
target_compiler=$cross_cc_m68k
;;
microblaze|microblazeel)
TARGET_ARCH=microblaze
bflt="yes"
echo "TARGET_ABI32=y" >> $config_target_mak
target_compiler=$cross_cc_microblaze
;;
mips|mipsel)
TARGET_ARCH=mips
target_compiler=$cross_cc_mips
echo "TARGET_ABI_MIPSO32=y" >> $config_target_mak
;;
mipsn32|mipsn32el)
TARGET_ARCH=mips64
TARGET_BASE_ARCH=mips
target_compiler=$cross_cc_mipsn32
echo "TARGET_ABI_MIPSN32=y" >> $config_target_mak
echo "TARGET_ABI32=y" >> $config_target_mak
;;
mips64|mips64el)
TARGET_ARCH=mips64
TARGET_BASE_ARCH=mips
target_compiler=$cross_cc_mips64
echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
;;
moxie)
target_compiler=$cross_cc_moxie
;;
nios2)
target_compiler=$cross_cc_nios2
;;
or1k)
target_compiler=$cross_cc_or1k
TARGET_ARCH=openrisc
TARGET_BASE_ARCH=openrisc
;;
ppc)
gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
target_compiler=$cross_cc_powerpc
;;
ppcemb)
TARGET_BASE_ARCH=ppc
TARGET_ABI_DIR=ppc
gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
target_compiler=$cross_cc_ppcemb
;;
ppc64)
TARGET_BASE_ARCH=ppc
TARGET_ABI_DIR=ppc
mttcg=yes
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml power-vsx.xml"
target_compiler=$cross_cc_ppc64
;;
ppc64le)
TARGET_ARCH=ppc64
@@ -7030,7 +6856,6 @@ case "$target_name" in
TARGET_ABI_DIR=ppc
mttcg=yes
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml power-vsx.xml"
target_compiler=$cross_cc_ppc64le
;;
ppc64abi32)
TARGET_ARCH=ppc64
@@ -7038,57 +6863,45 @@ case "$target_name" in
TARGET_ABI_DIR=ppc
echo "TARGET_ABI32=y" >> $config_target_mak
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml power-vsx.xml"
target_compiler=$cross_cc_ppc64abi32
;;
riscv32)
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
mttcg=yes
target_compiler=$cross_cc_riscv32
;;
riscv64)
TARGET_BASE_ARCH=riscv
TARGET_ABI_DIR=riscv
mttcg=yes
target_compiler=$cross_cc_riscv64
;;
sh4|sh4eb)
TARGET_ARCH=sh4
bflt="yes"
target_compiler=$cross_cc_sh4
;;
sparc)
target_compiler=$cross_cc_sparc
;;
sparc64)
TARGET_BASE_ARCH=sparc
target_compiler=$cross_cc_sparc64
;;
sparc32plus)
TARGET_ARCH=sparc64
TARGET_BASE_ARCH=sparc
TARGET_ABI_DIR=sparc
target_compiler=$cross_cc_sparc32plus
echo "TARGET_ABI32=y" >> $config_target_mak
;;
s390x)
mttcg=yes
gdb_xml_files="s390x-core64.xml s390-acr.xml s390-fpr.xml s390-vx.xml s390-cr.xml s390-virt.xml s390-gs.xml"
target_compiler=$cross_cc_s390x
;;
tilegx)
target_compiler=$cross_cc_tilegx
;;
tricore)
target_compiler=$cross_cc_tricore
;;
unicore32)
target_compiler=$cross_cc_unicore32
;;
xtensa|xtensaeb)
TARGET_ARCH=xtensa
mttcg="yes"
target_compiler=$cross_cc_xtensa
;;
*)
error_exit "Unsupported target CPU"
@@ -7099,27 +6912,6 @@ if [ "$TARGET_BASE_ARCH" = "" ]; then
TARGET_BASE_ARCH=$TARGET_ARCH
fi
# Do we have a cross compiler for this target?
if has $target_compiler; then
write_c_skeleton
if ! do_compiler "$target_compiler" $target_compiler_cflags -o $TMPE $TMPC -static ; then
# For host systems we might get away with building without -static
if ! do_compiler "$target_compiler" $target_compiler_cflags -o $TMPE $TMPC ; then
target_compiler=""
else
enabled_cross_compilers="${enabled_cross_compilers} '${target_compiler}'"
target_compiler_static="n"
fi
else
enabled_cross_compilers="${enabled_cross_compilers} '${target_compiler}'"
target_compiler_static="y"
fi
else
target_compiler=""
fi
symlink "$source_path/Makefile.target" "$target_dir/Makefile"
upper() {
@@ -7193,19 +6985,6 @@ if test "$target_bsd_user" = "yes" ; then
echo "CONFIG_BSD_USER=y" >> $config_target_mak
fi
if test -n "$target_compiler"; then
echo "CROSS_CC_GUEST=\"$target_compiler\"" >> $config_target_mak
if test -n "$target_compiler_static"; then
echo "CROSS_CC_GUEST_STATIC=$target_compiler_static" >> $config_target_mak
fi
if test -n "$target_compiler_cflags"; then
echo "CROSS_CC_GUEST_CFLAGS=$target_compiler_cflags" >> $config_target_mak
fi
fi
# generate QEMU_CFLAGS/LDFLAGS for targets
cflags=""
@@ -7328,12 +7107,7 @@ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
done # for target in $targets
if test -n "$enabled_cross_compilers"; then
echo
echo "NOTE: cross-compilers enabled: $enabled_cross_compilers"
fi
if [ "$fdt" = "git" ]; then
if [ "$dtc_internal" = "yes" ]; then
echo "config-host.h: subdir-dtc" >> $config_host_mak
fi
if [ "$capstone" = "git" -o "$capstone" = "internal" ]; then
@@ -7406,11 +7180,9 @@ for rom in seabios vgabios ; do
done
# set up tests data directory
for tests_subdir in acceptance data; do
if [ ! -e tests/$tests_subdir ]; then
symlink "$source_path/tests/$tests_subdir" tests/$tests_subdir
fi
done
if [ ! -e tests/data ]; then
symlink "$source_path/tests/data" tests/data
fi
# set up qemu-iotests in this build directory
iotests_common_env="tests/qemu-iotests/common.env"
+15 -82
View File
@@ -314,19 +314,22 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
msg.msg_controllen = 0;
}
/* Set the version in the flags when sending the reply */
vmsg->flags &= ~VHOST_USER_VERSION_MASK;
vmsg->flags |= VHOST_USER_VERSION;
vmsg->flags |= VHOST_USER_REPLY_MASK;
do {
rc = sendmsg(conn_fd, &msg, 0);
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
if (vmsg->size) {
do {
if (vmsg->data) {
rc = write(conn_fd, vmsg->data, vmsg->size);
} else {
rc = write(conn_fd, p + VHOST_USER_HDR_SIZE, vmsg->size);
}
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
}
do {
if (vmsg->data) {
rc = write(conn_fd, vmsg->data, vmsg->size);
} else {
rc = write(conn_fd, p + VHOST_USER_HDR_SIZE, vmsg->size);
}
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
if (rc <= 0) {
vu_panic(dev, "Error while writing: %s", strerror(errno));
@@ -336,39 +339,6 @@ vu_message_write(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
return true;
}
static bool
vu_send_reply(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
{
/* Set the version in the flags when sending the reply */
vmsg->flags &= ~VHOST_USER_VERSION_MASK;
vmsg->flags |= VHOST_USER_VERSION;
vmsg->flags |= VHOST_USER_REPLY_MASK;
return vu_message_write(dev, conn_fd, vmsg);
}
static bool
vu_process_message_reply(VuDev *dev, const VhostUserMsg *vmsg)
{
VhostUserMsg msg_reply;
if ((vmsg->flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
return true;
}
if (!vu_message_read(dev, dev->slave_fd, &msg_reply)) {
return false;
}
if (msg_reply.request != vmsg->request) {
DPRINT("Received unexpected msg type. Expected %d received %d",
vmsg->request, msg_reply.request);
return false;
}
return msg_reply.payload.u64 == 0;
}
/* Kick the log_call_fd if required. */
static void
vu_log_kick(VuDev *dev)
@@ -564,7 +534,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
/* Send the message back to qemu with the addresses filled in */
vmsg->fd_num = 0;
if (!vu_send_reply(dev, dev->sock, vmsg)) {
if (!vu_message_write(dev, dev->sock, vmsg)) {
vu_panic(dev, "failed to respond to set-mem-table for postcopy");
return false;
}
@@ -944,41 +914,6 @@ void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
}
}
bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
int size, int offset)
{
int qidx = vq - dev->vq;
int fd_num = 0;
VhostUserMsg vmsg = {
.request = VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG,
.flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK,
.size = sizeof(vmsg.payload.area),
.payload.area = {
.u64 = qidx & VHOST_USER_VRING_IDX_MASK,
.size = size,
.offset = offset,
},
};
if (fd == -1) {
vmsg.payload.area.u64 |= VHOST_USER_VRING_NOFD_MASK;
} else {
vmsg.fds[fd_num++] = fd;
}
vmsg.fd_num = fd_num;
if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) {
return false;
}
if (!vu_message_write(dev, dev->slave_fd, &vmsg)) {
return false;
}
return vu_process_message_reply(dev, &vmsg);
}
static bool
vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg)
{
@@ -1031,9 +966,7 @@ static bool
vu_get_protocol_features_exec(VuDev *dev, VhostUserMsg *vmsg)
{
uint64_t features = 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD |
1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ |
1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER |
1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD;
1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ;
if (have_userfault()) {
features |= 1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT;
@@ -1317,7 +1250,7 @@ vu_dispatch(VuDev *dev)
goto end;
}
if (!vu_send_reply(dev, dev->sock, &vmsg)) {
if (!vu_message_write(dev, dev->sock, &vmsg)) {
goto end;
}
-32
View File
@@ -51,8 +51,6 @@ enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
VHOST_USER_PROTOCOL_F_CONFIG = 9,
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11,
VHOST_USER_PROTOCOL_F_MAX
};
@@ -94,14 +92,6 @@ typedef enum VhostUserRequest {
VHOST_USER_MAX
} VhostUserRequest;
typedef enum VhostUserSlaveRequest {
VHOST_USER_SLAVE_NONE = 0,
VHOST_USER_SLAVE_IOTLB_MSG = 1,
VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG = 3,
VHOST_USER_SLAVE_MAX
} VhostUserSlaveRequest;
typedef struct VhostUserMemoryRegion {
uint64_t guest_phys_addr;
uint64_t memory_size;
@@ -132,12 +122,6 @@ static VhostUserConfig c __attribute__ ((unused));
+ sizeof(c.size) \
+ sizeof(c.flags))
typedef struct VhostUserVringArea {
uint64_t u64;
uint64_t size;
uint64_t offset;
} VhostUserVringArea;
#if defined(_WIN32)
# define VU_PACKED __attribute__((gcc_struct, packed))
#else
@@ -149,7 +133,6 @@ typedef struct VhostUserMsg {
#define VHOST_USER_VERSION_MASK (0x3)
#define VHOST_USER_REPLY_MASK (0x1 << 2)
#define VHOST_USER_NEED_REPLY_MASK (0x1 << 3)
uint32_t flags;
uint32_t size; /* the following payload size */
@@ -162,7 +145,6 @@ typedef struct VhostUserMsg {
VhostUserMemory memory;
VhostUserLog log;
VhostUserConfig config;
VhostUserVringArea area;
} payload;
int fds[VHOST_MEMORY_MAX_NREGIONS];
@@ -386,20 +368,6 @@ VuVirtq *vu_get_queue(VuDev *dev, int qidx);
void vu_set_queue_handler(VuDev *dev, VuVirtq *vq,
vu_queue_handler_cb handler);
/**
* vu_set_queue_host_notifier:
* @dev: a VuDev context
* @vq: a VuVirtq queue
* @fd: a file descriptor
* @size: host page size
* @offset: notifier offset in @fd file
*
* Set queue's host notifier. This function may be called several
* times for the same queue. If called with -1 @fd, the notifier
* is removed.
*/
bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
int size, int offset);
/**
* vu_queue_set_notification:
+13 -42
View File
@@ -31,7 +31,6 @@ typedef struct VubDev {
VugDev parent;
int blk_fd;
struct virtio_blk_config blkcfg;
bool enable_ro;
char *blk_name;
GMainLoop *loop;
} VubDev;
@@ -302,33 +301,14 @@ static void vub_queue_set_started(VuDev *vu_dev, int idx, bool started)
static uint64_t
vub_get_features(VuDev *dev)
{
uint64_t features;
VugDev *gdev;
VubDev *vdev_blk;
gdev = container_of(dev, VugDev, parent);
vdev_blk = container_of(gdev, VubDev, parent);
features = 1ull << VIRTIO_BLK_F_SIZE_MAX |
1ull << VIRTIO_BLK_F_SEG_MAX |
1ull << VIRTIO_BLK_F_TOPOLOGY |
1ull << VIRTIO_BLK_F_BLK_SIZE |
1ull << VIRTIO_BLK_F_FLUSH |
1ull << VIRTIO_BLK_F_CONFIG_WCE |
1ull << VIRTIO_F_VERSION_1 |
1ull << VHOST_USER_F_PROTOCOL_FEATURES;
if (vdev_blk->enable_ro) {
features |= 1ull << VIRTIO_BLK_F_RO;
}
return features;
}
static uint64_t
vub_get_protocol_features(VuDev *dev)
{
return 1ull << VHOST_USER_PROTOCOL_F_CONFIG;
return 1ull << VIRTIO_BLK_F_SIZE_MAX |
1ull << VIRTIO_BLK_F_SEG_MAX |
1ull << VIRTIO_BLK_F_TOPOLOGY |
1ull << VIRTIO_BLK_F_BLK_SIZE |
1ull << VIRTIO_BLK_F_FLUSH |
1ull << VIRTIO_BLK_F_CONFIG_WCE |
1ull << VIRTIO_F_VERSION_1 |
1ull << VHOST_USER_F_PROTOCOL_FEATURES;
}
static int
@@ -393,7 +373,6 @@ vub_set_config(VuDev *vu_dev, const uint8_t *data,
static const VuDevIface vub_iface = {
.get_features = vub_get_features,
.queue_set_started = vub_queue_set_started,
.get_protocol_features = vub_get_protocol_features,
.get_config = vub_get_config,
.set_config = vub_set_config,
};
@@ -490,7 +469,6 @@ vub_new(char *blk_file)
vub_free(vdev_blk);
return NULL;
}
vdev_blk->enable_ro = false;
vdev_blk->blkcfg.wce = 0;
vdev_blk->blk_name = blk_file;
@@ -505,11 +483,10 @@ int main(int argc, char **argv)
int opt;
char *unix_socket = NULL;
char *blk_file = NULL;
bool enable_ro = false;
int lsock = -1, csock = -1;
VubDev *vdev_blk = NULL;
while ((opt = getopt(argc, argv, "b:rs:h")) != -1) {
while ((opt = getopt(argc, argv, "b:s:h")) != -1) {
switch (opt) {
case 'b':
blk_file = g_strdup(optarg);
@@ -517,20 +494,17 @@ int main(int argc, char **argv)
case 's':
unix_socket = g_strdup(optarg);
break;
case 'r':
enable_ro = true;
break;
case 'h':
default:
printf("Usage: %s [ -b block device or file, -s UNIX domain socket"
" | -r Enable read-only ] | [ -h ]\n", argv[0]);
printf("Usage: %s [-b block device or file, -s UNIX domain socket]"
" | [ -h ]\n", argv[0]);
return 0;
}
}
if (!unix_socket || !blk_file) {
printf("Usage: %s [ -b block device or file, -s UNIX domain socket"
" | -r Enable read-only ] | [ -h ]\n", argv[0]);
printf("Usage: %s [-b block device or file, -s UNIX domain socket] |"
" [ -h ]\n", argv[0]);
return -1;
}
@@ -549,9 +523,6 @@ int main(int argc, char **argv)
if (!vdev_blk) {
goto err;
}
if (enable_ro) {
vdev_blk->enable_ro = true;
}
vug_init(&vdev_blk->parent, csock, vub_panic_cb, &vub_iface);
Loaded 100 of 1821 files, more files were not shown because too many files have changed in this diff. Show more