Compare commits
152 Commits
v2.6.0-rc0
...
pull-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b065e275a8 | ||
|
|
ce47d3d427 | ||
|
|
0263b3a72f | ||
|
|
2d73837466 | ||
|
|
1a782629f6 | ||
|
|
848c4d4480 | ||
|
|
27a7bbcdf9 | ||
|
|
441330f714 | ||
|
|
a263bac192 | ||
|
|
d44122ecd0 | ||
|
|
5158ac5830 | ||
|
|
3ef3dcef56 | ||
|
|
9bf8027dde | ||
|
|
3f647b510f | ||
|
|
c1c71e49bc | ||
|
|
1759386b7c | ||
|
|
0145b4e130 | ||
|
|
c4189d85bc | ||
|
|
4e876bcf2b | ||
|
|
40a99aace3 | ||
|
|
1fd06db03d | ||
|
|
c229708848 | ||
|
|
143605a200 | ||
|
|
af74e865c4 | ||
|
|
42bb626f7e | ||
|
|
9ca3003df3 | ||
|
|
39bf92dd70 | ||
|
|
a77fd4bb29 | ||
|
|
4e71220387 | ||
|
|
4553e10360 | ||
|
|
dc1ffa6661 | ||
|
|
3a15cc0e1e | ||
|
|
5144fe3605 | ||
|
|
fa49e4656a | ||
|
|
ca58b45fbe | ||
|
|
9628af036f | ||
|
|
8227e2d167 | ||
|
|
3be4f4d724 | ||
|
|
24790aefe0 | ||
|
|
5542417dae | ||
|
|
28ee01269e | ||
|
|
f2eb665a11 | ||
|
|
a110655a06 | ||
|
|
44d066a2f7 | ||
|
|
57a6c059a6 | ||
|
|
7e6bd36d61 | ||
|
|
696b55017d | ||
|
|
1a5512bb7e | ||
|
|
dacca04c8d | ||
|
|
156f6a10c2 | ||
|
|
6ff5816478 | ||
|
|
332a254b66 | ||
|
|
7548fe3116 | ||
|
|
8c6597123a | ||
|
|
c0301fcc81 | ||
|
|
b3f3fdeb95 | ||
|
|
ecba19935a | ||
|
|
089adafdc6 | ||
|
|
ead5268f21 | ||
|
|
3ccdbecf80 | ||
|
|
2e4278b534 | ||
|
|
a378b49a43 | ||
|
|
a8f2e5c8ff | ||
|
|
8a2fad57eb | ||
|
|
344dc16fae | ||
|
|
43c696a298 | ||
|
|
eb41cf78fc | ||
|
|
2b2cbcadc1 | ||
|
|
a3973f551d | ||
|
|
fecb48f744 | ||
|
|
3d100d0fa9 | ||
|
|
bab47d9a75 | ||
|
|
0f8445820f | ||
|
|
45aa4e8e39 | ||
|
|
8d0ac88e23 | ||
|
|
27559c214d | ||
|
|
3005c2c2fa | ||
|
|
e380023898 | ||
|
|
6625d83a6e | ||
|
|
27d92ebc5e | ||
|
|
0f9d6bd210 | ||
|
|
bfb1ac1402 | ||
|
|
b5ab677189 | ||
|
|
e0a039e50d | ||
|
|
91731d5f6d | ||
|
|
044d65525f | ||
|
|
74044c8ffc | ||
|
|
a1555559ab | ||
|
|
7acbff99c6 | ||
|
|
627b4e23cc | ||
|
|
2dc7553d0c | ||
|
|
43b0ea1a41 | ||
|
|
abd4556a17 | ||
|
|
31370dbe5d | ||
|
|
6a5c357fdb | ||
|
|
95c3df5a24 | ||
|
|
08db36f6ec | ||
|
|
a226f76536 | ||
|
|
cc621a9838 | ||
|
|
c44e92a415 | ||
|
|
69c0b278af | ||
|
|
2354bebaa4 | ||
|
|
b6afc654ae | ||
|
|
ca47a926ad | ||
|
|
ccffff48c9 | ||
|
|
a89ef0c357 | ||
|
|
0c52a80eeb | ||
|
|
64c800f808 | ||
|
|
53628efbc8 | ||
|
|
340849a9ff | ||
|
|
f0707d2e03 | ||
|
|
48e1a45c31 | ||
|
|
273c515c0a | ||
|
|
85bc2a1512 | ||
|
|
1b0d9b05d4 | ||
|
|
b89485a52e | ||
|
|
972e3ca3c1 | ||
|
|
7436268ce7 | ||
|
|
1d002037f9 | ||
|
|
6c93329186 | ||
|
|
1dbc7cc9b9 | ||
|
|
76b223200e | ||
|
|
5cf87fd68e | ||
|
|
efdaf797de | ||
|
|
f40eb921da | ||
|
|
5c94b2a5e5 | ||
|
|
2e3a76ae3e | ||
|
|
bf06c1123a | ||
|
|
094a7d0b9d | ||
|
|
e24fdd238a | ||
|
|
f911e0a323 | ||
|
|
0dc1982312 | ||
|
|
c40e13e106 | ||
|
|
e31f045187 | ||
|
|
9d227f194d | ||
|
|
bdc5db01c3 | ||
|
|
34fe9af09b | ||
|
|
0b11c03662 | ||
|
|
de1d099a44 | ||
|
|
eaf136f9a2 | ||
|
|
57528a3fef | ||
|
|
3623c57ed2 | ||
|
|
1458317c8a | ||
|
|
92741fc4b6 | ||
|
|
a1a668efd5 | ||
|
|
a6d4953b60 | ||
|
|
99affd1d5b | ||
|
|
acc6809ddc | ||
|
|
ab8eb29c4a | ||
|
|
891a2bb58c | ||
|
|
0d94b74655 | ||
|
|
d165b8cb8b |
82
.travis.yml
82
.travis.yml
@@ -42,83 +42,49 @@ notifications:
|
|||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- TEST_CMD="make check"
|
- TEST_CMD="make check"
|
||||||
- EXTRA_CONFIG=""
|
|
||||||
matrix:
|
matrix:
|
||||||
# Group major targets together with their linux-user counterparts
|
- CONFIG=""
|
||||||
- TARGETS=alpha-softmmu,alpha-linux-user,cris-softmmu,cris-linux-user,m68k-softmmu,m68k-linux-user,microblaze-softmmu,microblazeel-softmmu,microblaze-linux-user,microblazeel-linux-user
|
- CONFIG="--enable-debug --enable-debug-tcg --enable-trace-backends=log"
|
||||||
- TARGETS=arm-softmmu,arm-linux-user,armeb-linux-user,aarch64-softmmu,aarch64-linux-user
|
- CONFIG="--disable-linux-aio --disable-cap-ng --disable-attr --disable-brlapi --disable-uuid --disable-libusb"
|
||||||
- TARGETS=i386-softmmu,i386-linux-user,x86_64-softmmu,x86_64-linux-user
|
- CONFIG="--enable-modules"
|
||||||
- TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu,mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,mipsn32-linux-user,mipsn32el-linux-user
|
- CONFIG="--with-coroutine=ucontext"
|
||||||
- TARGETS=or32-softmmu,or32-linux-user,ppc-softmmu,ppc64-softmmu,ppcemb-softmmu,ppc-linux-user,ppc64-linux-user,ppc64abi32-linux-user,ppc64le-linux-user
|
- CONFIG="--with-coroutine=sigaltstack"
|
||||||
- TARGETS=s390x-softmmu,s390x-linux-user,sh4-softmmu,sh4eb-softmmu,sh4-linux-user,sh4eb-linux-user,sparc-softmmu,sparc64-softmmu,sparc-linux-user,sparc32plus-linux-user,sparc64-linux-user,unicore32-softmmu,unicore32-linux-user
|
|
||||||
# Group remaining softmmu only targets into one build
|
|
||||||
- TARGETS=lm32-softmmu,moxie-softmmu,tricore-softmmu,xtensa-softmmu,xtensaeb-softmmu
|
|
||||||
git:
|
git:
|
||||||
# we want to do this ourselves
|
# we want to do this ourselves
|
||||||
submodules: false
|
submodules: false
|
||||||
before_install:
|
before_install:
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update ; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install libffi gettext glib pixman ; fi
|
||||||
- wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
|
- wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
before_script:
|
before_script:
|
||||||
- ./configure --target-list=${TARGETS} --enable-debug-tcg ${EXTRA_CONFIG}
|
- ./configure ${CONFIG}
|
||||||
script:
|
script:
|
||||||
- make -j2 && ${TEST_CMD}
|
- make -j3 && ${TEST_CMD}
|
||||||
matrix:
|
matrix:
|
||||||
# We manually include a number of additional build for non-standard bits
|
|
||||||
include:
|
include:
|
||||||
# Debug related options
|
# Sparse is GCC only
|
||||||
- env: TARGETS=x86_64-softmmu
|
- env: CONFIG="--enable-sparse"
|
||||||
EXTRA_CONFIG="--enable-debug"
|
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
# We currently disable "make check"
|
# gprof/gcov are GCC features
|
||||||
- env: TARGETS=alpha-softmmu
|
- env: CONFIG="--enable-gprof --enable-gcov --disable-pie"
|
||||||
EXTRA_CONFIG="--enable-debug --enable-tcg-interpreter"
|
compiler: gcc
|
||||||
|
# We manually include builds which we disable "make check" for
|
||||||
|
- env: CONFIG="--enable-debug --enable-tcg-interpreter"
|
||||||
TEST_CMD=""
|
TEST_CMD=""
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
# Disable a few of the optional features
|
- env: CONFIG="--enable-trace-backends=simple"
|
||||||
- env: TARGETS=x86_64-softmmu
|
|
||||||
EXTRA_CONFIG="--disable-linux-aio --disable-cap-ng --disable-attr --disable-brlapi --disable-uuid --disable-libusb"
|
|
||||||
compiler: gcc
|
|
||||||
# Currently configure doesn't force --disable-pie
|
|
||||||
- env: TARGETS=x86_64-softmmu
|
|
||||||
EXTRA_CONFIG="--enable-gprof --enable-gcov --disable-pie"
|
|
||||||
compiler: gcc
|
|
||||||
# Sparse
|
|
||||||
- env: TARGETS=x86_64-softmmu
|
|
||||||
EXTRA_CONFIG="--enable-sparse"
|
|
||||||
compiler: gcc
|
|
||||||
# Modules
|
|
||||||
- env: TARGETS=arm-softmmu,x86_64-softmmu
|
|
||||||
EXTRA_CONFIG="--enable-modules"
|
|
||||||
compiler: gcc
|
|
||||||
# All the trace backends (apart from dtrace)
|
|
||||||
- env: TARGETS=i386-softmmu
|
|
||||||
EXTRA_CONFIG="--enable-trace-backends=log"
|
|
||||||
compiler: gcc
|
|
||||||
# We currently disable "make check" (until 41fc57e44ed regression fixed)
|
|
||||||
- env: TARGETS=x86_64-softmmu
|
|
||||||
EXTRA_CONFIG="--enable-trace-backends=simple"
|
|
||||||
TEST_CMD=""
|
TEST_CMD=""
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
# We currently disable "make check"
|
- env: CONFIG="--enable-trace-backends=ftrace"
|
||||||
- env: TARGETS=x86_64-softmmu
|
|
||||||
EXTRA_CONFIG="--enable-trace-backends=ftrace"
|
|
||||||
TEST_CMD=""
|
TEST_CMD=""
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
# We currently disable "make check"
|
- env: CONFIG="--enable-trace-backends=ust"
|
||||||
- env: TARGETS=x86_64-softmmu
|
|
||||||
EXTRA_CONFIG="--enable-trace-backends=ust"
|
|
||||||
TEST_CMD=""
|
TEST_CMD=""
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
# All the co-routine backends (apart from windows)
|
- env: CONFIG="--with-coroutine=gthread"
|
||||||
# We currently disable "make check"
|
|
||||||
- env: TARGETS=x86_64-softmmu
|
|
||||||
EXTRA_CONFIG="--with-coroutine=gthread"
|
|
||||||
TEST_CMD=""
|
TEST_CMD=""
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
- env: TARGETS=x86_64-softmmu
|
- env: CONFIG=""
|
||||||
EXTRA_CONFIG="--with-coroutine=ucontext"
|
os: osx
|
||||||
compiler: gcc
|
compiler: clang
|
||||||
- env: TARGETS=x86_64-softmmu
|
|
||||||
EXTRA_CONFIG="--with-coroutine=sigaltstack"
|
|
||||||
compiler: gcc
|
|
||||||
|
|||||||
10
MAINTAINERS
10
MAINTAINERS
@@ -278,7 +278,8 @@ Guest CPU Cores (Xen):
|
|||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
X86
|
X86
|
||||||
M: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
|
M: Stefano Stabellini <sstabellini@kernel.org>
|
||||||
|
M: Anthony Perard <anthony.perard@citrix.com>
|
||||||
L: xen-devel@lists.xensource.com
|
L: xen-devel@lists.xensource.com
|
||||||
S: Supported
|
S: Supported
|
||||||
F: xen-*
|
F: xen-*
|
||||||
@@ -357,10 +358,7 @@ F: include/hw/timer/a9gtimer.h
|
|||||||
F: include/hw/timer/arm_mptimer.h
|
F: include/hw/timer/arm_mptimer.h
|
||||||
|
|
||||||
Exynos
|
Exynos
|
||||||
M: Evgeny Voevodin <e.voevodin@samsung.com>
|
|
||||||
M: Maksim Kozlov <m.kozlov@samsung.com>
|
|
||||||
M: Igor Mitsyanko <i.mitsyanko@gmail.com>
|
M: Igor Mitsyanko <i.mitsyanko@gmail.com>
|
||||||
M: Dmitry Solodkiy <d.solodkiy@samsung.com>
|
|
||||||
L: qemu-arm@nongnu.org
|
L: qemu-arm@nongnu.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: hw/*/exynos*
|
F: hw/*/exynos*
|
||||||
@@ -987,6 +985,7 @@ F: tests/intel-hda-test.c
|
|||||||
|
|
||||||
Block layer core
|
Block layer core
|
||||||
M: Kevin Wolf <kwolf@redhat.com>
|
M: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
M: Max Reitz <mreitz@redhat.com>
|
||||||
L: qemu-block@nongnu.org
|
L: qemu-block@nongnu.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: block*
|
F: block*
|
||||||
@@ -1000,6 +999,7 @@ T: git git://repo.or.cz/qemu/kevin.git block
|
|||||||
|
|
||||||
Block I/O path
|
Block I/O path
|
||||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
M: Fam Zheng <famz@redhat.com>
|
||||||
L: qemu-block@nongnu.org
|
L: qemu-block@nongnu.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: async.c
|
F: async.c
|
||||||
@@ -1570,6 +1570,7 @@ F: block/win32-aio.c
|
|||||||
|
|
||||||
qcow2
|
qcow2
|
||||||
M: Kevin Wolf <kwolf@redhat.com>
|
M: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
M: Max Reitz <mreitz@redhat.com>
|
||||||
L: qemu-block@nongnu.org
|
L: qemu-block@nongnu.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: block/qcow2*
|
F: block/qcow2*
|
||||||
@@ -1582,6 +1583,7 @@ F: block/qcow.c
|
|||||||
|
|
||||||
blkdebug
|
blkdebug
|
||||||
M: Kevin Wolf <kwolf@redhat.com>
|
M: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
M: Max Reitz <mreitz@redhat.com>
|
||||||
L: qemu-block@nongnu.org
|
L: qemu-block@nongnu.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: block/blkdebug.c
|
F: block/blkdebug.c
|
||||||
|
|||||||
@@ -52,11 +52,14 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
error_setg(errp, "-mem-path not supported on this host");
|
error_setg(errp, "-mem-path not supported on this host");
|
||||||
#else
|
#else
|
||||||
if (!memory_region_size(&backend->mr)) {
|
if (!memory_region_size(&backend->mr)) {
|
||||||
|
gchar *path;
|
||||||
backend->force_prealloc = mem_prealloc;
|
backend->force_prealloc = mem_prealloc;
|
||||||
|
path = object_get_canonical_path(OBJECT(backend));
|
||||||
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
|
memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
|
||||||
object_get_canonical_path(OBJECT(backend)),
|
path,
|
||||||
backend->size, fb->share,
|
backend->size, fb->share,
|
||||||
fb->mem_path, errp);
|
fb->mem_path, errp);
|
||||||
|
g_free(path);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
7
block.c
7
block.c
@@ -1526,6 +1526,13 @@ static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename,
|
|||||||
if (!bs) {
|
if (!bs) {
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bs->throttle_state) {
|
||||||
|
error_setg(errp, "Cannot reference an existing block device for "
|
||||||
|
"which I/O throttling is enabled");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
bdrv_ref(bs);
|
bdrv_ref(bs);
|
||||||
*pbs = bs;
|
*pbs = bs;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
|
|||||||
OptsVisitor *ov;
|
OptsVisitor *ov;
|
||||||
QCryptoBlockOpenOptions *ret = NULL;
|
QCryptoBlockOpenOptions *ret = NULL;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
Error *end_err = NULL;
|
||||||
|
|
||||||
ret = g_new0(QCryptoBlockOpenOptions, 1);
|
ret = g_new0(QCryptoBlockOpenOptions, 1);
|
||||||
ret->format = format;
|
ret->format = format;
|
||||||
@@ -218,10 +219,9 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
|
|||||||
error_setg(&local_err, "Unsupported block format %d", format);
|
error_setg(&local_err, "Unsupported block format %d", format);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
error_propagate(errp, local_err);
|
|
||||||
local_err = NULL;
|
|
||||||
|
|
||||||
visit_end_struct(opts_get_visitor(ov), &local_err);
|
visit_end_struct(opts_get_visitor(ov), &end_err);
|
||||||
|
error_propagate(&local_err, end_err);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
@@ -242,6 +242,7 @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
|
|||||||
OptsVisitor *ov;
|
OptsVisitor *ov;
|
||||||
QCryptoBlockCreateOptions *ret = NULL;
|
QCryptoBlockCreateOptions *ret = NULL;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
Error *end_err = NULL;
|
||||||
|
|
||||||
ret = g_new0(QCryptoBlockCreateOptions, 1);
|
ret = g_new0(QCryptoBlockCreateOptions, 1);
|
||||||
ret->format = format;
|
ret->format = format;
|
||||||
@@ -264,10 +265,9 @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
|
|||||||
error_setg(&local_err, "Unsupported block format %d", format);
|
error_setg(&local_err, "Unsupported block format %d", format);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
error_propagate(errp, local_err);
|
|
||||||
local_err = NULL;
|
|
||||||
|
|
||||||
visit_end_struct(opts_get_visitor(ov), &local_err);
|
visit_end_struct(opts_get_visitor(ov), &end_err);
|
||||||
|
error_propagate(&local_err, end_err);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
|
|||||||
45
block/io.c
45
block/io.c
@@ -253,6 +253,47 @@ static void bdrv_drain_recurse(BlockDriverState *bs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Coroutine *co;
|
||||||
|
BlockDriverState *bs;
|
||||||
|
QEMUBH *bh;
|
||||||
|
bool done;
|
||||||
|
} BdrvCoDrainData;
|
||||||
|
|
||||||
|
static void bdrv_co_drain_bh_cb(void *opaque)
|
||||||
|
{
|
||||||
|
BdrvCoDrainData *data = opaque;
|
||||||
|
Coroutine *co = data->co;
|
||||||
|
|
||||||
|
qemu_bh_delete(data->bh);
|
||||||
|
bdrv_drain(data->bs);
|
||||||
|
data->done = true;
|
||||||
|
qemu_coroutine_enter(co, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BdrvCoDrainData data;
|
||||||
|
|
||||||
|
/* Calling bdrv_drain() from a BH ensures the current coroutine yields and
|
||||||
|
* other coroutines run if they were queued from
|
||||||
|
* qemu_co_queue_run_restart(). */
|
||||||
|
|
||||||
|
assert(qemu_in_coroutine());
|
||||||
|
data = (BdrvCoDrainData) {
|
||||||
|
.co = qemu_coroutine_self(),
|
||||||
|
.bs = bs,
|
||||||
|
.done = false,
|
||||||
|
.bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_drain_bh_cb, &data),
|
||||||
|
};
|
||||||
|
qemu_bh_schedule(data.bh);
|
||||||
|
|
||||||
|
qemu_coroutine_yield();
|
||||||
|
/* If we are resumed from some other event (such as an aio completion or a
|
||||||
|
* timer callback), it is a bug in the caller that should be fixed. */
|
||||||
|
assert(data.done);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for pending requests to complete on a single BlockDriverState subtree,
|
* Wait for pending requests to complete on a single BlockDriverState subtree,
|
||||||
* and suspend block driver's internal I/O until next request arrives.
|
* and suspend block driver's internal I/O until next request arrives.
|
||||||
@@ -269,6 +310,10 @@ void bdrv_drain(BlockDriverState *bs)
|
|||||||
bool busy = true;
|
bool busy = true;
|
||||||
|
|
||||||
bdrv_drain_recurse(bs);
|
bdrv_drain_recurse(bs);
|
||||||
|
if (qemu_in_coroutine()) {
|
||||||
|
bdrv_co_drain(bs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
while (busy) {
|
while (busy) {
|
||||||
/* Keep iterating */
|
/* Keep iterating */
|
||||||
bdrv_flush_io_queue(bs);
|
bdrv_flush_io_queue(bs);
|
||||||
|
|||||||
@@ -650,7 +650,7 @@ static void coroutine_fn mirror_run(void *opaque)
|
|||||||
* mirror_populate runs.
|
* mirror_populate runs.
|
||||||
*/
|
*/
|
||||||
trace_mirror_before_drain(s, cnt);
|
trace_mirror_before_drain(s, cnt);
|
||||||
bdrv_drain(bs);
|
bdrv_co_drain(bs);
|
||||||
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
|
cnt = bdrv_get_dirty_count(s->dirty_bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -319,10 +319,6 @@ int nbd_client_co_flush(BlockDriverState *bs)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->nbdflags & NBD_FLAG_SEND_FUA) {
|
|
||||||
request.type |= NBD_CMD_FLAG_FUA;
|
|
||||||
}
|
|
||||||
|
|
||||||
request.from = 0;
|
request.from = 0;
|
||||||
request.len = 0;
|
request.len = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,12 @@
|
|||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "qemu/iov.h"
|
#include "qemu/iov.h"
|
||||||
#include "qemu/uri.h"
|
#include "qemu/uri.h"
|
||||||
|
#include "qemu/cutils.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include <nfsc/libnfs.h>
|
#include <nfsc/libnfs.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1986,6 +1986,10 @@ static int qcow2_change_backing_file(BlockDriverState *bs,
|
|||||||
{
|
{
|
||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
|
|
||||||
|
if (backing_file && strlen(backing_file) > 1023) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_file ?: "");
|
pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_file ?: "");
|
||||||
pstrcpy(bs->backing_format, sizeof(bs->backing_format), backing_fmt ?: "");
|
pstrcpy(bs->backing_format, sizeof(bs->backing_format), backing_fmt ?: "");
|
||||||
|
|
||||||
|
|||||||
@@ -775,7 +775,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
|
|||||||
num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
|
num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
|
||||||
|
|
||||||
ret = blk_pwrite(blk, offset, buf, HEADER_SIZE);
|
ret = blk_pwrite(blk, offset, buf, HEADER_SIZE);
|
||||||
if (ret) {
|
if (ret < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
blockdev.c
12
blockdev.c
@@ -2661,6 +2661,13 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The BlockBackend must be the only parent */
|
||||||
|
assert(QLIST_FIRST(&bs->parents));
|
||||||
|
if (QLIST_NEXT(QLIST_FIRST(&bs->parents), next_parent)) {
|
||||||
|
error_setg(errp, "Cannot throttle device with multiple parents");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
throttle_config_init(&cfg);
|
throttle_config_init(&cfg);
|
||||||
cfg.buckets[THROTTLE_BPS_TOTAL].avg = bps;
|
cfg.buckets[THROTTLE_BPS_TOTAL].avg = bps;
|
||||||
cfg.buckets[THROTTLE_BPS_READ].avg = bps_rd;
|
cfg.buckets[THROTTLE_BPS_READ].avg = bps_rd;
|
||||||
@@ -4027,6 +4034,11 @@ void qmp_x_blockdev_del(bool has_id, const char *id,
|
|||||||
error_setg(errp, "Cannot find block backend %s", id);
|
error_setg(errp, "Cannot find block backend %s", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (blk_legacy_dinfo(blk)) {
|
||||||
|
error_setg(errp, "Deleting block backend added with drive-add"
|
||||||
|
" is not supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (blk_get_refcnt(blk) > 1) {
|
if (blk_get_refcnt(blk) > 1) {
|
||||||
error_setg(errp, "Block backend %s is in use", id);
|
error_setg(errp, "Block backend %s is in use", id);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/cutils.h"
|
||||||
|
#include "qemu/path.h"
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/* User memory access */
|
/* User memory access */
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/cutils.h"
|
||||||
|
|
||||||
#include "qemu.h"
|
#include "qemu.h"
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ abi_long target_strlen(abi_ulong guest_addr1)
|
|||||||
ptr = lock_user(VERIFY_READ, guest_addr, max_len, 1);
|
ptr = lock_user(VERIFY_READ, guest_addr, max_len, 1);
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return -TARGET_EFAULT;
|
return -TARGET_EFAULT;
|
||||||
len = qemu_strnlen((char *)ptr, max_len);
|
len = qemu_strnlen((const char *)ptr, max_len);
|
||||||
unlock_user(ptr, guest_addr, 0);
|
unlock_user(ptr, guest_addr, 0);
|
||||||
guest_addr += len;
|
guest_addr += len;
|
||||||
/* we don't allow wrapping or integer overflow */
|
/* we don't allow wrapping or integer overflow */
|
||||||
|
|||||||
10
cpus.c
10
cpus.c
@@ -338,10 +338,18 @@ static int64_t qemu_icount_round(int64_t count)
|
|||||||
|
|
||||||
static void icount_warp_rt(void)
|
static void icount_warp_rt(void)
|
||||||
{
|
{
|
||||||
|
unsigned seq;
|
||||||
|
int64_t warp_start;
|
||||||
|
|
||||||
/* The icount_warp_timer is rescheduled soon after vm_clock_warp_start
|
/* The icount_warp_timer is rescheduled soon after vm_clock_warp_start
|
||||||
* changes from -1 to another value, so the race here is okay.
|
* changes from -1 to another value, so the race here is okay.
|
||||||
*/
|
*/
|
||||||
if (atomic_read(&vm_clock_warp_start) == -1) {
|
do {
|
||||||
|
seq = seqlock_read_begin(&timers_state.vm_clock_seqlock);
|
||||||
|
warp_start = vm_clock_warp_start;
|
||||||
|
} while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq));
|
||||||
|
|
||||||
|
if (warp_start == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ MemoryRegion):
|
|||||||
|
|
||||||
- MMIO: a range of guest memory that is implemented by host callbacks;
|
- MMIO: a range of guest memory that is implemented by host callbacks;
|
||||||
each read or write causes a callback to be called on the host.
|
each read or write causes a callback to be called on the host.
|
||||||
You initialize these with memory_region_io(), passing it a MemoryRegionOps
|
You initialize these with memory_region_init_io(), passing it a
|
||||||
structure describing the callbacks.
|
MemoryRegionOps structure describing the callbacks.
|
||||||
|
|
||||||
- ROM: a ROM memory region works like RAM for reads (directly accessing
|
- ROM: a ROM memory region works like RAM for reads (directly accessing
|
||||||
a region of host memory), but like MMIO for writes (invoking a callback).
|
a region of host memory), but like MMIO for writes (invoking a callback).
|
||||||
@@ -185,9 +185,9 @@ an MMIO region mapped at 0x0, size 0x6000, priority 1. B currently has two
|
|||||||
of its own subregions: D of size 0x1000 at offset 0 and E of size 0x1000 at
|
of its own subregions: D of size 0x1000 at offset 0 and E of size 0x1000 at
|
||||||
offset 0x2000. As a diagram:
|
offset 0x2000. As a diagram:
|
||||||
|
|
||||||
0 1000 2000 3000 4000 5000 6000 7000 8000
|
0 1000 2000 3000 4000 5000 6000 7000 8000
|
||||||
|------|------|------|------|------|------|------|-------|
|
|------|------|------|------|------|------|------|------|
|
||||||
A: [ ]
|
A: [ ]
|
||||||
C: [CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC]
|
C: [CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC]
|
||||||
B: [ ]
|
B: [ ]
|
||||||
D: [DDDDD]
|
D: [DDDDD]
|
||||||
@@ -247,7 +247,7 @@ system_memory: container@0-2^48-1
|
|||||||
|
|
|
|
||||||
+---- himem: alias@0x100000000-0x11fffffff ---> #ram (0xe0000000-0xffffffff)
|
+---- himem: alias@0x100000000-0x11fffffff ---> #ram (0xe0000000-0xffffffff)
|
||||||
|
|
|
|
||||||
+---- vga-window: alias@0xa0000-0xbfffff ---> #pci (0xa0000-0xbffff)
|
+---- vga-window: alias@0xa0000-0xbffff ---> #pci (0xa0000-0xbffff)
|
||||||
| (prio 1)
|
| (prio 1)
|
||||||
|
|
|
|
||||||
+---- pci-hole: alias@0xe0000000-0xffffffff ---> #pci (0xe0000000-0xffffffff)
|
+---- pci-hole: alias@0xe0000000-0xffffffff ---> #pci (0xe0000000-0xffffffff)
|
||||||
|
|||||||
@@ -157,9 +157,9 @@ performance penalty.
|
|||||||
Note that regardless of the selected trace backend, events with the "disable"
|
Note that regardless of the selected trace backend, events with the "disable"
|
||||||
property will be generated with the "nop" backend.
|
property will be generated with the "nop" backend.
|
||||||
|
|
||||||
=== Stderr ===
|
=== Log ===
|
||||||
|
|
||||||
The "stderr" backend sends trace events directly to standard error. This
|
The "log" backend sends trace events directly to standard error. This
|
||||||
effectively turns trace events into debug printfs.
|
effectively turns trace events into debug printfs.
|
||||||
|
|
||||||
This is the simplest backend and can be used together with existing code that
|
This is the simplest backend and can be used together with existing code that
|
||||||
|
|||||||
4
exec.c
4
exec.c
@@ -1773,6 +1773,10 @@ static void reclaim_ramblock(RAMBlock *block)
|
|||||||
|
|
||||||
void qemu_ram_free(RAMBlock *block)
|
void qemu_ram_free(RAMBlock *block)
|
||||||
{
|
{
|
||||||
|
if (!block) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qemu_mutex_lock_ramlist();
|
qemu_mutex_lock_ramlist();
|
||||||
QLIST_REMOVE_RCU(block, next);
|
QLIST_REMOVE_RCU(block, next);
|
||||||
ram_list.mru_block = NULL;
|
ram_list.mru_block = NULL;
|
||||||
|
|||||||
@@ -139,9 +139,13 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
/* Connect timers from the CPU to the interrupt controller */
|
/* Connect timers from the CPU to the interrupt controller */
|
||||||
qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_PHYS,
|
qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_PHYS,
|
||||||
qdev_get_gpio_in_named(DEVICE(&s->control), "cntpsirq", n));
|
qdev_get_gpio_in_named(DEVICE(&s->control), "cntpnsirq", n));
|
||||||
qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_VIRT,
|
qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_VIRT,
|
||||||
qdev_get_gpio_in_named(DEVICE(&s->control), "cntvirq", n));
|
qdev_get_gpio_in_named(DEVICE(&s->control), "cntvirq", n));
|
||||||
|
qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_HYP,
|
||||||
|
qdev_get_gpio_in_named(DEVICE(&s->control), "cnthpirq", n));
|
||||||
|
qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_SEC,
|
||||||
|
qdev_get_gpio_in_named(DEVICE(&s->control), "cntpsirq", n));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
struct VirtIOBlockDataPlane {
|
struct VirtIOBlockDataPlane {
|
||||||
bool starting;
|
bool starting;
|
||||||
bool stopping;
|
bool stopping;
|
||||||
bool disabled;
|
|
||||||
|
|
||||||
VirtIOBlkConf *conf;
|
VirtIOBlkConf *conf;
|
||||||
|
|
||||||
@@ -185,6 +184,17 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
|
|||||||
g_free(s);
|
g_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_blk_data_plane_handle_output(VirtIODevice *vdev,
|
||||||
|
VirtQueue *vq)
|
||||||
|
{
|
||||||
|
VirtIOBlock *s = (VirtIOBlock *)vdev;
|
||||||
|
|
||||||
|
assert(s->dataplane);
|
||||||
|
assert(s->dataplane_started);
|
||||||
|
|
||||||
|
virtio_blk_handle_vq(s, vq);
|
||||||
|
}
|
||||||
|
|
||||||
/* Context: QEMU global mutex held */
|
/* Context: QEMU global mutex held */
|
||||||
void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
||||||
{
|
{
|
||||||
@@ -227,14 +237,15 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
|||||||
|
|
||||||
/* Get this show started by hooking up our callbacks */
|
/* Get this show started by hooking up our callbacks */
|
||||||
aio_context_acquire(s->ctx);
|
aio_context_acquire(s->ctx);
|
||||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, true, true);
|
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx,
|
||||||
|
virtio_blk_data_plane_handle_output);
|
||||||
aio_context_release(s->ctx);
|
aio_context_release(s->ctx);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail_host_notifier:
|
fail_host_notifier:
|
||||||
k->set_guest_notifiers(qbus->parent, 1, false);
|
k->set_guest_notifiers(qbus->parent, 1, false);
|
||||||
fail_guest_notifiers:
|
fail_guest_notifiers:
|
||||||
s->disabled = true;
|
vblk->dataplane_disabled = true;
|
||||||
s->starting = false;
|
s->starting = false;
|
||||||
vblk->dataplane_started = true;
|
vblk->dataplane_started = true;
|
||||||
}
|
}
|
||||||
@@ -251,8 +262,8 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Better luck next time. */
|
/* Better luck next time. */
|
||||||
if (s->disabled) {
|
if (vblk->dataplane_disabled) {
|
||||||
s->disabled = false;
|
vblk->dataplane_disabled = false;
|
||||||
vblk->dataplane_started = false;
|
vblk->dataplane_started = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -262,7 +273,7 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
|||||||
aio_context_acquire(s->ctx);
|
aio_context_acquire(s->ctx);
|
||||||
|
|
||||||
/* Stop notifications for new requests from guest */
|
/* Stop notifications for new requests from guest */
|
||||||
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, false, false);
|
virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, NULL);
|
||||||
|
|
||||||
/* Drain and switch bs back to the QEMU main loop */
|
/* Drain and switch bs back to the QEMU main loop */
|
||||||
blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context());
|
blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context());
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
|
|||||||
|
|
||||||
stb_p(&req->in->status, status);
|
stb_p(&req->in->status, status);
|
||||||
virtqueue_push(s->vq, &req->elem, req->in_len);
|
virtqueue_push(s->vq, &req->elem, req->in_len);
|
||||||
if (s->dataplane) {
|
if (s->dataplane_started && !s->dataplane_disabled) {
|
||||||
virtio_blk_data_plane_notify(s->dataplane);
|
virtio_blk_data_plane_notify(s->dataplane);
|
||||||
} else {
|
} else {
|
||||||
virtio_notify(vdev, s->vq);
|
virtio_notify(vdev, s->vq);
|
||||||
@@ -578,20 +578,11 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
|
||||||
{
|
{
|
||||||
VirtIOBlock *s = VIRTIO_BLK(vdev);
|
|
||||||
VirtIOBlockReq *req;
|
VirtIOBlockReq *req;
|
||||||
MultiReqBuffer mrb = {};
|
MultiReqBuffer mrb = {};
|
||||||
|
|
||||||
/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
|
|
||||||
* dataplane here instead of waiting for .set_status().
|
|
||||||
*/
|
|
||||||
if (s->dataplane && !s->dataplane_started) {
|
|
||||||
virtio_blk_data_plane_start(s->dataplane);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
blk_io_plug(s->blk);
|
blk_io_plug(s->blk);
|
||||||
|
|
||||||
while ((req = virtio_blk_get_request(s))) {
|
while ((req = virtio_blk_get_request(s))) {
|
||||||
@@ -605,6 +596,22 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
|||||||
blk_io_unplug(s->blk);
|
blk_io_unplug(s->blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||||
|
{
|
||||||
|
VirtIOBlock *s = (VirtIOBlock *)vdev;
|
||||||
|
|
||||||
|
if (s->dataplane) {
|
||||||
|
/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
|
||||||
|
* dataplane here instead of waiting for .set_status().
|
||||||
|
*/
|
||||||
|
virtio_blk_data_plane_start(s->dataplane);
|
||||||
|
if (!s->dataplane_disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtio_blk_handle_vq(s, vq);
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_blk_dma_restart_bh(void *opaque)
|
static void virtio_blk_dma_restart_bh(void *opaque)
|
||||||
{
|
{
|
||||||
VirtIOBlock *s = opaque;
|
VirtIOBlock *s = opaque;
|
||||||
|
|||||||
@@ -1053,6 +1053,20 @@ void rom_set_fw(FWCfgState *f)
|
|||||||
fw_cfg = f;
|
fw_cfg = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rom_set_order_override(int order)
|
||||||
|
{
|
||||||
|
if (!fw_cfg)
|
||||||
|
return;
|
||||||
|
fw_cfg_set_order_override(fw_cfg, order);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rom_reset_order_override(void)
|
||||||
|
{
|
||||||
|
if (!fw_cfg)
|
||||||
|
return;
|
||||||
|
fw_cfg_reset_order_override(fw_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
static Rom *find_rom(hwaddr addr)
|
static Rom *find_rom(hwaddr addr)
|
||||||
{
|
{
|
||||||
Rom *rom;
|
Rom *rom;
|
||||||
|
|||||||
@@ -572,10 +572,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
|
|||||||
scanout->width != ss.r.width ||
|
scanout->width != ss.r.width ||
|
||||||
scanout->height != ss.r.height) {
|
scanout->height != ss.r.height) {
|
||||||
/* realloc the surface ptr */
|
/* realloc the surface ptr */
|
||||||
scanout->ds = qemu_create_displaysurface_from
|
scanout->ds = qemu_create_displaysurface_pixman(res->image);
|
||||||
(ss.r.width, ss.r.height, format,
|
|
||||||
pixman_image_get_stride(res->image),
|
|
||||||
(uint8_t *)pixman_image_get_data(res->image) + offset);
|
|
||||||
if (!scanout->ds) {
|
if (!scanout->ds) {
|
||||||
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
||||||
return;
|
return;
|
||||||
@@ -920,6 +917,11 @@ const GraphicHwOps virtio_gpu_ops = {
|
|||||||
.gl_block = virtio_gpu_gl_block,
|
.gl_block = virtio_gpu_gl_block,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_virtio_gpu_unmigratable = {
|
||||||
|
.name = "virtio-gpu",
|
||||||
|
.unmigratable = 1,
|
||||||
|
};
|
||||||
|
|
||||||
static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
|
static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
|
||||||
{
|
{
|
||||||
VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
|
VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
|
||||||
@@ -971,6 +973,8 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
|
|||||||
dpy_gfx_replace_surface(g->scanout[i].con, NULL);
|
dpy_gfx_replace_surface(g->scanout[i].con, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vmstate_register(qdev, -1, &vmstate_virtio_gpu_unmigratable, g);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_gpu_instance_init(Object *obj)
|
static void virtio_gpu_instance_init(Object *obj)
|
||||||
|
|||||||
@@ -1406,6 +1406,7 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
|
|||||||
{
|
{
|
||||||
DeviceState *dev = NULL;
|
DeviceState *dev = NULL;
|
||||||
|
|
||||||
|
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_VGA);
|
||||||
if (pci_bus) {
|
if (pci_bus) {
|
||||||
PCIDevice *pcidev = pci_vga_init(pci_bus);
|
PCIDevice *pcidev = pci_vga_init(pci_bus);
|
||||||
dev = pcidev ? &pcidev->qdev : NULL;
|
dev = pcidev ? &pcidev->qdev : NULL;
|
||||||
@@ -1413,6 +1414,7 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
|
|||||||
ISADevice *isadev = isa_vga_init(isa_bus);
|
ISADevice *isadev = isa_vga_init(isa_bus);
|
||||||
dev = isadev ? DEVICE(isadev) : NULL;
|
dev = isadev ? DEVICE(isadev) : NULL;
|
||||||
}
|
}
|
||||||
|
rom_reset_order_override();
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1541,6 +1543,7 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_NIC);
|
||||||
for (i = 0; i < nb_nics; i++) {
|
for (i = 0; i < nb_nics; i++) {
|
||||||
NICInfo *nd = &nd_table[i];
|
NICInfo *nd = &nd_table[i];
|
||||||
|
|
||||||
@@ -1550,6 +1553,7 @@ void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
|
|||||||
pci_nic_init_nofail(nd, pci_bus, "e1000", NULL);
|
pci_nic_init_nofail(nd, pci_bus, "e1000", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rom_reset_order_override();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pc_pci_device_init(PCIBus *pci_bus)
|
void pc_pci_device_init(PCIBus *pci_bus)
|
||||||
|
|||||||
@@ -434,6 +434,7 @@ static void pc_i440fx_2_5_machine_options(MachineClass *m)
|
|||||||
m->alias = NULL;
|
m->alias = NULL;
|
||||||
m->is_default = 0;
|
m->is_default = 0;
|
||||||
pcmc->save_tsc_khz = false;
|
pcmc->save_tsc_khz = false;
|
||||||
|
m->legacy_fw_cfg_order = 1;
|
||||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
|
SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -298,6 +298,7 @@ static void pc_q35_2_5_machine_options(MachineClass *m)
|
|||||||
pc_q35_2_6_machine_options(m);
|
pc_q35_2_6_machine_options(m);
|
||||||
m->alias = NULL;
|
m->alias = NULL;
|
||||||
pcmc->save_tsc_khz = false;
|
pcmc->save_tsc_khz = false;
|
||||||
|
m->legacy_fw_cfg_order = 1;
|
||||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
|
SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -258,22 +258,10 @@ static const TypeInfo piix3_ide_info = {
|
|||||||
.class_init = piix3_ide_class_init,
|
.class_init = piix3_ide_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
|
|
||||||
{
|
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
||||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
|
||||||
|
|
||||||
k->realize = pci_piix_ide_realize;
|
|
||||||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
|
||||||
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
|
|
||||||
k->class_id = PCI_CLASS_STORAGE_IDE;
|
|
||||||
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const TypeInfo piix3_ide_xen_info = {
|
static const TypeInfo piix3_ide_xen_info = {
|
||||||
.name = "piix3-ide-xen",
|
.name = "piix3-ide-xen",
|
||||||
.parent = TYPE_PCI_IDE,
|
.parent = TYPE_PCI_IDE,
|
||||||
.class_init = piix3_ide_xen_class_init,
|
.class_init = piix3_ide_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void piix4_ide_class_init(ObjectClass *klass, void *data)
|
static void piix4_ide_class_init(ObjectClass *klass, void *data)
|
||||||
|
|||||||
@@ -628,7 +628,7 @@ static void ps2_kbd_reset(void *opaque)
|
|||||||
ps2_common_reset(&s->common);
|
ps2_common_reset(&s->common);
|
||||||
s->scan_enabled = 0;
|
s->scan_enabled = 0;
|
||||||
s->translate = 0;
|
s->translate = 0;
|
||||||
s->scancode_set = 0;
|
s->scancode_set = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ps2_mouse_reset(void *opaque)
|
static void ps2_mouse_reset(void *opaque)
|
||||||
|
|||||||
@@ -121,6 +121,8 @@ static const unsigned int keymap_qcode[Q_KEY_CODE__MAX] = {
|
|||||||
|
|
||||||
[Q_KEY_CODE_CTRL_R] = KEY_RIGHTCTRL,
|
[Q_KEY_CODE_CTRL_R] = KEY_RIGHTCTRL,
|
||||||
[Q_KEY_CODE_SYSRQ] = KEY_SYSRQ,
|
[Q_KEY_CODE_SYSRQ] = KEY_SYSRQ,
|
||||||
|
[Q_KEY_CODE_PRINT] = KEY_SYSRQ,
|
||||||
|
[Q_KEY_CODE_PAUSE] = KEY_PAUSE,
|
||||||
[Q_KEY_CODE_ALT_R] = KEY_RIGHTALT,
|
[Q_KEY_CODE_ALT_R] = KEY_RIGHTALT,
|
||||||
|
|
||||||
[Q_KEY_CODE_HOME] = KEY_HOME,
|
[Q_KEY_CODE_HOME] = KEY_HOME,
|
||||||
@@ -482,12 +484,12 @@ static struct virtio_input_config virtio_tablet_config[] = {
|
|||||||
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
||||||
.subsel = ABS_X,
|
.subsel = ABS_X,
|
||||||
.size = sizeof(virtio_input_absinfo),
|
.size = sizeof(virtio_input_absinfo),
|
||||||
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE),
|
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
|
||||||
},{
|
},{
|
||||||
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
||||||
.subsel = ABS_Y,
|
.subsel = ABS_Y,
|
||||||
.size = sizeof(virtio_input_absinfo),
|
.size = sizeof(virtio_input_absinfo),
|
||||||
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE),
|
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
|
||||||
},
|
},
|
||||||
{ /* end of list */ },
|
{ /* end of list */ },
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,13 +70,39 @@ static void virtio_input_bits_config(VirtIOInputHost *vih,
|
|||||||
virtio_input_add_config(VIRTIO_INPUT(vih), &bits);
|
virtio_input_add_config(VIRTIO_INPUT(vih), &bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_input_abs_config(VirtIOInputHost *vih, int axis)
|
||||||
|
{
|
||||||
|
virtio_input_config config;
|
||||||
|
struct input_absinfo absinfo;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ioctl(vih->fd, EVIOCGABS(axis), &absinfo);
|
||||||
|
if (rc < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&config, 0, sizeof(config));
|
||||||
|
config.select = VIRTIO_INPUT_CFG_ABS_INFO;
|
||||||
|
config.subsel = axis;
|
||||||
|
config.size = sizeof(virtio_input_absinfo);
|
||||||
|
|
||||||
|
config.u.abs.min = cpu_to_le32(absinfo.minimum);
|
||||||
|
config.u.abs.max = cpu_to_le32(absinfo.maximum);
|
||||||
|
config.u.abs.fuzz = cpu_to_le32(absinfo.fuzz);
|
||||||
|
config.u.abs.flat = cpu_to_le32(absinfo.flat);
|
||||||
|
config.u.abs.res = cpu_to_le32(absinfo.resolution);
|
||||||
|
|
||||||
|
virtio_input_add_config(VIRTIO_INPUT(vih), &config);
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_input_host_realize(DeviceState *dev, Error **errp)
|
static void virtio_input_host_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev);
|
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev);
|
||||||
VirtIOInput *vinput = VIRTIO_INPUT(dev);
|
VirtIOInput *vinput = VIRTIO_INPUT(dev);
|
||||||
virtio_input_config id;
|
virtio_input_config id, *abs;
|
||||||
struct input_id ids;
|
struct input_id ids;
|
||||||
int rc, ver;
|
int rc, ver, i, axis;
|
||||||
|
uint8_t byte;
|
||||||
|
|
||||||
if (!vih->evdev) {
|
if (!vih->evdev) {
|
||||||
error_setg(errp, "evdev property is required");
|
error_setg(errp, "evdev property is required");
|
||||||
@@ -125,6 +151,23 @@ static void virtio_input_host_realize(DeviceState *dev, Error **errp)
|
|||||||
virtio_input_bits_config(vih, EV_ABS, ABS_CNT);
|
virtio_input_bits_config(vih, EV_ABS, ABS_CNT);
|
||||||
virtio_input_bits_config(vih, EV_MSC, MSC_CNT);
|
virtio_input_bits_config(vih, EV_MSC, MSC_CNT);
|
||||||
virtio_input_bits_config(vih, EV_SW, SW_CNT);
|
virtio_input_bits_config(vih, EV_SW, SW_CNT);
|
||||||
|
virtio_input_bits_config(vih, EV_LED, LED_CNT);
|
||||||
|
|
||||||
|
abs = virtio_input_find_config(VIRTIO_INPUT(vih),
|
||||||
|
VIRTIO_INPUT_CFG_EV_BITS, EV_ABS);
|
||||||
|
if (abs) {
|
||||||
|
for (i = 0; i < abs->size; i++) {
|
||||||
|
byte = abs->u.bitmap[i];
|
||||||
|
axis = 8 * i;
|
||||||
|
while (byte) {
|
||||||
|
if (byte & 1) {
|
||||||
|
virtio_input_abs_config(vih, axis);
|
||||||
|
}
|
||||||
|
axis++;
|
||||||
|
byte >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih);
|
qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih);
|
||||||
return;
|
return;
|
||||||
@@ -145,6 +188,28 @@ static void virtio_input_host_unrealize(DeviceState *dev, Error **errp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_input_host_handle_status(VirtIOInput *vinput,
|
||||||
|
virtio_input_event *event)
|
||||||
|
{
|
||||||
|
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(vinput);
|
||||||
|
struct input_event evdev;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (gettimeofday(&evdev.time, NULL)) {
|
||||||
|
perror("virtio_input_host_handle_status: gettimeofday");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
evdev.type = le16_to_cpu(event->type);
|
||||||
|
evdev.code = le16_to_cpu(event->code);
|
||||||
|
evdev.value = le32_to_cpu(event->value);
|
||||||
|
|
||||||
|
rc = write(vih->fd, &evdev, sizeof(evdev));
|
||||||
|
if (rc == -1) {
|
||||||
|
perror("virtio_input_host_handle_status: write");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_virtio_input_host = {
|
static const VMStateDescription vmstate_virtio_input_host = {
|
||||||
.name = "virtio-input-host",
|
.name = "virtio-input-host",
|
||||||
.unmigratable = 1,
|
.unmigratable = 1,
|
||||||
@@ -164,6 +229,7 @@ static void virtio_input_host_class_init(ObjectClass *klass, void *data)
|
|||||||
dc->props = virtio_input_host_properties;
|
dc->props = virtio_input_host_properties;
|
||||||
vic->realize = virtio_input_host_realize;
|
vic->realize = virtio_input_host_realize;
|
||||||
vic->unrealize = virtio_input_host_unrealize;
|
vic->unrealize = virtio_input_host_unrealize;
|
||||||
|
vic->handle_status = virtio_input_host_handle_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_input_host_init(Object *obj)
|
static void virtio_input_host_init(Object *obj)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "standard-headers/linux/input.h"
|
#include "standard-headers/linux/input.h"
|
||||||
|
|
||||||
|
#define VIRTIO_INPUT_VM_VERSION 1
|
||||||
|
|
||||||
/* ----------------------------------------------------------------- */
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
|
void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
|
||||||
@@ -97,9 +99,9 @@ static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq)
|
|||||||
virtio_notify(vdev, vinput->sts);
|
virtio_notify(vdev, vinput->sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
|
virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
|
||||||
uint8_t select,
|
uint8_t select,
|
||||||
uint8_t subsel)
|
uint8_t subsel)
|
||||||
{
|
{
|
||||||
VirtIOInputConfig *cfg;
|
VirtIOInputConfig *cfg;
|
||||||
|
|
||||||
@@ -214,6 +216,38 @@ static void virtio_input_reset(VirtIODevice *vdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_input_save(QEMUFile *f, void *opaque)
|
||||||
|
{
|
||||||
|
VirtIOInput *vinput = opaque;
|
||||||
|
VirtIODevice *vdev = VIRTIO_DEVICE(vinput);
|
||||||
|
|
||||||
|
virtio_save(vdev, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virtio_input_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
|
{
|
||||||
|
VirtIOInput *vinput = opaque;
|
||||||
|
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vinput);
|
||||||
|
VirtIODevice *vdev = VIRTIO_DEVICE(vinput);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (version_id != VIRTIO_INPUT_VM_VERSION) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = virtio_load(vdev, f, version_id);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* post_load() */
|
||||||
|
vinput->active = vdev->status & VIRTIO_CONFIG_S_DRIVER_OK;
|
||||||
|
if (vic->change_active) {
|
||||||
|
vic->change_active(vinput);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_input_device_realize(DeviceState *dev, Error **errp)
|
static void virtio_input_device_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
|
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
|
||||||
@@ -245,14 +279,20 @@ static void virtio_input_device_realize(DeviceState *dev, Error **errp)
|
|||||||
vinput->cfg_size);
|
vinput->cfg_size);
|
||||||
vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt);
|
vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt);
|
||||||
vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts);
|
vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts);
|
||||||
|
|
||||||
|
register_savevm(dev, "virtio-input", -1, VIRTIO_INPUT_VM_VERSION,
|
||||||
|
virtio_input_save, virtio_input_load, vinput);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
|
static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
|
VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
|
||||||
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
|
||||||
|
VirtIOInput *vinput = VIRTIO_INPUT(dev);
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
unregister_savevm(dev, "virtio-input", vinput);
|
||||||
|
|
||||||
if (vic->unrealize) {
|
if (vic->unrealize) {
|
||||||
vic->unrealize(dev, &local_err);
|
vic->unrealize(dev, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
|
|||||||
@@ -66,18 +66,13 @@ static uint64_t itc_tag_read(void *opaque, hwaddr addr, unsigned size)
|
|||||||
{
|
{
|
||||||
MIPSITUState *tag = (MIPSITUState *)opaque;
|
MIPSITUState *tag = (MIPSITUState *)opaque;
|
||||||
uint64_t index = addr >> 3;
|
uint64_t index = addr >> 3;
|
||||||
uint64_t ret = 0;
|
|
||||||
|
|
||||||
switch (index) {
|
if (index >= ITC_ADDRESSMAP_NUM) {
|
||||||
case 0 ... ITC_ADDRESSMAP_NUM:
|
|
||||||
ret = tag->ITCAddressMap[index];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
qemu_log_mask(LOG_GUEST_ERROR, "Read 0x%" PRIx64 "\n", addr);
|
qemu_log_mask(LOG_GUEST_ERROR, "Read 0x%" PRIx64 "\n", addr);
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return tag->ITCAddressMap[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void itc_reconfigure(MIPSITUState *tag)
|
static void itc_reconfigure(MIPSITUState *tag)
|
||||||
|
|||||||
@@ -239,6 +239,7 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp)
|
|||||||
uint8_t *pci_conf;
|
uint8_t *pci_conf;
|
||||||
char *name;
|
char *name;
|
||||||
int r, i;
|
int r, i;
|
||||||
|
bool fastmmio = kvm_ioeventfd_any_length_enabled();
|
||||||
|
|
||||||
pci_conf = pci_dev->config;
|
pci_conf = pci_dev->config;
|
||||||
|
|
||||||
@@ -261,8 +262,12 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp)
|
|||||||
memcpy(test->hdr->name, name, strlen(name) + 1);
|
memcpy(test->hdr->name, name, strlen(name) + 1);
|
||||||
g_free(name);
|
g_free(name);
|
||||||
test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH);
|
test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH);
|
||||||
test->size = IOTEST_ACCESS_WIDTH;
|
|
||||||
test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd");
|
test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd");
|
||||||
|
if (fastmmio && IOTEST_IS_MEM(i) && !test->match_data) {
|
||||||
|
test->size = 0;
|
||||||
|
} else {
|
||||||
|
test->size = IOTEST_ACCESS_WIDTH;
|
||||||
|
}
|
||||||
test->hdr->test = i;
|
test->hdr->test = i;
|
||||||
test->hdr->data = test->match_data ? IOTEST_DATAMATCH : IOTEST_NOMATCH;
|
test->hdr->data = test->match_data ? IOTEST_DATAMATCH : IOTEST_NOMATCH;
|
||||||
test->hdr->width = IOTEST_ACCESS_WIDTH;
|
test->hdr->width = IOTEST_ACCESS_WIDTH;
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ static void mii_reset(Mii *s)
|
|||||||
{
|
{
|
||||||
memset(s->regs, 0, sizeof(s->regs));
|
memset(s->regs, 0, sizeof(s->regs));
|
||||||
s->regs[MII_BMCR] = 0x1000;
|
s->regs[MII_BMCR] = 0x1000;
|
||||||
s->regs[MII_BMSR] = 0x7848; /* no ext regs */
|
s->regs[MII_BMSR] = 0x7868; /* no ext regs */
|
||||||
s->regs[MII_PHYIDR1] = 0x2000;
|
s->regs[MII_PHYIDR1] = 0x2000;
|
||||||
s->regs[MII_PHYIDR2] = 0x5c90;
|
s->regs[MII_PHYIDR2] = 0x5c90;
|
||||||
s->regs[MII_ANAR] = 0x01e1;
|
s->regs[MII_ANAR] = 0x01e1;
|
||||||
|
|||||||
@@ -2046,7 +2046,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* transfer ownership to target */
|
/* transfer ownership to target */
|
||||||
txdw0 &= ~CP_RX_OWN;
|
txdw0 &= ~CP_TX_OWN;
|
||||||
|
|
||||||
/* reset error indicator bits */
|
/* reset error indicator bits */
|
||||||
txdw0 &= ~CP_TX_STATUS_UNF;
|
txdw0 &= ~CP_TX_STATUS_UNF;
|
||||||
|
|||||||
@@ -236,8 +236,18 @@ static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, si
|
|||||||
n = s->next_packet + s->np;
|
n = s->next_packet + s->np;
|
||||||
if (n >= 31)
|
if (n >= 31)
|
||||||
n -= 31;
|
n -= 31;
|
||||||
s->np++;
|
|
||||||
|
|
||||||
|
if (size >= sizeof(s->rx[n].data) - 6) {
|
||||||
|
/* If the packet won't fit into the
|
||||||
|
* emulated 2K RAM, this is reported
|
||||||
|
* as a FIFO overrun error.
|
||||||
|
*/
|
||||||
|
s->ris |= SE_INT_FOV;
|
||||||
|
stellaris_enet_update(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->np++;
|
||||||
s->rx[n].len = size + 6;
|
s->rx[n].len = size + 6;
|
||||||
p = s->rx[n].data;
|
p = s->rx[n].data;
|
||||||
*(p++) = (size + 6);
|
*(p++) = (size + 6);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "hw/isa/isa.h"
|
#include "hw/isa/isa.h"
|
||||||
#include "hw/nvram/fw_cfg.h"
|
#include "hw/nvram/fw_cfg.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
|
#include "hw/boards.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
@@ -69,11 +70,14 @@ struct FWCfgState {
|
|||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
|
||||||
FWCfgEntry entries[2][FW_CFG_MAX_ENTRY];
|
FWCfgEntry entries[2][FW_CFG_MAX_ENTRY];
|
||||||
|
int entry_order[FW_CFG_MAX_ENTRY];
|
||||||
FWCfgFiles *files;
|
FWCfgFiles *files;
|
||||||
uint16_t cur_entry;
|
uint16_t cur_entry;
|
||||||
uint32_t cur_offset;
|
uint32_t cur_offset;
|
||||||
Notifier machine_ready;
|
Notifier machine_ready;
|
||||||
|
|
||||||
|
int fw_cfg_order_override;
|
||||||
|
|
||||||
bool dma_enabled;
|
bool dma_enabled;
|
||||||
dma_addr_t dma_addr;
|
dma_addr_t dma_addr;
|
||||||
AddressSpace *dma_as;
|
AddressSpace *dma_as;
|
||||||
@@ -665,12 +669,87 @@ void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
|
|||||||
fw_cfg_add_bytes(s, key, copy, sizeof(value));
|
fw_cfg_add_bytes(s, key, copy, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fw_cfg_set_order_override(FWCfgState *s, int order)
|
||||||
|
{
|
||||||
|
assert(s->fw_cfg_order_override == 0);
|
||||||
|
s->fw_cfg_order_override = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fw_cfg_reset_order_override(FWCfgState *s)
|
||||||
|
{
|
||||||
|
assert(s->fw_cfg_order_override != 0);
|
||||||
|
s->fw_cfg_order_override = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the legacy order list. For legacy systems, files are in
|
||||||
|
* the fw_cfg in the order defined below, by the "order" value. Note
|
||||||
|
* that some entries (VGA ROMs, NIC option ROMS, etc.) go into a
|
||||||
|
* specific area, but there may be more than one and they occur in the
|
||||||
|
* order that the user specifies them on the command line. Those are
|
||||||
|
* handled in a special manner, using the order override above.
|
||||||
|
*
|
||||||
|
* For non-legacy, the files are sorted by filename to avoid this kind
|
||||||
|
* of complexity in the future.
|
||||||
|
*
|
||||||
|
* This is only for x86, other arches don't implement versioning so
|
||||||
|
* they won't set legacy mode.
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
int order;
|
||||||
|
} fw_cfg_order[] = {
|
||||||
|
{ "etc/boot-menu-wait", 10 },
|
||||||
|
{ "bootsplash.jpg", 11 },
|
||||||
|
{ "bootsplash.bmp", 12 },
|
||||||
|
{ "etc/boot-fail-wait", 15 },
|
||||||
|
{ "etc/smbios/smbios-tables", 20 },
|
||||||
|
{ "etc/smbios/smbios-anchor", 30 },
|
||||||
|
{ "etc/e820", 40 },
|
||||||
|
{ "etc/reserved-memory-end", 50 },
|
||||||
|
{ "genroms/kvmvapic.bin", 55 },
|
||||||
|
{ "genroms/linuxboot.bin", 60 },
|
||||||
|
{ }, /* VGA ROMs from pc_vga_init come here, 70. */
|
||||||
|
{ }, /* NIC option ROMs from pc_nic_init come here, 80. */
|
||||||
|
{ "etc/system-states", 90 },
|
||||||
|
{ }, /* User ROMs come here, 100. */
|
||||||
|
{ }, /* Device FW comes here, 110. */
|
||||||
|
{ "etc/extra-pci-roots", 120 },
|
||||||
|
{ "etc/acpi/tables", 130 },
|
||||||
|
{ "etc/table-loader", 140 },
|
||||||
|
{ "etc/tpm/log", 150 },
|
||||||
|
{ "etc/acpi/rsdp", 160 },
|
||||||
|
{ "bootorder", 170 },
|
||||||
|
|
||||||
|
#define FW_CFG_ORDER_OVERRIDE_LAST 200
|
||||||
|
};
|
||||||
|
|
||||||
|
static int get_fw_cfg_order(FWCfgState *s, const char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (s->fw_cfg_order_override > 0)
|
||||||
|
return s->fw_cfg_order_override;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(fw_cfg_order); i++) {
|
||||||
|
if (fw_cfg_order[i].name == NULL)
|
||||||
|
continue;
|
||||||
|
if (strcmp(name, fw_cfg_order[i].name) == 0)
|
||||||
|
return fw_cfg_order[i].order;
|
||||||
|
}
|
||||||
|
/* Stick unknown stuff at the end. */
|
||||||
|
error_report("warning: Unknown firmware file in legacy mode: %s\n", name);
|
||||||
|
return FW_CFG_ORDER_OVERRIDE_LAST;
|
||||||
|
}
|
||||||
|
|
||||||
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
||||||
FWCfgReadCallback callback, void *callback_opaque,
|
FWCfgReadCallback callback, void *callback_opaque,
|
||||||
void *data, size_t len)
|
void *data, size_t len)
|
||||||
{
|
{
|
||||||
int i, index;
|
int i, index, count;
|
||||||
size_t dsize;
|
size_t dsize;
|
||||||
|
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
|
||||||
|
int order = 0;
|
||||||
|
|
||||||
if (!s->files) {
|
if (!s->files) {
|
||||||
dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
|
dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
|
||||||
@@ -678,13 +757,48 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
|||||||
fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, s->files, dsize);
|
fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, s->files, dsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
index = be32_to_cpu(s->files->count);
|
count = be32_to_cpu(s->files->count);
|
||||||
assert(index < FW_CFG_FILE_SLOTS);
|
assert(count < FW_CFG_FILE_SLOTS);
|
||||||
|
|
||||||
pstrcpy(s->files->f[index].name, sizeof(s->files->f[index].name),
|
/* Find the insertion point. */
|
||||||
filename);
|
if (mc->legacy_fw_cfg_order) {
|
||||||
for (i = 0; i < index; i++) {
|
/*
|
||||||
if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
|
* Sort by order. For files with the same order, we keep them
|
||||||
|
* in the sequence in which they were added.
|
||||||
|
*/
|
||||||
|
order = get_fw_cfg_order(s, filename);
|
||||||
|
for (index = count;
|
||||||
|
index > 0 && order < s->entry_order[index - 1];
|
||||||
|
index--);
|
||||||
|
} else {
|
||||||
|
/* Sort by file name. */
|
||||||
|
for (index = count;
|
||||||
|
index > 0 && strcmp(filename, s->files->f[index - 1].name) < 0;
|
||||||
|
index--);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move all the entries from the index point and after down one
|
||||||
|
* to create a slot for the new entry. Because calculations are
|
||||||
|
* being done with the index, make it so that "i" is the current
|
||||||
|
* index and "i - 1" is the one being copied from, thus the
|
||||||
|
* unusual start and end in the for statement.
|
||||||
|
*/
|
||||||
|
for (i = count + 1; i > index; i--) {
|
||||||
|
s->files->f[i] = s->files->f[i - 1];
|
||||||
|
s->files->f[i].select = cpu_to_be16(FW_CFG_FILE_FIRST + i);
|
||||||
|
s->entries[0][FW_CFG_FILE_FIRST + i] =
|
||||||
|
s->entries[0][FW_CFG_FILE_FIRST + i - 1];
|
||||||
|
s->entry_order[i] = s->entry_order[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&s->files->f[index], 0, sizeof(FWCfgFile));
|
||||||
|
memset(&s->entries[0][FW_CFG_FILE_FIRST + index], 0, sizeof(FWCfgEntry));
|
||||||
|
|
||||||
|
pstrcpy(s->files->f[index].name, sizeof(s->files->f[index].name), filename);
|
||||||
|
for (i = 0; i <= count; i++) {
|
||||||
|
if (i != index &&
|
||||||
|
strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
|
||||||
error_report("duplicate fw_cfg file name: %s",
|
error_report("duplicate fw_cfg file name: %s",
|
||||||
s->files->f[index].name);
|
s->files->f[index].name);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -696,9 +810,10 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
|||||||
|
|
||||||
s->files->f[index].size = cpu_to_be32(len);
|
s->files->f[index].size = cpu_to_be32(len);
|
||||||
s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
|
s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index);
|
||||||
|
s->entry_order[index] = order;
|
||||||
trace_fw_cfg_add_file(s, index, s->files->f[index].name, len);
|
trace_fw_cfg_add_file(s, index, s->files->f[index].name, len);
|
||||||
|
|
||||||
s->files->count = cpu_to_be32(index+1);
|
s->files->count = cpu_to_be32(count+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fw_cfg_add_file(FWCfgState *s, const char *filename,
|
void fw_cfg_add_file(FWCfgState *s, const char *filename,
|
||||||
|
|||||||
@@ -78,6 +78,14 @@ err_bridge:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription i82801b11_bridge_dev_vmstate = {
|
||||||
|
.name = "i82801b11_bridge",
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
|
static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||||
@@ -89,6 +97,7 @@ static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
|
|||||||
k->revision = ICH9_D2P_A2_REVISION;
|
k->revision = ICH9_D2P_A2_REVISION;
|
||||||
k->init = i82801b11_bridge_initfn;
|
k->init = i82801b11_bridge_initfn;
|
||||||
k->config_write = pci_bridge_write_config;
|
k->config_write = pci_bridge_write_config;
|
||||||
|
dc->vmsd = &i82801b11_bridge_dev_vmstate;
|
||||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ static int pxb_dev_init_common(PCIDevice *dev, bool pcie)
|
|||||||
PCI_HOST_BRIDGE(ds)->bus = bus;
|
PCI_HOST_BRIDGE(ds)->bus = bus;
|
||||||
|
|
||||||
if (pxb_register_bus(dev, bus)) {
|
if (pxb_register_bus(dev, bus)) {
|
||||||
return -EINVAL;
|
goto err_register_bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdev_init_nofail(ds);
|
qdev_init_nofail(ds);
|
||||||
@@ -263,6 +263,12 @@ static int pxb_dev_init_common(PCIDevice *dev, bool pcie)
|
|||||||
|
|
||||||
pxb_dev_list = g_list_insert_sorted(pxb_dev_list, pxb, pxb_compare);
|
pxb_dev_list = g_list_insert_sorted(pxb_dev_list, pxb, pxb_compare);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_register_bus:
|
||||||
|
object_unref(OBJECT(bds));
|
||||||
|
object_unparent(OBJECT(bus));
|
||||||
|
object_unref(OBJECT(ds));
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pxb_dev_initfn(PCIDevice *dev)
|
static int pxb_dev_initfn(PCIDevice *dev)
|
||||||
|
|||||||
@@ -2208,6 +2208,10 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
|
|||||||
if (*errp) {
|
if (*errp) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (node < 0 || node >= MAX_NODES) {
|
||||||
|
error_setg(errp, "Invaild node %d", node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently PowerPC kernel doesn't allow hot-adding memory to
|
* Currently PowerPC kernel doesn't allow hot-adding memory to
|
||||||
|
|||||||
@@ -176,6 +176,12 @@ static void set_configured(sPAPRDRConnector *drc)
|
|||||||
drc->configured = true;
|
drc->configured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* has the guest been notified of device attachment? */
|
||||||
|
static void set_signalled(sPAPRDRConnector *drc)
|
||||||
|
{
|
||||||
|
drc->signalled = true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dr-entity-sense sensor value
|
* dr-entity-sense sensor value
|
||||||
* returned via get-sensor-state RTAS calls
|
* returned via get-sensor-state RTAS calls
|
||||||
@@ -358,6 +364,7 @@ static void attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
|||||||
drc->fdt = fdt;
|
drc->fdt = fdt;
|
||||||
drc->fdt_start_offset = fdt_start_offset;
|
drc->fdt_start_offset = fdt_start_offset;
|
||||||
drc->configured = coldplug;
|
drc->configured = coldplug;
|
||||||
|
drc->signalled = coldplug;
|
||||||
|
|
||||||
object_property_add_link(OBJECT(drc), "device",
|
object_property_add_link(OBJECT(drc), "device",
|
||||||
object_get_typename(OBJECT(drc->dev)),
|
object_get_typename(OBJECT(drc->dev)),
|
||||||
@@ -374,6 +381,26 @@ static void detach(sPAPRDRConnector *drc, DeviceState *d,
|
|||||||
drc->detach_cb = detach_cb;
|
drc->detach_cb = detach_cb;
|
||||||
drc->detach_cb_opaque = detach_cb_opaque;
|
drc->detach_cb_opaque = detach_cb_opaque;
|
||||||
|
|
||||||
|
/* if we've signalled device presence to the guest, or if the guest
|
||||||
|
* has gone ahead and configured the device (via manually-executed
|
||||||
|
* device add via drmgr in guest, namely), we need to wait
|
||||||
|
* for the guest to quiesce the device before completing detach.
|
||||||
|
* Otherwise, we can assume the guest hasn't seen it and complete the
|
||||||
|
* detach immediately. Note that there is a small race window
|
||||||
|
* just before, or during, configuration, which is this context
|
||||||
|
* refers mainly to fetching the device tree via RTAS.
|
||||||
|
* During this window the device access will be arbitrated by
|
||||||
|
* associated DRC, which will simply fail the RTAS calls as invalid.
|
||||||
|
* This is recoverable within guest and current implementations of
|
||||||
|
* drmgr should be able to cope.
|
||||||
|
*/
|
||||||
|
if (!drc->signalled && !drc->configured) {
|
||||||
|
/* if the guest hasn't seen the device we can't rely on it to
|
||||||
|
* set it back to an isolated state via RTAS, so do it here manually
|
||||||
|
*/
|
||||||
|
drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
|
||||||
|
}
|
||||||
|
|
||||||
if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
|
if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
|
||||||
DPRINTFN("awaiting transition to isolated state before removal");
|
DPRINTFN("awaiting transition to isolated state before removal");
|
||||||
drc->awaiting_release = true;
|
drc->awaiting_release = true;
|
||||||
@@ -412,6 +439,7 @@ static void reset(DeviceState *d)
|
|||||||
{
|
{
|
||||||
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
|
sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
|
||||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||||
|
sPAPRDREntitySense state;
|
||||||
|
|
||||||
DPRINTFN("drc reset: %x", drck->get_index(drc));
|
DPRINTFN("drc reset: %x", drck->get_index(drc));
|
||||||
/* immediately upon reset we can safely assume DRCs whose devices
|
/* immediately upon reset we can safely assume DRCs whose devices
|
||||||
@@ -439,6 +467,11 @@ static void reset(DeviceState *d)
|
|||||||
drck->set_allocation_state(drc, SPAPR_DR_ALLOCATION_STATE_UNUSABLE);
|
drck->set_allocation_state(drc, SPAPR_DR_ALLOCATION_STATE_UNUSABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drck->entity_sense(drc, &state);
|
||||||
|
if (state == SPAPR_DR_ENTITY_SENSE_PRESENT) {
|
||||||
|
drck->set_signalled(drc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void realize(DeviceState *d, Error **errp)
|
static void realize(DeviceState *d, Error **errp)
|
||||||
@@ -597,6 +630,7 @@ static void spapr_dr_connector_class_init(ObjectClass *k, void *data)
|
|||||||
drck->attach = attach;
|
drck->attach = attach;
|
||||||
drck->detach = detach;
|
drck->detach = detach;
|
||||||
drck->release_pending = release_pending;
|
drck->release_pending = release_pending;
|
||||||
|
drck->set_signalled = set_signalled;
|
||||||
/*
|
/*
|
||||||
* Reason: it crashes FIXME find and document the real reason
|
* Reason: it crashes FIXME find and document the real reason
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -389,6 +389,13 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
|
|||||||
qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
|
qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void spapr_hotplug_set_signalled(uint32_t drc_index)
|
||||||
|
{
|
||||||
|
sPAPRDRConnector *drc = spapr_dr_connector_by_index(drc_index);
|
||||||
|
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||||
|
drck->set_signalled(drc);
|
||||||
|
}
|
||||||
|
|
||||||
static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
|
static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
|
||||||
sPAPRDRConnectorType drc_type,
|
sPAPRDRConnectorType drc_type,
|
||||||
uint32_t drc)
|
uint32_t drc)
|
||||||
@@ -455,6 +462,10 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action,
|
|||||||
|
|
||||||
rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true);
|
rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true);
|
||||||
|
|
||||||
|
if (hp->hotplug_action == RTAS_LOG_V6_HP_ACTION_ADD) {
|
||||||
|
spapr_hotplug_set_signalled(drc);
|
||||||
|
}
|
||||||
|
|
||||||
qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
|
qemu_irq_pulse(xics_get_qirq(spapr->icp, spapr->check_exception_irq));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -824,7 +824,6 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu,
|
|||||||
{
|
{
|
||||||
CPUState *cs;
|
CPUState *cs;
|
||||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||||
target_ulong prefix;
|
|
||||||
|
|
||||||
if (!(pcc->insns_flags2 & PPC2_ISA207S)) {
|
if (!(pcc->insns_flags2 & PPC2_ISA207S)) {
|
||||||
return H_P2;
|
return H_P2;
|
||||||
@@ -836,25 +835,12 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu,
|
|||||||
return H_P4;
|
return H_P4;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mflags) {
|
if (mflags == AIL_RESERVED) {
|
||||||
case H_SET_MODE_ADDR_TRANS_NONE:
|
|
||||||
prefix = 0;
|
|
||||||
break;
|
|
||||||
case H_SET_MODE_ADDR_TRANS_0001_8000:
|
|
||||||
prefix = 0x18000;
|
|
||||||
break;
|
|
||||||
case H_SET_MODE_ADDR_TRANS_C000_0000_0000_4000:
|
|
||||||
prefix = 0xC000000000004000ULL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return H_UNSUPPORTED_FLAG;
|
return H_UNSUPPORTED_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPU_FOREACH(cs) {
|
CPU_FOREACH(cs) {
|
||||||
CPUPPCState *env = &POWERPC_CPU(cpu)->env;
|
|
||||||
|
|
||||||
set_spr(cs, SPR_LPCR, mflags << LPCR_AIL_SHIFT, LPCR_AIL);
|
set_spr(cs, SPR_LPCR, mflags << LPCR_AIL_SHIFT, LPCR_AIL);
|
||||||
env->excp_prefix = prefix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return H_SUCCESS;
|
return H_SUCCESS;
|
||||||
|
|||||||
@@ -684,6 +684,9 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
|
|||||||
int i;
|
int i;
|
||||||
uint32_t lrdr_capacity[5];
|
uint32_t lrdr_capacity[5];
|
||||||
MachineState *machine = MACHINE(qdev_get_machine());
|
MachineState *machine = MACHINE(qdev_get_machine());
|
||||||
|
sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
|
||||||
|
uint64_t max_hotplug_addr = spapr->hotplug_memory.base +
|
||||||
|
memory_region_size(&spapr->hotplug_memory.mr);
|
||||||
|
|
||||||
ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
|
ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -733,8 +736,8 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lrdr_capacity[0] = cpu_to_be32(((uint64_t)machine->maxram_size) >> 32);
|
lrdr_capacity[0] = cpu_to_be32(max_hotplug_addr >> 32);
|
||||||
lrdr_capacity[1] = cpu_to_be32(machine->maxram_size & 0xffffffff);
|
lrdr_capacity[1] = cpu_to_be32(max_hotplug_addr & 0xffffffff);
|
||||||
lrdr_capacity[2] = 0;
|
lrdr_capacity[2] = 0;
|
||||||
lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
|
lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE);
|
||||||
lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
|
lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads);
|
||||||
|
|||||||
@@ -38,7 +38,35 @@ void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n)
|
static void virtio_scsi_data_plane_handle_cmd(VirtIODevice *vdev,
|
||||||
|
VirtQueue *vq)
|
||||||
|
{
|
||||||
|
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||||
|
|
||||||
|
assert(s->ctx && s->dataplane_started);
|
||||||
|
virtio_scsi_handle_cmd_vq(s, vq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_scsi_data_plane_handle_ctrl(VirtIODevice *vdev,
|
||||||
|
VirtQueue *vq)
|
||||||
|
{
|
||||||
|
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||||
|
|
||||||
|
assert(s->ctx && s->dataplane_started);
|
||||||
|
virtio_scsi_handle_ctrl_vq(s, vq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_scsi_data_plane_handle_event(VirtIODevice *vdev,
|
||||||
|
VirtQueue *vq)
|
||||||
|
{
|
||||||
|
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||||
|
|
||||||
|
assert(s->ctx && s->dataplane_started);
|
||||||
|
virtio_scsi_handle_event_vq(s, vq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n,
|
||||||
|
void (*fn)(VirtIODevice *vdev, VirtQueue *vq))
|
||||||
{
|
{
|
||||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
|
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
|
||||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||||
@@ -53,7 +81,7 @@ static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtio_queue_aio_set_host_notifier_handler(vq, s->ctx, true, true);
|
virtio_queue_aio_set_host_notifier_handler(vq, s->ctx, fn);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,10 +98,10 @@ static void virtio_scsi_clear_aio(VirtIOSCSI *s)
|
|||||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
|
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
virtio_queue_aio_set_host_notifier_handler(vs->ctrl_vq, s->ctx, false, false);
|
virtio_queue_aio_set_host_notifier_handler(vs->ctrl_vq, s->ctx, NULL);
|
||||||
virtio_queue_aio_set_host_notifier_handler(vs->event_vq, s->ctx, false, false);
|
virtio_queue_aio_set_host_notifier_handler(vs->event_vq, s->ctx, NULL);
|
||||||
for (i = 0; i < vs->conf.num_queues; i++) {
|
for (i = 0; i < vs->conf.num_queues; i++) {
|
||||||
virtio_queue_aio_set_host_notifier_handler(vs->cmd_vqs[i], s->ctx, false, false);
|
virtio_queue_aio_set_host_notifier_handler(vs->cmd_vqs[i], s->ctx, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,16 +132,19 @@ void virtio_scsi_dataplane_start(VirtIOSCSI *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
aio_context_acquire(s->ctx);
|
aio_context_acquire(s->ctx);
|
||||||
rc = virtio_scsi_vring_init(s, vs->ctrl_vq, 0);
|
rc = virtio_scsi_vring_init(s, vs->ctrl_vq, 0,
|
||||||
|
virtio_scsi_data_plane_handle_ctrl);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
goto fail_vrings;
|
goto fail_vrings;
|
||||||
}
|
}
|
||||||
rc = virtio_scsi_vring_init(s, vs->event_vq, 1);
|
rc = virtio_scsi_vring_init(s, vs->event_vq, 1,
|
||||||
|
virtio_scsi_data_plane_handle_event);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
goto fail_vrings;
|
goto fail_vrings;
|
||||||
}
|
}
|
||||||
for (i = 0; i < vs->conf.num_queues; i++) {
|
for (i = 0; i < vs->conf.num_queues; i++) {
|
||||||
rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2);
|
rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2,
|
||||||
|
virtio_scsi_data_plane_handle_cmd);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
goto fail_vrings;
|
goto fail_vrings;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
|
|||||||
|
|
||||||
qemu_iovec_from_buf(&req->resp_iov, 0, &req->resp, req->resp_size);
|
qemu_iovec_from_buf(&req->resp_iov, 0, &req->resp, req->resp_size);
|
||||||
virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size);
|
virtqueue_push(vq, &req->elem, req->qsgl.size + req->resp_iov.size);
|
||||||
if (s->dataplane_started) {
|
if (s->dataplane_started && !s->dataplane_fenced) {
|
||||||
virtio_scsi_dataplane_notify(vdev, req);
|
virtio_scsi_dataplane_notify(vdev, req);
|
||||||
} else {
|
} else {
|
||||||
virtio_notify(vdev, vq);
|
virtio_notify(vdev, vq);
|
||||||
@@ -374,7 +374,7 @@ fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||||
{
|
{
|
||||||
VirtIODevice *vdev = (VirtIODevice *)s;
|
VirtIODevice *vdev = (VirtIODevice *)s;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
@@ -412,20 +412,28 @@ void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||||
{
|
{
|
||||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
|
||||||
VirtIOSCSIReq *req;
|
VirtIOSCSIReq *req;
|
||||||
|
|
||||||
if (s->ctx && !s->dataplane_started) {
|
|
||||||
virtio_scsi_dataplane_start(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while ((req = virtio_scsi_pop_req(s, vq))) {
|
while ((req = virtio_scsi_pop_req(s, vq))) {
|
||||||
virtio_scsi_handle_ctrl_req(s, req);
|
virtio_scsi_handle_ctrl_req(s, req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||||
|
{
|
||||||
|
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||||
|
|
||||||
|
if (s->ctx) {
|
||||||
|
virtio_scsi_dataplane_start(s);
|
||||||
|
if (!s->dataplane_fenced) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtio_scsi_handle_ctrl_vq(s, vq);
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req)
|
static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req)
|
||||||
{
|
{
|
||||||
/* Sense data is not in req->resp and is copied separately
|
/* Sense data is not in req->resp and is copied separately
|
||||||
@@ -508,7 +516,7 @@ static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
|
|||||||
virtio_scsi_complete_cmd_req(req);
|
virtio_scsi_complete_cmd_req(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
static bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||||
{
|
{
|
||||||
VirtIOSCSICommon *vs = &s->parent_obj;
|
VirtIOSCSICommon *vs = &s->parent_obj;
|
||||||
SCSIDevice *d;
|
SCSIDevice *d;
|
||||||
@@ -550,7 +558,7 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
static void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||||
{
|
{
|
||||||
SCSIRequest *sreq = req->sreq;
|
SCSIRequest *sreq = req->sreq;
|
||||||
if (scsi_req_enqueue(sreq)) {
|
if (scsi_req_enqueue(sreq)) {
|
||||||
@@ -560,17 +568,11 @@ void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
|||||||
scsi_req_unref(sreq);
|
scsi_req_unref(sreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||||
{
|
{
|
||||||
/* use non-QOM casts in the data path */
|
|
||||||
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
|
||||||
VirtIOSCSIReq *req, *next;
|
VirtIOSCSIReq *req, *next;
|
||||||
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
|
QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
|
||||||
|
|
||||||
if (s->ctx && !s->dataplane_started) {
|
|
||||||
virtio_scsi_dataplane_start(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while ((req = virtio_scsi_pop_req(s, vq))) {
|
while ((req = virtio_scsi_pop_req(s, vq))) {
|
||||||
if (virtio_scsi_handle_cmd_req_prepare(s, req)) {
|
if (virtio_scsi_handle_cmd_req_prepare(s, req)) {
|
||||||
QTAILQ_INSERT_TAIL(&reqs, req, next);
|
QTAILQ_INSERT_TAIL(&reqs, req, next);
|
||||||
@@ -582,6 +584,20 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
|
||||||
|
{
|
||||||
|
/* use non-QOM casts in the data path */
|
||||||
|
VirtIOSCSI *s = (VirtIOSCSI *)vdev;
|
||||||
|
|
||||||
|
if (s->ctx) {
|
||||||
|
virtio_scsi_dataplane_start(s);
|
||||||
|
if (!s->dataplane_fenced) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtio_scsi_handle_cmd_vq(s, vq);
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_scsi_get_config(VirtIODevice *vdev,
|
static void virtio_scsi_get_config(VirtIODevice *vdev,
|
||||||
uint8_t *config)
|
uint8_t *config)
|
||||||
{
|
{
|
||||||
@@ -725,17 +741,24 @@ out:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq)
|
||||||
|
{
|
||||||
|
if (s->events_dropped) {
|
||||||
|
virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
|
static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
|
||||||
{
|
{
|
||||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||||
|
|
||||||
if (s->ctx && !s->dataplane_started) {
|
if (s->ctx) {
|
||||||
virtio_scsi_dataplane_start(s);
|
virtio_scsi_dataplane_start(s);
|
||||||
return;
|
if (!s->dataplane_fenced) {
|
||||||
}
|
return;
|
||||||
if (s->events_dropped) {
|
}
|
||||||
virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
|
|
||||||
}
|
}
|
||||||
|
virtio_scsi_handle_event_vq(s, vq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
|
static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
|
||||||
@@ -773,7 +796,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||||||
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
|
||||||
SCSIDevice *sd = SCSI_DEVICE(dev);
|
SCSIDevice *sd = SCSI_DEVICE(dev);
|
||||||
|
|
||||||
if (s->ctx && !s->dataplane_disabled) {
|
if (s->ctx && !s->dataplane_fenced) {
|
||||||
VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier;
|
VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier;
|
||||||
|
|
||||||
if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
|
if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) {
|
||||||
|
|||||||
@@ -201,12 +201,7 @@ static void update_irq(struct HPETTimer *timer, int set)
|
|||||||
if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
|
if (!set || !timer_enabled(timer) || !hpet_enabled(timer->state)) {
|
||||||
s->isr &= ~mask;
|
s->isr &= ~mask;
|
||||||
if (!timer_fsb_route(timer)) {
|
if (!timer_fsb_route(timer)) {
|
||||||
/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
|
qemu_irq_lower(s->irqs[route]);
|
||||||
if (route >= ISA_NUM_IRQS) {
|
|
||||||
qemu_irq_raise(s->irqs[route]);
|
|
||||||
} else {
|
|
||||||
qemu_irq_lower(s->irqs[route]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (timer_fsb_route(timer)) {
|
} else if (timer_fsb_route(timer)) {
|
||||||
address_space_stl_le(&address_space_memory, timer->fsb >> 32,
|
address_space_stl_le(&address_space_memory, timer->fsb >> 32,
|
||||||
@@ -214,12 +209,7 @@ static void update_irq(struct HPETTimer *timer, int set)
|
|||||||
NULL);
|
NULL);
|
||||||
} else if (timer->config & HPET_TN_TYPE_LEVEL) {
|
} else if (timer->config & HPET_TN_TYPE_LEVEL) {
|
||||||
s->isr |= mask;
|
s->isr |= mask;
|
||||||
/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
|
qemu_irq_raise(s->irqs[route]);
|
||||||
if (route >= ISA_NUM_IRQS) {
|
|
||||||
qemu_irq_lower(s->irqs[route]);
|
|
||||||
} else {
|
|
||||||
qemu_irq_raise(s->irqs[route]);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
s->isr &= ~mask;
|
s->isr &= ~mask;
|
||||||
qemu_irq_pulse(s->irqs[route]);
|
qemu_irq_pulse(s->irqs[route]);
|
||||||
|
|||||||
@@ -426,6 +426,10 @@ static int virtio_balloon_load_device(VirtIODevice *vdev, QEMUFile *f,
|
|||||||
|
|
||||||
s->num_pages = qemu_get_be32(f);
|
s->num_pages = qemu_get_be32(f);
|
||||||
s->actual = qemu_get_be32(f);
|
s->actual = qemu_get_be32(f);
|
||||||
|
|
||||||
|
if (balloon_stats_enabled(s)) {
|
||||||
|
balloon_stats_change_timer(s, s->stats_poll_interval);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ struct VirtQueue
|
|||||||
|
|
||||||
uint16_t vector;
|
uint16_t vector;
|
||||||
void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
|
void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
|
||||||
|
void (*handle_aio_output)(VirtIODevice *vdev, VirtQueue *vq);
|
||||||
VirtIODevice *vdev;
|
VirtIODevice *vdev;
|
||||||
EventNotifier guest_notifier;
|
EventNotifier guest_notifier;
|
||||||
EventNotifier host_notifier;
|
EventNotifier host_notifier;
|
||||||
@@ -1088,7 +1089,17 @@ void virtio_queue_set_align(VirtIODevice *vdev, int n, int align)
|
|||||||
virtio_queue_update_rings(vdev, n);
|
virtio_queue_update_rings(vdev, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_queue_notify_vq(VirtQueue *vq)
|
static void virtio_queue_notify_aio_vq(VirtQueue *vq)
|
||||||
|
{
|
||||||
|
if (vq->vring.desc && vq->handle_aio_output) {
|
||||||
|
VirtIODevice *vdev = vq->vdev;
|
||||||
|
|
||||||
|
trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
|
||||||
|
vq->handle_aio_output(vdev, vq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_queue_notify_vq(VirtQueue *vq)
|
||||||
{
|
{
|
||||||
if (vq->vring.desc && vq->handle_output) {
|
if (vq->vring.desc && vq->handle_output) {
|
||||||
VirtIODevice *vdev = vq->vdev;
|
VirtIODevice *vdev = vq->vdev;
|
||||||
@@ -1143,6 +1154,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
|
|||||||
vdev->vq[i].vring.num_default = queue_size;
|
vdev->vq[i].vring.num_default = queue_size;
|
||||||
vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
|
vdev->vq[i].vring.align = VIRTIO_PCI_VRING_ALIGN;
|
||||||
vdev->vq[i].handle_output = handle_output;
|
vdev->vq[i].handle_output = handle_output;
|
||||||
|
vdev->vq[i].handle_aio_output = NULL;
|
||||||
|
|
||||||
return &vdev->vq[i];
|
return &vdev->vq[i];
|
||||||
}
|
}
|
||||||
@@ -1780,6 +1792,31 @@ EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
|
|||||||
return &vq->guest_notifier;
|
return &vq->guest_notifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_queue_host_notifier_aio_read(EventNotifier *n)
|
||||||
|
{
|
||||||
|
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
|
||||||
|
if (event_notifier_test_and_clear(n)) {
|
||||||
|
virtio_queue_notify_aio_vq(vq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
||||||
|
void (*handle_output)(VirtIODevice *,
|
||||||
|
VirtQueue *))
|
||||||
|
{
|
||||||
|
if (handle_output) {
|
||||||
|
vq->handle_aio_output = handle_output;
|
||||||
|
aio_set_event_notifier(ctx, &vq->host_notifier, true,
|
||||||
|
virtio_queue_host_notifier_aio_read);
|
||||||
|
} else {
|
||||||
|
aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL);
|
||||||
|
/* Test and clear notifier before after disabling event,
|
||||||
|
* in case poll callback didn't have time to run. */
|
||||||
|
virtio_queue_host_notifier_aio_read(&vq->host_notifier);
|
||||||
|
vq->handle_aio_output = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_queue_host_notifier_read(EventNotifier *n)
|
static void virtio_queue_host_notifier_read(EventNotifier *n)
|
||||||
{
|
{
|
||||||
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
|
VirtQueue *vq = container_of(n, VirtQueue, host_notifier);
|
||||||
@@ -1788,22 +1825,6 @@ static void virtio_queue_host_notifier_read(EventNotifier *n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
|
||||||
bool assign, bool set_handler)
|
|
||||||
{
|
|
||||||
if (assign && set_handler) {
|
|
||||||
aio_set_event_notifier(ctx, &vq->host_notifier, true,
|
|
||||||
virtio_queue_host_notifier_read);
|
|
||||||
} else {
|
|
||||||
aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL);
|
|
||||||
}
|
|
||||||
if (!assign) {
|
|
||||||
/* Test and clear notifier before after disabling event,
|
|
||||||
* in case poll callback didn't have time to run. */
|
|
||||||
virtio_queue_host_notifier_read(&vq->host_notifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
|
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
|
||||||
bool set_handler)
|
bool set_handler)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -372,6 +372,7 @@ int bdrv_flush(BlockDriverState *bs);
|
|||||||
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
|
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
|
||||||
void bdrv_close_all(void);
|
void bdrv_close_all(void);
|
||||||
void bdrv_drain(BlockDriverState *bs);
|
void bdrv_drain(BlockDriverState *bs);
|
||||||
|
void coroutine_fn bdrv_co_drain(BlockDriverState *bs);
|
||||||
void bdrv_drain_all(void);
|
void bdrv_drain_all(void);
|
||||||
|
|
||||||
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
|
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
|
||||||
|
|||||||
@@ -369,6 +369,7 @@ build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
|
|||||||
const char *oem_id, const char *oem_table_id);
|
const char *oem_id, const char *oem_table_id);
|
||||||
|
|
||||||
int
|
int
|
||||||
build_append_named_dword(GArray *array, const char *name_format, ...);
|
build_append_named_dword(GArray *array, const char *name_format, ...)
|
||||||
|
GCC_FMT_ATTR(2, 3);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -108,7 +108,8 @@ struct MachineClass {
|
|||||||
no_cdrom:1,
|
no_cdrom:1,
|
||||||
no_sdcard:1,
|
no_sdcard:1,
|
||||||
has_dynamic_sysbus:1,
|
has_dynamic_sysbus:1,
|
||||||
pci_allow_0_address:1;
|
pci_allow_0_address:1,
|
||||||
|
legacy_fw_cfg_order:1;
|
||||||
int is_default;
|
int is_default;
|
||||||
const char *default_machine_opts;
|
const char *default_machine_opts;
|
||||||
const char *default_boot_order;
|
const char *default_boot_order;
|
||||||
|
|||||||
@@ -128,6 +128,8 @@ int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
|||||||
size_t romsize, hwaddr addr);
|
size_t romsize, hwaddr addr);
|
||||||
int rom_check_and_register_reset(void);
|
int rom_check_and_register_reset(void);
|
||||||
void rom_set_fw(FWCfgState *f);
|
void rom_set_fw(FWCfgState *f);
|
||||||
|
void rom_set_order_override(int order);
|
||||||
|
void rom_reset_order_override(void);
|
||||||
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
|
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
|
||||||
void *rom_ptr(hwaddr addr);
|
void *rom_ptr(hwaddr addr);
|
||||||
void hmp_info_roms(Monitor *mon, const QDict *qdict);
|
void hmp_info_roms(Monitor *mon, const QDict *qdict);
|
||||||
|
|||||||
@@ -11,6 +11,14 @@ typedef struct FWCfgFile {
|
|||||||
char name[FW_CFG_MAX_FILE_PATH];
|
char name[FW_CFG_MAX_FILE_PATH];
|
||||||
} FWCfgFile;
|
} FWCfgFile;
|
||||||
|
|
||||||
|
#define FW_CFG_ORDER_OVERRIDE_VGA 70
|
||||||
|
#define FW_CFG_ORDER_OVERRIDE_NIC 80
|
||||||
|
#define FW_CFG_ORDER_OVERRIDE_USER 100
|
||||||
|
#define FW_CFG_ORDER_OVERRIDE_DEVICE 110
|
||||||
|
|
||||||
|
void fw_cfg_set_order_override(FWCfgState *fw_cfg, int order);
|
||||||
|
void fw_cfg_reset_order_override(FWCfgState *fw_cfg);
|
||||||
|
|
||||||
typedef struct FWCfgFiles {
|
typedef struct FWCfgFiles {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
FWCfgFile f[];
|
FWCfgFile f[];
|
||||||
|
|||||||
@@ -204,11 +204,6 @@ struct sPAPRMachineState {
|
|||||||
#define H_SET_MODE_ENDIAN_BIG 0
|
#define H_SET_MODE_ENDIAN_BIG 0
|
||||||
#define H_SET_MODE_ENDIAN_LITTLE 1
|
#define H_SET_MODE_ENDIAN_LITTLE 1
|
||||||
|
|
||||||
/* Flags for H_SET_MODE_RESOURCE_ADDR_TRANS_MODE */
|
|
||||||
#define H_SET_MODE_ADDR_TRANS_NONE 0
|
|
||||||
#define H_SET_MODE_ADDR_TRANS_0001_8000 2
|
|
||||||
#define H_SET_MODE_ADDR_TRANS_C000_0000_0000_4000 3
|
|
||||||
|
|
||||||
/* VASI States */
|
/* VASI States */
|
||||||
#define H_VASI_INVALID 0
|
#define H_VASI_INVALID 0
|
||||||
#define H_VASI_ENABLED 1
|
#define H_VASI_ENABLED 1
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ typedef struct sPAPRDRConnector {
|
|||||||
bool configured;
|
bool configured;
|
||||||
|
|
||||||
bool awaiting_release;
|
bool awaiting_release;
|
||||||
|
bool signalled;
|
||||||
|
|
||||||
/* device pointer, via link property */
|
/* device pointer, via link property */
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
@@ -188,6 +189,7 @@ typedef struct sPAPRDRConnectorClass {
|
|||||||
spapr_drc_detach_cb *detach_cb,
|
spapr_drc_detach_cb *detach_cb,
|
||||||
void *detach_cb_opaque, Error **errp);
|
void *detach_cb_opaque, Error **errp);
|
||||||
bool (*release_pending)(sPAPRDRConnector *drc);
|
bool (*release_pending)(sPAPRDRConnector *drc);
|
||||||
|
void (*set_signalled)(sPAPRDRConnector *drc);
|
||||||
} sPAPRDRConnectorClass;
|
} sPAPRDRConnectorClass;
|
||||||
|
|
||||||
sPAPRDRConnector *spapr_dr_connector_new(Object *owner,
|
sPAPRDRConnector *spapr_dr_connector_new(Object *owner,
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ typedef struct VirtIOBlock {
|
|||||||
unsigned short sector_mask;
|
unsigned short sector_mask;
|
||||||
bool original_wce;
|
bool original_wce;
|
||||||
VMChangeStateEntry *change;
|
VMChangeStateEntry *change;
|
||||||
|
bool dataplane_disabled;
|
||||||
bool dataplane_started;
|
bool dataplane_started;
|
||||||
struct VirtIOBlockDataPlane *dataplane;
|
struct VirtIOBlockDataPlane *dataplane;
|
||||||
} VirtIOBlock;
|
} VirtIOBlock;
|
||||||
@@ -85,4 +86,6 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb);
|
|||||||
|
|
||||||
void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb);
|
void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb);
|
||||||
|
|
||||||
|
void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,20 +13,6 @@ typedef struct virtio_input_absinfo virtio_input_absinfo;
|
|||||||
typedef struct virtio_input_config virtio_input_config;
|
typedef struct virtio_input_config virtio_input_config;
|
||||||
typedef struct virtio_input_event virtio_input_event;
|
typedef struct virtio_input_event virtio_input_event;
|
||||||
|
|
||||||
#if defined(HOST_WORDS_BIGENDIAN)
|
|
||||||
# define const_le32(_x) \
|
|
||||||
(((_x & 0x000000ffU) << 24) | \
|
|
||||||
((_x & 0x0000ff00U) << 8) | \
|
|
||||||
((_x & 0x00ff0000U) >> 8) | \
|
|
||||||
((_x & 0xff000000U) >> 24))
|
|
||||||
# define const_le16(_x) \
|
|
||||||
(((_x & 0x00ff) << 8) | \
|
|
||||||
((_x & 0xff00) >> 8))
|
|
||||||
#else
|
|
||||||
# define const_le32(_x) (_x)
|
|
||||||
# define const_le16(_x) (_x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------- */
|
/* ----------------------------------------------------------------- */
|
||||||
/* qemu internals */
|
/* qemu internals */
|
||||||
|
|
||||||
@@ -111,6 +97,9 @@ struct VirtIOInputHost {
|
|||||||
void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event);
|
void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event);
|
||||||
void virtio_input_init_config(VirtIOInput *vinput,
|
void virtio_input_init_config(VirtIOInput *vinput,
|
||||||
virtio_input_config *config);
|
virtio_input_config *config);
|
||||||
|
virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
|
||||||
|
uint8_t select,
|
||||||
|
uint8_t subsel);
|
||||||
void virtio_input_add_config(VirtIOInput *vinput,
|
void virtio_input_add_config(VirtIOInput *vinput,
|
||||||
virtio_input_config *config);
|
virtio_input_config *config);
|
||||||
void virtio_input_idstr_config(VirtIOInput *vinput,
|
void virtio_input_idstr_config(VirtIOInput *vinput,
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ typedef struct VirtIOSCSI {
|
|||||||
bool dataplane_started;
|
bool dataplane_started;
|
||||||
bool dataplane_starting;
|
bool dataplane_starting;
|
||||||
bool dataplane_stopping;
|
bool dataplane_stopping;
|
||||||
bool dataplane_disabled;
|
|
||||||
bool dataplane_fenced;
|
bool dataplane_fenced;
|
||||||
Error *blocker;
|
Error *blocker;
|
||||||
uint32_t host_features;
|
uint32_t host_features;
|
||||||
@@ -140,9 +139,9 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
|
|||||||
HandleOutput cmd);
|
HandleOutput cmd);
|
||||||
|
|
||||||
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
|
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
|
||||||
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||||
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||||
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq);
|
||||||
void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
|
void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
|
||||||
void virtio_scsi_free_req(VirtIOSCSIReq *req);
|
void virtio_scsi_free_req(VirtIOSCSIReq *req);
|
||||||
void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
|
void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
|
||||||
|
|||||||
@@ -251,8 +251,8 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
|
|||||||
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
|
void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign,
|
||||||
bool set_handler);
|
bool set_handler);
|
||||||
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,
|
||||||
bool assign, bool set_handler);
|
void (*fn)(VirtIODevice *,
|
||||||
void virtio_queue_notify_vq(VirtQueue *vq);
|
VirtQueue *));
|
||||||
void virtio_irq(VirtQueue *vq);
|
void virtio_irq(VirtQueue *vq);
|
||||||
VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
|
VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
|
||||||
VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
|
VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
|
||||||
|
|||||||
@@ -42,30 +42,34 @@
|
|||||||
* loads/stores past the atomic operation load/store. However there is
|
* loads/stores past the atomic operation load/store. However there is
|
||||||
* no explicit memory barrier for the processor.
|
* no explicit memory barrier for the processor.
|
||||||
*/
|
*/
|
||||||
#define atomic_read(ptr) \
|
#define atomic_read(ptr) \
|
||||||
({ \
|
({ \
|
||||||
typeof(*ptr) _val; \
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
__atomic_load(ptr, &_val, __ATOMIC_RELAXED); \
|
typeof(*ptr) _val; \
|
||||||
_val; \
|
__atomic_load(ptr, &_val, __ATOMIC_RELAXED); \
|
||||||
|
_val; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define atomic_set(ptr, i) do { \
|
#define atomic_set(ptr, i) do { \
|
||||||
typeof(*ptr) _val = (i); \
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
__atomic_store(ptr, &_val, __ATOMIC_RELAXED); \
|
typeof(*ptr) _val = (i); \
|
||||||
|
__atomic_store(ptr, &_val, __ATOMIC_RELAXED); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/* Atomic RCU operations imply weak memory barriers */
|
/* Atomic RCU operations imply weak memory barriers */
|
||||||
|
|
||||||
#define atomic_rcu_read(ptr) \
|
#define atomic_rcu_read(ptr) \
|
||||||
({ \
|
({ \
|
||||||
typeof(*ptr) _val; \
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
__atomic_load(ptr, &_val, __ATOMIC_CONSUME); \
|
typeof(*ptr) _val; \
|
||||||
_val; \
|
__atomic_load(ptr, &_val, __ATOMIC_CONSUME); \
|
||||||
|
_val; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define atomic_rcu_set(ptr, i) do { \
|
#define atomic_rcu_set(ptr, i) do { \
|
||||||
typeof(*ptr) _val = (i); \
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
__atomic_store(ptr, &_val, __ATOMIC_RELEASE); \
|
typeof(*ptr) _val = (i); \
|
||||||
|
__atomic_store(ptr, &_val, __ATOMIC_RELEASE); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/* atomic_mb_read/set semantics map Java volatile variables. They are
|
/* atomic_mb_read/set semantics map Java volatile variables. They are
|
||||||
@@ -79,6 +83,7 @@
|
|||||||
#if defined(_ARCH_PPC)
|
#if defined(_ARCH_PPC)
|
||||||
#define atomic_mb_read(ptr) \
|
#define atomic_mb_read(ptr) \
|
||||||
({ \
|
({ \
|
||||||
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
typeof(*ptr) _val; \
|
typeof(*ptr) _val; \
|
||||||
__atomic_load(ptr, &_val, __ATOMIC_RELAXED); \
|
__atomic_load(ptr, &_val, __ATOMIC_RELAXED); \
|
||||||
smp_rmb(); \
|
smp_rmb(); \
|
||||||
@@ -86,22 +91,25 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
#define atomic_mb_set(ptr, i) do { \
|
#define atomic_mb_set(ptr, i) do { \
|
||||||
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
typeof(*ptr) _val = (i); \
|
typeof(*ptr) _val = (i); \
|
||||||
smp_wmb(); \
|
smp_wmb(); \
|
||||||
__atomic_store(ptr, &_val, __ATOMIC_RELAXED); \
|
__atomic_store(ptr, &_val, __ATOMIC_RELAXED); \
|
||||||
smp_mb(); \
|
smp_mb(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
#else
|
#else
|
||||||
#define atomic_mb_read(ptr) \
|
#define atomic_mb_read(ptr) \
|
||||||
({ \
|
({ \
|
||||||
typeof(*ptr) _val; \
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
__atomic_load(ptr, &_val, __ATOMIC_SEQ_CST); \
|
typeof(*ptr) _val; \
|
||||||
_val; \
|
__atomic_load(ptr, &_val, __ATOMIC_SEQ_CST); \
|
||||||
|
_val; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define atomic_mb_set(ptr, i) do { \
|
#define atomic_mb_set(ptr, i) do { \
|
||||||
typeof(*ptr) _val = (i); \
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
__atomic_store(ptr, &_val, __ATOMIC_SEQ_CST); \
|
typeof(*ptr) _val = (i); \
|
||||||
|
__atomic_store(ptr, &_val, __ATOMIC_SEQ_CST); \
|
||||||
} while(0)
|
} while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -109,6 +117,7 @@
|
|||||||
/* All the remaining operations are fully sequentially consistent */
|
/* All the remaining operations are fully sequentially consistent */
|
||||||
|
|
||||||
#define atomic_xchg(ptr, i) ({ \
|
#define atomic_xchg(ptr, i) ({ \
|
||||||
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
typeof(*ptr) _new = (i), _old; \
|
typeof(*ptr) _new = (i), _old; \
|
||||||
__atomic_exchange(ptr, &_new, &_old, __ATOMIC_SEQ_CST); \
|
__atomic_exchange(ptr, &_new, &_old, __ATOMIC_SEQ_CST); \
|
||||||
_old; \
|
_old; \
|
||||||
@@ -117,6 +126,7 @@
|
|||||||
/* Returns the eventual value, failed or not */
|
/* Returns the eventual value, failed or not */
|
||||||
#define atomic_cmpxchg(ptr, old, new) \
|
#define atomic_cmpxchg(ptr, old, new) \
|
||||||
({ \
|
({ \
|
||||||
|
QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
|
||||||
typeof(*ptr) _old = (old), _new = (new); \
|
typeof(*ptr) _old = (old), _new = (new); \
|
||||||
__atomic_compare_exchange(ptr, &_old, &_new, false, \
|
__atomic_compare_exchange(ptr, &_old, &_new, false, \
|
||||||
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \
|
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \
|
||||||
|
|||||||
@@ -125,6 +125,25 @@ static inline uint32_t qemu_bswap_len(uint32_t value, int len)
|
|||||||
return bswap32(value) >> (32 - 8 * len);
|
return bswap32(value) >> (32 - 8 * len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same as cpu_to_le{16,23}, except that gcc will figure the result is
|
||||||
|
* a compile-time constant if you pass in a constant. So this can be
|
||||||
|
* used to initialize static variables.
|
||||||
|
*/
|
||||||
|
#if defined(HOST_WORDS_BIGENDIAN)
|
||||||
|
# define const_le32(_x) \
|
||||||
|
((((_x) & 0x000000ffU) << 24) | \
|
||||||
|
(((_x) & 0x0000ff00U) << 8) | \
|
||||||
|
(((_x) & 0x00ff0000U) >> 8) | \
|
||||||
|
(((_x) & 0xff000000U) >> 24))
|
||||||
|
# define const_le16(_x) \
|
||||||
|
((((_x) & 0x00ff) << 8) | \
|
||||||
|
(((_x) & 0xff00) >> 8))
|
||||||
|
#else
|
||||||
|
# define const_le32(_x) (_x)
|
||||||
|
# define const_le16(_x) (_x)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Unions for reinterpreting between floats and integers. */
|
/* Unions for reinterpreting between floats and integers. */
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
|||||||
@@ -95,23 +95,6 @@ qemu_log_vprintf(const char *fmt, va_list va)
|
|||||||
|
|
||||||
/* Maintenance: */
|
/* Maintenance: */
|
||||||
|
|
||||||
/* fflush() the log file */
|
|
||||||
static inline void qemu_log_flush(void)
|
|
||||||
{
|
|
||||||
fflush(qemu_logfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the log file */
|
|
||||||
static inline void qemu_log_close(void)
|
|
||||||
{
|
|
||||||
if (qemu_logfile) {
|
|
||||||
if (qemu_logfile != stderr) {
|
|
||||||
fclose(qemu_logfile);
|
|
||||||
}
|
|
||||||
qemu_logfile = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* define log items */
|
/* define log items */
|
||||||
typedef struct QEMULogItem {
|
typedef struct QEMULogItem {
|
||||||
int mask;
|
int mask;
|
||||||
@@ -146,4 +129,9 @@ int qemu_str_to_log_mask(const char *str);
|
|||||||
*/
|
*/
|
||||||
void qemu_print_log_usage(FILE *f);
|
void qemu_print_log_usage(FILE *f);
|
||||||
|
|
||||||
|
/* fflush() the log file */
|
||||||
|
void qemu_log_flush(void);
|
||||||
|
/* Close the log file */
|
||||||
|
void qemu_log_close(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -226,7 +226,9 @@
|
|||||||
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
|
(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
|
||||||
|
|
||||||
/* Declare the various hypercall operations. */
|
/* Declare the various hypercall operations. */
|
||||||
#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT 0x0008
|
#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
|
||||||
|
#define HVCALL_POST_MESSAGE 0x005c
|
||||||
|
#define HVCALL_SIGNAL_EVENT 0x005d
|
||||||
|
|
||||||
#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001
|
#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001
|
||||||
#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT 12
|
#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT 12
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ struct input_mask {
|
|||||||
#define BUS_GSC 0x1A
|
#define BUS_GSC 0x1A
|
||||||
#define BUS_ATARI 0x1B
|
#define BUS_ATARI 0x1B
|
||||||
#define BUS_SPI 0x1C
|
#define BUS_SPI 0x1C
|
||||||
|
#define BUS_RMI 0x1D
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MT_TOOL types
|
* MT_TOOL types
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
#include <stdint.h>
|
/* For QEMU all types are already defined via osdep.h, so this
|
||||||
#include "qemu/compiler.h"
|
* header does not need to do anything.
|
||||||
|
*/
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ struct virtio_balloon_config {
|
|||||||
#define VIRTIO_BALLOON_S_MINFLT 3 /* Number of minor faults */
|
#define VIRTIO_BALLOON_S_MINFLT 3 /* Number of minor faults */
|
||||||
#define VIRTIO_BALLOON_S_MEMFREE 4 /* Total amount of free memory */
|
#define VIRTIO_BALLOON_S_MEMFREE 4 /* Total amount of free memory */
|
||||||
#define VIRTIO_BALLOON_S_MEMTOT 5 /* Total amount of memory */
|
#define VIRTIO_BALLOON_S_MEMTOT 5 /* Total amount of memory */
|
||||||
#define VIRTIO_BALLOON_S_AVAIL 6 /* Amount of available memory in guest */
|
#define VIRTIO_BALLOON_S_AVAIL 6 /* Available memory as in /proc */
|
||||||
#define VIRTIO_BALLOON_S_NR 7
|
#define VIRTIO_BALLOON_S_NR 7
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -43,10 +43,10 @@
|
|||||||
#ifndef VIRTIO_BLK_NO_LEGACY
|
#ifndef VIRTIO_BLK_NO_LEGACY
|
||||||
#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
|
#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
|
||||||
#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
|
#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */
|
||||||
#define VIRTIO_BLK_F_WCE 9 /* Writeback mode enabled after reset */
|
#define VIRTIO_BLK_F_FLUSH 9 /* Flush command supported */
|
||||||
#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
|
#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */
|
||||||
/* Old (deprecated) name for VIRTIO_BLK_F_WCE. */
|
/* Old (deprecated) name for VIRTIO_BLK_F_FLUSH. */
|
||||||
#define VIRTIO_BLK_F_FLUSH VIRTIO_BLK_F_WCE
|
#define VIRTIO_BLK_F_WCE VIRTIO_BLK_F_FLUSH
|
||||||
#endif /* !VIRTIO_BLK_NO_LEGACY */
|
#endif /* !VIRTIO_BLK_NO_LEGACY */
|
||||||
|
|
||||||
#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */
|
#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ DisplayState *init_displaystate(void);
|
|||||||
DisplaySurface *qemu_create_displaysurface_from(int width, int height,
|
DisplaySurface *qemu_create_displaysurface_from(int width, int height,
|
||||||
pixman_format_code_t format,
|
pixman_format_code_t format,
|
||||||
int linesize, uint8_t *data);
|
int linesize, uint8_t *data);
|
||||||
|
DisplaySurface *qemu_create_displaysurface_pixman(pixman_image_t *image);
|
||||||
DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height,
|
DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height,
|
||||||
pixman_format_code_t format,
|
pixman_format_code_t format,
|
||||||
int linesize,
|
int linesize,
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ struct kvm_regs {
|
|||||||
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
|
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
|
||||||
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
|
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
|
||||||
#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
|
#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
|
||||||
|
#define KVM_ARM_VCPU_PMU_V3 3 /* Support guest PMUv3 */
|
||||||
|
|
||||||
struct kvm_vcpu_init {
|
struct kvm_vcpu_init {
|
||||||
__u32 target;
|
__u32 target;
|
||||||
@@ -204,6 +205,11 @@ struct kvm_arch_memory_slot {
|
|||||||
#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
|
#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
|
||||||
#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
|
#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
|
||||||
|
|
||||||
|
/* Device Control API on vcpu fd */
|
||||||
|
#define KVM_ARM_VCPU_PMU_V3_CTRL 0
|
||||||
|
#define KVM_ARM_VCPU_PMU_V3_IRQ 0
|
||||||
|
#define KVM_ARM_VCPU_PMU_V3_INIT 1
|
||||||
|
|
||||||
/* KVM_IRQ_LINE irq field index values */
|
/* KVM_IRQ_LINE irq field index values */
|
||||||
#define KVM_ARM_IRQ_TYPE_SHIFT 24
|
#define KVM_ARM_IRQ_TYPE_SHIFT 24
|
||||||
#define KVM_ARM_IRQ_TYPE_MASK 0xff
|
#define KVM_ARM_IRQ_TYPE_MASK 0xff
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
#define EV_SUCCESS 0
|
#define EV_SUCCESS 0
|
||||||
#define EV_EPERM 1 /* Operation not permitted */
|
#define EV_EPERM 1 /* Operation not permitted */
|
||||||
#define EV_ENOENT 2 /* Entry Not Found */
|
#define EV_ENOENT 2 /* Entry Not Found */
|
||||||
#define EV_EIO 3 /* I/O error occured */
|
#define EV_EIO 3 /* I/O error occurred */
|
||||||
#define EV_EAGAIN 4 /* The operation had insufficient
|
#define EV_EAGAIN 4 /* The operation had insufficient
|
||||||
* resources to complete and should be
|
* resources to complete and should be
|
||||||
* retried
|
* retried
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
#define EV_ENODEV 7 /* No such device */
|
#define EV_ENODEV 7 /* No such device */
|
||||||
#define EV_EINVAL 8 /* An argument supplied to the hcall
|
#define EV_EINVAL 8 /* An argument supplied to the hcall
|
||||||
was out of range or invalid */
|
was out of range or invalid */
|
||||||
#define EV_INTERNAL 9 /* An internal error occured */
|
#define EV_INTERNAL 9 /* An internal error occurred */
|
||||||
#define EV_CONFIG 10 /* A configuration error was detected */
|
#define EV_CONFIG 10 /* A configuration error was detected */
|
||||||
#define EV_INVALID_STATE 11 /* The object is in an invalid state */
|
#define EV_INVALID_STATE 11 /* The object is in an invalid state */
|
||||||
#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */
|
#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */
|
||||||
|
|||||||
@@ -333,6 +333,15 @@ struct kvm_create_spapr_tce {
|
|||||||
__u32 window_size;
|
__u32 window_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* for KVM_CAP_SPAPR_TCE_64 */
|
||||||
|
struct kvm_create_spapr_tce_64 {
|
||||||
|
__u64 liobn;
|
||||||
|
__u32 page_shift;
|
||||||
|
__u32 flags;
|
||||||
|
__u64 offset; /* in pages */
|
||||||
|
__u64 size; /* in pages */
|
||||||
|
};
|
||||||
|
|
||||||
/* for KVM_ALLOCATE_RMA */
|
/* for KVM_ALLOCATE_RMA */
|
||||||
struct kvm_allocate_rma {
|
struct kvm_allocate_rma {
|
||||||
__u64 rma_size;
|
__u64 rma_size;
|
||||||
|
|||||||
@@ -375,5 +375,7 @@
|
|||||||
#define __NR_membarrier 375
|
#define __NR_membarrier 375
|
||||||
#define __NR_mlock2 376
|
#define __NR_mlock2 376
|
||||||
#define __NR_copy_file_range 377
|
#define __NR_copy_file_range 377
|
||||||
|
#define __NR_preadv2 378
|
||||||
|
#define __NR_pwritev2 379
|
||||||
|
|
||||||
#endif /* _ASM_X86_UNISTD_32_H */
|
#endif /* _ASM_X86_UNISTD_32_H */
|
||||||
|
|||||||
@@ -328,5 +328,7 @@
|
|||||||
#define __NR_membarrier 324
|
#define __NR_membarrier 324
|
||||||
#define __NR_mlock2 325
|
#define __NR_mlock2 325
|
||||||
#define __NR_copy_file_range 326
|
#define __NR_copy_file_range 326
|
||||||
|
#define __NR_preadv2 327
|
||||||
|
#define __NR_pwritev2 328
|
||||||
|
|
||||||
#endif /* _ASM_X86_UNISTD_64_H */
|
#endif /* _ASM_X86_UNISTD_64_H */
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ struct kvm_s390_skeys {
|
|||||||
|
|
||||||
struct kvm_hyperv_exit {
|
struct kvm_hyperv_exit {
|
||||||
#define KVM_EXIT_HYPERV_SYNIC 1
|
#define KVM_EXIT_HYPERV_SYNIC 1
|
||||||
|
#define KVM_EXIT_HYPERV_HCALL 2
|
||||||
__u32 type;
|
__u32 type;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
@@ -165,6 +166,11 @@ struct kvm_hyperv_exit {
|
|||||||
__u64 evt_page;
|
__u64 evt_page;
|
||||||
__u64 msg_page;
|
__u64 msg_page;
|
||||||
} synic;
|
} synic;
|
||||||
|
struct {
|
||||||
|
__u64 input;
|
||||||
|
__u64 result;
|
||||||
|
__u64 params[2];
|
||||||
|
} hcall;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -856,6 +862,9 @@ struct kvm_ppc_smmu_info {
|
|||||||
#define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
|
#define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
|
||||||
#define KVM_CAP_HYPERV_SYNIC 123
|
#define KVM_CAP_HYPERV_SYNIC 123
|
||||||
#define KVM_CAP_S390_RI 124
|
#define KVM_CAP_S390_RI 124
|
||||||
|
#define KVM_CAP_SPAPR_TCE_64 125
|
||||||
|
#define KVM_CAP_ARM_PMU_V3 126
|
||||||
|
#define KVM_CAP_VCPU_ATTRIBUTES 127
|
||||||
|
|
||||||
#ifdef KVM_CAP_IRQ_ROUTING
|
#ifdef KVM_CAP_IRQ_ROUTING
|
||||||
|
|
||||||
@@ -1148,6 +1157,8 @@ struct kvm_s390_ucas_mapping {
|
|||||||
/* Available with KVM_CAP_PPC_ALLOC_HTAB */
|
/* Available with KVM_CAP_PPC_ALLOC_HTAB */
|
||||||
#define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32)
|
#define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32)
|
||||||
#define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce)
|
#define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce)
|
||||||
|
#define KVM_CREATE_SPAPR_TCE_64 _IOW(KVMIO, 0xa8, \
|
||||||
|
struct kvm_create_spapr_tce_64)
|
||||||
/* Available with KVM_CAP_RMA */
|
/* Available with KVM_CAP_RMA */
|
||||||
#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma)
|
#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma)
|
||||||
/* Available with KVM_CAP_PPC_HTAB_FD */
|
/* Available with KVM_CAP_PPC_HTAB_FD */
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ struct uffd_msg {
|
|||||||
__u64 reserved3;
|
__u64 reserved3;
|
||||||
} reserved;
|
} reserved;
|
||||||
} arg;
|
} arg;
|
||||||
} __packed;
|
} __attribute__((packed));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start at 0x12 and not at 0 to be more strict against bugs.
|
* Start at 0x12 and not at 0 to be more strict against bugs.
|
||||||
|
|||||||
@@ -59,6 +59,33 @@
|
|||||||
#define VFIO_TYPE (';')
|
#define VFIO_TYPE (';')
|
||||||
#define VFIO_BASE 100
|
#define VFIO_BASE 100
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For extension of INFO ioctls, VFIO makes use of a capability chain
|
||||||
|
* designed after PCI/e capabilities. A flag bit indicates whether
|
||||||
|
* this capability chain is supported and a field defined in the fixed
|
||||||
|
* structure defines the offset of the first capability in the chain.
|
||||||
|
* This field is only valid when the corresponding bit in the flags
|
||||||
|
* bitmap is set. This offset field is relative to the start of the
|
||||||
|
* INFO buffer, as is the next field within each capability header.
|
||||||
|
* The id within the header is a shared address space per INFO ioctl,
|
||||||
|
* while the version field is specific to the capability id. The
|
||||||
|
* contents following the header are specific to the capability id.
|
||||||
|
*/
|
||||||
|
struct vfio_info_cap_header {
|
||||||
|
__u16 id; /* Identifies capability */
|
||||||
|
__u16 version; /* Version specific to the capability ID */
|
||||||
|
__u32 next; /* Offset of next capability */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callers of INFO ioctls passing insufficiently sized buffers will see
|
||||||
|
* the capability chain flag bit set, a zero value for the first capability
|
||||||
|
* offset (if available within the provided argsz), and argsz will be
|
||||||
|
* updated to report the necessary buffer size. For compatibility, the
|
||||||
|
* INFO ioctl will not report error in this case, but the capability chain
|
||||||
|
* will not be available.
|
||||||
|
*/
|
||||||
|
|
||||||
/* -------- IOCTLs for VFIO file descriptor (/dev/vfio/vfio) -------- */
|
/* -------- IOCTLs for VFIO file descriptor (/dev/vfio/vfio) -------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,13 +221,73 @@ struct vfio_region_info {
|
|||||||
#define VFIO_REGION_INFO_FLAG_READ (1 << 0) /* Region supports read */
|
#define VFIO_REGION_INFO_FLAG_READ (1 << 0) /* Region supports read */
|
||||||
#define VFIO_REGION_INFO_FLAG_WRITE (1 << 1) /* Region supports write */
|
#define VFIO_REGION_INFO_FLAG_WRITE (1 << 1) /* Region supports write */
|
||||||
#define VFIO_REGION_INFO_FLAG_MMAP (1 << 2) /* Region supports mmap */
|
#define VFIO_REGION_INFO_FLAG_MMAP (1 << 2) /* Region supports mmap */
|
||||||
|
#define VFIO_REGION_INFO_FLAG_CAPS (1 << 3) /* Info supports caps */
|
||||||
__u32 index; /* Region index */
|
__u32 index; /* Region index */
|
||||||
__u32 resv; /* Reserved for alignment */
|
__u32 cap_offset; /* Offset within info struct of first cap */
|
||||||
__u64 size; /* Region size (bytes) */
|
__u64 size; /* Region size (bytes) */
|
||||||
__u64 offset; /* Region offset from start of device fd */
|
__u64 offset; /* Region offset from start of device fd */
|
||||||
};
|
};
|
||||||
#define VFIO_DEVICE_GET_REGION_INFO _IO(VFIO_TYPE, VFIO_BASE + 8)
|
#define VFIO_DEVICE_GET_REGION_INFO _IO(VFIO_TYPE, VFIO_BASE + 8)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The sparse mmap capability allows finer granularity of specifying areas
|
||||||
|
* within a region with mmap support. When specified, the user should only
|
||||||
|
* mmap the offset ranges specified by the areas array. mmaps outside of the
|
||||||
|
* areas specified may fail (such as the range covering a PCI MSI-X table) or
|
||||||
|
* may result in improper device behavior.
|
||||||
|
*
|
||||||
|
* The structures below define version 1 of this capability.
|
||||||
|
*/
|
||||||
|
#define VFIO_REGION_INFO_CAP_SPARSE_MMAP 1
|
||||||
|
|
||||||
|
struct vfio_region_sparse_mmap_area {
|
||||||
|
__u64 offset; /* Offset of mmap'able area within region */
|
||||||
|
__u64 size; /* Size of mmap'able area */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vfio_region_info_cap_sparse_mmap {
|
||||||
|
struct vfio_info_cap_header header;
|
||||||
|
__u32 nr_areas;
|
||||||
|
__u32 reserved;
|
||||||
|
struct vfio_region_sparse_mmap_area areas[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The device specific type capability allows regions unique to a specific
|
||||||
|
* device or class of devices to be exposed. This helps solve the problem for
|
||||||
|
* vfio bus drivers of defining which region indexes correspond to which region
|
||||||
|
* on the device, without needing to resort to static indexes, as done by
|
||||||
|
* vfio-pci. For instance, if we were to go back in time, we might remove
|
||||||
|
* VFIO_PCI_VGA_REGION_INDEX and let vfio-pci simply define that all indexes
|
||||||
|
* greater than or equal to VFIO_PCI_NUM_REGIONS are device specific and we'd
|
||||||
|
* make a "VGA" device specific type to describe the VGA access space. This
|
||||||
|
* means that non-VGA devices wouldn't need to waste this index, and thus the
|
||||||
|
* address space associated with it due to implementation of device file
|
||||||
|
* descriptor offsets in vfio-pci.
|
||||||
|
*
|
||||||
|
* The current implementation is now part of the user ABI, so we can't use this
|
||||||
|
* for VGA, but there are other upcoming use cases, such as opregions for Intel
|
||||||
|
* IGD devices and framebuffers for vGPU devices. We missed VGA, but we'll
|
||||||
|
* use this for future additions.
|
||||||
|
*
|
||||||
|
* The structure below defines version 1 of this capability.
|
||||||
|
*/
|
||||||
|
#define VFIO_REGION_INFO_CAP_TYPE 2
|
||||||
|
|
||||||
|
struct vfio_region_info_cap_type {
|
||||||
|
struct vfio_info_cap_header header;
|
||||||
|
__u32 type; /* global per bus driver */
|
||||||
|
__u32 subtype; /* type specific */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VFIO_REGION_TYPE_PCI_VENDOR_TYPE (1 << 31)
|
||||||
|
#define VFIO_REGION_TYPE_PCI_VENDOR_MASK (0xffff)
|
||||||
|
|
||||||
|
/* 8086 Vendor sub-types */
|
||||||
|
#define VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION (1)
|
||||||
|
#define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
|
||||||
|
#define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG (3)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VFIO_DEVICE_GET_IRQ_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 9,
|
* VFIO_DEVICE_GET_IRQ_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 9,
|
||||||
* struct vfio_irq_info)
|
* struct vfio_irq_info)
|
||||||
@@ -336,7 +423,8 @@ enum {
|
|||||||
* between described ranges are unimplemented.
|
* between described ranges are unimplemented.
|
||||||
*/
|
*/
|
||||||
VFIO_PCI_VGA_REGION_INDEX,
|
VFIO_PCI_VGA_REGION_INDEX,
|
||||||
VFIO_PCI_NUM_REGIONS
|
VFIO_PCI_NUM_REGIONS = 9 /* Fixed user ABI, region indexes >=9 use */
|
||||||
|
/* device specific cap to define content. */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|||||||
@@ -126,6 +126,12 @@ struct vhost_memory {
|
|||||||
#define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file)
|
#define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file)
|
||||||
/* Set eventfd to signal an error */
|
/* Set eventfd to signal an error */
|
||||||
#define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file)
|
#define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file)
|
||||||
|
/* Set busy loop timeout (in us) */
|
||||||
|
#define VHOST_SET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x23, \
|
||||||
|
struct vhost_vring_state)
|
||||||
|
/* Get busy loop timeout (in us) */
|
||||||
|
#define VHOST_GET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x24, \
|
||||||
|
struct vhost_vring_state)
|
||||||
|
|
||||||
/* VHOST_NET specific defines */
|
/* VHOST_NET specific defines */
|
||||||
|
|
||||||
|
|||||||
@@ -907,6 +907,9 @@ void cpu_loop(CPUARMState *env)
|
|||||||
if (do_kernel_trap(env))
|
if (do_kernel_trap(env))
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
|
case EXCP_YIELD:
|
||||||
|
/* nothing to do here for user-mode, just resume guest code */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
error:
|
error:
|
||||||
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
|
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
|
||||||
@@ -1097,6 +1100,9 @@ void cpu_loop(CPUARMState *env)
|
|||||||
case EXCP_SEMIHOST:
|
case EXCP_SEMIHOST:
|
||||||
env->xregs[0] = do_arm_semihosting(env);
|
env->xregs[0] = do_arm_semihosting(env);
|
||||||
break;
|
break;
|
||||||
|
case EXCP_YIELD:
|
||||||
|
/* nothing to do here for user-mode, just resume guest code */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
|
EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
|
||||||
abort();
|
abort();
|
||||||
|
|||||||
63
nbd/client.c
63
nbd/client.c
@@ -73,16 +73,46 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static int nbd_handle_reply_err(uint32_t opt, uint32_t type, Error **errp)
|
/* If type represents success, return 1 without further action.
|
||||||
|
* If type represents an error reply, consume the rest of the packet on ioc.
|
||||||
|
* Then return 0 for unsupported (so the client can fall back to
|
||||||
|
* other approaches), or -1 with errp set for other errors.
|
||||||
|
*/
|
||||||
|
static int nbd_handle_reply_err(QIOChannel *ioc, uint32_t opt, uint32_t type,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
uint32_t len;
|
||||||
|
char *msg = NULL;
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
if (!(type & (1 << 31))) {
|
if (!(type & (1 << 31))) {
|
||||||
return 0;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) {
|
||||||
|
error_setg(errp, "failed to read option length");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
len = be32_to_cpu(len);
|
||||||
|
if (len) {
|
||||||
|
if (len > NBD_MAX_BUFFER_SIZE) {
|
||||||
|
error_setg(errp, "server's error message is too long");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
msg = g_malloc(len + 1);
|
||||||
|
if (read_sync(ioc, msg, len) != len) {
|
||||||
|
error_setg(errp, "failed to read option error message");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
msg[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NBD_REP_ERR_UNSUP:
|
case NBD_REP_ERR_UNSUP:
|
||||||
error_setg(errp, "Unsupported option type %x", opt);
|
TRACE("server doesn't understand request %d, attempting fallback",
|
||||||
break;
|
opt);
|
||||||
|
result = 0;
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
case NBD_REP_ERR_POLICY:
|
case NBD_REP_ERR_POLICY:
|
||||||
error_setg(errp, "Denied by server for option %x", opt);
|
error_setg(errp, "Denied by server for option %x", opt);
|
||||||
@@ -101,7 +131,13 @@ static int nbd_handle_reply_err(uint32_t opt, uint32_t type, Error **errp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
if (msg) {
|
||||||
|
error_append_hint(errp, "%s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
g_free(msg);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
|
static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
|
||||||
@@ -111,6 +147,7 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
|
|||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t namelen;
|
uint32_t namelen;
|
||||||
|
int error;
|
||||||
|
|
||||||
*name = NULL;
|
*name = NULL;
|
||||||
if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
|
if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
|
||||||
@@ -138,11 +175,9 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
type = be32_to_cpu(type);
|
type = be32_to_cpu(type);
|
||||||
if (type == NBD_REP_ERR_UNSUP) {
|
error = nbd_handle_reply_err(ioc, opt, type, errp);
|
||||||
return 0;
|
if (error <= 0) {
|
||||||
}
|
return error;
|
||||||
if (nbd_handle_reply_err(opt, type, errp) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) {
|
if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) {
|
||||||
@@ -628,16 +663,16 @@ ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request)
|
|||||||
uint8_t buf[NBD_REQUEST_SIZE];
|
uint8_t buf[NBD_REQUEST_SIZE];
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
|
TRACE("Sending request to server: "
|
||||||
|
"{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}",
|
||||||
|
request->from, request->len, request->handle, request->type);
|
||||||
|
|
||||||
cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
|
cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
|
||||||
cpu_to_be32w((uint32_t*)(buf + 4), request->type);
|
cpu_to_be32w((uint32_t*)(buf + 4), request->type);
|
||||||
cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
|
cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
|
||||||
cpu_to_be64w((uint64_t*)(buf + 16), request->from);
|
cpu_to_be64w((uint64_t*)(buf + 16), request->from);
|
||||||
cpu_to_be32w((uint32_t*)(buf + 24), request->len);
|
cpu_to_be32w((uint32_t*)(buf + 24), request->len);
|
||||||
|
|
||||||
TRACE("Sending request to client: "
|
|
||||||
"{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}",
|
|
||||||
request->from, request->len, request->handle, request->type);
|
|
||||||
|
|
||||||
ret = write_sync(ioc, buf, sizeof(buf));
|
ret = write_sync(ioc, buf, sizeof(buf));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -50,9 +50,12 @@ ssize_t nbd_wr_syncv(QIOChannel *ioc,
|
|||||||
* qio_channel_yield() that works with AIO contexts
|
* qio_channel_yield() that works with AIO contexts
|
||||||
* and consider using that in this branch */
|
* and consider using that in this branch */
|
||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
} else {
|
} else if (done) {
|
||||||
|
/* XXX this is needed by nbd_reply_ready. */
|
||||||
qio_channel_wait(ioc,
|
qio_channel_wait(ioc,
|
||||||
do_read ? G_IO_IN : G_IO_OUT);
|
do_read ? G_IO_IN : G_IO_OUT);
|
||||||
|
} else {
|
||||||
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,18 +33,21 @@
|
|||||||
/* #define DEBUG_NBD */
|
/* #define DEBUG_NBD */
|
||||||
|
|
||||||
#ifdef DEBUG_NBD
|
#ifdef DEBUG_NBD
|
||||||
#define TRACE(msg, ...) do { \
|
#define DEBUG_NBD_PRINT 1
|
||||||
LOG(msg, ## __VA_ARGS__); \
|
|
||||||
} while(0)
|
|
||||||
#else
|
#else
|
||||||
#define TRACE(msg, ...) \
|
#define DEBUG_NBD_PRINT 0
|
||||||
do { } while (0)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TRACE(msg, ...) do { \
|
||||||
|
if (DEBUG_NBD_PRINT) { \
|
||||||
|
LOG(msg, ## __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define LOG(msg, ...) do { \
|
#define LOG(msg, ...) do { \
|
||||||
fprintf(stderr, "%s:%s():L%d: " msg "\n", \
|
fprintf(stderr, "%s:%s():L%d: " msg "\n", \
|
||||||
__FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
|
__FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
|
||||||
} while(0)
|
} while (0)
|
||||||
|
|
||||||
/* This is all part of the "official" NBD API.
|
/* This is all part of the "official" NBD API.
|
||||||
*
|
*
|
||||||
|
|||||||
11
nbd/server.c
11
nbd/server.c
@@ -26,6 +26,7 @@ static int system_errno_to_nbd_errno(int err)
|
|||||||
case 0:
|
case 0:
|
||||||
return NBD_SUCCESS;
|
return NBD_SUCCESS;
|
||||||
case EPERM:
|
case EPERM:
|
||||||
|
case EROFS:
|
||||||
return NBD_EPERM;
|
return NBD_EPERM;
|
||||||
case EIO:
|
case EIO:
|
||||||
return NBD_EIO;
|
return NBD_EIO;
|
||||||
@@ -482,9 +483,12 @@ static int nbd_negotiate_options(NBDClient *client)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
default:
|
default:
|
||||||
TRACE("Unsupported option 0x%x", clientflags);
|
TRACE("Unsupported option 0x%x", clientflags);
|
||||||
|
if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_UNSUP,
|
nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_UNSUP,
|
||||||
clientflags);
|
clientflags);
|
||||||
return -EINVAL;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@@ -655,6 +659,9 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, struct nbd_reply *reply)
|
|||||||
|
|
||||||
reply->error = system_errno_to_nbd_errno(reply->error);
|
reply->error = system_errno_to_nbd_errno(reply->error);
|
||||||
|
|
||||||
|
TRACE("Sending response to client: { .error = %d, handle = %" PRIu64 " }",
|
||||||
|
reply->error, reply->handle);
|
||||||
|
|
||||||
/* Reply
|
/* Reply
|
||||||
[ 0 .. 3] magic (NBD_REPLY_MAGIC)
|
[ 0 .. 3] magic (NBD_REPLY_MAGIC)
|
||||||
[ 4 .. 7] error (0 == no error)
|
[ 4 .. 7] error (0 == no error)
|
||||||
@@ -664,8 +671,6 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, struct nbd_reply *reply)
|
|||||||
stl_be_p(buf + 4, reply->error);
|
stl_be_p(buf + 4, reply->error);
|
||||||
stq_be_p(buf + 8, reply->handle);
|
stq_be_p(buf + 8, reply->handle);
|
||||||
|
|
||||||
TRACE("Sending response to client");
|
|
||||||
|
|
||||||
ret = write_sync(ioc, buf, sizeof(buf));
|
ret = write_sync(ioc, buf, sizeof(buf));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ static void netfilter_set_status(Object *obj, const char *str, Error **errp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nf->on = !nf->on;
|
nf->on = !nf->on;
|
||||||
if (nfc->status_changed) {
|
if (nf->netdev && nfc->status_changed) {
|
||||||
nfc->status_changed(nf, errp);
|
nfc->status_changed(nf, errp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
58
net/net.c
58
net/net.c
@@ -81,34 +81,6 @@ int default_net = 1;
|
|||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/* network device redirectors */
|
/* network device redirectors */
|
||||||
|
|
||||||
#if defined(DEBUG_NET)
|
|
||||||
static void hex_dump(FILE *f, const uint8_t *buf, int size)
|
|
||||||
{
|
|
||||||
int len, i, j, c;
|
|
||||||
|
|
||||||
for(i=0;i<size;i+=16) {
|
|
||||||
len = size - i;
|
|
||||||
if (len > 16)
|
|
||||||
len = 16;
|
|
||||||
fprintf(f, "%08x ", i);
|
|
||||||
for(j=0;j<16;j++) {
|
|
||||||
if (j < len)
|
|
||||||
fprintf(f, " %02x", buf[i+j]);
|
|
||||||
else
|
|
||||||
fprintf(f, " ");
|
|
||||||
}
|
|
||||||
fprintf(f, " ");
|
|
||||||
for(j=0;j<len;j++) {
|
|
||||||
c = buf[i+j];
|
|
||||||
if (c < ' ' || c > '~')
|
|
||||||
c = '.';
|
|
||||||
fprintf(f, "%c", c);
|
|
||||||
}
|
|
||||||
fprintf(f, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
|
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
|
||||||
{
|
{
|
||||||
const char *p, *p1;
|
const char *p, *p1;
|
||||||
@@ -664,7 +636,7 @@ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
|
|||||||
|
|
||||||
#ifdef DEBUG_NET
|
#ifdef DEBUG_NET
|
||||||
printf("qemu_send_packet_async:\n");
|
printf("qemu_send_packet_async:\n");
|
||||||
hex_dump(stdout, buf, size);
|
qemu_hexdump((const char *)buf, stdout, "net", size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sender->link_down || !sender->peer) {
|
if (sender->link_down || !sender->peer) {
|
||||||
@@ -711,23 +683,28 @@ ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
|
|||||||
static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov,
|
static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov,
|
||||||
int iovcnt, unsigned flags)
|
int iovcnt, unsigned flags)
|
||||||
{
|
{
|
||||||
uint8_t buf[NET_BUFSIZE];
|
uint8_t *buf = NULL;
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
if (iovcnt == 1) {
|
if (iovcnt == 1) {
|
||||||
buffer = iov[0].iov_base;
|
buffer = iov[0].iov_base;
|
||||||
offset = iov[0].iov_len;
|
offset = iov[0].iov_len;
|
||||||
} else {
|
} else {
|
||||||
|
buf = g_new(uint8_t, NET_BUFSIZE);
|
||||||
buffer = buf;
|
buffer = buf;
|
||||||
offset = iov_to_buf(iov, iovcnt, 0, buf, sizeof(buf));
|
offset = iov_to_buf(iov, iovcnt, 0, buf, NET_BUFSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) {
|
if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) {
|
||||||
return nc->info->receive_raw(nc, buffer, offset);
|
ret = nc->info->receive_raw(nc, buffer, offset);
|
||||||
} else {
|
} else {
|
||||||
return nc->info->receive(nc, buffer, offset);
|
ret = nc->info->receive(nc, buffer, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free(buf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t qemu_deliver_packet_iov(NetClientState *sender,
|
ssize_t qemu_deliver_packet_iov(NetClientState *sender,
|
||||||
@@ -1054,32 +1031,32 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error **errp)
|
|||||||
|
|
||||||
{
|
{
|
||||||
/* Parse convenience option format ip6-net=fec0::0[/64] */
|
/* Parse convenience option format ip6-net=fec0::0[/64] */
|
||||||
const char *ip6_net = qemu_opt_get(opts, "ip6-net");
|
const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
|
||||||
|
|
||||||
if (ip6_net) {
|
if (ip6_net) {
|
||||||
char buf[strlen(ip6_net) + 1];
|
char buf[strlen(ip6_net) + 1];
|
||||||
|
|
||||||
if (get_str_sep(buf, sizeof(buf), &ip6_net, '/') < 0) {
|
if (get_str_sep(buf, sizeof(buf), &ip6_net, '/') < 0) {
|
||||||
/* Default 64bit prefix length. */
|
/* Default 64bit prefix length. */
|
||||||
qemu_opt_set(opts, "ip6-prefix", ip6_net, &error_abort);
|
qemu_opt_set(opts, "ipv6-prefix", ip6_net, &error_abort);
|
||||||
qemu_opt_set_number(opts, "ip6-prefixlen", 64, &error_abort);
|
qemu_opt_set_number(opts, "ipv6-prefixlen", 64, &error_abort);
|
||||||
} else {
|
} else {
|
||||||
/* User-specified prefix length. */
|
/* User-specified prefix length. */
|
||||||
unsigned long len;
|
unsigned long len;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
qemu_opt_set(opts, "ip6-prefix", buf, &error_abort);
|
qemu_opt_set(opts, "ipv6-prefix", buf, &error_abort);
|
||||||
err = qemu_strtoul(ip6_net, NULL, 10, &len);
|
err = qemu_strtoul(ip6_net, NULL, 10, &len);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
||||||
"ip6-prefix", "a number");
|
"ipv6-prefix", "a number");
|
||||||
} else {
|
} else {
|
||||||
qemu_opt_set_number(opts, "ip6-prefixlen", len,
|
qemu_opt_set_number(opts, "ipv6-prefixlen", len,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qemu_opt_unset(opts, "ip6-net");
|
qemu_opt_unset(opts, "ipv6-net");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1100,6 +1077,7 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
error_propagate(errp, err);
|
error_propagate(errp, err);
|
||||||
|
opts_visitor_cleanup(ov);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "clients.h"
|
#include "clients.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
#include "qemu/iov.h"
|
#include "qemu/iov.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
|
|
||||||
|
|||||||
36
net/slirp.c
36
net/slirp.c
@@ -136,8 +136,8 @@ static NetClientInfo net_slirp_info = {
|
|||||||
|
|
||||||
static int net_slirp_init(NetClientState *peer, const char *model,
|
static int net_slirp_init(NetClientState *peer, const char *model,
|
||||||
const char *name, int restricted,
|
const char *name, int restricted,
|
||||||
const char *vnetwork, const char *vhost,
|
bool ipv4, const char *vnetwork, const char *vhost,
|
||||||
const char *vprefix6, int vprefix6_len,
|
bool ipv6, const char *vprefix6, int vprefix6_len,
|
||||||
const char *vhost6,
|
const char *vhost6,
|
||||||
const char *vhostname, const char *tftp_export,
|
const char *vhostname, const char *tftp_export,
|
||||||
const char *bootfile, const char *vdhcp_start,
|
const char *bootfile, const char *vdhcp_start,
|
||||||
@@ -165,6 +165,19 @@ static int net_slirp_init(NetClientState *peer, const char *model,
|
|||||||
char *end;
|
char *end;
|
||||||
struct slirp_config_str *config;
|
struct slirp_config_str *config;
|
||||||
|
|
||||||
|
if (!ipv4 && (vnetwork || vhost || vnameserver)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ipv6 && (vprefix6 || vhost6 || vnameserver6)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ipv4 && !ipv6) {
|
||||||
|
/* It doesn't make sense to disable both */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!tftp_export) {
|
if (!tftp_export) {
|
||||||
tftp_export = legacy_tftp_prefix;
|
tftp_export = legacy_tftp_prefix;
|
||||||
}
|
}
|
||||||
@@ -309,8 +322,8 @@ static int net_slirp_init(NetClientState *peer, const char *model,
|
|||||||
|
|
||||||
s = DO_UPCAST(SlirpState, nc, nc);
|
s = DO_UPCAST(SlirpState, nc, nc);
|
||||||
|
|
||||||
s->slirp = slirp_init(restricted, net, mask, host,
|
s->slirp = slirp_init(restricted, ipv4, net, mask, host,
|
||||||
ip6_prefix, vprefix6_len, ip6_host,
|
ipv6, ip6_prefix, vprefix6_len, ip6_host,
|
||||||
vhostname, tftp_export, bootfile, dhcp,
|
vhostname, tftp_export, bootfile, dhcp,
|
||||||
dns, ip6_dns, dnssearch, s);
|
dns, ip6_dns, dnssearch, s);
|
||||||
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
|
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
|
||||||
@@ -813,10 +826,20 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
|
|||||||
int ret;
|
int ret;
|
||||||
const NetdevUserOptions *user;
|
const NetdevUserOptions *user;
|
||||||
const char **dnssearch;
|
const char **dnssearch;
|
||||||
|
bool ipv4 = true, ipv6 = true;
|
||||||
|
|
||||||
assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER);
|
assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER);
|
||||||
user = opts->u.user.data;
|
user = opts->u.user.data;
|
||||||
|
|
||||||
|
if ((user->has_ipv6 && user->ipv6 && !user->has_ipv4) ||
|
||||||
|
(user->has_ipv4 && !user->ipv4)) {
|
||||||
|
ipv4 = 0;
|
||||||
|
}
|
||||||
|
if ((user->has_ipv4 && user->ipv4 && !user->has_ipv6) ||
|
||||||
|
(user->has_ipv6 && !user->ipv6)) {
|
||||||
|
ipv6 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
vnet = user->has_net ? g_strdup(user->net) :
|
vnet = user->has_net ? g_strdup(user->net) :
|
||||||
user->has_ip ? g_strdup_printf("%s/24", user->ip) :
|
user->has_ip ? g_strdup_printf("%s/24", user->ip) :
|
||||||
NULL;
|
NULL;
|
||||||
@@ -828,8 +851,9 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
|
|||||||
net_init_slirp_configs(user->hostfwd, SLIRP_CFG_HOSTFWD);
|
net_init_slirp_configs(user->hostfwd, SLIRP_CFG_HOSTFWD);
|
||||||
net_init_slirp_configs(user->guestfwd, 0);
|
net_init_slirp_configs(user->guestfwd, 0);
|
||||||
|
|
||||||
ret = net_slirp_init(peer, "user", name, user->q_restrict, vnet,
|
ret = net_slirp_init(peer, "user", name, user->q_restrict,
|
||||||
user->host, user->ipv6_prefix, user->ipv6_prefixlen,
|
ipv4, vnet, user->host,
|
||||||
|
ipv6, user->ipv6_prefix, user->ipv6_prefixlen,
|
||||||
user->ipv6_host, user->hostname, user->tftp,
|
user->ipv6_host, user->hostname, user->tftp,
|
||||||
user->bootfile, user->dhcpstart,
|
user->bootfile, user->dhcpstart,
|
||||||
user->dns, user->ipv6_dns, user->smb,
|
user->dns, user->ipv6_dns, user->smb,
|
||||||
|
|||||||
@@ -2425,6 +2425,12 @@
|
|||||||
#
|
#
|
||||||
# @restrict: #optional isolate the guest from the host
|
# @restrict: #optional isolate the guest from the host
|
||||||
#
|
#
|
||||||
|
# @ipv4: #optional whether to support IPv4, default true for enabled
|
||||||
|
# (since 2.6)
|
||||||
|
#
|
||||||
|
# @ipv6: #optional whether to support IPv6, default true for enabled
|
||||||
|
# (since 2.6)
|
||||||
|
#
|
||||||
# @ip: #optional legacy parameter, use net= instead
|
# @ip: #optional legacy parameter, use net= instead
|
||||||
#
|
#
|
||||||
# @net: #optional IP network address that the guest will see, in the
|
# @net: #optional IP network address that the guest will see, in the
|
||||||
@@ -2473,6 +2479,8 @@
|
|||||||
'data': {
|
'data': {
|
||||||
'*hostname': 'str',
|
'*hostname': 'str',
|
||||||
'*restrict': 'bool',
|
'*restrict': 'bool',
|
||||||
|
'*ipv4': 'bool',
|
||||||
|
'*ipv6': 'bool',
|
||||||
'*ip': 'str',
|
'*ip': 'str',
|
||||||
'*net': 'str',
|
'*net': 'str',
|
||||||
'*host': 'str',
|
'*host': 'str',
|
||||||
|
|||||||
39
qemu-char.c
39
qemu-char.c
@@ -225,12 +225,12 @@ static void qemu_chr_fe_write_log(CharDriverState *s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (done < len) {
|
while (done < len) {
|
||||||
do {
|
retry:
|
||||||
ret = write(s->logfd, buf + done, len - done);
|
ret = write(s->logfd, buf + done, len - done);
|
||||||
if (ret == -1 && errno == EAGAIN) {
|
if (ret == -1 && errno == EAGAIN) {
|
||||||
g_usleep(100);
|
g_usleep(100);
|
||||||
}
|
goto retry;
|
||||||
} while (ret == -1 && errno == EAGAIN);
|
}
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
return;
|
return;
|
||||||
@@ -246,12 +246,12 @@ static int qemu_chr_fe_write_buffer(CharDriverState *s, const uint8_t *buf, int
|
|||||||
|
|
||||||
qemu_mutex_lock(&s->chr_write_lock);
|
qemu_mutex_lock(&s->chr_write_lock);
|
||||||
while (*offset < len) {
|
while (*offset < len) {
|
||||||
do {
|
retry:
|
||||||
res = s->chr_write(s, buf + *offset, len - *offset);
|
res = s->chr_write(s, buf + *offset, len - *offset);
|
||||||
if (res == -1 && errno == EAGAIN) {
|
if (res < 0 && errno == EAGAIN) {
|
||||||
g_usleep(100);
|
g_usleep(100);
|
||||||
}
|
goto retry;
|
||||||
} while (res == -1 && errno == EAGAIN);
|
}
|
||||||
|
|
||||||
if (res <= 0) {
|
if (res <= 0) {
|
||||||
break;
|
break;
|
||||||
@@ -333,12 +333,12 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (offset < len) {
|
while (offset < len) {
|
||||||
do {
|
retry:
|
||||||
res = s->chr_sync_read(s, buf + offset, len - offset);
|
res = s->chr_sync_read(s, buf + offset, len - offset);
|
||||||
if (res == -1 && errno == EAGAIN) {
|
if (res == -1 && errno == EAGAIN) {
|
||||||
g_usleep(100);
|
g_usleep(100);
|
||||||
}
|
goto retry;
|
||||||
} while (res == -1 && errno == EAGAIN);
|
}
|
||||||
|
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
break;
|
break;
|
||||||
@@ -3081,6 +3081,8 @@ static int tcp_chr_new_client(CharDriverState *chr, QIOChannelSocket *sioc)
|
|||||||
s->sioc = sioc;
|
s->sioc = sioc;
|
||||||
object_ref(OBJECT(sioc));
|
object_ref(OBJECT(sioc));
|
||||||
|
|
||||||
|
qio_channel_set_blocking(s->ioc, false, NULL);
|
||||||
|
|
||||||
if (s->do_nodelay) {
|
if (s->do_nodelay) {
|
||||||
qio_channel_set_delay(s->ioc, false);
|
qio_channel_set_delay(s->ioc, false);
|
||||||
}
|
}
|
||||||
@@ -3112,7 +3114,6 @@ static int tcp_chr_add_client(CharDriverState *chr, int fd)
|
|||||||
if (!sioc) {
|
if (!sioc) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
qio_channel_set_blocking(QIO_CHANNEL(sioc), false, NULL);
|
|
||||||
ret = tcp_chr_new_client(chr, sioc);
|
ret = tcp_chr_new_client(chr, sioc);
|
||||||
object_unref(OBJECT(sioc));
|
object_unref(OBJECT(sioc));
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "block/blockjob.h"
|
#include "block/blockjob.h"
|
||||||
#include "block/qapi.h"
|
#include "block/qapi.h"
|
||||||
|
#include "crypto/init.h"
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
#define QEMU_IMG_VERSION "qemu-img version " QEMU_VERSION QEMU_PKGVERSION \
|
#define QEMU_IMG_VERSION "qemu-img version " QEMU_VERSION QEMU_PKGVERSION \
|
||||||
@@ -256,7 +257,7 @@ static BlockBackend *img_open_opts(const char *optstr,
|
|||||||
options = qemu_opts_to_qdict(opts, NULL);
|
options = qemu_opts_to_qdict(opts, NULL);
|
||||||
blk = blk_new_open(NULL, NULL, options, flags, &local_err);
|
blk = blk_new_open(NULL, NULL, options, flags, &local_err);
|
||||||
if (!blk) {
|
if (!blk) {
|
||||||
error_reportf_err(local_err, "Could not open '%s'", optstr);
|
error_reportf_err(local_err, "Could not open '%s': ", optstr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
blk_set_enable_write_cache(blk, !writethrough);
|
blk_set_enable_write_cache(blk, !writethrough);
|
||||||
@@ -3486,6 +3487,11 @@ int main(int argc, char **argv)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qcrypto_init(&local_error) < 0) {
|
||||||
|
error_reportf_err(local_error, "cannot initialize crypto: ");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
module_call_init(MODULE_INIT_QOM);
|
module_call_init(MODULE_INIT_QOM);
|
||||||
bdrv_init();
|
bdrv_init();
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "sysemu/block-backend.h"
|
#include "sysemu/block-backend.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "trace/control.h"
|
#include "trace/control.h"
|
||||||
|
#include "crypto/init.h"
|
||||||
|
|
||||||
#define CMD_NOFILE_OK 0x01
|
#define CMD_NOFILE_OK 0x01
|
||||||
|
|
||||||
@@ -443,6 +444,11 @@ int main(int argc, char **argv)
|
|||||||
progname = basename(argv[0]);
|
progname = basename(argv[0]);
|
||||||
qemu_init_exec_dir(argv[0]);
|
qemu_init_exec_dir(argv[0]);
|
||||||
|
|
||||||
|
if (qcrypto_init(&local_error) < 0) {
|
||||||
|
error_reportf_err(local_error, "cannot initialize crypto: ");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
module_call_init(MODULE_INIT_QOM);
|
module_call_init(MODULE_INIT_QOM);
|
||||||
qemu_add_opts(&qemu_object_opts);
|
qemu_add_opts(&qemu_object_opts);
|
||||||
bdrv_init();
|
bdrv_init();
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "qapi/qmp/qstring.h"
|
#include "qapi/qmp/qstring.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include "io/channel-socket.h"
|
#include "io/channel-socket.h"
|
||||||
|
#include "crypto/init.h"
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
@@ -75,6 +76,7 @@ static void usage(const char *name)
|
|||||||
" -e, --shared=NUM device can be shared by NUM clients (default '1')\n"
|
" -e, --shared=NUM device can be shared by NUM clients (default '1')\n"
|
||||||
" -t, --persistent don't exit on the last connection\n"
|
" -t, --persistent don't exit on the last connection\n"
|
||||||
" -v, --verbose display extra debugging information\n"
|
" -v, --verbose display extra debugging information\n"
|
||||||
|
" -x, --export-name=NAME expose export by name\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Exposing part of the image:\n"
|
"Exposing part of the image:\n"
|
||||||
" -o, --offset=OFFSET offset into the image\n"
|
" -o, --offset=OFFSET offset into the image\n"
|
||||||
@@ -518,6 +520,12 @@ int main(int argc, char **argv)
|
|||||||
memset(&sa_sigterm, 0, sizeof(sa_sigterm));
|
memset(&sa_sigterm, 0, sizeof(sa_sigterm));
|
||||||
sa_sigterm.sa_handler = termsig_handler;
|
sa_sigterm.sa_handler = termsig_handler;
|
||||||
sigaction(SIGTERM, &sa_sigterm, NULL);
|
sigaction(SIGTERM, &sa_sigterm, NULL);
|
||||||
|
|
||||||
|
if (qcrypto_init(&local_err) < 0) {
|
||||||
|
error_reportf_err(local_err, "cannot initialize crypto: ");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
module_call_init(MODULE_INIT_QOM);
|
module_call_init(MODULE_INIT_QOM);
|
||||||
qemu_add_opts(&qemu_object_opts);
|
qemu_add_opts(&qemu_object_opts);
|
||||||
qemu_init_exec_dir(argv[0]);
|
qemu_init_exec_dir(argv[0]);
|
||||||
|
|||||||
@@ -1551,8 +1551,9 @@ DEF("smb", HAS_ARG, QEMU_OPTION_smb, "", QEMU_ARCH_ALL)
|
|||||||
|
|
||||||
DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
|
DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
|
||||||
#ifdef CONFIG_SLIRP
|
#ifdef CONFIG_SLIRP
|
||||||
"-netdev user,id=str[,net=addr[/mask]][,host=addr][,ipv6-net=addr[/int]]\n"
|
"-netdev user,id=str[,ipv4[=on|off]][,net=addr[/mask]][,host=addr]\n"
|
||||||
" [,ipv6-host=addr][,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
|
" [,ipv6[=on|off]][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
|
||||||
|
" [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
|
||||||
" [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,tftp=dir]\n"
|
" [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,tftp=dir]\n"
|
||||||
" [,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
|
" [,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@@ -1701,6 +1702,9 @@ Connect user mode stack to VLAN @var{n} (@var{n} = 0 is the default).
|
|||||||
@itemx name=@var{name}
|
@itemx name=@var{name}
|
||||||
Assign symbolic name for use in monitor commands.
|
Assign symbolic name for use in monitor commands.
|
||||||
|
|
||||||
|
@option{ipv4} and @option{ipv6} specify that either IPv4 or IPv6 must
|
||||||
|
be enabled. If neither is specified both protocols are enabled.
|
||||||
|
|
||||||
@item net=@var{addr}[/@var{mask}]
|
@item net=@var{addr}[/@var{mask}]
|
||||||
Set IP network address the guest will see. Optionally specify the netmask,
|
Set IP network address the guest will see. Optionally specify the netmask,
|
||||||
either in the form a.b.c.d or as number of valid top-most bits. Default is
|
either in the form a.b.c.d or as number of valid top-most bits. Default is
|
||||||
@@ -3884,7 +3888,7 @@ parameter provides the ID of a previously defined secret that contains
|
|||||||
the AES-256 decryption key. This key should be 32-bytes long and be
|
the AES-256 decryption key. This key should be 32-bytes long and be
|
||||||
base64 encoded. The @var{iv} parameter provides the random initialization
|
base64 encoded. The @var{iv} parameter provides the random initialization
|
||||||
vector used for encryption of this particular secret and should be a
|
vector used for encryption of this particular secret and should be a
|
||||||
base64 encrypted string of the 32-byte IV.
|
base64 encrypted string of the 16-byte IV.
|
||||||
|
|
||||||
The simplest (insecure) usage is to provide the secret inline
|
The simplest (insecure) usage is to provide the secret inline
|
||||||
|
|
||||||
|
|||||||
@@ -373,6 +373,7 @@ static gboolean guest_exec_output_watch(GIOChannel *ch,
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
close:
|
close:
|
||||||
|
g_io_channel_shutdown(ch, true, NULL);
|
||||||
g_io_channel_unref(ch);
|
g_io_channel_unref(ch);
|
||||||
g_atomic_int_set(&p->closed, 1);
|
g_atomic_int_set(&p->closed, 1);
|
||||||
return false;
|
return false;
|
||||||
@@ -447,6 +448,7 @@ GuestExec *qmp_guest_exec(const char *path,
|
|||||||
g_io_channel_set_encoding(in_ch, NULL, NULL);
|
g_io_channel_set_encoding(in_ch, NULL, NULL);
|
||||||
g_io_channel_set_buffered(in_ch, false);
|
g_io_channel_set_buffered(in_ch, false);
|
||||||
g_io_channel_set_flags(in_ch, G_IO_FLAG_NONBLOCK, NULL);
|
g_io_channel_set_flags(in_ch, G_IO_FLAG_NONBLOCK, NULL);
|
||||||
|
g_io_channel_set_close_on_unref(in_ch, true);
|
||||||
g_io_add_watch(in_ch, G_IO_OUT, guest_exec_input_watch, &gei->in);
|
g_io_add_watch(in_ch, G_IO_OUT, guest_exec_input_watch, &gei->in);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,6 +464,8 @@ GuestExec *qmp_guest_exec(const char *path,
|
|||||||
g_io_channel_set_encoding(err_ch, NULL, NULL);
|
g_io_channel_set_encoding(err_ch, NULL, NULL);
|
||||||
g_io_channel_set_buffered(out_ch, false);
|
g_io_channel_set_buffered(out_ch, false);
|
||||||
g_io_channel_set_buffered(err_ch, false);
|
g_io_channel_set_buffered(err_ch, false);
|
||||||
|
g_io_channel_set_close_on_unref(out_ch, true);
|
||||||
|
g_io_channel_set_close_on_unref(err_ch, true);
|
||||||
g_io_add_watch(out_ch, G_IO_IN | G_IO_HUP,
|
g_io_add_watch(out_ch, G_IO_IN | G_IO_HUP,
|
||||||
guest_exec_output_watch, &gei->out);
|
guest_exec_output_watch, &gei->out);
|
||||||
g_io_add_watch(err_ch, G_IO_IN | G_IO_HUP,
|
g_io_add_watch(err_ch, G_IO_IN | G_IO_HUP,
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
<File Id="gspawn-win32-helper-console.exe" Name="gspawn-win32-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
<File Id="gspawn-win32-helper-console.exe" Name="gspawn-win32-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="gspawn-helper" Guid="{CD67A5A3-2DB1-4DA1-A67A-8D71E797B466}">
|
<Component Id="gspawn-helper" Guid="{CD67A5A3-2DB1-4DA1-A67A-8D71E797B466}">
|
||||||
<File Id="gspawn-win32-helper.exe" Name="gspawn-win32-helper.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper.exe" KeyPath="yes" DiskId="1"/>
|
<File Id="gspawn-win32-helper.exe" Name="gspawn-win32-helper.exe" Source="$(var.Mingw_bin)/gspawn-win32-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
||||||
</Component>
|
</Component>
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<?if $(var.Arch) = "64"?>
|
<?if $(var.Arch) = "64"?>
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
<File Id="gspawn-win64-helper-console.exe" Name="gspawn-win64-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
<File Id="gspawn-win64-helper-console.exe" Name="gspawn-win64-helper-console.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="gspawn-helper" Guid="{D201AD22-1846-4E4F-B6E1-C7A908ED2457}">
|
<Component Id="gspawn-helper" Guid="{D201AD22-1846-4E4F-B6E1-C7A908ED2457}">
|
||||||
<File Id="gspawn-win64-helper.exe" Name="gspawn-win64-helper.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper.exe" KeyPath="yes" DiskId="1"/>
|
<File Id="gspawn-win64-helper.exe" Name="gspawn-win64-helper.exe" Source="$(var.Mingw_bin)/gspawn-win64-helper-console.exe" KeyPath="yes" DiskId="1"/>
|
||||||
</Component>
|
</Component>
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<Component Id="iconv" Guid="{35EE3558-D34B-4F0A-B8BD-430FF0775246}">
|
<Component Id="iconv" Guid="{35EE3558-D34B-4F0A-B8BD-430FF0775246}">
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ our @typeList = (
|
|||||||
qr{${Ident}_t},
|
qr{${Ident}_t},
|
||||||
qr{${Ident}_handler},
|
qr{${Ident}_handler},
|
||||||
qr{${Ident}_handler_fn},
|
qr{${Ident}_handler_fn},
|
||||||
|
qr{target_(?:u)?long},
|
||||||
);
|
);
|
||||||
|
|
||||||
# This can be modified by sub possible. Since it can be empty, be careful
|
# This can be modified by sub possible. Since it can be empty, be careful
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ static void ra_timer_handler(void *opaque)
|
|||||||
|
|
||||||
void icmp6_init(Slirp *slirp)
|
void icmp6_init(Slirp *slirp)
|
||||||
{
|
{
|
||||||
|
if (!slirp->in6_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
slirp->ra_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, ra_timer_handler, slirp);
|
slirp->ra_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, ra_timer_handler, slirp);
|
||||||
timer_mod(slirp->ra_timer,
|
timer_mod(slirp->ra_timer,
|
||||||
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval);
|
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval);
|
||||||
@@ -31,6 +35,10 @@ void icmp6_init(Slirp *slirp)
|
|||||||
|
|
||||||
void icmp6_cleanup(Slirp *slirp)
|
void icmp6_cleanup(Slirp *slirp)
|
||||||
{
|
{
|
||||||
|
if (!slirp->in6_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
timer_del(slirp->ra_timer);
|
timer_del(slirp->ra_timer);
|
||||||
timer_free(slirp->ra_timer);
|
timer_free(slirp->ra_timer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ void ip6_cleanup(Slirp *slirp)
|
|||||||
void ip6_input(struct mbuf *m)
|
void ip6_input(struct mbuf *m)
|
||||||
{
|
{
|
||||||
struct ip6 *ip6;
|
struct ip6 *ip6;
|
||||||
|
Slirp *slirp = m->slirp;
|
||||||
|
|
||||||
|
if (!slirp->in6_enabled) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_CALL("ip6_input");
|
DEBUG_CALL("ip6_input");
|
||||||
DEBUG_ARG("m = %lx", (long)m);
|
DEBUG_ARG("m = %lx", (long)m);
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ ip_input(struct mbuf *m)
|
|||||||
register struct ip *ip;
|
register struct ip *ip;
|
||||||
int hlen;
|
int hlen;
|
||||||
|
|
||||||
|
if (!slirp->in_enabled) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_CALL("ip_input");
|
DEBUG_CALL("ip_input");
|
||||||
DEBUG_ARG("m = %p", m);
|
DEBUG_ARG("m = %p", m);
|
||||||
DEBUG_ARG("m_len = %d", m->m_len);
|
DEBUG_ARG("m_len = %d", m->m_len);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user