Merge remote-tracking branch 'upstream/master' into main

This commit is contained in:
Andrea Fioraldi 2023-02-27 17:25:14 +01:00
commit a0a2480e9c
269 changed files with 3506 additions and 3134 deletions

View File

@ -11,6 +11,8 @@
# and show the duration of each line. # and show the duration of each line.
FF_SCRIPT_SECTIONS: 1 FF_SCRIPT_SECTIONS: 1
interruptible: true
rules: rules:
############################################################# #############################################################
# Stage 1: exclude scenarios where we definitely don't # Stage 1: exclude scenarios where we definitely don't

View File

@ -11,12 +11,10 @@
fi fi
- mkdir build - mkdir build
- cd build - cd build
- if test -n "$TARGETS"; - ../configure --enable-werror --disable-docs --enable-fdt=system
then ${LD_JOBS:+--meson=git} ${TARGETS:+--target-list="$TARGETS"}
../configure --enable-werror --disable-docs ${LD_JOBS:+--meson=git} $CONFIGURE_ARGS --target-list="$TARGETS" ; $CONFIGURE_ARGS ||
else { cat config.log meson-logs/meson-log.txt && exit 1; }
../configure --enable-werror --disable-docs ${LD_JOBS:+--meson=git} $CONFIGURE_ARGS ;
fi || { cat config.log meson-logs/meson-log.txt && exit 1; }
- if test -n "$LD_JOBS"; - if test -n "$LD_JOBS";
then then
../meson/meson.py configure . -Dbackend_max_links="$LD_JOBS" ; ../meson/meson.py configure . -Dbackend_max_links="$LD_JOBS" ;

View File

@ -41,8 +41,8 @@ build-system-ubuntu:
job: amd64-ubuntu2004-container job: amd64-ubuntu2004-container
variables: variables:
IMAGE: ubuntu2004 IMAGE: ubuntu2004
CONFIGURE_ARGS: --enable-docs --enable-fdt=system --enable-capstone CONFIGURE_ARGS: --enable-docs
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu TARGETS: alpha-softmmu cris-softmmu hppa-softmmu
microblazeel-softmmu mips64el-softmmu microblazeel-softmmu mips64el-softmmu
MAKE_CHECK_ARGS: check-build MAKE_CHECK_ARGS: check-build
artifacts: artifacts:
@ -74,6 +74,7 @@ build-system-debian:
job: amd64-debian-container job: amd64-debian-container
variables: variables:
IMAGE: debian-amd64 IMAGE: debian-amd64
CONFIGURE_ARGS: --with-coroutine=sigaltstack
TARGETS: arm-softmmu avr-softmmu i386-softmmu mipsel-softmmu TARGETS: arm-softmmu avr-softmmu i386-softmmu mipsel-softmmu
riscv64-softmmu sh4eb-softmmu sparc-softmmu xtensaeb-softmmu riscv64-softmmu sh4eb-softmmu sparc-softmmu xtensaeb-softmmu
MAKE_CHECK_ARGS: check-build MAKE_CHECK_ARGS: check-build
@ -119,7 +120,6 @@ build-system-fedora:
variables: variables:
IMAGE: fedora IMAGE: fedora
CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs
--enable-fdt=system --enable-slirp --enable-capstone
TARGETS: tricore-softmmu microblaze-softmmu mips-softmmu TARGETS: tricore-softmmu microblaze-softmmu mips-softmmu
xtensa-softmmu m68k-softmmu riscv32-softmmu ppc-softmmu sparc64-softmmu xtensa-softmmu m68k-softmmu riscv32-softmmu ppc-softmmu sparc64-softmmu
MAKE_CHECK_ARGS: check-build MAKE_CHECK_ARGS: check-build
@ -165,9 +165,8 @@ build-system-centos:
job: amd64-centos8-container job: amd64-centos8-container
variables: variables:
IMAGE: centos8 IMAGE: centos8
CONFIGURE_ARGS: --disable-nettle --enable-gcrypt --enable-fdt=system CONFIGURE_ARGS: --disable-nettle --enable-gcrypt --enable-vfio-user-server
--enable-modules --enable-trace-backends=dtrace --enable-docs --enable-modules --enable-trace-backends=dtrace --enable-docs
--enable-vfio-user-server
TARGETS: ppc64-softmmu or1k-softmmu s390x-softmmu TARGETS: ppc64-softmmu or1k-softmmu s390x-softmmu
x86_64-softmmu rx-softmmu sh4-softmmu nios2-softmmu x86_64-softmmu rx-softmmu sh4-softmmu nios2-softmmu
MAKE_CHECK_ARGS: check-build MAKE_CHECK_ARGS: check-build
@ -200,7 +199,6 @@ build-system-opensuse:
job: amd64-opensuse-leap-container job: amd64-opensuse-leap-container
variables: variables:
IMAGE: opensuse-leap IMAGE: opensuse-leap
CONFIGURE_ARGS: --enable-fdt=system
TARGETS: s390x-softmmu x86_64-softmmu aarch64-softmmu TARGETS: s390x-softmmu x86_64-softmmu aarch64-softmmu
MAKE_CHECK_ARGS: check-build MAKE_CHECK_ARGS: check-build
artifacts: artifacts:
@ -463,7 +461,7 @@ tsan-build:
variables: variables:
IMAGE: ubuntu2004 IMAGE: ubuntu2004
CONFIGURE_ARGS: --enable-tsan --cc=clang-10 --cxx=clang++-10 CONFIGURE_ARGS: --enable-tsan --cc=clang-10 --cxx=clang++-10
--enable-trace-backends=ust --enable-fdt=system --disable-slirp --enable-trace-backends=ust --disable-slirp
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
MAKE_CHECK_ARGS: bench V=1 MAKE_CHECK_ARGS: bench V=1
@ -534,18 +532,6 @@ build-tci:
- QTEST_QEMU_BINARY="./qemu-system-s390x" ./tests/qtest/pxe-test -m slow - QTEST_QEMU_BINARY="./qemu-system-s390x" ./tests/qtest/pxe-test -m slow
- make check-tcg - make check-tcg
# Alternate coroutines implementations are only really of interest to KVM users
# However we can't test against KVM on Gitlab-CI so we can only run unit tests
build-coroutine-sigaltstack:
extends: .native_build_job_template
needs:
job: amd64-ubuntu2004-container
variables:
IMAGE: ubuntu2004
CONFIGURE_ARGS: --with-coroutine=sigaltstack --disable-tcg
--enable-trace-backends=ftrace
MAKE_CHECK_ARGS: check-unit
# Check our reduced build configurations # Check our reduced build configurations
build-without-defaults: build-without-defaults:
extends: .native_build_job_template extends: .native_build_job_template

View File

@ -6,8 +6,9 @@
script: script:
- mkdir build - mkdir build
- cd build - cd build
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS - ../configure --enable-werror --disable-docs --enable-fdt=system
--disable-user --target-list-exclude="arm-softmmu cris-softmmu --disable-user $QEMU_CONFIGURE_OPTS $EXTRA_CONFIGURE_OPTS
--target-list-exclude="arm-softmmu cris-softmmu
i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu
mips64-softmmu ppc-softmmu riscv32-softmmu sh4-softmmu mips64-softmmu ppc-softmmu riscv32-softmmu sh4-softmmu
sparc-softmmu xtensa-softmmu $CROSS_SKIP_TARGETS" sparc-softmmu xtensa-softmmu $CROSS_SKIP_TARGETS"

View File

@ -159,7 +159,7 @@ cross-s390x-kvm-only:
job: s390x-debian-cross-container job: s390x-debian-cross-container
variables: variables:
IMAGE: debian-s390x-cross IMAGE: debian-s390x-cross
EXTRA_CONFIGURE_OPTS: --disable-tcg EXTRA_CONFIGURE_OPTS: --disable-tcg --enable-trace-backends=ftrace
cross-mips64el-kvm-only: cross-mips64el-kvm-only:
extends: .cross_accel_build_job extends: .cross_accel_build_job
@ -175,6 +175,7 @@ cross-win32-system:
job: win32-fedora-cross-container job: win32-fedora-cross-container
variables: variables:
IMAGE: fedora-win32-cross IMAGE: fedora-win32-cross
EXTRA_CONFIGURE_OPTS: --enable-fdt=internal
CROSS_SKIP_TARGETS: alpha-softmmu avr-softmmu hppa-softmmu m68k-softmmu CROSS_SKIP_TARGETS: alpha-softmmu avr-softmmu hppa-softmmu m68k-softmmu
microblazeel-softmmu mips64el-softmmu nios2-softmmu microblazeel-softmmu mips64el-softmmu nios2-softmmu
artifacts: artifacts:
@ -187,6 +188,7 @@ cross-win64-system:
job: win64-fedora-cross-container job: win64-fedora-cross-container
variables: variables:
IMAGE: fedora-win64-cross IMAGE: fedora-win64-cross
EXTRA_CONFIGURE_OPTS: --enable-fdt=internal
CROSS_SKIP_TARGETS: alpha-softmmu avr-softmmu hppa-softmmu CROSS_SKIP_TARGETS: alpha-softmmu avr-softmmu hppa-softmmu
m68k-softmmu microblazeel-softmmu nios2-softmmu m68k-softmmu microblazeel-softmmu nios2-softmmu
or1k-softmmu rx-softmmu sh4eb-softmmu sparc64-softmmu or1k-softmmu rx-softmmu sh4eb-softmmu sparc64-softmmu

View File

@ -23,12 +23,12 @@ check-dco:
before_script: before_script:
- apk -U add git - apk -U add git
check-python-pipenv: check-python-minreqs:
extends: .base_job_template extends: .base_job_template
stage: test stage: test
image: $CI_REGISTRY_IMAGE/qemu/python:latest image: $CI_REGISTRY_IMAGE/qemu/python:latest
script: script:
- make -C python check-pipenv - make -C python check-minreqs
variables: variables:
GIT_DEPTH: 1 GIT_DEPTH: 1
needs: needs:

View File

@ -38,6 +38,7 @@ msys2-64bit:
mingw-w64-x86_64-capstone mingw-w64-x86_64-capstone
mingw-w64-x86_64-curl mingw-w64-x86_64-curl
mingw-w64-x86_64-cyrus-sasl mingw-w64-x86_64-cyrus-sasl
mingw-w64-x86_64-dtc
mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc
mingw-w64-x86_64-glib2 mingw-w64-x86_64-glib2
mingw-w64-x86_64-gnutls mingw-w64-x86_64-gnutls
@ -71,7 +72,7 @@ msys2-64bit:
# for the msys2 64-bit job, due to the build could not complete within # for the msys2 64-bit job, due to the build could not complete within
# the project timeout. # the project timeout.
- ..\msys64\usr\bin\bash -lc '../configure --target-list=x86_64-softmmu - ..\msys64\usr\bin\bash -lc '../configure --target-list=x86_64-softmmu
--without-default-devices' --without-default-devices --enable-fdt=system'
- ..\msys64\usr\bin\bash -lc 'make' - ..\msys64\usr\bin\bash -lc 'make'
# qTests don't run successfully with "--without-default-devices", # qTests don't run successfully with "--without-default-devices",
# so let's exclude the qtests from CI for now. # so let's exclude the qtests from CI for now.
@ -86,6 +87,7 @@ msys2-32bit:
mingw-w64-i686-capstone mingw-w64-i686-capstone
mingw-w64-i686-curl mingw-w64-i686-curl
mingw-w64-i686-cyrus-sasl mingw-w64-i686-cyrus-sasl
mingw-w64-i686-dtc
mingw-w64-i686-gcc mingw-w64-i686-gcc
mingw-w64-i686-glib2 mingw-w64-i686-glib2
mingw-w64-i686-gnutls mingw-w64-i686-gnutls
@ -113,7 +115,8 @@ msys2-32bit:
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink - $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
- mkdir output - mkdir output
- cd output - cd output
- ..\msys64\usr\bin\bash -lc '../configure --target-list=ppc64-softmmu' - ..\msys64\usr\bin\bash -lc '../configure --target-list=ppc64-softmmu
--enable-fdt=system'
- ..\msys64\usr\bin\bash -lc 'make' - ..\msys64\usr\bin\bash -lc 'make'
- ..\msys64\usr\bin\bash -lc 'make check MTESTARGS=\"--no-suite qtest\" || - ..\msys64\usr\bin\bash -lc 'make check MTESTARGS=\"--no-suite qtest\" ||
{ cat meson-logs/testlog.txt; exit 1; }' { cat meson-logs/testlog.txt; exit 1; }'

View File

@ -161,6 +161,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org L: qemu-arm@nongnu.org
S: Maintained S: Maintained
F: target/arm/ F: target/arm/
F: target/arm/tcg/
F: tests/tcg/arm/ F: tests/tcg/arm/
F: tests/tcg/aarch64/ F: tests/tcg/aarch64/
F: tests/qtest/arm-cpu-features.c F: tests/qtest/arm-cpu-features.c
@ -287,6 +288,9 @@ RISC-V TCG CPUs
M: Palmer Dabbelt <palmer@dabbelt.com> M: Palmer Dabbelt <palmer@dabbelt.com>
M: Alistair Francis <alistair.francis@wdc.com> M: Alistair Francis <alistair.francis@wdc.com>
M: Bin Meng <bin.meng@windriver.com> M: Bin Meng <bin.meng@windriver.com>
R: Weiwei Li <liweiwei@iscas.ac.cn>
R: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
R: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
L: qemu-riscv@nongnu.org L: qemu-riscv@nongnu.org
S: Supported S: Supported
F: target/riscv/ F: target/riscv/
@ -2273,7 +2277,6 @@ F: hw/acpi/vmgenid.c
F: include/hw/acpi/vmgenid.h F: include/hw/acpi/vmgenid.h
F: docs/specs/vmgenid.txt F: docs/specs/vmgenid.txt
F: tests/qtest/vmgenid-test.c F: tests/qtest/vmgenid-test.c
F: stubs/vmgenid.c
LED LED
M: Philippe Mathieu-Daudé <philmd@linaro.org> M: Philippe Mathieu-Daudé <philmd@linaro.org>

View File

@ -286,8 +286,16 @@ static void *translator_access(CPUArchState *env, DisasContextBase *db,
if (host == NULL) { if (host == NULL) {
tb_page_addr_t phys_page = tb_page_addr_t phys_page =
get_page_addr_code_hostp(env, base, &db->host_addr[1]); get_page_addr_code_hostp(env, base, &db->host_addr[1]);
/* We cannot handle MMIO as second page. */
assert(phys_page != -1); /*
* If the second page is MMIO, treat as if the first page
* was MMIO as well, so that we do not cache the TB.
*/
if (unlikely(phys_page == -1)) {
tb_set_page_addr0(tb, -1);
return NULL;
}
tb_set_page_addr1(tb, phys_page); tb_set_page_addr1(tb, phys_page);
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
page_protect(end); page_protect(end);

View File

@ -30,7 +30,6 @@
#include "qapi/qapi-visit-authz.h" #include "qapi/qapi-visit-authz.h"
#include "qapi/qmp/qjson.h" #include "qapi/qmp/qjson.h"
#include "qapi/qmp/qobject.h" #include "qapi/qmp/qobject.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qobject-input-visitor.h" #include "qapi/qobject-input-visitor.h"

View File

@ -28,7 +28,6 @@
#ifdef CONFIG_VHOST_CRYPTO #ifdef CONFIG_VHOST_CRYPTO
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "hw/virtio/virtio-crypto.h" #include "hw/virtio/virtio-crypto.h"
#include "sysemu/cryptodev-vhost-user.h" #include "sysemu/cryptodev-vhost-user.h"

View File

@ -13,7 +13,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "sysemu/rng.h" #include "sysemu/rng.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "qom/object_interfaces.h" #include "qom/object_interfaces.h"

View File

@ -13,7 +13,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "qom/object_interfaces.h" #include "qom/object_interfaces.h"
#include "sysemu/vhost-user-backend.h" #include "sysemu/vhost-user-backend.h"

10
block.c
View File

@ -277,7 +277,7 @@ bool bdrv_is_read_only(BlockDriverState *bs)
return !(bs->open_flags & BDRV_O_RDWR); return !(bs->open_flags & BDRV_O_RDWR);
} }
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, static int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
bool ignore_allow_rdw, Error **errp) bool ignore_allow_rdw, Error **errp)
{ {
IO_CODE(); IO_CODE();
@ -533,6 +533,7 @@ int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
int ret; int ret;
GLOBAL_STATE_CODE(); GLOBAL_STATE_CODE();
ERRP_GUARD(); ERRP_GUARD();
assert_bdrv_graph_readable();
if (!drv->bdrv_co_create_opts) { if (!drv->bdrv_co_create_opts) {
error_setg(errp, "Driver '%s' does not support image creation", error_setg(errp, "Driver '%s' does not support image creation",
@ -739,6 +740,7 @@ int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
IO_CODE(); IO_CODE();
assert(bs != NULL); assert(bs != NULL);
assert_bdrv_graph_readable();
if (!bs->drv) { if (!bs->drv) {
error_setg(errp, "Block node '%s' is not opened", bs->filename); error_setg(errp, "Block node '%s' is not opened", bs->filename);
@ -1040,6 +1042,7 @@ int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
if (!drv) { if (!drv) {
return -ENOMEDIUM; return -ENOMEDIUM;
@ -5841,6 +5844,7 @@ int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
if (!drv) if (!drv)
return -ENOMEDIUM; return -ENOMEDIUM;
@ -5862,6 +5866,7 @@ int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs)
{ {
int64_t ret; int64_t ret;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
ret = bdrv_co_nb_sectors(bs); ret = bdrv_co_nb_sectors(bs);
if (ret < 0) { if (ret < 0) {
@ -6825,6 +6830,7 @@ bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs)
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
BdrvChild *child; BdrvChild *child;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
if (!drv) { if (!drv) {
return false; return false;
@ -6847,6 +6853,7 @@ void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
if (drv && drv->bdrv_co_eject) { if (drv && drv->bdrv_co_eject) {
drv->bdrv_co_eject(bs, eject_flag); drv->bdrv_co_eject(bs, eject_flag);
@ -6861,6 +6868,7 @@ void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
trace_bdrv_lock_medium(bs, locked); trace_bdrv_lock_medium(bs, locked);
if (drv && drv->bdrv_co_lock_medium) { if (drv && drv->bdrv_co_lock_medium) {

View File

@ -22,7 +22,6 @@
#include "block/block-copy.h" #include "block/block-copy.h"
#include "block/dirty-bitmap.h" #include "block/dirty-bitmap.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
#include "qemu/bitmap.h" #include "qemu/bitmap.h"
@ -270,7 +269,10 @@ static int coroutine_fn backup_run(Job *job, Error **errp)
return -ECANCELED; return -ECANCELED;
} }
/* rdlock protects the subsequent call to bdrv_is_allocated() */
bdrv_graph_co_rdlock();
ret = block_copy_reset_unallocated(s->bcs, offset, &count); ret = block_copy_reset_unallocated(s->bcs, offset, &count);
bdrv_graph_co_rdunlock();
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }

View File

@ -626,7 +626,7 @@ static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
return -error; return -error;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -647,7 +647,7 @@ blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -668,7 +668,7 @@ blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
} }
static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs) static int GRAPH_RDLOCK coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
{ {
int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH); int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH);
@ -679,8 +679,8 @@ static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
return bdrv_co_flush(bs->file->bs); return bdrv_co_flush(bs->file->bs);
} }
static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, blkdebug_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
uint32_t align = MAX(bs->bl.request_alignment, uint32_t align = MAX(bs->bl.request_alignment,
@ -712,8 +712,8 @@ static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
} }
static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) blkdebug_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
uint32_t align = bs->bl.pdiscard_alignment; uint32_t align = bs->bl.pdiscard_alignment;
int err; int err;
@ -967,7 +967,8 @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
return false; return false;
} }
static int64_t coroutine_fn blkdebug_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
blkdebug_co_getlength(BlockDriverState *bs)
{ {
return bdrv_co_getlength(bs->file->bs); return bdrv_co_getlength(bs->file->bs);
} }

View File

@ -267,7 +267,8 @@ static void blk_log_writes_close(BlockDriverState *bs)
s->log_file = NULL; s->log_file = NULL;
} }
static int64_t coroutine_fn blk_log_writes_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_getlength(BlockDriverState *bs)
{ {
return bdrv_co_getlength(bs->file->bs); return bdrv_co_getlength(bs->file->bs);
} }
@ -294,7 +295,7 @@ static void blk_log_writes_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.request_alignment = s->sectorsize; bs->bl.request_alignment = s->sectorsize;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, blk_log_writes_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -307,7 +308,7 @@ typedef struct BlkLogWritesFileReq {
uint64_t bytes; uint64_t bytes;
int file_flags; int file_flags;
QEMUIOVector *qiov; QEMUIOVector *qiov;
int (*func)(struct BlkLogWritesFileReq *r); int GRAPH_RDLOCK_PTR (*func)(struct BlkLogWritesFileReq *r);
int file_ret; int file_ret;
} BlkLogWritesFileReq; } BlkLogWritesFileReq;
@ -319,7 +320,8 @@ typedef struct {
int log_ret; int log_ret;
} BlkLogWritesLogReq; } BlkLogWritesLogReq;
static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr) static void coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
{ {
BDRVBlkLogWritesState *s = lr->bs->opaque; BDRVBlkLogWritesState *s = lr->bs->opaque;
uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits; uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
@ -368,15 +370,16 @@ static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
} }
} }
static void coroutine_fn blk_log_writes_co_do_file(BlkLogWritesFileReq *fr) static void coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file(BlkLogWritesFileReq *fr)
{ {
fr->file_ret = fr->func(fr); fr->file_ret = fr->func(fr);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes, blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, int flags, QEMUIOVector *qiov, int flags,
int (*file_func)(BlkLogWritesFileReq *r), int /*GRAPH_RDLOCK*/ (*file_func)(BlkLogWritesFileReq *r),
uint64_t entry_flags, bool is_zero_write) uint64_t entry_flags, bool is_zero_write)
{ {
QEMUIOVector log_qiov; QEMUIOVector log_qiov;
@ -428,32 +431,33 @@ blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
return fr.file_ret; return fr.file_ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr) blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr)
{ {
return bdrv_co_pwritev(fr->bs->file, fr->offset, fr->bytes, return bdrv_co_pwritev(fr->bs->file, fr->offset, fr->bytes,
fr->qiov, fr->file_flags); fr->qiov, fr->file_flags);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr) blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr)
{ {
return bdrv_co_pwrite_zeroes(fr->bs->file, fr->offset, fr->bytes, return bdrv_co_pwrite_zeroes(fr->bs->file, fr->offset, fr->bytes,
fr->file_flags); fr->file_flags);
} }
static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr) static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
{ {
return bdrv_co_flush(fr->bs->file->bs); return bdrv_co_flush(fr->bs->file->bs);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr) blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
{ {
return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes); return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -461,7 +465,7 @@ blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
blk_log_writes_co_do_file_pwritev, 0, false); blk_log_writes_co_do_file_pwritev, 0, false);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
int64_t bytes, BdrvRequestFlags flags) int64_t bytes, BdrvRequestFlags flags)
{ {
@ -470,14 +474,15 @@ blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
true); true);
} }
static int coroutine_fn blk_log_writes_co_flush_to_disk(BlockDriverState *bs) static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
{ {
return blk_log_writes_co_log(bs, 0, 0, NULL, 0, return blk_log_writes_co_log(bs, 0, 0, NULL, 0,
blk_log_writes_co_do_file_flush, blk_log_writes_co_do_file_flush,
LOG_FLUSH_FLAG, false); LOG_FLUSH_FLAG, false);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
return blk_log_writes_co_log(bs, offset, bytes, NULL, 0, return blk_log_writes_co_log(bs, offset, bytes, NULL, 0,

View File

@ -40,7 +40,8 @@ fail:
return ret; return ret;
} }
static int64_t coroutine_fn blkreplay_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
blkreplay_co_getlength(BlockDriverState *bs)
{ {
return bdrv_co_getlength(bs->file->bs); return bdrv_co_getlength(bs->file->bs);
} }
@ -69,8 +70,9 @@ static void block_request_create(uint64_t reqid, BlockDriverState *bs,
replay_block_event(req->bh, reqid); replay_block_event(req->bh, reqid);
} }
static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) blkreplay_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
uint64_t reqid = blkreplay_next_id(); uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
@ -80,8 +82,9 @@ static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) blkreplay_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
uint64_t reqid = blkreplay_next_id(); uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
@ -91,8 +94,9 @@ static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, BdrvRequestFlags flags) blkreplay_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{ {
uint64_t reqid = blkreplay_next_id(); uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); int ret = bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
@ -102,8 +106,8 @@ static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) blkreplay_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
uint64_t reqid = blkreplay_next_id(); uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_pdiscard(bs->file, offset, bytes); int ret = bdrv_co_pdiscard(bs->file, offset, bytes);
@ -113,7 +117,7 @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs) static int coroutine_fn GRAPH_RDLOCK blkreplay_co_flush(BlockDriverState *bs)
{ {
uint64_t reqid = blkreplay_next_id(); uint64_t reqid = blkreplay_next_id();
int ret = bdrv_co_flush(bs->file->bs); int ret = bdrv_co_flush(bs->file->bs);

View File

@ -155,7 +155,8 @@ static void blkverify_close(BlockDriverState *bs)
s->test_file = NULL; s->test_file = NULL;
} }
static int64_t coroutine_fn blkverify_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
blkverify_co_getlength(BlockDriverState *bs)
{ {
BDRVBlkverifyState *s = bs->opaque; BDRVBlkverifyState *s = bs->opaque;
@ -256,7 +257,7 @@ blkverify_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
return blkverify_co_prwv(bs, &r, offset, bytes, qiov, qiov, flags, true); return blkverify_co_prwv(bs, &r, offset, bytes, qiov, qiov, flags, true);
} }
static int coroutine_fn blkverify_co_flush(BlockDriverState *bs) static int coroutine_fn GRAPH_RDLOCK blkverify_co_flush(BlockDriverState *bs)
{ {
BDRVBlkverifyState *s = bs->opaque; BDRVBlkverifyState *s = bs->opaque;

View File

@ -1235,8 +1235,8 @@ void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
blk->disable_request_queuing = disable; blk->disable_request_queuing = disable;
} }
static coroutine_fn int blk_check_byte_request(BlockBackend *blk, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) blk_check_byte_request(BlockBackend *blk, int64_t offset, int64_t bytes)
{ {
int64_t len; int64_t len;
@ -1244,7 +1244,7 @@ static coroutine_fn int blk_check_byte_request(BlockBackend *blk,
return -EIO; return -EIO;
} }
if (!blk_is_available(blk)) { if (!blk_co_is_available(blk)) {
return -ENOMEDIUM; return -ENOMEDIUM;
} }
@ -1289,6 +1289,7 @@ blk_co_do_preadv_part(BlockBackend *blk, int64_t offset, int64_t bytes,
IO_CODE(); IO_CODE();
blk_wait_while_drained(blk); blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
/* Call blk_bs() only after waiting, the graph may have changed */ /* Call blk_bs() only after waiting, the graph may have changed */
bs = blk_bs(blk); bs = blk_bs(blk);
@ -1363,6 +1364,7 @@ blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
IO_CODE(); IO_CODE();
blk_wait_while_drained(blk); blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
/* Call blk_bs() only after waiting, the graph may have changed */ /* Call blk_bs() only after waiting, the graph may have changed */
bs = blk_bs(blk); bs = blk_bs(blk);
@ -1431,6 +1433,7 @@ int coroutine_fn blk_co_block_status_above(BlockBackend *blk,
BlockDriverState **file) BlockDriverState **file)
{ {
IO_CODE(); IO_CODE();
GRAPH_RDLOCK_GUARD();
return bdrv_co_block_status_above(blk_bs(blk), base, offset, bytes, pnum, return bdrv_co_block_status_above(blk_bs(blk), base, offset, bytes, pnum,
map, file); map, file);
} }
@ -1441,6 +1444,7 @@ int coroutine_fn blk_co_is_allocated_above(BlockBackend *blk,
int64_t bytes, int64_t *pnum) int64_t bytes, int64_t *pnum)
{ {
IO_CODE(); IO_CODE();
GRAPH_RDLOCK_GUARD();
return bdrv_co_is_allocated_above(blk_bs(blk), base, include_base, offset, return bdrv_co_is_allocated_above(blk_bs(blk), base, include_base, offset,
bytes, pnum); bytes, pnum);
} }
@ -1602,8 +1606,9 @@ BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
int64_t coroutine_fn blk_co_getlength(BlockBackend *blk) int64_t coroutine_fn blk_co_getlength(BlockBackend *blk)
{ {
IO_CODE(); IO_CODE();
GRAPH_RDLOCK_GUARD();
if (!blk_is_available(blk)) { if (!blk_co_is_available(blk)) {
return -ENOMEDIUM; return -ENOMEDIUM;
} }
@ -1623,8 +1628,9 @@ void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk) int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk)
{ {
IO_CODE(); IO_CODE();
GRAPH_RDLOCK_GUARD();
if (!blk_is_available(blk)) { if (!blk_co_is_available(blk)) {
return -ENOMEDIUM; return -ENOMEDIUM;
} }
@ -1670,8 +1676,9 @@ blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
IO_CODE(); IO_CODE();
blk_wait_while_drained(blk); blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
if (!blk_is_available(blk)) { if (!blk_co_is_available(blk)) {
return -ENOMEDIUM; return -ENOMEDIUM;
} }
@ -1716,6 +1723,7 @@ blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes)
IO_CODE(); IO_CODE();
blk_wait_while_drained(blk); blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
ret = blk_check_byte_request(blk, offset, bytes); ret = blk_check_byte_request(blk, offset, bytes);
if (ret < 0) { if (ret < 0) {
@ -1759,10 +1767,11 @@ int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
/* To be called between exactly one pair of blk_inc/dec_in_flight() */ /* To be called between exactly one pair of blk_inc/dec_in_flight() */
static int coroutine_fn blk_co_do_flush(BlockBackend *blk) static int coroutine_fn blk_co_do_flush(BlockBackend *blk)
{ {
blk_wait_while_drained(blk);
IO_CODE(); IO_CODE();
blk_wait_while_drained(blk);
GRAPH_RDLOCK_GUARD();
if (!blk_is_available(blk)) { if (!blk_co_is_available(blk)) {
return -ENOMEDIUM; return -ENOMEDIUM;
} }
@ -1989,20 +1998,22 @@ bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
{ {
BlockDriverState *bs = blk_bs(blk); BlockDriverState *bs = blk_bs(blk);
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
return bs && bdrv_co_is_inserted(bs); return bs && bdrv_co_is_inserted(bs);
} }
bool blk_is_available(BlockBackend *blk) bool coroutine_fn blk_co_is_available(BlockBackend *blk)
{ {
IO_CODE(); IO_CODE();
return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk); return blk_co_is_inserted(blk) && !blk_dev_is_tray_open(blk);
} }
void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked) void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked)
{ {
BlockDriverState *bs = blk_bs(blk); BlockDriverState *bs = blk_bs(blk);
IO_CODE(); IO_CODE();
GRAPH_RDLOCK_GUARD();
if (bs) { if (bs) {
bdrv_co_lock_medium(bs, locked); bdrv_co_lock_medium(bs, locked);
@ -2014,6 +2025,7 @@ void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag)
BlockDriverState *bs = blk_bs(blk); BlockDriverState *bs = blk_bs(blk);
char *id; char *id;
IO_CODE(); IO_CODE();
GRAPH_RDLOCK_GUARD();
if (bs) { if (bs) {
bdrv_co_eject(bs, eject_flag); bdrv_co_eject(bs, eject_flag);
@ -2321,6 +2333,7 @@ void coroutine_fn blk_co_io_plug(BlockBackend *blk)
{ {
BlockDriverState *bs = blk_bs(blk); BlockDriverState *bs = blk_bs(blk);
IO_CODE(); IO_CODE();
GRAPH_RDLOCK_GUARD();
if (bs) { if (bs) {
bdrv_co_io_plug(bs); bdrv_co_io_plug(bs);
@ -2331,6 +2344,7 @@ void coroutine_fn blk_co_io_unplug(BlockBackend *blk)
{ {
BlockDriverState *bs = blk_bs(blk); BlockDriverState *bs = blk_bs(blk);
IO_CODE(); IO_CODE();
GRAPH_RDLOCK_GUARD();
if (bs) { if (bs) {
bdrv_co_io_unplug(bs); bdrv_co_io_unplug(bs);
@ -2372,7 +2386,8 @@ int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact,
Error **errp) Error **errp)
{ {
IO_OR_GS_CODE(); IO_OR_GS_CODE();
if (!blk_is_available(blk)) { GRAPH_RDLOCK_GUARD();
if (!blk_co_is_available(blk)) {
error_setg(errp, "No medium inserted"); error_setg(errp, "No medium inserted");
return -ENOMEDIUM; return -ENOMEDIUM;
} }
@ -2627,6 +2642,7 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
{ {
int r; int r;
IO_CODE(); IO_CODE();
GRAPH_RDLOCK_GUARD();
r = blk_check_byte_request(blk_in, off_in, bytes); r = blk_check_byte_request(blk_in, off_in, bytes);
if (r) { if (r) {
@ -2636,6 +2652,7 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
if (r) { if (r) {
return r; return r;
} }
return bdrv_co_copy_range(blk_in->root, off_in, return bdrv_co_copy_range(blk_in->root, off_in,
blk_out->root, off_out, blk_out->root, off_out,
bytes, read_flags, write_flags); bytes, read_flags, write_flags);

View File

@ -469,10 +469,9 @@ static coroutine_fn int block_copy_task_run(AioTaskPool *pool,
* value of @method should be used for subsequent tasks. * value of @method should be used for subsequent tasks.
* Returns 0 on success. * Returns 0 on success.
*/ */
static int coroutine_fn block_copy_do_copy(BlockCopyState *s, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, block_copy_do_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
BlockCopyMethod *method, BlockCopyMethod *method, bool *error_is_read)
bool *error_is_read)
{ {
int ret; int ret;
int64_t nbytes = MIN(offset + bytes, s->len) - offset; int64_t nbytes = MIN(offset + bytes, s->len) - offset;
@ -558,8 +557,10 @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
BlockCopyMethod method = t->method; BlockCopyMethod method = t->method;
int ret; int ret;
WITH_GRAPH_RDLOCK_GUARD() {
ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method, ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method,
&error_is_read); &error_is_read);
}
WITH_QEMU_LOCK_GUARD(&s->lock) { WITH_QEMU_LOCK_GUARD(&s->lock) {
if (s->method == t->method) { if (s->method == t->method) {
@ -581,9 +582,9 @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
return ret; return ret;
} }
static coroutine_fn int block_copy_block_status(BlockCopyState *s, static coroutine_fn GRAPH_RDLOCK
int64_t offset, int block_copy_block_status(BlockCopyState *s, int64_t offset, int64_t bytes,
int64_t bytes, int64_t *pnum) int64_t *pnum)
{ {
int64_t num; int64_t num;
BlockDriverState *base; BlockDriverState *base;
@ -618,8 +619,8 @@ static coroutine_fn int block_copy_block_status(BlockCopyState *s,
* Check if the cluster starting at offset is allocated or not. * Check if the cluster starting at offset is allocated or not.
* return via pnum the number of contiguous clusters sharing this allocation. * return via pnum the number of contiguous clusters sharing this allocation.
*/ */
static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
int64_t *pnum) int64_t *pnum)
{ {
BlockDriverState *bs = s->source->bs; BlockDriverState *bs = s->source->bs;
@ -630,6 +631,7 @@ static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s,
assert(QEMU_IS_ALIGNED(offset, s->cluster_size)); assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
while (true) { while (true) {
/* protected in backup_run() */
ret = bdrv_co_is_allocated(bs, offset, bytes, &count); ret = bdrv_co_is_allocated(bs, offset, bytes, &count);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
@ -704,7 +706,7 @@ int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s,
* Returns 1 if dirty clusters found and successfully copied, 0 if no dirty * Returns 1 if dirty clusters found and successfully copied, 0 if no dirty
* clusters found and -errno on failure. * clusters found and -errno on failure.
*/ */
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
block_copy_dirty_clusters(BlockCopyCallState *call_state) block_copy_dirty_clusters(BlockCopyCallState *call_state)
{ {
BlockCopyState *s = call_state->s; BlockCopyState *s = call_state->s;
@ -827,7 +829,8 @@ void block_copy_kick(BlockCopyCallState *call_state)
* it means that some I/O operation failed in context of _this_ block_copy call, * it means that some I/O operation failed in context of _this_ block_copy call,
* not some parallel operation. * not some parallel operation.
*/ */
static int coroutine_fn block_copy_common(BlockCopyCallState *call_state) static int coroutine_fn GRAPH_RDLOCK
block_copy_common(BlockCopyCallState *call_state)
{ {
int ret; int ret;
BlockCopyState *s = call_state->s; BlockCopyState *s = call_state->s;
@ -892,6 +895,7 @@ static int coroutine_fn block_copy_common(BlockCopyCallState *call_state)
static void coroutine_fn block_copy_async_co_entry(void *opaque) static void coroutine_fn block_copy_async_co_entry(void *opaque)
{ {
GRAPH_RDLOCK_GUARD();
block_copy_common(opaque); block_copy_common(opaque);
} }

View File

@ -237,7 +237,7 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset)); return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
bochs_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, bochs_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {

View File

@ -18,7 +18,6 @@
#include "block/block_int.h" #include "block/block_int.h"
#include "block/blockjob_int.h" #include "block/blockjob_int.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h" #include "qemu/ratelimit.h"
#include "qemu/memalign.h" #include "qemu/memalign.h"
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
@ -207,8 +206,9 @@ static const BlockJobDriver commit_job_driver = {
}, },
}; };
static int coroutine_fn bdrv_commit_top_preadv(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) bdrv_commit_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags); return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
} }

View File

@ -78,8 +78,8 @@ typedef struct BDRVCopyBeforeWriteState {
int snapshot_error; int snapshot_error;
} BDRVCopyBeforeWriteState; } BDRVCopyBeforeWriteState;
static coroutine_fn int cbw_co_preadv( static int coroutine_fn GRAPH_RDLOCK
BlockDriverState *bs, int64_t offset, int64_t bytes, cbw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
@ -149,8 +149,8 @@ static coroutine_fn int cbw_do_copy_before_write(BlockDriverState *bs,
return 0; return 0;
} }
static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) cbw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
int ret = cbw_do_copy_before_write(bs, offset, bytes, 0); int ret = cbw_do_copy_before_write(bs, offset, bytes, 0);
if (ret < 0) { if (ret < 0) {
@ -160,8 +160,9 @@ static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs,
return bdrv_co_pdiscard(bs->file, offset, bytes); return bdrv_co_pdiscard(bs->file, offset, bytes);
} }
static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, BdrvRequestFlags flags) cbw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{ {
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags); int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
if (ret < 0) { if (ret < 0) {
@ -171,11 +172,9 @@ static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
} }
static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs, static coroutine_fn GRAPH_RDLOCK
int64_t offset, int cbw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
QEMUIOVector *qiov,
BdrvRequestFlags flags)
{ {
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags); int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
if (ret < 0) { if (ret < 0) {
@ -185,7 +184,7 @@ static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
} }
static int coroutine_fn cbw_co_flush(BlockDriverState *bs) static int coroutine_fn GRAPH_RDLOCK cbw_co_flush(BlockDriverState *bs)
{ {
if (!bs->file) { if (!bs->file) {
return 0; return 0;
@ -257,7 +256,7 @@ cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)
g_free(req); g_free(req);
} }
static coroutine_fn int static int coroutine_fn GRAPH_RDLOCK
cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes, cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset) QEMUIOVector *qiov, size_t qiov_offset)
{ {
@ -289,7 +288,7 @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
return 0; return 0;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
cbw_co_snapshot_block_status(BlockDriverState *bs, cbw_co_snapshot_block_status(BlockDriverState *bs,
bool want_zero, int64_t offset, int64_t bytes, bool want_zero, int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map, int64_t *pnum, int64_t *map,
@ -322,8 +321,8 @@ cbw_co_snapshot_block_status(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn cbw_co_pdiscard_snapshot(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) cbw_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
BDRVCopyBeforeWriteState *s = bs->opaque; BDRVCopyBeforeWriteState *s = bs->opaque;

View File

@ -121,16 +121,15 @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
} }
static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK cor_co_getlength(BlockDriverState *bs)
{ {
return bdrv_co_getlength(bs->file->bs); return bdrv_co_getlength(bs->file->bs);
} }
static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, cor_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, QEMUIOVector *qiov, size_t qiov_offset,
size_t qiov_offset,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
int64_t n; int64_t n;
@ -180,11 +179,9 @@ static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs,
} }
static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, cor_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset, return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
@ -192,24 +189,23 @@ static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs,
} }
static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, cor_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
} }
static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) cor_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
return bdrv_co_pdiscard(bs->file, offset, bytes); return bdrv_co_pdiscard(bs->file, offset, bytes);
} }
static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, cor_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t bytes,
QEMUIOVector *qiov) QEMUIOVector *qiov)
{ {
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, return bdrv_co_pwritev(bs->file, offset, bytes, qiov,
@ -217,13 +213,15 @@ static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs,
} }
static void coroutine_fn cor_co_eject(BlockDriverState *bs, bool eject_flag) static void coroutine_fn GRAPH_RDLOCK
cor_co_eject(BlockDriverState *bs, bool eject_flag)
{ {
bdrv_co_eject(bs->file->bs, eject_flag); bdrv_co_eject(bs->file->bs, eject_flag);
} }
static void coroutine_fn cor_co_lock_medium(BlockDriverState *bs, bool locked) static void coroutine_fn GRAPH_RDLOCK
cor_co_lock_medium(BlockDriverState *bs, bool locked)
{ {
bdrv_co_lock_medium(bs->file->bs, locked); bdrv_co_lock_medium(bs->file->bs, locked);
} }

View File

@ -43,7 +43,7 @@ bdrv_co_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
int coroutine_fn GRAPH_RDLOCK int coroutine_fn GRAPH_RDLOCK
bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp); bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp);
int coroutine_fn int coroutine_fn GRAPH_RDLOCK
bdrv_co_common_block_status_above(BlockDriverState *bs, bdrv_co_common_block_status_above(BlockDriverState *bs,
BlockDriverState *base, BlockDriverState *base,
bool include_base, bool include_base,

View File

@ -43,6 +43,7 @@ static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
int ret; int ret;
GLOBAL_STATE_CODE(); GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD();
job_progress_set_remaining(&s->common, 1); job_progress_set_remaining(&s->common, 1);
ret = s->drv->bdrv_co_create(s->opts, errp); ret = s->drv->bdrv_co_create(s->opts, errp);
@ -59,6 +60,12 @@ static const JobDriver blockdev_create_job_driver = {
.run = blockdev_create_run, .run = blockdev_create_run,
}; };
/* Checking whether the function is present doesn't require the graph lock */
static inline bool TSA_NO_TSA has_bdrv_co_create(BlockDriver *drv)
{
return drv->bdrv_co_create;
}
void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options, void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
Error **errp) Error **errp)
{ {
@ -79,7 +86,7 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
} }
/* Error out if the driver doesn't support .bdrv_co_create */ /* Error out if the driver doesn't support .bdrv_co_create */
if (!drv->bdrv_co_create) { if (!has_bdrv_co_create(drv)) {
error_setg(errp, "Driver does not support blockdev-create"); error_setg(errp, "Driver does not support blockdev-create");
return; return;
} }

View File

@ -359,7 +359,7 @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact, block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
PreallocMode prealloc, BdrvRequestFlags flags, PreallocMode prealloc, BdrvRequestFlags flags,
Error **errp) Error **errp)
@ -397,7 +397,7 @@ static int block_crypto_reopen_prepare(BDRVReopenState *state,
*/ */
#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024) #define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
static coroutine_fn int static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -459,7 +459,7 @@ block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
} }
static coroutine_fn int static int coroutine_fn GRAPH_RDLOCK
block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -530,7 +530,8 @@ static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
} }
static int64_t coroutine_fn block_crypto_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
block_crypto_co_getlength(BlockDriverState *bs)
{ {
BlockCrypto *crypto = bs->opaque; BlockCrypto *crypto = bs->opaque;
int64_t len = bdrv_co_getlength(bs->file->bs); int64_t len = bdrv_co_getlength(bs->file->bs);
@ -664,10 +665,9 @@ fail:
return ret; return ret;
} }
static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
QCryptoBlockCreateOptions *create_opts = NULL; QCryptoBlockCreateOptions *create_opts = NULL;
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;

View File

@ -394,6 +394,7 @@ int coroutine_fn
bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name, bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
Error **errp) Error **errp)
{ {
assert_bdrv_graph_readable();
if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) { if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) {
return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp); return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
} }
@ -415,6 +416,7 @@ bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
uint32_t granularity, Error **errp) uint32_t granularity, Error **errp)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
assert_bdrv_graph_readable();
if (!drv) { if (!drv) {
error_setg_errno(errp, ENOMEDIUM, error_setg_errno(errp, ENOMEDIUM,

View File

@ -2607,10 +2607,9 @@ out:
return result; return result;
} }
static int coroutine_fn raw_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, raw_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
BlockdevCreateOptions options; BlockdevCreateOptions options;
int64_t total_size = 0; int64_t total_size = 0;
@ -2920,8 +2919,8 @@ static void coroutine_fn check_cache_dropped(BlockDriverState *bs, Error **errp)
} }
#endif /* __linux__ */ #endif /* __linux__ */
static void coroutine_fn raw_co_invalidate_cache(BlockDriverState *bs, static void coroutine_fn GRAPH_RDLOCK
Error **errp) raw_co_invalidate_cache(BlockDriverState *bs, Error **errp)
{ {
BDRVRawState *s = bs->opaque; BDRVRawState *s = bs->opaque;
int ret; int ret;
@ -3272,7 +3271,7 @@ static void raw_abort_perm_update(BlockDriverState *bs)
raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL); raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL);
} }
static int coroutine_fn raw_co_copy_range_from( static int coroutine_fn GRAPH_RDLOCK raw_co_copy_range_from(
BlockDriverState *bs, BdrvChild *src, int64_t src_offset, BlockDriverState *bs, BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset, int64_t bytes, BdrvChild *dst, int64_t dst_offset, int64_t bytes,
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags) BdrvRequestFlags read_flags, BdrvRequestFlags write_flags)
@ -3281,13 +3280,11 @@ static int coroutine_fn raw_co_copy_range_from(
read_flags, write_flags); read_flags, write_flags);
} }
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvChild *src, raw_co_copy_range_to(BlockDriverState *bs,
int64_t src_offset, BdrvChild *src, int64_t src_offset,
BdrvChild *dst, BdrvChild *dst, int64_t dst_offset,
int64_t dst_offset, int64_t bytes, BdrvRequestFlags read_flags,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
RawPosixAIOData acb; RawPosixAIOData acb;

View File

@ -613,10 +613,9 @@ static int raw_co_create(BlockdevCreateOptions *options, Error **errp)
return 0; return 0;
} }
static int coroutine_fn raw_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, raw_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
BlockdevCreateOptions options; BlockdevCreateOptions options;
int64_t total_size = 0; int64_t total_size = 0;

View File

@ -55,16 +55,16 @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags,
} }
static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
compress_co_getlength(BlockDriverState *bs)
{ {
return bdrv_co_getlength(bs->file->bs); return bdrv_co_getlength(bs->file->bs);
} }
static int coroutine_fn compress_co_preadv_part(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, compress_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, QEMUIOVector *qiov, size_t qiov_offset,
size_t qiov_offset,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset, return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
@ -72,11 +72,9 @@ static int coroutine_fn compress_co_preadv_part(BlockDriverState *bs,
} }
static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, compress_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset, return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
@ -84,16 +82,16 @@ static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs,
} }
static int coroutine_fn compress_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, compress_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
} }
static int coroutine_fn compress_co_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) compress_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
return bdrv_co_pdiscard(bs->file, offset, bytes); return bdrv_co_pdiscard(bs->file, offset, bytes);
} }
@ -117,14 +115,14 @@ static void compress_refresh_limits(BlockDriverState *bs, Error **errp)
} }
static void coroutine_fn static void coroutine_fn GRAPH_RDLOCK
compress_co_eject(BlockDriverState *bs, bool eject_flag) compress_co_eject(BlockDriverState *bs, bool eject_flag)
{ {
bdrv_co_eject(bs->file->bs, eject_flag); bdrv_co_eject(bs->file->bs, eject_flag);
} }
static void coroutine_fn static void coroutine_fn GRAPH_RDLOCK
compress_co_lock_medium(BlockDriverState *bs, bool locked) compress_co_lock_medium(BlockDriverState *bs, bool locked)
{ {
bdrv_co_lock_medium(bs->file->bs, locked); bdrv_co_lock_medium(bs->file->bs, locked);

View File

@ -160,6 +160,7 @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
bool have_limits; bool have_limits;
GLOBAL_STATE_CODE(); GLOBAL_STATE_CODE();
assume_graph_lock(); /* FIXME */
if (tran) { if (tran) {
BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1); BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
@ -932,6 +933,7 @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
{ {
int ret; int ret;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
ret = bdrv_co_pwrite(child, offset, bytes, buf, flags); ret = bdrv_co_pwrite(child, offset, bytes, buf, flags);
if (ret < 0) { if (ret < 0) {
@ -959,16 +961,16 @@ static void bdrv_co_io_em_complete(void *opaque, int ret)
aio_co_wake(co->coroutine); aio_co_wake(co->coroutine);
} }
static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, bdrv_driver_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, QEMUIOVector *qiov, size_t qiov_offset, int flags)
size_t qiov_offset, int flags)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
int64_t sector_num; int64_t sector_num;
unsigned int nb_sectors; unsigned int nb_sectors;
QEMUIOVector local_qiov; QEMUIOVector local_qiov;
int ret; int ret;
assert_bdrv_graph_readable();
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
assert(!(flags & ~bs->supported_read_flags)); assert(!(flags & ~bs->supported_read_flags));
@ -1028,10 +1030,9 @@ out:
return ret; return ret;
} }
static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, bdrv_driver_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, QEMUIOVector *qiov, size_t qiov_offset,
size_t qiov_offset,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
@ -1040,6 +1041,7 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
unsigned int nb_sectors; unsigned int nb_sectors;
QEMUIOVector local_qiov; QEMUIOVector local_qiov;
int ret; int ret;
assert_bdrv_graph_readable();
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
@ -1110,7 +1112,7 @@ emulate_flags:
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset, bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
int64_t bytes, QEMUIOVector *qiov, int64_t bytes, QEMUIOVector *qiov,
size_t qiov_offset) size_t qiov_offset)
@ -1118,6 +1120,7 @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
QEMUIOVector local_qiov; QEMUIOVector local_qiov;
int ret; int ret;
assert_bdrv_graph_readable();
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort); bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
@ -1145,9 +1148,9 @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
return ret; return ret;
} }
static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, QEMUIOVector *qiov, bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
size_t qiov_offset, int flags) QEMUIOVector *qiov, size_t qiov_offset, int flags)
{ {
BlockDriverState *bs = child->bs; BlockDriverState *bs = child->bs;
@ -1309,9 +1312,10 @@ err:
* handles copy on read, zeroing after EOF, and fragmentation of large * handles copy on read, zeroing after EOF, and fragmentation of large
* reads; any other features must be implemented by the caller. * reads; any other features must be implemented by the caller.
*/ */
static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, static int coroutine_fn GRAPH_RDLOCK
BdrvTrackedRequest *req, int64_t offset, int64_t bytes, bdrv_aligned_preadv(BdrvChild *child, BdrvTrackedRequest *req,
int64_t align, QEMUIOVector *qiov, size_t qiov_offset, int flags) int64_t offset, int64_t bytes, int64_t align,
QEMUIOVector *qiov, size_t qiov_offset, int flags)
{ {
BlockDriverState *bs = child->bs; BlockDriverState *bs = child->bs;
int64_t total_bytes, max_bytes; int64_t total_bytes, max_bytes;
@ -1478,10 +1482,9 @@ static bool bdrv_init_padding(BlockDriverState *bs,
return true; return true;
} }
static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child, static int coroutine_fn GRAPH_RDLOCK
BdrvTrackedRequest *req, bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req,
BdrvRequestPadding *pad, BdrvRequestPadding *pad, bool zero_middle)
bool zero_middle)
{ {
QEMUIOVector local_qiov; QEMUIOVector local_qiov;
BlockDriverState *bs = child->bs; BlockDriverState *bs = child->bs;
@ -1669,8 +1672,9 @@ fail:
return ret; return ret;
} }
static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, BdrvRequestFlags flags) bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{ {
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
QEMUIOVector qiov; QEMUIOVector qiov;
@ -1686,6 +1690,7 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
bs->bl.request_alignment); bs->bl.request_alignment);
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER); int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER);
assert_bdrv_graph_readable();
bdrv_check_request(offset, bytes, &error_abort); bdrv_check_request(offset, bytes, &error_abort);
if (!drv) { if (!drv) {
@ -1889,9 +1894,10 @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, int64_t bytes,
* Forwards an already correctly aligned write request to the BlockDriver, * Forwards an already correctly aligned write request to the BlockDriver,
* after possibly fragmenting it. * after possibly fragmenting it.
*/ */
static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, static int coroutine_fn GRAPH_RDLOCK
BdrvTrackedRequest *req, int64_t offset, int64_t bytes, bdrv_aligned_pwritev(BdrvChild *child, BdrvTrackedRequest *req,
int64_t align, QEMUIOVector *qiov, size_t qiov_offset, int64_t offset, int64_t bytes, int64_t align,
QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
BlockDriverState *bs = child->bs; BlockDriverState *bs = child->bs;
@ -1976,11 +1982,9 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
return ret; return ret;
} }
static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t offset, int64_t bytes,
int64_t bytes, BdrvRequestFlags flags, BdrvTrackedRequest *req)
BdrvRequestFlags flags,
BdrvTrackedRequest *req)
{ {
BlockDriverState *bs = child->bs; BlockDriverState *bs = child->bs;
QEMUIOVector local_qiov; QEMUIOVector local_qiov;
@ -2153,6 +2157,7 @@ int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
{ {
IO_CODE(); IO_CODE();
trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags); trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags);
assert_bdrv_graph_readable();
if (!(child->bs->open_flags & BDRV_O_UNMAP)) { if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
flags &= ~BDRV_REQ_MAY_UNMAP; flags &= ~BDRV_REQ_MAY_UNMAP;
@ -2224,11 +2229,10 @@ int bdrv_flush_all(void)
* BDRV_BLOCK_OFFSET_VALID bit is set, 'map' and 'file' (if non-NULL) are * BDRV_BLOCK_OFFSET_VALID bit is set, 'map' and 'file' (if non-NULL) are
* set to the host mapping and BDS corresponding to the guest offset. * set to the host mapping and BDS corresponding to the guest offset.
*/ */
static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
bool want_zero, bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
int64_t offset, int64_t bytes, int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map, int64_t *pnum, int64_t *map, BlockDriverState **file)
BlockDriverState **file)
{ {
int64_t total_size; int64_t total_size;
int64_t n; /* bytes */ int64_t n; /* bytes */
@ -2240,6 +2244,7 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
bool has_filtered_child; bool has_filtered_child;
assert(pnum); assert(pnum);
assert_bdrv_graph_readable();
*pnum = 0; *pnum = 0;
total_size = bdrv_getlength(bs); total_size = bdrv_getlength(bs);
if (total_size < 0) { if (total_size < 0) {
@ -2470,6 +2475,7 @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
IO_CODE(); IO_CODE();
assert(!include_base || base); /* Can't include NULL base */ assert(!include_base || base); /* Can't include NULL base */
assert_bdrv_graph_readable();
if (!depth) { if (!depth) {
depth = &dummy; depth = &dummy;
@ -2836,6 +2842,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
int ret = 0; int ret = 0;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
bdrv_inc_in_flight(bs); bdrv_inc_in_flight(bs);
if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) || if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) ||
@ -2961,6 +2968,7 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
int head, tail, align; int head, tail, align;
BlockDriverState *bs = child->bs; BlockDriverState *bs = child->bs;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) { if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) {
return -ENOMEDIUM; return -ENOMEDIUM;
@ -3080,6 +3088,7 @@ int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
}; };
BlockAIOCB *acb; BlockAIOCB *acb;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
bdrv_inc_in_flight(bs); bdrv_inc_in_flight(bs);
if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) { if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
@ -3144,6 +3153,7 @@ void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs)
{ {
BdrvChild *child; BdrvChild *child;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
QLIST_FOREACH(child, &bs->children, next) { QLIST_FOREACH(child, &bs->children, next) {
bdrv_co_io_plug(child->bs); bdrv_co_io_plug(child->bs);
@ -3161,6 +3171,7 @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
{ {
BdrvChild *child; BdrvChild *child;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
assert(bs->io_plugged); assert(bs->io_plugged);
if (qatomic_fetch_dec(&bs->io_plugged) == 1) { if (qatomic_fetch_dec(&bs->io_plugged) == 1) {
@ -3176,13 +3187,15 @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
} }
/* Helper that undoes bdrv_register_buf() when it fails partway through */ /* Helper that undoes bdrv_register_buf() when it fails partway through */
static void bdrv_register_buf_rollback(BlockDriverState *bs, static void GRAPH_RDLOCK
void *host, bdrv_register_buf_rollback(BlockDriverState *bs, void *host, size_t size,
size_t size,
BdrvChild *final_child) BdrvChild *final_child)
{ {
BdrvChild *child; BdrvChild *child;
GLOBAL_STATE_CODE();
assert_bdrv_graph_readable();
QLIST_FOREACH(child, &bs->children, next) { QLIST_FOREACH(child, &bs->children, next) {
if (child == final_child) { if (child == final_child) {
break; break;
@ -3202,6 +3215,8 @@ bool bdrv_register_buf(BlockDriverState *bs, void *host, size_t size,
BdrvChild *child; BdrvChild *child;
GLOBAL_STATE_CODE(); GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();
if (bs->drv && bs->drv->bdrv_register_buf) { if (bs->drv && bs->drv->bdrv_register_buf) {
if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) { if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) {
return false; return false;
@ -3221,6 +3236,8 @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size)
BdrvChild *child; BdrvChild *child;
GLOBAL_STATE_CODE(); GLOBAL_STATE_CODE();
GRAPH_RDLOCK_GUARD_MAINLOOP();
if (bs->drv && bs->drv->bdrv_unregister_buf) { if (bs->drv && bs->drv->bdrv_unregister_buf) {
bs->drv->bdrv_unregister_buf(bs, host, size); bs->drv->bdrv_unregister_buf(bs, host, size);
} }
@ -3229,7 +3246,7 @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size)
} }
} }
static int coroutine_fn bdrv_co_copy_range_internal( static int coroutine_fn GRAPH_RDLOCK bdrv_co_copy_range_internal(
BdrvChild *src, int64_t src_offset, BdrvChild *dst, BdrvChild *src, int64_t src_offset, BdrvChild *dst,
int64_t dst_offset, int64_t bytes, int64_t dst_offset, int64_t bytes,
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags, BdrvRequestFlags read_flags, BdrvRequestFlags write_flags,
@ -3237,6 +3254,7 @@ static int coroutine_fn bdrv_co_copy_range_internal(
{ {
BdrvTrackedRequest req; BdrvTrackedRequest req;
int ret; int ret;
assert_bdrv_graph_readable();
/* TODO We can support BDRV_REQ_NO_FALLBACK here */ /* TODO We can support BDRV_REQ_NO_FALLBACK here */
assert(!(read_flags & BDRV_REQ_NO_FALLBACK)); assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
@ -3318,6 +3336,7 @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes, trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags); read_flags, write_flags);
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset, return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
@ -3335,6 +3354,7 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags); read_flags, write_flags);
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset, return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
@ -3347,6 +3367,8 @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
return bdrv_co_copy_range_from(src, src_offset, return bdrv_co_copy_range_from(src, src_offset,
dst, dst_offset, dst, dst_offset,
bytes, read_flags, write_flags); bytes, read_flags, write_flags);
@ -3380,6 +3402,7 @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
int64_t old_size, new_bytes; int64_t old_size, new_bytes;
int ret; int ret;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */ /* if bs->drv == NULL, bs is closed, so there's nothing to do here */
if (!drv) { if (!drv) {
@ -3517,6 +3540,7 @@ bdrv_co_preadv_snapshot(BdrvChild *child, int64_t offset, int64_t bytes,
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
int ret; int ret;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
if (!drv) { if (!drv) {
return -ENOMEDIUM; return -ENOMEDIUM;
@ -3542,6 +3566,7 @@ bdrv_co_snapshot_block_status(BlockDriverState *bs,
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
int ret; int ret;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
if (!drv) { if (!drv) {
return -ENOMEDIUM; return -ENOMEDIUM;
@ -3565,6 +3590,7 @@ bdrv_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
BlockDriver *drv = bs->drv; BlockDriver *drv = bs->drv;
int ret; int ret;
IO_CODE(); IO_CODE();
assert_bdrv_graph_readable();
if (!drv) { if (!drv) {
return -ENOMEDIUM; return -ENOMEDIUM;

View File

@ -2190,13 +2190,11 @@ static void coroutine_fn iscsi_co_invalidate_cache(BlockDriverState *bs,
iscsi_allocmap_invalidate(iscsilun); iscsi_allocmap_invalidate(iscsilun);
} }
static int coroutine_fn iscsi_co_copy_range_from(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvChild *src, iscsi_co_copy_range_from(BlockDriverState *bs,
int64_t src_offset, BdrvChild *src, int64_t src_offset,
BdrvChild *dst, BdrvChild *dst, int64_t dst_offset,
int64_t dst_offset, int64_t bytes, BdrvRequestFlags read_flags,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
@ -2331,13 +2329,11 @@ static void iscsi_xcopy_data(struct iscsi_data *data,
src_lba, dst_lba); src_lba, dst_lba);
} }
static int coroutine_fn iscsi_co_copy_range_to(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvChild *src, iscsi_co_copy_range_to(BlockDriverState *bs,
int64_t src_offset, BdrvChild *src, int64_t src_offset,
BdrvChild *dst, BdrvChild *dst, int64_t dst_offset,
int64_t dst_offset, int64_t bytes, BdrvRequestFlags read_flags,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
IscsiLun *dst_lun = dst->bs->opaque; IscsiLun *dst_lun = dst->bs->opaque;

View File

@ -21,7 +21,6 @@
#include "block/dirty-bitmap.h" #include "block/dirty-bitmap.h"
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h" #include "qemu/ratelimit.h"
#include "qemu/bitmap.h" #include "qemu/bitmap.h"
#include "qemu/memalign.h" #include "qemu/memalign.h"
@ -390,8 +389,10 @@ static void coroutine_fn mirror_co_read(void *opaque)
op->is_in_flight = true; op->is_in_flight = true;
trace_mirror_one_iteration(s, op->offset, op->bytes); trace_mirror_one_iteration(s, op->offset, op->bytes);
WITH_GRAPH_RDLOCK_GUARD() {
ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes, ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes,
&op->qiov, 0); &op->qiov, 0);
}
mirror_read_complete(op, ret); mirror_read_complete(op, ret);
} }
@ -558,9 +559,11 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
MirrorMethod mirror_method = MIRROR_METHOD_COPY; MirrorMethod mirror_method = MIRROR_METHOD_COPY;
assert(!(offset % s->granularity)); assert(!(offset % s->granularity));
WITH_GRAPH_RDLOCK_GUARD() {
ret = bdrv_block_status_above(source, NULL, offset, ret = bdrv_block_status_above(source, NULL, offset,
nb_chunks * s->granularity, nb_chunks * s->granularity,
&io_bytes, NULL, NULL); &io_bytes, NULL, NULL);
}
if (ret < 0) { if (ret < 0) {
io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes); io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes);
} else if (ret & BDRV_BLOCK_DATA) { } else if (ret & BDRV_BLOCK_DATA) {
@ -863,8 +866,10 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
return 0; return 0;
} }
ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset, bytes, WITH_GRAPH_RDLOCK_GUARD() {
&count); ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset,
bytes, &count);
}
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -896,6 +901,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
{ {
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job); MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
BlockDriverState *bs = s->mirror_top_bs->backing->bs; BlockDriverState *bs = s->mirror_top_bs->backing->bs;
MirrorBDSOpaque *mirror_top_opaque = s->mirror_top_bs->opaque;
BlockDriverState *target_bs = blk_bs(s->target); BlockDriverState *target_bs = blk_bs(s->target);
bool need_drain = true; bool need_drain = true;
BlockDeviceIoStatus iostatus; BlockDeviceIoStatus iostatus;
@ -910,7 +916,10 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
goto immediate_exit; goto immediate_exit;
} }
bdrv_graph_co_rdlock();
s->bdev_length = bdrv_co_getlength(bs); s->bdev_length = bdrv_co_getlength(bs);
bdrv_graph_co_rdunlock();
if (s->bdev_length < 0) { if (s->bdev_length < 0) {
ret = s->bdev_length; ret = s->bdev_length;
goto immediate_exit; goto immediate_exit;
@ -985,6 +994,12 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
} }
} }
/*
* Only now the job is fully initialised and mirror_top_bs should start
* accessing it.
*/
mirror_top_opaque->job = s;
assert(!s->dbi); assert(!s->dbi);
s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap); s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
for (;;) { for (;;) {
@ -1426,14 +1441,16 @@ static void coroutine_fn active_write_settle(MirrorOp *op)
g_free(op); g_free(op);
} }
static int coroutine_fn bdrv_mirror_top_preadv(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) bdrv_mirror_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags); return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
} }
static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
MirrorMethod method, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, bdrv_mirror_top_do_write(BlockDriverState *bs, MirrorMethod method,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
int flags) int flags)
{ {
MirrorOp *op = NULL; MirrorOp *op = NULL;
@ -1483,8 +1500,9 @@ out:
return ret; return ret;
} }
static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) bdrv_mirror_top_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
MirrorBDSOpaque *s = bs->opaque; MirrorBDSOpaque *s = bs->opaque;
QEMUIOVector bounce_qiov; QEMUIOVector bounce_qiov;
@ -1524,7 +1542,7 @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs) static int coroutine_fn GRAPH_RDLOCK bdrv_mirror_top_flush(BlockDriverState *bs)
{ {
if (bs->backing == NULL) { if (bs->backing == NULL) {
/* we can be here after failed bdrv_append in mirror_start_job */ /* we can be here after failed bdrv_append in mirror_start_job */
@ -1533,15 +1551,16 @@ static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs)
return bdrv_co_flush(bs->backing->bs); return bdrv_co_flush(bs->backing->bs);
} }
static int coroutine_fn bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, BdrvRequestFlags flags) bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
int64_t bytes, BdrvRequestFlags flags)
{ {
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL, return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL,
flags); flags);
} }
static int coroutine_fn bdrv_mirror_top_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) bdrv_mirror_top_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_DISCARD, offset, bytes, return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_DISCARD, offset, bytes,
NULL, 0); NULL, 0);
@ -1704,7 +1723,6 @@ static BlockJob *mirror_start_job(
if (!s) { if (!s) {
goto fail; goto fail;
} }
bs_opaque->job = s;
/* The block job now has a reference to this node */ /* The block job now has a reference to this node */
bdrv_unref(mirror_top_bs); bdrv_unref(mirror_top_bs);

View File

@ -165,8 +165,8 @@ static int64_t block_status(BDRVParallelsState *s, int64_t sector_num,
return start_off; return start_off;
} }
static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs, static int64_t coroutine_fn GRAPH_RDLOCK
int64_t sector_num, allocate_clusters(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum) int nb_sectors, int *pnum)
{ {
int ret = 0; int ret = 0;
@ -261,7 +261,8 @@ static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs,
} }
static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs) static int coroutine_fn GRAPH_RDLOCK
parallels_co_flush_to_os(BlockDriverState *bs)
{ {
BDRVParallelsState *s = bs->opaque; BDRVParallelsState *s = bs->opaque;
unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block); unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block);
@ -320,8 +321,8 @@ static int coroutine_fn parallels_co_block_status(BlockDriverState *bs,
return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID; return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
} }
static coroutine_fn int parallels_co_writev(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t sector_num, int nb_sectors, parallels_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags) QEMUIOVector *qiov, int flags)
{ {
BDRVParallelsState *s = bs->opaque; BDRVParallelsState *s = bs->opaque;
@ -363,8 +364,9 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
return ret; return ret;
} }
static coroutine_fn int parallels_co_readv(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) parallels_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
{ {
BDRVParallelsState *s = bs->opaque; BDRVParallelsState *s = bs->opaque;
uint64_t bytes_done = 0; uint64_t bytes_done = 0;
@ -414,8 +416,8 @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
} }
static int coroutine_fn parallels_co_check(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvCheckResult *res, parallels_co_check(BlockDriverState *bs, BdrvCheckResult *res,
BdrvCheckMode fix) BdrvCheckMode fix)
{ {
BDRVParallelsState *s = bs->opaque; BDRVParallelsState *s = bs->opaque;
@ -620,10 +622,9 @@ exit:
goto out; goto out;
} }
static int coroutine_fn parallels_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, parallels_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
BlockdevCreateOptions *create_options = NULL; BlockdevCreateOptions *create_options = NULL;
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;

View File

@ -226,16 +226,17 @@ static void preallocate_reopen_abort(BDRVReopenState *state)
state->opaque = NULL; state->opaque = NULL;
} }
static coroutine_fn int preallocate_co_preadv_part( static int coroutine_fn GRAPH_RDLOCK
BlockDriverState *bs, int64_t offset, int64_t bytes, preallocate_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags) QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{ {
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset, return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
flags); flags);
} }
static int coroutine_fn preallocate_co_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) preallocate_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
return bdrv_co_pdiscard(bs->file, offset, bytes); return bdrv_co_pdiscard(bs->file, offset, bytes);
} }
@ -269,8 +270,9 @@ static bool has_prealloc_perms(BlockDriverState *bs)
* want_merge_zero is used to merge write-zero request with preallocation in * want_merge_zero is used to merge write-zero request with preallocation in
* one bdrv_co_pwrite_zeroes() call. * one bdrv_co_pwrite_zeroes() call.
*/ */
static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset, static bool coroutine_fn GRAPH_RDLOCK
int64_t bytes, bool want_merge_zero) handle_write(BlockDriverState *bs, int64_t offset, int64_t bytes,
bool want_merge_zero)
{ {
BDRVPreallocateState *s = bs->opaque; BDRVPreallocateState *s = bs->opaque;
int64_t end = offset + bytes; int64_t end = offset + bytes;
@ -345,8 +347,9 @@ static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
return want_merge_zero; return want_merge_zero;
} }
static int coroutine_fn preallocate_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, BdrvRequestFlags flags) preallocate_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
int64_t bytes, BdrvRequestFlags flags)
{ {
bool want_merge_zero = bool want_merge_zero =
!(flags & ~(BDRV_REQ_ZERO_WRITE | BDRV_REQ_NO_FALLBACK)); !(flags & ~(BDRV_REQ_ZERO_WRITE | BDRV_REQ_NO_FALLBACK));
@ -357,11 +360,9 @@ static int coroutine_fn preallocate_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
} }
static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, preallocate_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset,
QEMUIOVector *qiov,
size_t qiov_offset,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
handle_write(bs, offset, bytes, false); handle_write(bs, offset, bytes, false);
@ -370,7 +371,7 @@ static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs,
flags); flags);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
preallocate_co_truncate(BlockDriverState *bs, int64_t offset, preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
bool exact, PreallocMode prealloc, bool exact, PreallocMode prealloc,
BdrvRequestFlags flags, Error **errp) BdrvRequestFlags flags, Error **errp)
@ -437,12 +438,13 @@ preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
return 0; return 0;
} }
static int coroutine_fn preallocate_co_flush(BlockDriverState *bs) static int coroutine_fn GRAPH_RDLOCK preallocate_co_flush(BlockDriverState *bs)
{ {
return bdrv_co_flush(bs->file->bs); return bdrv_co_flush(bs->file->bs);
} }
static int64_t coroutine_fn preallocate_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
preallocate_co_getlength(BlockDriverState *bs)
{ {
int64_t ret; int64_t ret;
BDRVPreallocateState *s = bs->opaque; BDRVPreallocateState *s = bs->opaque;

View File

@ -92,8 +92,8 @@ typedef struct BDRVQcowState {
static QemuOptsList qcow_create_opts; static QemuOptsList qcow_create_opts;
static int coroutine_fn decompress_cluster(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
uint64_t cluster_offset); decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
{ {
@ -350,10 +350,9 @@ static int qcow_reopen_prepare(BDRVReopenState *state,
* return 0 if not allocated, 1 if *result is assigned, and negative * return 0 if not allocated, 1 if *result is assigned, and negative
* errno on failure. * errno on failure.
*/ */
static int coroutine_fn get_cluster_offset(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
uint64_t offset, int allocate, get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
int compressed_size, int compressed_size, int n_start, int n_end,
int n_start, int n_end,
uint64_t *result) uint64_t *result)
{ {
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
@ -525,11 +524,10 @@ static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
return 1; return 1;
} }
static int coroutine_fn qcow_co_block_status(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
bool want_zero, qcow_co_block_status(BlockDriverState *bs, bool want_zero,
int64_t offset, int64_t bytes, int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *pnum, int64_t *map, int64_t *map, BlockDriverState **file)
BlockDriverState **file)
{ {
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
int index_in_cluster, ret; int index_in_cluster, ret;
@ -586,8 +584,8 @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
return 0; return 0;
} }
static int coroutine_fn decompress_cluster(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
uint64_t cluster_offset) decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
{ {
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
int ret, csize; int ret, csize;
@ -619,9 +617,9 @@ static void qcow_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.request_alignment = BDRV_SECTOR_SIZE; bs->bl.request_alignment = BDRV_SECTOR_SIZE;
} }
static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset, static int coroutine_fn GRAPH_RDLOCK
int64_t bytes, QEMUIOVector *qiov, qcow_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
int offset_in_cluster; int offset_in_cluster;
@ -715,9 +713,9 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset,
return ret; return ret;
} }
static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset, static int coroutine_fn GRAPH_RDLOCK
int64_t bytes, QEMUIOVector *qiov, qcow_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
BDRVQcowState *s = bs->opaque; BDRVQcowState *s = bs->opaque;
int offset_in_cluster; int offset_in_cluster;
@ -923,8 +921,8 @@ exit:
return ret; return ret;
} }
static int coroutine_fn qcow_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, qcow_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, Error **errp) QemuOpts *opts, Error **errp)
{ {
BlockdevCreateOptions *create_options = NULL; BlockdevCreateOptions *create_options = NULL;
@ -1046,7 +1044,7 @@ static int qcow_make_empty(BlockDriverState *bs)
/* XXX: put compressed sectors first, then all the cluster aligned /* XXX: put compressed sectors first, then all the cluster aligned
tables to avoid losing bytes in alignment */ tables to avoid losing bytes in alignment */
static coroutine_fn int static int coroutine_fn GRAPH_RDLOCK
qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov) QEMUIOVector *qiov)
{ {

View File

@ -491,10 +491,9 @@ static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters,
return count; return count;
} }
static int coroutine_fn do_perform_cow_read(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
uint64_t src_cluster_offset, do_perform_cow_read(BlockDriverState *bs, uint64_t src_cluster_offset,
unsigned offset_in_cluster, unsigned offset_in_cluster, QEMUIOVector *qiov)
QEMUIOVector *qiov)
{ {
int ret; int ret;
@ -535,10 +534,9 @@ static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
return 0; return 0;
} }
static int coroutine_fn do_perform_cow_write(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
uint64_t cluster_offset, do_perform_cow_write(BlockDriverState *bs, uint64_t cluster_offset,
unsigned offset_in_cluster, unsigned offset_in_cluster, QEMUIOVector *qiov)
QEMUIOVector *qiov)
{ {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
int ret; int ret;
@ -886,7 +884,8 @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
return 0; return 0;
} }
static int coroutine_fn perform_cow(BlockDriverState *bs, QCowL2Meta *m) static int coroutine_fn GRAPH_RDLOCK
perform_cow(BlockDriverState *bs, QCowL2Meta *m)
{ {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
Qcow2COWRegion *start = &m->cow_start; Qcow2COWRegion *start = &m->cow_start;

View File

@ -601,8 +601,8 @@ static void qcow2_add_check_result(BdrvCheckResult *out,
} }
} }
static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvCheckResult *result, qcow2_co_check_locked(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix) BdrvCheckMode fix)
{ {
BdrvCheckResult snapshot_res = {}; BdrvCheckResult snapshot_res = {};
@ -640,8 +640,8 @@ static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn qcow2_co_check(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvCheckResult *result, qcow2_co_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix) BdrvCheckMode fix)
{ {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
@ -1294,9 +1294,9 @@ static int validate_compression_type(BDRVQcow2State *s, Error **errp)
} }
/* Called with s->lock held. */ /* Called with s->lock held. */
static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, static int coroutine_fn GRAPH_RDLOCK
int flags, bool open_data_file, qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp) bool open_data_file, Error **errp)
{ {
ERRP_GUARD(); ERRP_GUARD();
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
@ -1890,6 +1890,8 @@ static void coroutine_fn qcow2_open_entry(void *opaque)
QCow2OpenCo *qoc = opaque; QCow2OpenCo *qoc = opaque;
BDRVQcow2State *s = qoc->bs->opaque; BDRVQcow2State *s = qoc->bs->opaque;
assume_graph_lock(); /* FIXME */
qemu_co_mutex_lock(&s->lock); qemu_co_mutex_lock(&s->lock);
qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true, qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true,
qoc->errp); qoc->errp);
@ -2137,9 +2139,8 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
return status; return status;
} }
static coroutine_fn int qcow2_handle_l2meta(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
QCowL2Meta **pl2meta, qcow2_handle_l2meta(BlockDriverState *bs, QCowL2Meta **pl2meta, bool link_l2)
bool link_l2)
{ {
int ret = 0; int ret = 0;
QCowL2Meta *l2meta = *pl2meta; QCowL2Meta *l2meta = *pl2meta;
@ -2170,7 +2171,7 @@ out:
return ret; return ret;
} }
static coroutine_fn int static int coroutine_fn GRAPH_RDLOCK
qcow2_co_preadv_encrypted(BlockDriverState *bs, qcow2_co_preadv_encrypted(BlockDriverState *bs,
uint64_t host_offset, uint64_t host_offset,
uint64_t offset, uint64_t offset,
@ -2271,12 +2272,10 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
return 0; return 0;
} }
static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
QCow2SubclusterType subc_type, qcow2_co_preadv_task(BlockDriverState *bs, QCow2SubclusterType subc_type,
uint64_t host_offset, uint64_t host_offset, uint64_t offset, uint64_t bytes,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, size_t qiov_offset)
QEMUIOVector *qiov,
size_t qiov_offset)
{ {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
@ -2315,7 +2314,11 @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
g_assert_not_reached(); g_assert_not_reached();
} }
static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task) /*
* This function can count as GRAPH_RDLOCK because qcow2_co_preadv_part() holds
* the graph lock and keeps it until this coroutine has terminated.
*/
static int coroutine_fn GRAPH_RDLOCK qcow2_co_preadv_task_entry(AioTask *task)
{ {
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task); Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
@ -2326,10 +2329,9 @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task)
t->qiov, t->qiov_offset); t->qiov, t->qiov_offset);
} }
static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, qcow2_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, QEMUIOVector *qiov, size_t qiov_offset,
size_t qiov_offset,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
@ -2450,7 +2452,8 @@ static bool merge_cow(uint64_t offset, unsigned bytes,
* Return 1 if the COW regions read as zeroes, 0 if not, < 0 on error. * Return 1 if the COW regions read as zeroes, 0 if not, < 0 on error.
* Note that returning 0 does not guarantee non-zero data. * Note that returning 0 does not guarantee non-zero data.
*/ */
static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m) static int coroutine_fn GRAPH_RDLOCK
is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
{ {
/* /*
* This check is designed for optimization shortcut so it must be * This check is designed for optimization shortcut so it must be
@ -2468,8 +2471,8 @@ static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
m->cow_end.nb_bytes); m->cow_end.nb_bytes);
} }
static int coroutine_fn handle_alloc_space(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
QCowL2Meta *l2meta) handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
{ {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
QCowL2Meta *m; QCowL2Meta *m;
@ -2532,12 +2535,10 @@ static int coroutine_fn handle_alloc_space(BlockDriverState *bs,
* l2meta - if not NULL, qcow2_co_pwritev_task() will consume it. Caller must * l2meta - if not NULL, qcow2_co_pwritev_task() will consume it. Caller must
* not use it somehow after qcow2_co_pwritev_task() call * not use it somehow after qcow2_co_pwritev_task() call
*/ */
static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs, static coroutine_fn GRAPH_RDLOCK
uint64_t host_offset, int qcow2_co_pwritev_task(BlockDriverState *bs, uint64_t host_offset,
uint64_t offset, uint64_t bytes, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
QEMUIOVector *qiov, uint64_t qiov_offset, QCowL2Meta *l2meta)
uint64_t qiov_offset,
QCowL2Meta *l2meta)
{ {
int ret; int ret;
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
@ -2603,7 +2604,11 @@ out_locked:
return ret; return ret;
} }
static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task) /*
* This function can count as GRAPH_RDLOCK because qcow2_co_pwritev_part() holds
* the graph lock and keeps it until this coroutine has terminated.
*/
static coroutine_fn GRAPH_RDLOCK int qcow2_co_pwritev_task_entry(AioTask *task)
{ {
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task); Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
@ -2614,9 +2619,10 @@ static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task)
t->l2meta); t->l2meta);
} }
static coroutine_fn int qcow2_co_pwritev_part( static int coroutine_fn GRAPH_RDLOCK
BlockDriverState *bs, int64_t offset, int64_t bytes, qcow2_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags) QEMUIOVector *qiov, size_t qiov_offset,
BdrvRequestFlags flags)
{ {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
int offset_in_cluster; int offset_in_cluster;
@ -2771,8 +2777,8 @@ static void qcow2_close(BlockDriverState *bs)
qcow2_do_close(bs, true); qcow2_do_close(bs, true);
} }
static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs, static void coroutine_fn GRAPH_RDLOCK
Error **errp) qcow2_co_invalidate_cache(BlockDriverState *bs, Error **errp)
{ {
ERRP_GUARD(); ERRP_GUARD();
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
@ -3183,9 +3189,9 @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
* *
* Returns: 0 on success, -errno on failure. * Returns: 0 on success, -errno on failure.
*/ */
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset, static int coroutine_fn GRAPH_RDLOCK
uint64_t new_length, PreallocMode mode, preallocate_co(BlockDriverState *bs, uint64_t offset, uint64_t new_length,
Error **errp) PreallocMode mode, Error **errp)
{ {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
uint64_t bytes; uint64_t bytes;
@ -3810,9 +3816,8 @@ out:
return ret; return ret;
} }
static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
QemuOpts *opts,
Error **errp) Error **errp)
{ {
BlockdevCreateOptions *create_options = NULL; BlockdevCreateOptions *create_options = NULL;
@ -3974,8 +3979,9 @@ static bool is_zero(BlockDriverState *bs, int64_t offset, int64_t bytes)
return res >= 0 && (res & BDRV_BLOCK_ZERO) && bytes == 0; return res >= 0 && (res & BDRV_BLOCK_ZERO) && bytes == 0;
} }
static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, BdrvRequestFlags flags) qcow2_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags)
{ {
int ret; int ret;
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
@ -4058,7 +4064,7 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
qcow2_co_copy_range_from(BlockDriverState *bs, qcow2_co_copy_range_from(BlockDriverState *bs,
BdrvChild *src, int64_t src_offset, BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset, BdrvChild *dst, int64_t dst_offset,
@ -4141,7 +4147,7 @@ out:
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
qcow2_co_copy_range_to(BlockDriverState *bs, qcow2_co_copy_range_to(BlockDriverState *bs,
BdrvChild *src, int64_t src_offset, BdrvChild *src, int64_t src_offset,
BdrvChild *dst, int64_t dst_offset, BdrvChild *dst, int64_t dst_offset,
@ -4209,9 +4215,9 @@ fail:
return ret; return ret;
} }
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset, static int coroutine_fn GRAPH_RDLOCK
bool exact, PreallocMode prealloc, qcow2_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
BdrvRequestFlags flags, Error **errp) PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
{ {
BDRVQcow2State *s = bs->opaque; BDRVQcow2State *s = bs->opaque;
uint64_t old_length; uint64_t old_length;
@ -4585,7 +4591,7 @@ fail:
return ret; return ret;
} }
static coroutine_fn int static int coroutine_fn GRAPH_RDLOCK
qcow2_co_pwritev_compressed_task(BlockDriverState *bs, qcow2_co_pwritev_compressed_task(BlockDriverState *bs,
uint64_t offset, uint64_t bytes, uint64_t offset, uint64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset) QEMUIOVector *qiov, size_t qiov_offset)
@ -4649,7 +4655,13 @@ fail:
return ret; return ret;
} }
static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task) /*
* This function can count as GRAPH_RDLOCK because
* qcow2_co_pwritev_compressed_part() holds the graph lock and keeps it until
* this coroutine has terminated.
*/
static int coroutine_fn GRAPH_RDLOCK
qcow2_co_pwritev_compressed_task_entry(AioTask *task)
{ {
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task); Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
@ -4663,7 +4675,7 @@ static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
* XXX: put compressed sectors first, then all the cluster aligned * XXX: put compressed sectors first, then all the cluster aligned
* tables to avoid losing bytes in alignment * tables to avoid losing bytes in alignment
*/ */
static coroutine_fn int static int coroutine_fn GRAPH_RDLOCK
qcow2_co_pwritev_compressed_part(BlockDriverState *bs, qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
int64_t offset, int64_t bytes, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset) QEMUIOVector *qiov, size_t qiov_offset)
@ -4726,7 +4738,7 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
qcow2_co_preadv_compressed(BlockDriverState *bs, qcow2_co_preadv_compressed(BlockDriverState *bs,
uint64_t l2_entry, uint64_t l2_entry,
uint64_t offset, uint64_t offset,
@ -5288,8 +5300,8 @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs,
return pos; return pos;
} }
static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
QEMUIOVector *qiov, int64_t pos) qcow2_co_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
{ {
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos); int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
if (offset < 0) { if (offset < 0) {
@ -5300,8 +5312,8 @@ static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs,
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0); return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
} }
static coroutine_fn int qcow2_co_load_vmstate(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
QEMUIOVector *qiov, int64_t pos) qcow2_co_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
{ {
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos); int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
if (offset < 0) { if (offset < 0) {

View File

@ -846,7 +846,7 @@ int qcow2_validate_table(BlockDriverState *bs, uint64_t offset,
Error **errp); Error **errp);
/* qcow2-refcount.c functions */ /* qcow2-refcount.c functions */
int coroutine_fn qcow2_refcount_init(BlockDriverState *bs); int coroutine_fn GRAPH_RDLOCK qcow2_refcount_init(BlockDriverState *bs);
void qcow2_refcount_close(BlockDriverState *bs); void qcow2_refcount_close(BlockDriverState *bs);
int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index, int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
@ -893,14 +893,17 @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order, int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
BlockDriverAmendStatusCB *status_cb, BlockDriverAmendStatusCB *status_cb,
void *cb_opaque, Error **errp); void *cb_opaque, Error **errp);
int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs); int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs);
int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size); int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs); int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs);
/* qcow2-cluster.c functions */ /* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
bool exact_size); bool exact_size);
int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
int coroutine_fn GRAPH_RDLOCK
qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index); int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
uint8_t *buf, int nb_sectors, bool enc, Error **errp); uint8_t *buf, int nb_sectors, bool enc, Error **errp);
@ -918,14 +921,17 @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry, void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
uint64_t *coffset, int *csize); uint64_t *coffset, int *csize);
int coroutine_fn qcow2_alloc_cluster_link_l2(BlockDriverState *bs, int coroutine_fn GRAPH_RDLOCK
QCowL2Meta *m); qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m); void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset, int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, enum qcow2_discard_type type, uint64_t bytes, enum qcow2_discard_type type,
bool full_discard); bool full_discard);
int coroutine_fn qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, int flags); int coroutine_fn GRAPH_RDLOCK
qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
int flags);
int qcow2_expand_zero_clusters(BlockDriverState *bs, int qcow2_expand_zero_clusters(BlockDriverState *bs,
BlockDriverAmendStatusCB *status_cb, BlockDriverAmendStatusCB *status_cb,
@ -948,9 +954,10 @@ void qcow2_free_snapshots(BlockDriverState *bs);
int qcow2_read_snapshots(BlockDriverState *bs, Error **errp); int qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
int qcow2_write_snapshots(BlockDriverState *bs); int qcow2_write_snapshots(BlockDriverState *bs);
int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs, int coroutine_fn GRAPH_RDLOCK
BdrvCheckResult *result, qcow2_check_read_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix); BdrvCheckMode fix);
int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs, int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs,
BdrvCheckResult *result, BdrvCheckResult *result,
BdrvCheckMode fix); BdrvCheckMode fix);

View File

@ -107,7 +107,8 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
/** /**
* Descend tables and check each cluster is referenced once only * Descend tables and check each cluster is referenced once only
*/ */
static int coroutine_fn qed_check_l1_table(QEDCheck *check, QEDTable *table) static int coroutine_fn GRAPH_RDLOCK
qed_check_l1_table(QEDCheck *check, QEDTable *table)
{ {
BDRVQEDState *s = check->s; BDRVQEDState *s = check->s;
unsigned int i, num_invalid_l1 = 0; unsigned int i, num_invalid_l1 = 0;

View File

@ -21,8 +21,8 @@
#include "qemu/memalign.h" #include "qemu/memalign.h"
/* Called with table_lock held. */ /* Called with table_lock held. */
static int coroutine_fn qed_read_table(BDRVQEDState *s, uint64_t offset, static int coroutine_fn GRAPH_RDLOCK
QEDTable *table) qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
{ {
unsigned int bytes = s->header.cluster_size * s->header.table_size; unsigned int bytes = s->header.cluster_size * s->header.table_size;
@ -63,9 +63,9 @@ out:
* *
* Called with table_lock held. * Called with table_lock held.
*/ */
static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset, static int coroutine_fn GRAPH_RDLOCK
QEDTable *table, unsigned int index, qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
unsigned int n, bool flush) unsigned int index, unsigned int n, bool flush)
{ {
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1; unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
unsigned int start, end, i; unsigned int start, end, i;

View File

@ -100,7 +100,7 @@ int qed_write_header_sync(BDRVQEDState *s)
* *
* No new allocating reqs can start while this function runs. * No new allocating reqs can start while this function runs.
*/ */
static int coroutine_fn qed_write_header(BDRVQEDState *s) static int coroutine_fn GRAPH_RDLOCK qed_write_header(BDRVQEDState *s)
{ {
/* We must write full sectors for O_DIRECT but cannot necessarily generate /* We must write full sectors for O_DIRECT but cannot necessarily generate
* the data following the header if an unrecognized compat feature is * the data following the header if an unrecognized compat feature is
@ -282,11 +282,12 @@ static void coroutine_fn qed_unplug_allocating_write_reqs(BDRVQEDState *s)
qemu_co_mutex_unlock(&s->table_lock); qemu_co_mutex_unlock(&s->table_lock);
} }
static void coroutine_fn qed_need_check_timer(BDRVQEDState *s) static void coroutine_fn GRAPH_RDLOCK qed_need_check_timer(BDRVQEDState *s)
{ {
int ret; int ret;
trace_qed_need_check_timer_cb(s); trace_qed_need_check_timer_cb(s);
assert_bdrv_graph_readable();
if (!qed_plug_allocating_write_reqs(s)) { if (!qed_plug_allocating_write_reqs(s)) {
return; return;
@ -312,6 +313,7 @@ static void coroutine_fn qed_need_check_timer(BDRVQEDState *s)
static void coroutine_fn qed_need_check_timer_entry(void *opaque) static void coroutine_fn qed_need_check_timer_entry(void *opaque)
{ {
BDRVQEDState *s = opaque; BDRVQEDState *s = opaque;
GRAPH_RDLOCK_GUARD();
qed_need_check_timer(opaque); qed_need_check_timer(opaque);
bdrv_dec_in_flight(s->bs); bdrv_dec_in_flight(s->bs);
@ -393,8 +395,8 @@ static void bdrv_qed_init_state(BlockDriverState *bs)
} }
/* Called with table_lock held. */ /* Called with table_lock held. */
static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options, static int coroutine_fn GRAPH_RDLOCK
int flags, Error **errp) bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
{ {
BDRVQEDState *s = bs->opaque; BDRVQEDState *s = bs->opaque;
QEDHeader le_header; QEDHeader le_header;
@ -555,7 +557,7 @@ typedef struct QEDOpenCo {
int ret; int ret;
} QEDOpenCo; } QEDOpenCo;
static void coroutine_fn bdrv_qed_open_entry(void *opaque) static void coroutine_fn GRAPH_RDLOCK bdrv_qed_open_entry(void *opaque)
{ {
QEDOpenCo *qoc = opaque; QEDOpenCo *qoc = opaque;
BDRVQEDState *s = qoc->bs->opaque; BDRVQEDState *s = qoc->bs->opaque;
@ -577,6 +579,8 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
}; };
int ret; int ret;
assume_graph_lock(); /* FIXME */
ret = bdrv_open_file_child(NULL, options, "file", bs, errp); ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
@ -750,10 +754,9 @@ out:
return ret; return ret;
} }
static int coroutine_fn bdrv_qed_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
BlockdevCreateOptions *create_options = NULL; BlockdevCreateOptions *create_options = NULL;
QDict *qdict; QDict *qdict;
@ -822,10 +825,9 @@ fail:
return ret; return ret;
} }
static int coroutine_fn bdrv_qed_co_block_status(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
bool want_zero, bdrv_qed_co_block_status(BlockDriverState *bs, bool want_zero, int64_t pos,
int64_t pos, int64_t bytes, int64_t bytes, int64_t *pnum, int64_t *map,
int64_t *pnum, int64_t *map,
BlockDriverState **file) BlockDriverState **file)
{ {
BDRVQEDState *s = bs->opaque; BDRVQEDState *s = bs->opaque;
@ -879,8 +881,8 @@ static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
* This function reads qiov->size bytes starting at pos from the backing file. * This function reads qiov->size bytes starting at pos from the backing file.
* If there is no backing file then zeroes are read. * If there is no backing file then zeroes are read.
*/ */
static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos, static int coroutine_fn GRAPH_RDLOCK
QEMUIOVector *qiov) qed_read_backing_file(BDRVQEDState *s, uint64_t pos, QEMUIOVector *qiov)
{ {
if (s->bs->backing) { if (s->bs->backing) {
BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO); BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
@ -898,8 +900,8 @@ static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
* @len: Number of bytes * @len: Number of bytes
* @offset: Byte offset in image file * @offset: Byte offset in image file
*/ */
static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s, static int coroutine_fn GRAPH_RDLOCK
uint64_t pos, uint64_t len, qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos, uint64_t len,
uint64_t offset) uint64_t offset)
{ {
QEMUIOVector qiov; QEMUIOVector qiov;
@ -993,7 +995,7 @@ static void coroutine_fn qed_aio_complete(QEDAIOCB *acb)
* *
* Called with table_lock held. * Called with table_lock held.
*/ */
static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb) static int coroutine_fn GRAPH_RDLOCK qed_aio_write_l1_update(QEDAIOCB *acb)
{ {
BDRVQEDState *s = acb_to_s(acb); BDRVQEDState *s = acb_to_s(acb);
CachedL2Table *l2_table = acb->request.l2_table; CachedL2Table *l2_table = acb->request.l2_table;
@ -1023,7 +1025,8 @@ static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb)
* *
* Called with table_lock held. * Called with table_lock held.
*/ */
static int coroutine_fn qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset) static int coroutine_fn GRAPH_RDLOCK
qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
{ {
BDRVQEDState *s = acb_to_s(acb); BDRVQEDState *s = acb_to_s(acb);
bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1; bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1;
@ -1061,7 +1064,7 @@ static int coroutine_fn qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
* *
* Called with table_lock *not* held. * Called with table_lock *not* held.
*/ */
static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb) static int coroutine_fn GRAPH_RDLOCK qed_aio_write_main(QEDAIOCB *acb)
{ {
BDRVQEDState *s = acb_to_s(acb); BDRVQEDState *s = acb_to_s(acb);
uint64_t offset = acb->cur_cluster + uint64_t offset = acb->cur_cluster +
@ -1079,7 +1082,7 @@ static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
* *
* Called with table_lock held. * Called with table_lock held.
*/ */
static int coroutine_fn qed_aio_write_cow(QEDAIOCB *acb) static int coroutine_fn GRAPH_RDLOCK qed_aio_write_cow(QEDAIOCB *acb)
{ {
BDRVQEDState *s = acb_to_s(acb); BDRVQEDState *s = acb_to_s(acb);
uint64_t start, len, offset; uint64_t start, len, offset;
@ -1157,7 +1160,8 @@ static bool qed_should_set_need_check(BDRVQEDState *s)
* *
* Called with table_lock held. * Called with table_lock held.
*/ */
static int coroutine_fn qed_aio_write_alloc(QEDAIOCB *acb, size_t len) static int coroutine_fn GRAPH_RDLOCK
qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
{ {
BDRVQEDState *s = acb_to_s(acb); BDRVQEDState *s = acb_to_s(acb);
int ret; int ret;
@ -1220,8 +1224,8 @@ static int coroutine_fn qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
* *
* Called with table_lock held. * Called with table_lock held.
*/ */
static int coroutine_fn qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, static int coroutine_fn GRAPH_RDLOCK
size_t len) qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
{ {
BDRVQEDState *s = acb_to_s(acb); BDRVQEDState *s = acb_to_s(acb);
int r; int r;
@ -1263,8 +1267,8 @@ out:
* *
* Called with table_lock held. * Called with table_lock held.
*/ */
static int coroutine_fn qed_aio_write_data(void *opaque, int ret, static int coroutine_fn GRAPH_RDLOCK
uint64_t offset, size_t len) qed_aio_write_data(void *opaque, int ret, uint64_t offset, size_t len)
{ {
QEDAIOCB *acb = opaque; QEDAIOCB *acb = opaque;
@ -1296,8 +1300,8 @@ static int coroutine_fn qed_aio_write_data(void *opaque, int ret,
* *
* Called with table_lock held. * Called with table_lock held.
*/ */
static int coroutine_fn qed_aio_read_data(void *opaque, int ret, static int coroutine_fn GRAPH_RDLOCK
uint64_t offset, size_t len) qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
{ {
QEDAIOCB *acb = opaque; QEDAIOCB *acb = opaque;
BDRVQEDState *s = acb_to_s(acb); BDRVQEDState *s = acb_to_s(acb);
@ -1334,7 +1338,7 @@ static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
/** /**
* Begin next I/O or complete the request * Begin next I/O or complete the request
*/ */
static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb) static int coroutine_fn GRAPH_RDLOCK qed_aio_next_io(QEDAIOCB *acb)
{ {
BDRVQEDState *s = acb_to_s(acb); BDRVQEDState *s = acb_to_s(acb);
uint64_t offset; uint64_t offset;
@ -1379,9 +1383,9 @@ static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb)
return ret; return ret;
} }
static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num, static int coroutine_fn GRAPH_RDLOCK
QEMUIOVector *qiov, int nb_sectors, qed_co_request(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov,
int flags) int nb_sectors, int flags)
{ {
QEDAIOCB acb = { QEDAIOCB acb = {
.bs = bs, .bs = bs,
@ -1398,23 +1402,22 @@ static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num,
return qed_aio_next_io(&acb); return qed_aio_next_io(&acb);
} }
static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t sector_num, int nb_sectors, bdrv_qed_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov) QEMUIOVector *qiov)
{ {
return qed_co_request(bs, sector_num, qiov, nb_sectors, 0); return qed_co_request(bs, sector_num, qiov, nb_sectors, 0);
} }
static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t sector_num, int nb_sectors, bdrv_qed_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags) QEMUIOVector *qiov, int flags)
{ {
return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE); return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
} }
static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t bytes,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
BDRVQEDState *s = bs->opaque; BDRVQEDState *s = bs->opaque;
@ -1569,8 +1572,8 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,
return ret; return ret;
} }
static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs, static void coroutine_fn GRAPH_RDLOCK
Error **errp) bdrv_qed_co_invalidate_cache(BlockDriverState *bs, Error **errp)
{ {
BDRVQEDState *s = bs->opaque; BDRVQEDState *s = bs->opaque;
int ret; int ret;
@ -1586,8 +1589,8 @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
} }
} }
static int coroutine_fn bdrv_qed_co_check(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvCheckResult *result, bdrv_qed_co_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix) BdrvCheckMode fix)
{ {
BDRVQEDState *s = bs->opaque; BDRVQEDState *s = bs->opaque;

View File

@ -200,33 +200,40 @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
/** /**
* Table I/O functions * Table I/O functions
*/ */
int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s); int coroutine_fn GRAPH_RDLOCK qed_read_l1_table_sync(BDRVQEDState *s);
int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
unsigned int n); int coroutine_fn GRAPH_RDLOCK
int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
unsigned int n);
int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, int coroutine_fn GRAPH_RDLOCK
uint64_t offset); qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, unsigned int n);
int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
uint64_t offset); int coroutine_fn GRAPH_RDLOCK
int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
unsigned int index, unsigned int n,
bool flush); int coroutine_fn GRAPH_RDLOCK
int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request, qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
unsigned int index, unsigned int n,
bool flush); int coroutine_fn GRAPH_RDLOCK
qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, unsigned int index,
unsigned int n, bool flush);
int coroutine_fn GRAPH_RDLOCK
qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
unsigned int index, unsigned int n, bool flush);
/** /**
* Cluster functions * Cluster functions
*/ */
int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request, int coroutine_fn GRAPH_RDLOCK
uint64_t pos, size_t *len, qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
uint64_t *img_offset); size_t *len, uint64_t *img_offset);
/** /**
* Consistency check * Consistency check
*/ */
int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix); int coroutine_fn GRAPH_RDLOCK
qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
QEDTable *qed_alloc_table(BDRVQEDState *s); QEDTable *qed_alloc_table(BDRVQEDState *s);

View File

@ -270,7 +270,11 @@ static void quorum_report_bad_versions(BDRVQuorumState *s,
} }
} }
static void coroutine_fn quorum_rewrite_entry(void *opaque) /*
* This function can count as GRAPH_RDLOCK because read_quorum_children() holds
* the graph lock and keeps it until this coroutine has terminated.
*/
static void coroutine_fn GRAPH_RDLOCK quorum_rewrite_entry(void *opaque)
{ {
QuorumCo *co = opaque; QuorumCo *co = opaque;
QuorumAIOCB *acb = co->acb; QuorumAIOCB *acb = co->acb;
@ -290,8 +294,8 @@ static void coroutine_fn quorum_rewrite_entry(void *opaque)
} }
} }
static bool quorum_rewrite_bad_versions(QuorumAIOCB *acb, static bool coroutine_fn GRAPH_RDLOCK
QuorumVoteValue *value) quorum_rewrite_bad_versions(QuorumAIOCB *acb, QuorumVoteValue *value)
{ {
QuorumVoteVersion *version; QuorumVoteVersion *version;
QuorumVoteItem *item; QuorumVoteItem *item;
@ -491,7 +495,7 @@ static int quorum_vote_error(QuorumAIOCB *acb)
return ret; return ret;
} }
static void quorum_vote(QuorumAIOCB *acb) static void coroutine_fn GRAPH_RDLOCK quorum_vote(QuorumAIOCB *acb)
{ {
bool quorum = true; bool quorum = true;
int i, j, ret; int i, j, ret;
@ -571,7 +575,11 @@ free_exit:
quorum_free_vote_list(&acb->votes); quorum_free_vote_list(&acb->votes);
} }
static void coroutine_fn read_quorum_children_entry(void *opaque) /*
* This function can count as GRAPH_RDLOCK because read_quorum_children() holds
* the graph lock and keeps it until this coroutine has terminated.
*/
static void coroutine_fn GRAPH_RDLOCK read_quorum_children_entry(void *opaque)
{ {
QuorumCo *co = opaque; QuorumCo *co = opaque;
QuorumAIOCB *acb = co->acb; QuorumAIOCB *acb = co->acb;
@ -599,7 +607,7 @@ static void coroutine_fn read_quorum_children_entry(void *opaque)
} }
} }
static int coroutine_fn read_quorum_children(QuorumAIOCB *acb) static int coroutine_fn GRAPH_RDLOCK read_quorum_children(QuorumAIOCB *acb)
{ {
BDRVQuorumState *s = acb->bs->opaque; BDRVQuorumState *s = acb->bs->opaque;
int i; int i;
@ -640,7 +648,7 @@ static int coroutine_fn read_quorum_children(QuorumAIOCB *acb)
return acb->vote_ret; return acb->vote_ret;
} }
static int coroutine_fn read_fifo_child(QuorumAIOCB *acb) static int coroutine_fn GRAPH_RDLOCK read_fifo_child(QuorumAIOCB *acb)
{ {
BDRVQuorumState *s = acb->bs->opaque; BDRVQuorumState *s = acb->bs->opaque;
int n, ret; int n, ret;
@ -661,10 +669,9 @@ static int coroutine_fn read_fifo_child(QuorumAIOCB *acb)
return ret; return ret;
} }
static int coroutine_fn quorum_co_preadv(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, quorum_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, QEMUIOVector *qiov, BdrvRequestFlags flags)
BdrvRequestFlags flags)
{ {
BDRVQuorumState *s = bs->opaque; BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags); QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
@ -683,7 +690,11 @@ static int coroutine_fn quorum_co_preadv(BlockDriverState *bs,
return ret; return ret;
} }
static void coroutine_fn write_quorum_entry(void *opaque) /*
* This function can count as GRAPH_RDLOCK because quorum_co_pwritev() holds the
* graph lock and keeps it until this coroutine has terminated.
*/
static void coroutine_fn GRAPH_RDLOCK write_quorum_entry(void *opaque)
{ {
QuorumCo *co = opaque; QuorumCo *co = opaque;
QuorumAIOCB *acb = co->acb; QuorumAIOCB *acb = co->acb;
@ -714,9 +725,9 @@ static void coroutine_fn write_quorum_entry(void *opaque)
} }
} }
static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset, static int coroutine_fn GRAPH_RDLOCK
int64_t bytes, QEMUIOVector *qiov, quorum_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
BDRVQuorumState *s = bs->opaque; BDRVQuorumState *s = bs->opaque;
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags); QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
@ -745,16 +756,16 @@ static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset,
return ret; return ret;
} }
static int coroutine_fn quorum_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, quorum_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
return quorum_co_pwritev(bs, offset, bytes, NULL, return quorum_co_pwritev(bs, offset, bytes, NULL,
flags | BDRV_REQ_ZERO_WRITE); flags | BDRV_REQ_ZERO_WRITE);
} }
static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
quorum_co_getlength(BlockDriverState *bs)
{ {
BDRVQuorumState *s = bs->opaque; BDRVQuorumState *s = bs->opaque;
int64_t result; int64_t result;
@ -778,7 +789,7 @@ static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs)
return result; return result;
} }
static coroutine_fn int quorum_co_flush(BlockDriverState *bs) static coroutine_fn GRAPH_RDLOCK int quorum_co_flush(BlockDriverState *bs)
{ {
BDRVQuorumState *s = bs->opaque; BDRVQuorumState *s = bs->opaque;
QuorumVoteVersion *winner = NULL; QuorumVoteVersion *winner = NULL;
@ -1217,11 +1228,10 @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
* return BDRV_BLOCK_ZERO if *all* children agree that a certain * return BDRV_BLOCK_ZERO if *all* children agree that a certain
* region contains zeroes, and BDRV_BLOCK_DATA otherwise. * region contains zeroes, and BDRV_BLOCK_DATA otherwise.
*/ */
static int coroutine_fn quorum_co_block_status(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
bool want_zero, quorum_co_block_status(BlockDriverState *bs, bool want_zero,
int64_t offset, int64_t count, int64_t offset, int64_t count,
int64_t *pnum, int64_t *map, int64_t *pnum, int64_t *map, BlockDriverState **file)
BlockDriverState **file)
{ {
BDRVQuorumState *s = bs->opaque; BDRVQuorumState *s = bs->opaque;
int i, ret; int i, ret;

View File

@ -203,9 +203,9 @@ static inline int raw_adjust_offset(BlockDriverState *bs, int64_t *offset,
return 0; return 0;
} }
static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset, static int coroutine_fn GRAPH_RDLOCK
int64_t bytes, QEMUIOVector *qiov, raw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
int ret; int ret;
@ -218,9 +218,9 @@ static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
} }
static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset, static int coroutine_fn GRAPH_RDLOCK
int64_t bytes, QEMUIOVector *qiov, raw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
void *buf = NULL; void *buf = NULL;
BlockDriver *drv; BlockDriver *drv;
@ -292,8 +292,8 @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID; return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
} }
static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, raw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
int ret; int ret;
@ -305,8 +305,8 @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
} }
static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
int ret; int ret;
@ -317,7 +317,8 @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
return bdrv_co_pdiscard(bs->file, offset, bytes); return bdrv_co_pdiscard(bs->file, offset, bytes);
} }
static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
raw_co_getlength(BlockDriverState *bs)
{ {
int64_t len; int64_t len;
BDRVRawState *s = bs->opaque; BDRVRawState *s = bs->opaque;
@ -384,9 +385,9 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
} }
} }
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset, static int coroutine_fn GRAPH_RDLOCK
bool exact, PreallocMode prealloc, raw_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
BdrvRequestFlags flags, Error **errp) PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
{ {
BDRVRawState *s = bs->opaque; BDRVRawState *s = bs->opaque;
@ -405,18 +406,20 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp); return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
} }
static void coroutine_fn raw_co_eject(BlockDriverState *bs, bool eject_flag) static void coroutine_fn GRAPH_RDLOCK
raw_co_eject(BlockDriverState *bs, bool eject_flag)
{ {
bdrv_co_eject(bs->file->bs, eject_flag); bdrv_co_eject(bs->file->bs, eject_flag);
} }
static void coroutine_fn raw_co_lock_medium(BlockDriverState *bs, bool locked) static void coroutine_fn GRAPH_RDLOCK
raw_co_lock_medium(BlockDriverState *bs, bool locked)
{ {
bdrv_co_lock_medium(bs->file->bs, locked); bdrv_co_lock_medium(bs->file->bs, locked);
} }
static int coroutine_fn raw_co_ioctl(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
unsigned long int req, void *buf) raw_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
{ {
BDRVRawState *s = bs->opaque; BDRVRawState *s = bs->opaque;
if (s->offset || s->has_size) { if (s->offset || s->has_size) {
@ -430,10 +433,9 @@ static int raw_has_zero_init(BlockDriverState *bs)
return bdrv_has_zero_init(bs->file->bs); return bdrv_has_zero_init(bs->file->bs);
} }
static int coroutine_fn raw_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, raw_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
return bdrv_co_create_file(filename, opts, errp); return bdrv_co_create_file(filename, opts, errp);
} }
@ -536,13 +538,11 @@ static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
return bdrv_probe_geometry(bs->file->bs, geo); return bdrv_probe_geometry(bs->file->bs, geo);
} }
static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvChild *src, raw_co_copy_range_from(BlockDriverState *bs,
int64_t src_offset, BdrvChild *src, int64_t src_offset,
BdrvChild *dst, BdrvChild *dst, int64_t dst_offset,
int64_t dst_offset, int64_t bytes, BdrvRequestFlags read_flags,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
int ret; int ret;
@ -555,13 +555,11 @@ static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
bytes, read_flags, write_flags); bytes, read_flags, write_flags);
} }
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvChild *src, raw_co_copy_range_to(BlockDriverState *bs,
int64_t src_offset, BdrvChild *src, int64_t src_offset,
BdrvChild *dst, BdrvChild *dst, int64_t dst_offset,
int64_t dst_offset, int64_t bytes, BdrvRequestFlags read_flags,
int64_t bytes,
BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags) BdrvRequestFlags write_flags)
{ {
int ret; int ret;

View File

@ -72,6 +72,16 @@ static const char rbd_luks2_header_verification[
'L', 'U', 'K', 'S', 0xBA, 0xBE, 0, 2 'L', 'U', 'K', 'S', 0xBA, 0xBE, 0, 2
}; };
static const char rbd_layered_luks_header_verification[
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {
'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 1
};
static const char rbd_layered_luks2_header_verification[
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {
'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 2
};
typedef enum { typedef enum {
RBD_AIO_READ, RBD_AIO_READ,
RBD_AIO_WRITE, RBD_AIO_WRITE,
@ -386,7 +396,6 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
{ {
int r = 0; int r = 0;
g_autofree char *passphrase = NULL; g_autofree char *passphrase = NULL;
size_t passphrase_len;
rbd_encryption_format_t format; rbd_encryption_format_t format;
rbd_encryption_options_t opts; rbd_encryption_options_t opts;
rbd_encryption_luks1_format_options_t luks_opts; rbd_encryption_luks1_format_options_t luks_opts;
@ -408,12 +417,12 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
opts_size = sizeof(luks_opts); opts_size = sizeof(luks_opts);
r = qemu_rbd_convert_luks_create_options( r = qemu_rbd_convert_luks_create_options(
qapi_RbdEncryptionCreateOptionsLUKS_base(&encrypt->u.luks), qapi_RbdEncryptionCreateOptionsLUKS_base(&encrypt->u.luks),
&luks_opts.alg, &passphrase, &passphrase_len, errp); &luks_opts.alg, &passphrase, &luks_opts.passphrase_size,
errp);
if (r < 0) { if (r < 0) {
return r; return r;
} }
luks_opts.passphrase = passphrase; luks_opts.passphrase = passphrase;
luks_opts.passphrase_size = passphrase_len;
break; break;
} }
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: { case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
@ -424,12 +433,12 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
r = qemu_rbd_convert_luks_create_options( r = qemu_rbd_convert_luks_create_options(
qapi_RbdEncryptionCreateOptionsLUKS2_base( qapi_RbdEncryptionCreateOptionsLUKS2_base(
&encrypt->u.luks2), &encrypt->u.luks2),
&luks2_opts.alg, &passphrase, &passphrase_len, errp); &luks2_opts.alg, &passphrase, &luks2_opts.passphrase_size,
errp);
if (r < 0) { if (r < 0) {
return r; return r;
} }
luks2_opts.passphrase = passphrase; luks2_opts.passphrase = passphrase;
luks2_opts.passphrase_size = passphrase_len;
break; break;
} }
default: { default: {
@ -468,9 +477,11 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
{ {
int r = 0; int r = 0;
g_autofree char *passphrase = NULL; g_autofree char *passphrase = NULL;
size_t passphrase_len;
rbd_encryption_luks1_format_options_t luks_opts; rbd_encryption_luks1_format_options_t luks_opts;
rbd_encryption_luks2_format_options_t luks2_opts; rbd_encryption_luks2_format_options_t luks2_opts;
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
rbd_encryption_luks_format_options_t luks_any_opts;
#endif
rbd_encryption_format_t format; rbd_encryption_format_t format;
rbd_encryption_options_t opts; rbd_encryption_options_t opts;
size_t opts_size; size_t opts_size;
@ -483,12 +494,11 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
opts_size = sizeof(luks_opts); opts_size = sizeof(luks_opts);
r = qemu_rbd_convert_luks_options( r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKS_base(&encrypt->u.luks), qapi_RbdEncryptionOptionsLUKS_base(&encrypt->u.luks),
&passphrase, &passphrase_len, errp); &passphrase, &luks_opts.passphrase_size, errp);
if (r < 0) { if (r < 0) {
return r; return r;
} }
luks_opts.passphrase = passphrase; luks_opts.passphrase = passphrase;
luks_opts.passphrase_size = passphrase_len;
break; break;
} }
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: { case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
@ -498,14 +508,29 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
opts_size = sizeof(luks2_opts); opts_size = sizeof(luks2_opts);
r = qemu_rbd_convert_luks_options( r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKS2_base(&encrypt->u.luks2), qapi_RbdEncryptionOptionsLUKS2_base(&encrypt->u.luks2),
&passphrase, &passphrase_len, errp); &passphrase, &luks2_opts.passphrase_size, errp);
if (r < 0) { if (r < 0) {
return r; return r;
} }
luks2_opts.passphrase = passphrase; luks2_opts.passphrase = passphrase;
luks2_opts.passphrase_size = passphrase_len;
break; break;
} }
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: {
memset(&luks_any_opts, 0, sizeof(luks_any_opts));
format = RBD_ENCRYPTION_FORMAT_LUKS;
opts = &luks_any_opts;
opts_size = sizeof(luks_any_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKSAny_base(&encrypt->u.luks_any),
&passphrase, &luks_any_opts.passphrase_size, errp);
if (r < 0) {
return r;
}
luks_any_opts.passphrase = passphrase;
break;
}
#endif
default: { default: {
r = -ENOTSUP; r = -ENOTSUP;
error_setg_errno( error_setg_errno(
@ -523,6 +548,128 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
return 0; return 0;
} }
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
static int qemu_rbd_encryption_load2(rbd_image_t image,
RbdEncryptionOptions *encrypt,
Error **errp)
{
int r = 0;
int encrypt_count = 1;
int i;
RbdEncryptionOptions *curr_encrypt;
rbd_encryption_spec_t *specs;
rbd_encryption_luks1_format_options_t *luks_opts;
rbd_encryption_luks2_format_options_t *luks2_opts;
rbd_encryption_luks_format_options_t *luks_any_opts;
/* count encryption options */
for (curr_encrypt = encrypt->parent; curr_encrypt;
curr_encrypt = curr_encrypt->parent) {
++encrypt_count;
}
specs = g_new0(rbd_encryption_spec_t, encrypt_count);
curr_encrypt = encrypt;
for (i = 0; i < encrypt_count; ++i) {
switch (curr_encrypt->format) {
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS: {
specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS1;
luks_opts = g_new0(rbd_encryption_luks1_format_options_t, 1);
specs[i].opts = luks_opts;
specs[i].opts_size = sizeof(*luks_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKS_base(
&curr_encrypt->u.luks),
(char **)&luks_opts->passphrase,
&luks_opts->passphrase_size,
errp);
break;
}
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS2;
luks2_opts = g_new0(rbd_encryption_luks2_format_options_t, 1);
specs[i].opts = luks2_opts;
specs[i].opts_size = sizeof(*luks2_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKS2_base(
&curr_encrypt->u.luks2),
(char **)&luks2_opts->passphrase,
&luks2_opts->passphrase_size,
errp);
break;
}
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: {
specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS;
luks_any_opts = g_new0(rbd_encryption_luks_format_options_t, 1);
specs[i].opts = luks_any_opts;
specs[i].opts_size = sizeof(*luks_any_opts);
r = qemu_rbd_convert_luks_options(
qapi_RbdEncryptionOptionsLUKSAny_base(
&curr_encrypt->u.luks_any),
(char **)&luks_any_opts->passphrase,
&luks_any_opts->passphrase_size,
errp);
break;
}
default: {
r = -ENOTSUP;
error_setg_errno(
errp, -r, "unknown image encryption format: %u",
curr_encrypt->format);
}
}
if (r < 0) {
goto exit;
}
curr_encrypt = curr_encrypt->parent;
}
r = rbd_encryption_load2(image, specs, encrypt_count);
if (r < 0) {
error_setg_errno(errp, -r, "layered encryption load fail");
goto exit;
}
exit:
for (i = 0; i < encrypt_count; ++i) {
if (!specs[i].opts) {
break;
}
switch (specs[i].format) {
case RBD_ENCRYPTION_FORMAT_LUKS1: {
luks_opts = specs[i].opts;
g_free((void *)luks_opts->passphrase);
break;
}
case RBD_ENCRYPTION_FORMAT_LUKS2: {
luks2_opts = specs[i].opts;
g_free((void *)luks2_opts->passphrase);
break;
}
case RBD_ENCRYPTION_FORMAT_LUKS: {
luks_any_opts = specs[i].opts;
g_free((void *)luks_any_opts->passphrase);
break;
}
}
g_free(specs[i].opts);
}
g_free(specs);
return r;
}
#endif
#endif #endif
/* FIXME Deprecate and remove keypairs or make it available in QMP. */ /* FIXME Deprecate and remove keypairs or make it available in QMP. */
@ -989,7 +1136,16 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
if (opts->encrypt) { if (opts->encrypt) {
#ifdef LIBRBD_SUPPORTS_ENCRYPTION #ifdef LIBRBD_SUPPORTS_ENCRYPTION
if (opts->encrypt->parent) {
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
r = qemu_rbd_encryption_load2(s->image, opts->encrypt, errp);
#else
r = -ENOTSUP;
error_setg(errp, "RBD library does not support layered encryption");
#endif
} else {
r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp); r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp);
}
if (r < 0) { if (r < 0) {
goto failed_post_open; goto failed_post_open;
} }
@ -1281,6 +1437,16 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
spec_info->u.rbd.data->encryption_format = spec_info->u.rbd.data->encryption_format =
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2; RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
spec_info->u.rbd.data->has_encryption_format = true; spec_info->u.rbd.data->has_encryption_format = true;
} else if (memcmp(buf, rbd_layered_luks_header_verification,
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
spec_info->u.rbd.data->encryption_format =
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
spec_info->u.rbd.data->has_encryption_format = true;
} else if (memcmp(buf, rbd_layered_luks2_header_verification,
RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
spec_info->u.rbd.data->encryption_format =
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
spec_info->u.rbd.data->has_encryption_format = true;
} else { } else {
spec_info->u.rbd.data->has_encryption_format = false; spec_info->u.rbd.data->has_encryption_format = false;
} }

View File

@ -179,7 +179,8 @@ static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
return; return;
} }
static int64_t coroutine_fn replication_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
replication_co_getlength(BlockDriverState *bs)
{ {
return bdrv_co_getlength(bs->file->bs); return bdrv_co_getlength(bs->file->bs);
} }
@ -220,10 +221,9 @@ static int replication_return_value(BDRVReplicationState *s, int ret)
return ret; return ret;
} }
static coroutine_fn int replication_co_readv(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t sector_num, replication_co_readv(BlockDriverState *bs, int64_t sector_num,
int remaining_sectors, int remaining_sectors, QEMUIOVector *qiov)
QEMUIOVector *qiov)
{ {
BDRVReplicationState *s = bs->opaque; BDRVReplicationState *s = bs->opaque;
int ret; int ret;
@ -244,11 +244,9 @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs,
return replication_return_value(s, ret); return replication_return_value(s, ret);
} }
static coroutine_fn int replication_co_writev(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t sector_num, replication_co_writev(BlockDriverState *bs, int64_t sector_num,
int remaining_sectors, int remaining_sectors, QEMUIOVector *qiov, int flags)
QEMUIOVector *qiov,
int flags)
{ {
BDRVReplicationState *s = bs->opaque; BDRVReplicationState *s = bs->opaque;
QEMUIOVector hd_qiov; QEMUIOVector hd_qiov;

View File

@ -26,7 +26,7 @@
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "block/block_int.h" #include "block/block_int.h"
static coroutine_fn int static int coroutine_fn GRAPH_RDLOCK
snapshot_access_co_preadv_part(BlockDriverState *bs, snapshot_access_co_preadv_part(BlockDriverState *bs,
int64_t offset, int64_t bytes, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset, QEMUIOVector *qiov, size_t qiov_offset,
@ -39,7 +39,7 @@ snapshot_access_co_preadv_part(BlockDriverState *bs,
return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset); return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
snapshot_access_co_block_status(BlockDriverState *bs, snapshot_access_co_block_status(BlockDriverState *bs,
bool want_zero, int64_t offset, bool want_zero, int64_t offset,
int64_t bytes, int64_t *pnum, int64_t bytes, int64_t *pnum,
@ -49,8 +49,8 @@ snapshot_access_co_block_status(BlockDriverState *bs,
bytes, pnum, map, file); bytes, pnum, map, file);
} }
static int coroutine_fn snapshot_access_co_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) snapshot_access_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes); return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes);
} }

View File

@ -16,7 +16,6 @@
#include "block/block_int.h" #include "block/block_int.h"
#include "block/blockjob_int.h" #include "block/blockjob_int.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qdict.h" #include "qapi/qmp/qdict.h"
#include "qemu/ratelimit.h" #include "qemu/ratelimit.h"
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
@ -141,10 +140,12 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
return 0; return 0;
} }
len = bdrv_getlength(s->target_bs); WITH_GRAPH_RDLOCK_GUARD() {
len = bdrv_co_getlength(s->target_bs);
if (len < 0) { if (len < 0) {
return len; return len;
} }
}
job_progress_set_remaining(&s->common.job, len); job_progress_set_remaining(&s->common.job, len);
for ( ; offset < len; offset += n) { for ( ; offset < len; offset += n) {
@ -161,12 +162,15 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
copy = false; copy = false;
WITH_GRAPH_RDLOCK_GUARD() {
ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n); ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n);
if (ret == 1) { if (ret == 1) {
/* Allocated in the top, no need to copy. */ /* Allocated in the top, no need to copy. */
} else if (ret >= 0) { } else if (ret >= 0) {
/* Copy if allocated in the intermediate images. Limit to the /*
* known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). */ * Copy if allocated in the intermediate images. Limit to the
* known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE).
*/
ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs), ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs),
s->base_overlay, true, s->base_overlay, true,
offset, n, &n); offset, n, &n);
@ -177,6 +181,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
copy = (ret > 0); copy = (ret > 0);
} }
}
trace_stream_one_iteration(s, offset, n, ret); trace_stream_one_iteration(s, offset, n, ret);
if (copy) { if (copy) {
ret = stream_populate(s->blk, offset, n); ret = stream_populate(s->blk, offset, n);

View File

@ -106,15 +106,15 @@ static void throttle_close(BlockDriverState *bs)
} }
static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs) static int64_t coroutine_fn GRAPH_RDLOCK
throttle_co_getlength(BlockDriverState *bs)
{ {
return bdrv_co_getlength(bs->file->bs); return bdrv_co_getlength(bs->file->bs);
} }
static int coroutine_fn throttle_co_preadv(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, throttle_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, QEMUIOVector *qiov, BdrvRequestFlags flags)
BdrvRequestFlags flags)
{ {
ThrottleGroupMember *tgm = bs->opaque; ThrottleGroupMember *tgm = bs->opaque;
@ -123,10 +123,9 @@ static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags); return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
} }
static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, throttle_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, QEMUIOVector *qiov, BdrvRequestFlags flags)
BdrvRequestFlags flags)
{ {
ThrottleGroupMember *tgm = bs->opaque; ThrottleGroupMember *tgm = bs->opaque;
throttle_group_co_io_limits_intercept(tgm, bytes, true); throttle_group_co_io_limits_intercept(tgm, bytes, true);
@ -134,8 +133,8 @@ static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs,
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
} }
static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes, throttle_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
ThrottleGroupMember *tgm = bs->opaque; ThrottleGroupMember *tgm = bs->opaque;
@ -144,8 +143,8 @@ static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs,
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
} }
static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, int64_t bytes) throttle_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{ {
ThrottleGroupMember *tgm = bs->opaque; ThrottleGroupMember *tgm = bs->opaque;
throttle_group_co_io_limits_intercept(tgm, bytes, true); throttle_group_co_io_limits_intercept(tgm, bytes, true);
@ -153,16 +152,15 @@ static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
return bdrv_co_pdiscard(bs->file, offset, bytes); return bdrv_co_pdiscard(bs->file, offset, bytes);
} }
static int coroutine_fn throttle_co_pwritev_compressed(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, throttle_co_pwritev_compressed(BlockDriverState *bs, int64_t offset,
int64_t bytes, int64_t bytes, QEMUIOVector *qiov)
QEMUIOVector *qiov)
{ {
return throttle_co_pwritev(bs, offset, bytes, qiov, return throttle_co_pwritev(bs, offset, bytes, qiov,
BDRV_REQ_WRITE_COMPRESSED); BDRV_REQ_WRITE_COMPRESSED);
} }
static int coroutine_fn throttle_co_flush(BlockDriverState *bs) static int coroutine_fn GRAPH_RDLOCK throttle_co_flush(BlockDriverState *bs)
{ {
return bdrv_co_flush(bs->file->bs); return bdrv_co_flush(bs->file->bs);
} }

View File

@ -544,7 +544,7 @@ static int coroutine_fn vdi_co_block_status(BlockDriverState *bs,
(s->header.image_type == VDI_TYPE_STATIC ? BDRV_BLOCK_RECURSE : 0); (s->header.image_type == VDI_TYPE_STATIC ? BDRV_BLOCK_RECURSE : 0);
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -600,7 +600,7 @@ vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -898,10 +898,9 @@ static int coroutine_fn vdi_co_create(BlockdevCreateOptions *create_options,
return vdi_co_do_create(create_options, DEFAULT_CLUSTER_SIZE, errp); return vdi_co_do_create(create_options, DEFAULT_CLUSTER_SIZE, errp);
} }
static int coroutine_fn vdi_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, vdi_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
QDict *qdict = NULL; QDict *qdict = NULL;
BlockdevCreateOptions *create_options = NULL; BlockdevCreateOptions *create_options = NULL;

View File

@ -1172,8 +1172,9 @@ vhdx_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
} }
static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, static int coroutine_fn GRAPH_RDLOCK
int nb_sectors, QEMUIOVector *qiov) vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov)
{ {
BDRVVHDXState *s = bs->opaque; BDRVVHDXState *s = bs->opaque;
int ret = 0; int ret = 0;
@ -1324,9 +1325,9 @@ int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s)
return ret; return ret;
} }
static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, static int coroutine_fn GRAPH_RDLOCK
int nb_sectors, QEMUIOVector *qiov, vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
int flags) QEMUIOVector *qiov, int flags)
{ {
int ret = -ENOTSUP; int ret = -ENOTSUP;
BDRVVHDXState *s = bs->opaque; BDRVVHDXState *s = bs->opaque;
@ -2058,10 +2059,9 @@ delete_and_exit:
return ret; return ret;
} }
static int coroutine_fn vhdx_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, vhdx_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
BlockdevCreateOptions *create_options = NULL; BlockdevCreateOptions *create_options = NULL;
QDict *qdict; QDict *qdict;

View File

@ -1403,12 +1403,10 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
* [@skip_start_sector, @skip_end_sector) is not copied or written, and leave * [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
* it for call to write user data in the request. * it for call to write user data in the request.
*/ */
static int coroutine_fn get_whole_cluster(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
VmdkExtent *extent, get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent,
uint64_t cluster_offset, uint64_t cluster_offset, uint64_t offset,
uint64_t offset, uint64_t skip_start_bytes, uint64_t skip_end_bytes,
uint64_t skip_start_bytes,
uint64_t skip_end_bytes,
bool zeroed) bool zeroed)
{ {
int ret = VMDK_OK; int ret = VMDK_OK;
@ -1484,8 +1482,8 @@ exit:
return ret; return ret;
} }
static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, static int coroutine_fn GRAPH_RDLOCK
uint32_t offset) vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, uint32_t offset)
{ {
offset = cpu_to_le32(offset); offset = cpu_to_le32(offset);
/* update L2 table */ /* update L2 table */
@ -1536,13 +1534,10 @@ static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
* VMDK_UNALLOC if cluster is not mapped and @allocate is false. * VMDK_UNALLOC if cluster is not mapped and @allocate is false.
* VMDK_ERROR if failed. * VMDK_ERROR if failed.
*/ */
static int coroutine_fn get_cluster_offset(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
VmdkExtent *extent, get_cluster_offset(BlockDriverState *bs, VmdkExtent *extent,
VmdkMetaData *m_data, VmdkMetaData *m_data, uint64_t offset, bool allocate,
uint64_t offset, uint64_t *cluster_offset, uint64_t skip_start_bytes,
bool allocate,
uint64_t *cluster_offset,
uint64_t skip_start_bytes,
uint64_t skip_end_bytes) uint64_t skip_end_bytes)
{ {
unsigned int l1_index, l2_offset, l2_index; unsigned int l1_index, l2_offset, l2_index;
@ -1736,11 +1731,10 @@ static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
return extent_relative_offset % cluster_size; return extent_relative_offset % cluster_size;
} }
static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
bool want_zero, vmdk_co_block_status(BlockDriverState *bs, bool want_zero,
int64_t offset, int64_t bytes, int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *pnum, int64_t *map, int64_t *map, BlockDriverState **file)
BlockDriverState **file)
{ {
BDRVVmdkState *s = bs->opaque; BDRVVmdkState *s = bs->opaque;
int64_t index_in_cluster, n, ret; int64_t index_in_cluster, n, ret;
@ -1785,7 +1779,7 @@ static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
int64_t offset_in_cluster, QEMUIOVector *qiov, int64_t offset_in_cluster, QEMUIOVector *qiov,
uint64_t qiov_offset, uint64_t n_bytes, uint64_t qiov_offset, uint64_t n_bytes,
@ -1867,10 +1861,9 @@ vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
int64_t offset_in_cluster, QEMUIOVector *qiov, int64_t offset_in_cluster, QEMUIOVector *qiov, int bytes)
int bytes)
{ {
int ret; int ret;
int cluster_bytes, buf_bytes; int cluster_bytes, buf_bytes;
@ -1934,7 +1927,7 @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
vmdk_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, vmdk_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -2016,9 +2009,9 @@ fail:
* *
* Returns: error code with 0 for success. * Returns: error code with 0 for success.
*/ */
static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset, static int coroutine_fn GRAPH_RDLOCK
uint64_t bytes, QEMUIOVector *qiov, vmdk_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
bool zeroed, bool zero_dry_run) QEMUIOVector *qiov, bool zeroed, bool zero_dry_run)
{ {
BDRVVmdkState *s = bs->opaque; BDRVVmdkState *s = bs->opaque;
VmdkExtent *extent = NULL; VmdkExtent *extent = NULL;
@ -2114,7 +2107,7 @@ static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
return 0; return 0;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -2126,7 +2119,7 @@ vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov) QEMUIOVector *qiov)
{ {
@ -2154,9 +2147,8 @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
return vmdk_co_pwritev(bs, offset, bytes, qiov, 0); return vmdk_co_pwritev(bs, offset, bytes, qiov, 0);
} }
static int coroutine_fn vmdk_co_pwrite_zeroes(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
int64_t offset, vmdk_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t bytes,
BdrvRequestFlags flags) BdrvRequestFlags flags)
{ {
int ret; int ret;
@ -2285,10 +2277,9 @@ exit:
return ret; return ret;
} }
static int coroutine_fn vmdk_create_extent(const char *filename, static int coroutine_fn GRAPH_RDLOCK
int64_t filesize, bool flat, vmdk_create_extent(const char *filename, int64_t filesize, bool flat,
bool compress, bool zeroed_grain, bool compress, bool zeroed_grain, BlockBackend **pbb,
BlockBackend **pbb,
QemuOpts *opts, Error **errp) QemuOpts *opts, Error **errp)
{ {
int ret; int ret;
@ -2367,13 +2358,9 @@ static int filename_decompose(const char *filename, char *path, char *prefix,
* non-split format. * non-split format.
* idx >= 1: get the n-th extent if in a split subformat * idx >= 1: get the n-th extent if in a split subformat
*/ */
typedef BlockBackend * coroutine_fn (*vmdk_create_extent_fn)(int64_t size, typedef BlockBackend * coroutine_fn /* GRAPH_RDLOCK */
int idx, (*vmdk_create_extent_fn)(int64_t size, int idx, bool flat, bool split,
bool flat, bool compress, bool zeroed_grain, void *opaque,
bool split,
bool compress,
bool zeroed_grain,
void *opaque,
Error **errp); Error **errp);
static void vmdk_desc_add_extent(GString *desc, static void vmdk_desc_add_extent(GString *desc,
@ -2387,7 +2374,8 @@ static void vmdk_desc_add_extent(GString *desc,
g_free(basename); g_free(basename);
} }
static int coroutine_fn vmdk_co_do_create(int64_t size, static int coroutine_fn GRAPH_RDLOCK
vmdk_co_do_create(int64_t size,
BlockdevVmdkSubformat subformat, BlockdevVmdkSubformat subformat,
BlockdevVmdkAdapterType adapter_type, BlockdevVmdkAdapterType adapter_type,
const char *backing_file, const char *backing_file,
@ -2617,9 +2605,9 @@ typedef struct {
QemuOpts *opts; QemuOpts *opts;
} VMDKCreateOptsData; } VMDKCreateOptsData;
static BlockBackend * coroutine_fn vmdk_co_create_opts_cb(int64_t size, int idx, static BlockBackend * coroutine_fn GRAPH_RDLOCK
bool flat, bool split, bool compress, vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split,
bool zeroed_grain, void *opaque, bool compress, bool zeroed_grain, void *opaque,
Error **errp) Error **errp)
{ {
BlockBackend *blk = NULL; BlockBackend *blk = NULL;
@ -2659,10 +2647,9 @@ exit:
return blk; return blk;
} }
static int coroutine_fn vmdk_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, vmdk_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
Error *local_err = NULL; Error *local_err = NULL;
char *desc = NULL; char *desc = NULL;
@ -2822,8 +2809,8 @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
return blk; return blk;
} }
static int coroutine_fn vmdk_co_create(BlockdevCreateOptions *create_options, static int coroutine_fn GRAPH_RDLOCK
Error **errp) vmdk_co_create(BlockdevCreateOptions *create_options, Error **errp)
{ {
BlockdevCreateOptionsVmdk *opts; BlockdevCreateOptionsVmdk *opts;
@ -2918,9 +2905,8 @@ static VmdkExtentInfo *vmdk_get_extent_info(VmdkExtent *extent)
return info; return info;
} }
static int coroutine_fn vmdk_co_check(BlockDriverState *bs, static int coroutine_fn GRAPH_RDLOCK
BdrvCheckResult *result, vmdk_co_check(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix)
BdrvCheckMode fix)
{ {
BDRVVmdkState *s = bs->opaque; BDRVVmdkState *s = bs->opaque;
VmdkExtent *extent = NULL; VmdkExtent *extent = NULL;

View File

@ -610,7 +610,7 @@ vpc_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
return 0; return 0;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
vpc_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes, vpc_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -660,7 +660,7 @@ fail:
return ret; return ret;
} }
static int coroutine_fn static int coroutine_fn GRAPH_RDLOCK
vpc_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, vpc_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, BdrvRequestFlags flags) QEMUIOVector *qiov, BdrvRequestFlags flags)
{ {
@ -1087,10 +1087,9 @@ out:
return ret; return ret;
} }
static int coroutine_fn vpc_co_create_opts(BlockDriver *drv, static int coroutine_fn GRAPH_RDLOCK
const char *filename, vpc_co_create_opts(BlockDriver *drv, const char *filename,
QemuOpts *opts, QemuOpts *opts, Error **errp)
Error **errp)
{ {
BlockdevCreateOptions *create_options = NULL; BlockdevCreateOptions *create_options = NULL;
QDict *qdict; QDict *qdict;

View File

@ -3,3 +3,4 @@ TARGET_SYSTBL_ABI=common
TARGET_SYSTBL=syscall.tbl TARGET_SYSTBL=syscall.tbl
TARGET_BIG_ENDIAN=y TARGET_BIG_ENDIAN=y
TARGET_HAS_BFLT=y TARGET_HAS_BFLT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -2,3 +2,4 @@ TARGET_ARCH=microblaze
TARGET_BIG_ENDIAN=y TARGET_BIG_ENDIAN=y
TARGET_SUPPORTS_MTTCG=y TARGET_SUPPORTS_MTTCG=y
TARGET_NEED_FDT=y TARGET_NEED_FDT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -2,3 +2,4 @@ TARGET_ARCH=microblaze
TARGET_SYSTBL_ABI=common TARGET_SYSTBL_ABI=common
TARGET_SYSTBL=syscall.tbl TARGET_SYSTBL=syscall.tbl
TARGET_HAS_BFLT=y TARGET_HAS_BFLT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -1,3 +1,4 @@
TARGET_ARCH=microblaze TARGET_ARCH=microblaze
TARGET_SUPPORTS_MTTCG=y TARGET_SUPPORTS_MTTCG=y
TARGET_NEED_FDT=y TARGET_NEED_FDT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

8
configure vendored
View File

@ -31,8 +31,12 @@ then
fi fi
fi fi
mkdir build if ! mkdir build || ! touch $MARKER
touch $MARKER then
echo "ERROR: Could not create ./build directory. Check the permissions on"
echo "your source directory, or try doing an out-of-tree build."
exit 1
fi
cat > GNUmakefile <<'EOF' cat > GNUmakefile <<'EOF'
# This file is auto-generated by configure to support in-source tree # This file is auto-generated by configure to support in-source tree

View File

@ -12,8 +12,7 @@
# GNU Library General Public License for more details. # GNU Library General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software # along with this program. If not, see <https://www.gnu.org/licenses/>.
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
# Authors : Gregorio Robles <grex@gsyc.escet.urjc.es> # Authors : Gregorio Robles <grex@gsyc.escet.urjc.es>
# Authors : Germán Póo-Caamaño <gpoo@gnome.org> # Authors : Germán Póo-Caamaño <gpoo@gnome.org>

View File

@ -192,6 +192,11 @@ void start_exclusive(void)
CPUState *other_cpu; CPUState *other_cpu;
int running_cpus; int running_cpus;
if (current_cpu->exclusive_context_count) {
current_cpu->exclusive_context_count++;
return;
}
qemu_mutex_lock(&qemu_cpu_list_lock); qemu_mutex_lock(&qemu_cpu_list_lock);
exclusive_idle(); exclusive_idle();
@ -219,13 +224,16 @@ void start_exclusive(void)
*/ */
qemu_mutex_unlock(&qemu_cpu_list_lock); qemu_mutex_unlock(&qemu_cpu_list_lock);
current_cpu->in_exclusive_context = true; current_cpu->exclusive_context_count = 1;
} }
/* Finish an exclusive operation. */ /* Finish an exclusive operation. */
void end_exclusive(void) void end_exclusive(void)
{ {
current_cpu->in_exclusive_context = false; current_cpu->exclusive_context_count--;
if (current_cpu->exclusive_context_count) {
return;
}
qemu_mutex_lock(&qemu_cpu_list_lock); qemu_mutex_lock(&qemu_cpu_list_lock);
qatomic_set(&pending_cpus, 0); qatomic_set(&pending_cpus, 0);

View File

@ -86,6 +86,38 @@ respective ports repository, while NetBSD will use the pkgsrc repository.
For macOS, `Homebrew`_ will be used, although `MacPorts`_ is expected to carry For macOS, `Homebrew`_ will be used, although `MacPorts`_ is expected to carry
similar versions. similar versions.
Some build dependencies may follow less conservative rules:
Python runtime
Distributions with long-term support often provide multiple versions
of the Python runtime. While QEMU will initially aim to support the
distribution's default runtime, it may later increase its minimum version
to any newer python that is available as an option from the vendor.
In this case, it will be necessary to use the ``--python`` command line
option of the ``configure`` script to point QEMU to a supported
version of the Python runtime.
As of QEMU |version|, the minimum supported version of Python is 3.6.
Python build dependencies
Some of QEMU's build dependencies are written in Python. Usually these
are only packaged by distributions for the default Python runtime.
If QEMU bumps its minimum Python version and a non-default runtime is
required, it may be necessary to fetch python modules from the Python
Package Index (PyPI) via ``pip``, in order to build QEMU.
Optional build dependencies
Build components whose absence does not affect the ability to build
QEMU may not be available in distros, or may be too old for QEMU's
requirements. Many of these, such as the Avocado testing framework
or various linters, are written in Python and therefore can also
be installed using ``pip``. Cross compilers are another example
of optional build-time dependency; in this case it is possible to
download them from repositories such as EPEL, to use container-based
cross compilation using ``docker`` or ``podman``, or to use pre-built
binaries distributed with QEMU.
Windows Windows
------- -------

View File

@ -99,6 +99,12 @@ form is preferred.
The HPET setting has been turned into a machine property. The HPET setting has been turned into a machine property.
Use ``-machine hpet=off`` instead. Use ``-machine hpet=off`` instead.
``-no-acpi`` (since 8.0)
''''''''''''''''''''''''
The ``-no-acpi`` setting has been turned into a machine property.
Use ``-machine acpi=off`` instead.
``-accel hax`` (since 8.0) ``-accel hax`` (since 8.0)
'''''''''''''''''''''''''' ''''''''''''''''''''''''''

View File

@ -306,6 +306,6 @@ variable::
host_kconfig = \ host_kconfig = \
(have_tpm ? ['CONFIG_TPM=y'] : []) + \ (have_tpm ? ['CONFIG_TPM=y'] : []) + \
('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \ ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
(have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
... ...

View File

@ -685,9 +685,10 @@ change in the QMP syntax (usually by allowing values or operations
that previously resulted in an error). QMP clients may still need to that previously resulted in an error). QMP clients may still need to
know whether the extension is available. know whether the extension is available.
For this purpose, a list of features can be specified for a command or For this purpose, a list of features can be specified for definitions,
struct type. Each list member can either be ``{ 'name': STRING, '*if': enumeration values, and struct members. Each feature list member can
COND }``, or STRING, which is shorthand for ``{ 'name': STRING }``. either be ``{ 'name': STRING, '*if': COND }``, or STRING, which is
shorthand for ``{ 'name': STRING }``.
The optional 'if' member specifies a conditional. See `Configuring The optional 'if' member specifies a conditional. See `Configuring
the schema`_ below for more on this. the schema`_ below for more on this.
@ -817,8 +818,8 @@ member 'bar' ::
A union's discriminator may not be conditional. A union's discriminator may not be conditional.
Likewise, individual enumeration values be conditional. This requires Likewise, individual enumeration values may be conditional. This
the longhand form of ENUM-VALUE_. requires the longhand form of ENUM-VALUE_.
Example: an enum type with unconditional value 'foo' and conditional Example: an enum type with unconditional value 'foo' and conditional
value 'bar' :: value 'bar' ::
@ -1157,9 +1158,8 @@ Example: the SchemaInfo for EVENT_C from section Events_ ::
Type "q_obj-EVENT_C-arg" is an implicitly defined object type with Type "q_obj-EVENT_C-arg" is an implicitly defined object type with
the two members from the event's definition. the two members from the event's definition.
The SchemaInfo for struct and union types has meta-type "object". The SchemaInfo for struct and union types has meta-type "object" and
variant member "members".
The SchemaInfo for a struct type has variant member "members".
The SchemaInfo for a union type additionally has variant members "tag" The SchemaInfo for a union type additionally has variant members "tag"
and "variants". and "variants".

View File

@ -1854,7 +1854,8 @@ static void dump_init(DumpState *s, int fd, bool has_format,
*/ */
ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks); ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);
if (ret < 0) { if (ret < 0) {
error_setg(errp, QERR_UNSUPPORTED); error_setg(errp,
"dumping guest memory is not supported on this target");
goto cleanup; goto cleanup;
} }
@ -1864,10 +1865,7 @@ static void dump_init(DumpState *s, int fd, bool has_format,
s->note_size = cpu_get_note_size(s->dump_info.d_class, s->note_size = cpu_get_note_size(s->dump_info.d_class,
s->dump_info.d_machine, nr_cpus); s->dump_info.d_machine, nr_cpus);
if (s->note_size < 0) { assert(s->note_size >= 0);
error_setg(errp, QERR_UNSUPPORTED);
goto cleanup;
}
/* /*
* The goal of this block is to (a) update the previously guessed * The goal of this block is to (a) update the previously guessed

View File

@ -0,0 +1,67 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2008 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.microblaze.core">
<reg name="r0" bitsize="32" regnum="0"/>
<reg name="r1" bitsize="32" type="data_ptr"/>
<reg name="r2" bitsize="32"/>
<reg name="r3" bitsize="32"/>
<reg name="r4" bitsize="32"/>
<reg name="r5" bitsize="32"/>
<reg name="r6" bitsize="32"/>
<reg name="r7" bitsize="32"/>
<reg name="r8" bitsize="32"/>
<reg name="r9" bitsize="32"/>
<reg name="r10" bitsize="32"/>
<reg name="r11" bitsize="32"/>
<reg name="r12" bitsize="32"/>
<reg name="r13" bitsize="32"/>
<reg name="r14" bitsize="32"/>
<reg name="r15" bitsize="32"/>
<reg name="r16" bitsize="32"/>
<reg name="r17" bitsize="32"/>
<reg name="r18" bitsize="32"/>
<reg name="r19" bitsize="32"/>
<reg name="r20" bitsize="32"/>
<reg name="r21" bitsize="32"/>
<reg name="r22" bitsize="32"/>
<reg name="r23" bitsize="32"/>
<reg name="r24" bitsize="32"/>
<reg name="r25" bitsize="32"/>
<reg name="r26" bitsize="32"/>
<reg name="r27" bitsize="32"/>
<reg name="r28" bitsize="32"/>
<reg name="r29" bitsize="32"/>
<reg name="r30" bitsize="32"/>
<reg name="r31" bitsize="32"/>
<reg name="rpc" bitsize="32" type="code_ptr"/>
<reg name="rmsr" bitsize="32"/>
<reg name="rear" bitsize="32"/>
<reg name="resr" bitsize="32"/>
<reg name="rfsr" bitsize="32"/>
<reg name="rbtr" bitsize="32"/>
<reg name="rpvr0" bitsize="32"/>
<reg name="rpvr1" bitsize="32"/>
<reg name="rpvr2" bitsize="32"/>
<reg name="rpvr3" bitsize="32"/>
<reg name="rpvr4" bitsize="32"/>
<reg name="rpvr5" bitsize="32"/>
<reg name="rpvr6" bitsize="32"/>
<reg name="rpvr7" bitsize="32"/>
<reg name="rpvr8" bitsize="32"/>
<reg name="rpvr9" bitsize="32"/>
<reg name="rpvr10" bitsize="32"/>
<reg name="rpvr11" bitsize="32"/>
<reg name="redr" bitsize="32"/>
<reg name="rpid" bitsize="32"/>
<reg name="rzpr" bitsize="32"/>
<reg name="rtlbx" bitsize="32"/>
<reg name="rtlbsx" bitsize="32"/>
<reg name="rtlblo" bitsize="32"/>
<reg name="rtlbhi" bitsize="32"/>
</feature>

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2008 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.microblaze.stack-protect">
<reg name="rslr" bitsize="32"/>
<reg name="rshr" bitsize="32"/>
</feature>

View File

@ -19,11 +19,9 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "hw/acpi/acpi.h" #include "hw/acpi/acpi.h"
void acpi_table_add(const QemuOpts *opts, Error **errp) void acpi_table_add(const QemuOpts *opts, Error **errp)
{ {
error_setg(errp, QERR_UNSUPPORTED); g_assert_not_reached();
} }

View File

@ -12,7 +12,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qapi-commands-machine.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "hw/acpi/acpi.h" #include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h" #include "hw/acpi/aml-build.h"
@ -244,20 +243,3 @@ static void vmgenid_register_types(void)
} }
type_init(vmgenid_register_types) type_init(vmgenid_register_types)
GuidInfo *qmp_query_vm_generation_id(Error **errp)
{
GuidInfo *info;
VmGenIdState *vms;
Object *obj = find_vmgenid_dev();
if (!obj) {
error_setg(errp, "VM Generation ID device not found");
return NULL;
}
vms = VMGENID(obj);
info = g_malloc0(sizeof(*info));
info->guid = qemu_uuid_unparse_strdup(&vms->guid);
return info;
}

View File

@ -18,6 +18,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "hw/char/serial.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "hw/arm/allwinner-a10.h" #include "hw/arm/allwinner-a10.h"
#include "hw/misc/unimp.h" #include "hw/misc/unimp.h"

View File

@ -15,6 +15,7 @@
#include "hw/arm/boot.h" #include "hw/arm/boot.h"
#include "hw/arm/linux-boot-if.h" #include "hw/arm/linux-boot-if.h"
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "sysemu/tcg.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/numa.h" #include "sysemu/numa.h"
#include "hw/boards.h" #include "hw/boards.h"
@ -827,9 +828,12 @@ static void do_cpu_reset(void *opaque)
info->secondary_cpu_reset_hook(cpu, info); info->secondary_cpu_reset_hook(cpu, info);
} }
} }
if (tcg_enabled()) {
arm_rebuild_hflags(env); arm_rebuild_hflags(env);
} }
} }
}
static int do_arm_linux_init(Object *obj, void *opaque) static int do_arm_linux_init(Object *obj, void *opaque)
{ {

View File

@ -507,7 +507,7 @@ static uint64_t exynos4210_calc_affinity(int cpu)
return (0x9 << ARM_AFF1_SHIFT) | cpu; return (0x9 << ARM_AFF1_SHIFT) | cpu;
} }
static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate, static DeviceState *pl330_create(uint32_t base, OrIRQState *orgate,
qemu_irq irq, int nreq, int nevents, int width) qemu_irq irq, int nreq, int nevents, int width)
{ {
SysBusDevice *busdev; SysBusDevice *busdev;
@ -806,7 +806,7 @@ static void exynos4210_init(Object *obj)
for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) { for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
char *name = g_strdup_printf("pl330-irq-orgate%d", i); char *name = g_strdup_printf("pl330-irq-orgate%d", i);
qemu_or_irq *orgate = &s->pl330_irq_orgate[i]; OrIRQState *orgate = &s->pl330_irq_orgate[i];
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ); object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
g_free(name); g_free(name);

View File

@ -152,7 +152,7 @@ struct MPS2TZMachineState {
TZMSC msc[4]; TZMSC msc[4];
CMSDKAPBUART uart[6]; CMSDKAPBUART uart[6];
SplitIRQ sec_resp_splitter; SplitIRQ sec_resp_splitter;
qemu_or_irq uart_irq_orgate; OrIRQState uart_irq_orgate;
DeviceState *lan9118; DeviceState *lan9118;
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX]; SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
Clock *sysclk; Clock *sysclk;

View File

@ -35,6 +35,7 @@
#include "hw/boards.h" #include "hw/boards.h"
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "hw/qdev-properties.h"
#include "hw/misc/unimp.h" #include "hw/misc/unimp.h"
#include "hw/char/cmsdk-apb-uart.h" #include "hw/char/cmsdk-apb-uart.h"
#include "hw/timer/cmsdk-apb-timer.h" #include "hw/timer/cmsdk-apb-timer.h"
@ -282,6 +283,9 @@ static void mps2_common_init(MachineState *machine)
qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12)); qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
DeviceState *dev;
SysBusDevice *s;
static const hwaddr uartbase[] = {0x40004000, 0x40005000, static const hwaddr uartbase[] = {0x40004000, 0x40005000,
0x40006000, 0x40007000, 0x40006000, 0x40007000,
0x40009000}; 0x40009000};
@ -294,12 +298,16 @@ static void mps2_common_init(MachineState *machine)
rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1); rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
} }
cmsdk_apb_uart_create(uartbase[i], dev = qdev_new(TYPE_CMSDK_APB_UART);
qdev_get_gpio_in(armv7m, uartirq[i] + 1), s = SYS_BUS_DEVICE(dev);
qdev_get_gpio_in(armv7m, uartirq[i]), qdev_prop_set_chr(dev, "chardev", serial_hd(i));
txovrint, rxovrint, qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
NULL, sysbus_realize_and_unref(s, &error_fatal);
serial_hd(i), SYSCLK_FRQ); sysbus_mmio_map(s, 0, uartbase[i]);
sysbus_connect_irq(s, 0, qdev_get_gpio_in(armv7m, uartirq[i] + 1));
sysbus_connect_irq(s, 1, qdev_get_gpio_in(armv7m, uartirq[i]));
sysbus_connect_irq(s, 2, txovrint);
sysbus_connect_irq(s, 3, rxovrint);
} }
break; break;
} }
@ -324,7 +332,8 @@ static void mps2_common_init(MachineState *machine)
0x4002c000, 0x4002d000, 0x4002c000, 0x4002d000,
0x4002e000}; 0x4002e000};
Object *txrx_orgate; Object *txrx_orgate;
DeviceState *txrx_orgate_dev; DeviceState *txrx_orgate_dev, *dev;
SysBusDevice *s;
txrx_orgate = object_new(TYPE_OR_IRQ); txrx_orgate = object_new(TYPE_OR_IRQ);
object_property_set_int(txrx_orgate, "num-lines", 2, &error_fatal); object_property_set_int(txrx_orgate, "num-lines", 2, &error_fatal);
@ -332,13 +341,17 @@ static void mps2_common_init(MachineState *machine)
txrx_orgate_dev = DEVICE(txrx_orgate); txrx_orgate_dev = DEVICE(txrx_orgate);
qdev_connect_gpio_out(txrx_orgate_dev, 0, qdev_connect_gpio_out(txrx_orgate_dev, 0,
qdev_get_gpio_in(armv7m, uart_txrx_irqno[i])); qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
cmsdk_apb_uart_create(uartbase[i],
qdev_get_gpio_in(txrx_orgate_dev, 0), dev = qdev_new(TYPE_CMSDK_APB_UART);
qdev_get_gpio_in(txrx_orgate_dev, 1), s = SYS_BUS_DEVICE(dev);
qdev_get_gpio_in(orgate_dev, i * 2), qdev_prop_set_chr(dev, "chardev", serial_hd(i));
qdev_get_gpio_in(orgate_dev, i * 2 + 1), qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
NULL, sysbus_realize_and_unref(s, &error_fatal);
serial_hd(i), SYSCLK_FRQ); sysbus_mmio_map(s, 0, uartbase[i]);
sysbus_connect_irq(s, 0, qdev_get_gpio_in(txrx_orgate_dev, 0));
sysbus_connect_irq(s, 1, qdev_get_gpio_in(txrx_orgate_dev, 1));
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
} }
break; break;
} }

View File

@ -1072,7 +1072,6 @@ struct musicpal_key_state {
SysBusDevice parent_obj; SysBusDevice parent_obj;
/*< public >*/ /*< public >*/
MemoryRegion iomem;
uint32_t kbd_extended; uint32_t kbd_extended;
uint32_t pressed_keys; uint32_t pressed_keys;
qemu_irq out[8]; qemu_irq out[8];
@ -1161,9 +1160,6 @@ static void musicpal_key_init(Object *obj)
DeviceState *dev = DEVICE(sbd); DeviceState *dev = DEVICE(sbd);
musicpal_key_state *s = MUSICPAL_KEY(dev); musicpal_key_state *s = MUSICPAL_KEY(dev);
memory_region_init(&s->iomem, obj, "dummy", 0);
sysbus_init_mmio(sbd, &s->iomem);
s->kbd_extended = 0; s->kbd_extended = 0;
s->pressed_keys = 0; s->pressed_keys = 0;

View File

@ -1146,9 +1146,14 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (board->dc2 & (1 << i)) { if (board->dc2 & (1 << i)) {
pl011_luminary_create(0x4000c000 + i * 0x1000, SysBusDevice *sbd;
qdev_get_gpio_in(nvic, uart_irq[i]),
serial_hd(i)); dev = qdev_new("pl011_luminary");
sbd = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
sysbus_realize_and_unref(sbd, &error_fatal);
sysbus_mmio_map(sbd, 0, 0x4000c000 + i * 0x1000);
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(nvic, uart_irq[i]));
} }
} }
if (board->dc2 & (1 << 4)) { if (board->dc2 & (1 << 4)) {

View File

@ -19,10 +19,12 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/char/pl011.h" #include "hw/char/pl011.h"
#include "hw/irq.h" #include "hw/irq.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "hw/qdev-clock.h" #include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h" #include "hw/qdev-properties-system.h"
#include "migration/vmstate.h" #include "migration/vmstate.h"
#include "chardev/char-fe.h" #include "chardev/char-fe.h"
@ -31,6 +33,21 @@
#include "qemu/module.h" #include "qemu/module.h"
#include "trace.h" #include "trace.h"
DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
{
DeviceState *dev;
SysBusDevice *s;
dev = qdev_new("pl011");
s = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", chr);
sysbus_realize_and_unref(s, &error_fatal);
sysbus_mmio_map(s, 0, addr);
sysbus_connect_irq(s, 0, irq);
return dev;
}
#define PL011_INT_TX 0x20 #define PL011_INT_TX 0x20
#define PL011_INT_RX 0x10 #define PL011_INT_RX 0x10

View File

@ -24,6 +24,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu/log.h" #include "qemu/log.h"
#include "hw/char/xilinx_uartlite.h"
#include "hw/irq.h" #include "hw/irq.h"
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h" #include "hw/qdev-properties-system.h"
@ -53,9 +54,6 @@
#define CONTROL_RST_RX 0x02 #define CONTROL_RST_RX 0x02
#define CONTROL_IE 0x10 #define CONTROL_IE 0x10
#define TYPE_XILINX_UARTLITE "xlnx.xps-uartlite"
OBJECT_DECLARE_SIMPLE_TYPE(XilinxUARTLite, XILINX_UARTLITE)
struct XilinxUARTLite { struct XilinxUARTLite {
SysBusDevice parent_obj; SysBusDevice parent_obj;

View File

@ -26,8 +26,7 @@
#include "hw/irq.h" #include "hw/irq.h"
#include "qom/object.h" #include "qom/object.h"
DECLARE_INSTANCE_CHECKER(struct IRQState, IRQ, OBJECT_DECLARE_SIMPLE_TYPE(IRQState, IRQ)
TYPE_IRQ)
struct IRQState { struct IRQState {
Object parent_obj; Object parent_obj;
@ -68,7 +67,7 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n) qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
{ {
struct IRQState *irq; IRQState *irq;
irq = IRQ(object_new(TYPE_IRQ)); irq = IRQ(object_new(TYPE_IRQ));
irq->handler = handler; irq->handler = handler;
@ -94,7 +93,7 @@ void qemu_free_irq(qemu_irq irq)
static void qemu_notirq(void *opaque, int line, int level) static void qemu_notirq(void *opaque, int line, int level)
{ {
struct IRQState *irq = opaque; IRQState *irq = opaque;
irq->handler(irq->opaque, irq->n, !level); irq->handler(irq->opaque, irq->n, !level);
} }
@ -120,7 +119,7 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
static const TypeInfo irq_type_info = { static const TypeInfo irq_type_info = {
.name = TYPE_IRQ, .name = TYPE_IRQ,
.parent = TYPE_OBJECT, .parent = TYPE_OBJECT,
.instance_size = sizeof(struct IRQState), .instance_size = sizeof(IRQState),
}; };
static void irq_register_types(void) static void irq_register_types(void)

View File

@ -8,6 +8,7 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "hw/acpi/vmgenid.h"
#include "hw/boards.h" #include "hw/boards.h"
#include "hw/intc/intc.h" #include "hw/intc/intc.h"
#include "hw/mem/memory-device.h" #include "hw/mem/memory-device.h"
@ -15,7 +16,6 @@
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qapi-builtin-visit.h" #include "qapi/qapi-builtin-visit.h"
#include "qapi/qapi-commands-machine.h" #include "qapi/qapi-commands-machine.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qobject.h" #include "qapi/qmp/qobject.h"
#include "qapi/qobject-input-visitor.h" #include "qapi/qobject-input-visitor.h"
#include "qapi/type-helpers.h" #include "qapi/type-helpers.h"
@ -140,7 +140,7 @@ HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
MachineClass *mc = MACHINE_GET_CLASS(ms); MachineClass *mc = MACHINE_GET_CLASS(ms);
if (!mc->has_hotpluggable_cpus) { if (!mc->has_hotpluggable_cpus) {
error_setg(errp, QERR_FEATURE_DISABLED, "query-hotpluggable-cpus"); error_setg(errp, "machine does not support hot-plugging CPUs");
return NULL; return NULL;
} }
@ -383,3 +383,20 @@ HumanReadableText *qmp_x_query_irq(Error **errp)
return human_readable_text_from_str(buf); return human_readable_text_from_str(buf);
} }
GuidInfo *qmp_query_vm_generation_id(Error **errp)
{
GuidInfo *info;
VmGenIdState *vms;
Object *obj = find_vmgenid_dev();
if (!obj) {
error_setg(errp, "VM Generation ID device not found");
return NULL;
}
vms = VMGENID(obj);
info = g_malloc0(sizeof(*info));
info->guid = qemu_uuid_unparse_strdup(&vms->guid);
return info;
}

View File

@ -13,7 +13,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu/option.h" #include "qemu/option.h"
#include "qemu/accel.h" #include "qemu/accel.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/replay.h" #include "sysemu/replay.h"
#include "qemu/units.h" #include "qemu/units.h"
#include "hw/boards.h" #include "hw/boards.h"

View File

@ -22,7 +22,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "hw/nmi.h" #include "hw/nmi.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "monitor/monitor.h" #include "monitor/monitor.h"
@ -70,7 +69,7 @@ void nmi_monitor_handle(int cpu_index, Error **errp)
if (ns.handled) { if (ns.handled) {
error_propagate(errp, ns.err); error_propagate(errp, ns.err);
} else { } else {
error_setg(errp, QERR_UNSUPPORTED); error_setg(errp, "machine does not provide NMIs");
} }
} }

View File

@ -31,7 +31,7 @@
static void or_irq_handler(void *opaque, int n, int level) static void or_irq_handler(void *opaque, int n, int level)
{ {
qemu_or_irq *s = OR_IRQ(opaque); OrIRQState *s = OR_IRQ(opaque);
int or_level = 0; int or_level = 0;
int i; int i;
@ -46,7 +46,7 @@ static void or_irq_handler(void *opaque, int n, int level)
static void or_irq_reset(DeviceState *dev) static void or_irq_reset(DeviceState *dev)
{ {
qemu_or_irq *s = OR_IRQ(dev); OrIRQState *s = OR_IRQ(dev);
int i; int i;
for (i = 0; i < MAX_OR_LINES; i++) { for (i = 0; i < MAX_OR_LINES; i++) {
@ -56,7 +56,7 @@ static void or_irq_reset(DeviceState *dev)
static void or_irq_realize(DeviceState *dev, Error **errp) static void or_irq_realize(DeviceState *dev, Error **errp)
{ {
qemu_or_irq *s = OR_IRQ(dev); OrIRQState *s = OR_IRQ(dev);
assert(s->num_lines <= MAX_OR_LINES); assert(s->num_lines <= MAX_OR_LINES);
@ -65,7 +65,7 @@ static void or_irq_realize(DeviceState *dev, Error **errp)
static void or_irq_init(Object *obj) static void or_irq_init(Object *obj)
{ {
qemu_or_irq *s = OR_IRQ(obj); OrIRQState *s = OR_IRQ(obj);
qdev_init_gpio_out(DEVICE(obj), &s->out_irq, 1); qdev_init_gpio_out(DEVICE(obj), &s->out_irq, 1);
} }
@ -84,7 +84,7 @@ static void or_irq_init(Object *obj)
static bool vmstate_extras_needed(void *opaque) static bool vmstate_extras_needed(void *opaque)
{ {
qemu_or_irq *s = OR_IRQ(opaque); OrIRQState *s = OR_IRQ(opaque);
return s->num_lines >= OLD_MAX_OR_LINES; return s->num_lines >= OLD_MAX_OR_LINES;
} }
@ -95,7 +95,7 @@ static const VMStateDescription vmstate_or_irq_extras = {
.minimum_version_id = 1, .minimum_version_id = 1,
.needed = vmstate_extras_needed, .needed = vmstate_extras_needed,
.fields = (VMStateField[]) { .fields = (VMStateField[]) {
VMSTATE_VARRAY_UINT16_UNSAFE(levels, qemu_or_irq, num_lines, 0, VMSTATE_VARRAY_UINT16_UNSAFE(levels, OrIRQState, num_lines, 0,
vmstate_info_bool, bool), vmstate_info_bool, bool),
VMSTATE_END_OF_LIST(), VMSTATE_END_OF_LIST(),
}, },
@ -106,7 +106,7 @@ static const VMStateDescription vmstate_or_irq = {
.version_id = 1, .version_id = 1,
.minimum_version_id = 1, .minimum_version_id = 1,
.fields = (VMStateField[]) { .fields = (VMStateField[]) {
VMSTATE_BOOL_SUB_ARRAY(levels, qemu_or_irq, 0, OLD_MAX_OR_LINES), VMSTATE_BOOL_SUB_ARRAY(levels, OrIRQState, 0, OLD_MAX_OR_LINES),
VMSTATE_END_OF_LIST(), VMSTATE_END_OF_LIST(),
}, },
.subsections = (const VMStateDescription*[]) { .subsections = (const VMStateDescription*[]) {
@ -116,7 +116,7 @@ static const VMStateDescription vmstate_or_irq = {
}; };
static Property or_irq_properties[] = { static Property or_irq_properties[] = {
DEFINE_PROP_UINT16("num-lines", qemu_or_irq, num_lines, 1), DEFINE_PROP_UINT16("num-lines", OrIRQState, num_lines, 1),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };
@ -136,7 +136,7 @@ static void or_irq_class_init(ObjectClass *klass, void *data)
static const TypeInfo or_irq_type_info = { static const TypeInfo or_irq_type_info = {
.name = TYPE_OR_IRQ, .name = TYPE_OR_IRQ,
.parent = TYPE_DEVICE, .parent = TYPE_DEVICE,
.instance_size = sizeof(qemu_or_irq), .instance_size = sizeof(OrIRQState),
.instance_init = or_irq_init, .instance_init = or_irq_init,
.class_init = or_irq_class_init, .class_init = or_irq_class_init,
}; };

View File

@ -183,11 +183,10 @@ static void max7310_gpio_set(void *opaque, int line, int level)
* but also accepts sequences that are not SMBus so return an I2C device. */ * but also accepts sequences that are not SMBus so return an I2C device. */
static void max7310_realize(DeviceState *dev, Error **errp) static void max7310_realize(DeviceState *dev, Error **errp)
{ {
I2CSlave *i2c = I2C_SLAVE(dev);
MAX7310State *s = MAX7310(dev); MAX7310State *s = MAX7310(dev);
qdev_init_gpio_in(&i2c->qdev, max7310_gpio_set, 8); qdev_init_gpio_in(dev, max7310_gpio_set, ARRAY_SIZE(s->handler));
qdev_init_gpio_out(&i2c->qdev, s->handler, 8); qdev_init_gpio_out(dev, s->handler, ARRAY_SIZE(s->handler));
} }
static void max7310_class_init(ObjectClass *klass, void *data) static void max7310_class_init(ObjectClass *klass, void *data)

View File

@ -92,7 +92,6 @@
#include "hw/mem/memory-device.h" #include "hw/mem/memory-device.h"
#include "sysemu/replay.h" #include "sysemu/replay.h"
#include "target/i386/cpu.h" #include "target/i386/cpu.h"
#include "qapi/qmp/qerror.h"
#include "e820_memory_layout.h" #include "e820_memory_layout.h"
#include "fw_cfg.h" #include "fw_cfg.h"
#include "trace.h" #include "trace.h"

View File

@ -28,7 +28,6 @@
#include "qemu/datadir.h" #include "qemu/datadir.h"
#include "qemu/guest-random.h" #include "qemu/guest-random.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qapi-visit-common.h" #include "qapi/qapi-visit-common.h"
#include "qapi/clone-visitor.h" #include "qapi/clone-visitor.h"
#include "qapi/qapi-visit-machine.h" #include "qapi/qapi-visit-machine.h"

View File

@ -18,6 +18,7 @@
#include "hw/intc/armv7m_nvic.h" #include "hw/intc/armv7m_nvic.h"
#include "hw/irq.h" #include "hw/irq.h"
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "sysemu/tcg.h"
#include "sysemu/runstate.h" #include "sysemu/runstate.h"
#include "target/arm/cpu.h" #include "target/arm/cpu.h"
#include "exec/exec-all.h" #include "exec/exec-all.h"
@ -577,7 +578,7 @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
* which saves having to have an extra argument is_terminal * which saves having to have an extra argument is_terminal
* that we'd only use in one place. * that we'd only use in one place.
*/ */
cpu_abort(&s->cpu->parent_obj, cpu_abort(CPU(s->cpu),
"Lockup: can't take terminal derived exception " "Lockup: can't take terminal derived exception "
"(original exception priority %d)\n", "(original exception priority %d)\n",
s->vectpending_prio); s->vectpending_prio);
@ -643,7 +644,7 @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
* Lockup condition due to a guest bug. We don't model * Lockup condition due to a guest bug. We don't model
* Lockup, so report via cpu_abort() instead. * Lockup, so report via cpu_abort() instead.
*/ */
cpu_abort(&s->cpu->parent_obj, cpu_abort(CPU(s->cpu),
"Lockup: can't escalate %d to HardFault " "Lockup: can't escalate %d to HardFault "
"(current priority %d)\n", irq, running); "(current priority %d)\n", irq, running);
} }
@ -741,7 +742,7 @@ void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure)
* We want to escalate to HardFault but the context the * We want to escalate to HardFault but the context the
* FP state belongs to prevents the exception pre-empting. * FP state belongs to prevents the exception pre-empting.
*/ */
cpu_abort(&s->cpu->parent_obj, cpu_abort(CPU(s->cpu),
"Lockup: can't escalate to HardFault during " "Lockup: can't escalate to HardFault during "
"lazy FP register stacking\n"); "lazy FP register stacking\n");
} }
@ -2454,8 +2455,10 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
/* This is UNPREDICTABLE; treat as RAZ/WI */ /* This is UNPREDICTABLE; treat as RAZ/WI */
exit_ok: exit_ok:
if (tcg_enabled()) {
/* Ensure any changes made are reflected in the cached hflags. */ /* Ensure any changes made are reflected in the cached hflags. */
arm_rebuild_hflags(&s->cpu->env); arm_rebuild_hflags(&s->cpu->env);
}
return MEMTX_OK; return MEMTX_OK;
} }
@ -2636,12 +2639,15 @@ static void armv7m_nvic_reset(DeviceState *dev)
} }
} }
if (tcg_enabled()) {
/* /*
* We updated state that affects the CPU's MMUidx and thus its hflags; * We updated state that affects the CPU's MMUidx and thus its
* and we can't guarantee that we run before the CPU reset function. * hflags; and we can't guarantee that we run before the CPU
* reset function.
*/ */
arm_rebuild_hflags(&s->cpu->env); arm_rebuild_hflags(&s->cpu->env);
} }
}
static void nvic_systick_trigger(void *opaque, int n, int level) static void nvic_systick_trigger(void *opaque, int n, int level)
{ {

View File

@ -100,8 +100,11 @@ petalogix_s3adsp1800_init(MachineState *machine)
irq[i] = qdev_get_gpio_in(dev, i); irq[i] = qdev_get_gpio_in(dev, i);
} }
xilinx_uartlite_create(UARTLITE_BASEADDR, irq[UARTLITE_IRQ], dev = qdev_new(TYPE_XILINX_UARTLITE);
serial_hd(0)); qdev_prop_set_chr(dev, "chardev", serial_hd(0));
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[UARTLITE_IRQ]);
/* 2 timers at irq 2 @ 62 Mhz. */ /* 2 timers at irq 2 @ 62 Mhz. */
dev = qdev_new("xlnx.xps-timer"); dev = qdev_new("xlnx.xps-timer");

View File

@ -18,7 +18,6 @@
#include "hw/register.h" #include "hw/register.h"
#include "qemu/bitops.h" #include "qemu/bitops.h"
#include "qapi/qmp/qerror.h"
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h" #include "hw/misc/xlnx-zynqmp-apu-ctrl.h"

View File

@ -1,6 +1,5 @@
/* /*
* QMP Target options - Commands handled based on a target config * QMP command stubs
* versus a host config
* *
* Copyright (c) 2015 David Ahern <dsahern@gmail.com> * Copyright (c) 2015 David Ahern <dsahern@gmail.com>
* *
@ -18,17 +17,16 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qapi-commands-rocker.h" #include "qapi/qapi-commands-rocker.h"
#include "qapi/qmp/qerror.h"
RockerSwitch *qmp_query_rocker(const char *name, Error **errp) RockerSwitch *qmp_query_rocker(const char *name, Error **errp)
{ {
error_setg(errp, QERR_FEATURE_DISABLED, "rocker"); error_setg(errp, "rocker %s not found", name);
return NULL; return NULL;
}; };
RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp) RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp)
{ {
error_setg(errp, QERR_FEATURE_DISABLED, "rocker"); error_setg(errp, "rocker %s not found", name);
return NULL; return NULL;
}; };
@ -37,7 +35,7 @@ RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name,
uint32_t tbl_id, uint32_t tbl_id,
Error **errp) Error **errp)
{ {
error_setg(errp, QERR_FEATURE_DISABLED, "rocker"); error_setg(errp, "rocker %s not found", name);
return NULL; return NULL;
}; };
@ -46,6 +44,6 @@ RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name,
uint8_t type, uint8_t type,
Error **errp) Error **errp)
{ {
error_setg(errp, QERR_FEATURE_DISABLED, "rocker"); error_setg(errp, "rocker %s not found", name);
return NULL; return NULL;
}; };

View File

@ -11,7 +11,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu/units.h" #include "qemu/units.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "hw/hw.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "hw/pci/pci_device.h" #include "hw/pci/pci_device.h"
#include "hw/pci/pci_host.h" #include "hw/pci/pci_host.h"

View File

@ -60,7 +60,7 @@ DECLARE_INSTANCE_CHECKER(PREPPCIState, RAVEN_PCI_HOST_BRIDGE,
struct PRePPCIState { struct PRePPCIState {
PCIHostState parent_obj; PCIHostState parent_obj;
qemu_or_irq *or_irq; OrIRQState *or_irq;
qemu_irq pci_irqs[PCI_NUM_PINS]; qemu_irq pci_irqs[PCI_NUM_PINS];
PCIBus pci_bus; PCIBus pci_bus;
AddressSpace pci_io_as; AddressSpace pci_io_as;

View File

@ -10,7 +10,6 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu/units.h" #include "qemu/units.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "hw/hw.h"
#include "hw/ppc/ppc.h" #include "hw/ppc/ppc.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "hw/pci/pci_host.h" #include "hw/pci/pci_host.h"

View File

@ -173,43 +173,7 @@ target_ulong riscv_load_firmware(const char *firmware_filename,
exit(1); exit(1);
} }
target_ulong riscv_load_kernel(MachineState *machine, static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
target_ulong kernel_start_addr,
symbol_fn_t sym_cb)
{
const char *kernel_filename = machine->kernel_filename;
uint64_t kernel_load_base, kernel_entry;
g_assert(kernel_filename != NULL);
/*
* NB: Use low address not ELF entry point to ensure that the fw_dynamic
* behaviour when loading an ELF matches the fw_payload, fw_jump and BBL
* behaviour, as well as fw_dynamic with a raw binary, all of which jump to
* the (expected) load address load address. This allows kernels to have
* separate SBI and ELF entry points (used by FreeBSD, for example).
*/
if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
NULL, &kernel_load_base, NULL, NULL, 0,
EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
return kernel_load_base;
}
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
NULL, NULL, NULL) > 0) {
return kernel_entry;
}
if (load_image_targphys_as(kernel_filename, kernel_start_addr,
current_machine->ram_size, NULL) > 0) {
return kernel_start_addr;
}
error_report("could not load kernel '%s'", kernel_filename);
exit(1);
}
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
{ {
const char *filename = machine->initrd_filename; const char *filename = machine->initrd_filename;
uint64_t mem_size = machine->ram_size; uint64_t mem_size = machine->ram_size;
@ -249,6 +213,67 @@ void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
} }
} }
target_ulong riscv_load_kernel(MachineState *machine,
RISCVHartArrayState *harts,
target_ulong kernel_start_addr,
bool load_initrd,
symbol_fn_t sym_cb)
{
const char *kernel_filename = machine->kernel_filename;
uint64_t kernel_load_base, kernel_entry;
void *fdt = machine->fdt;
g_assert(kernel_filename != NULL);
/*
* NB: Use low address not ELF entry point to ensure that the fw_dynamic
* behaviour when loading an ELF matches the fw_payload, fw_jump and BBL
* behaviour, as well as fw_dynamic with a raw binary, all of which jump to
* the (expected) load address load address. This allows kernels to have
* separate SBI and ELF entry points (used by FreeBSD, for example).
*/
if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
NULL, &kernel_load_base, NULL, NULL, 0,
EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
kernel_entry = kernel_load_base;
goto out;
}
if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
NULL, NULL, NULL) > 0) {
goto out;
}
if (load_image_targphys_as(kernel_filename, kernel_start_addr,
current_machine->ram_size, NULL) > 0) {
kernel_entry = kernel_start_addr;
goto out;
}
error_report("could not load kernel '%s'", kernel_filename);
exit(1);
out:
/*
* For 32 bit CPUs 'kernel_entry' can be sign-extended by
* load_elf_ram_sym().
*/
if (riscv_is_32bit(harts)) {
kernel_entry = extract64(kernel_entry, 0, 32);
}
if (load_initrd && machine->initrd_filename) {
riscv_load_initrd(machine, kernel_entry);
}
if (fdt && machine->kernel_cmdline && *machine->kernel_cmdline) {
qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
machine->kernel_cmdline);
}
return kernel_entry;
}
/* /*
* This function makes an assumption that the DRAM interval * This function makes an assumption that the DRAM interval
* 'dram_base' + 'dram_size' is contiguous. * 'dram_base' + 'dram_size' is contiguous.

View File

@ -629,16 +629,8 @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus, kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
firmware_end_addr); firmware_end_addr);
kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL); kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
kernel_start_addr, true, NULL);
if (machine->initrd_filename) {
riscv_load_initrd(machine, kernel_entry);
}
if (machine->kernel_cmdline && *machine->kernel_cmdline) {
qemu_fdt_setprop_string(machine->fdt, "/chosen",
"bootargs", machine->kernel_cmdline);
}
/* Compute the fdt load address in dram */ /* Compute the fdt load address in dram */
fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base, fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,

View File

@ -101,7 +101,9 @@ static void opentitan_board_init(MachineState *machine)
} }
if (machine->kernel_filename) { if (machine->kernel_filename) {
riscv_load_kernel(machine, memmap[IBEX_DEV_RAM].base, NULL); riscv_load_kernel(machine, &s->soc.cpus,
memmap[IBEX_DEV_RAM].base,
false, NULL);
} }
} }

View File

@ -114,7 +114,9 @@ static void sifive_e_machine_init(MachineState *machine)
memmap[SIFIVE_E_DEV_MROM].base, &address_space_memory); memmap[SIFIVE_E_DEV_MROM].base, &address_space_memory);
if (machine->kernel_filename) { if (machine->kernel_filename) {
riscv_load_kernel(machine, memmap[SIFIVE_E_DEV_DTIM].base, NULL); riscv_load_kernel(machine, &s->soc.cpus,
memmap[SIFIVE_E_DEV_DTIM].base,
false, NULL);
} }
} }

Some files were not shown because too many files have changed in this diff Show More