Compare commits
159 Commits
v10.0.0
...
factory-tm
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ad0d77979 | |||
| e8e25372e6 | |||
|
|
ac7c1fdf34 | ||
|
|
1a628f8432 | ||
|
|
13967c6f55 | ||
|
|
aca3bd489a | ||
|
|
85080b2e16 | ||
|
|
0217be221c | ||
| b0b6a79d59 | |||
|
|
c7d5ffda99 | ||
|
|
ce16801b98 | ||
| 7144e917d1 | |||
| 443e6b83fa | |||
| c8b89351de | |||
| 421ac7010a | |||
| 1f17ae756c | |||
|
|
fc39803e2e | ||
| 350a2257cf | |||
|
|
705797b274 | ||
|
|
03f0034809 | ||
|
|
4f8790600f | ||
|
|
1e2df3292c | ||
|
|
09fdc8d134 | ||
|
|
371d8a34ae | ||
|
|
91a5f8f76a | ||
|
|
fdbc2893bb | ||
|
|
b40443987c | ||
|
|
32f99eb3e9 | ||
|
|
9d1f67bbdb | ||
|
|
8f54a3aa8c | ||
|
|
63d05c5a42 | ||
|
|
23908f14c1 | ||
| 8bd1d20c9b | |||
|
|
e8bb983199 | ||
| 8f967fe55e | |||
| a01ddbc9e0 | |||
| 1481f28d89 | |||
| 480693258f | |||
| 834d2d4c05 | |||
| a64556e38c | |||
| 92cf0ae853 | |||
| 3731806241 | |||
| c9792dcd74 | |||
| 1d22b6bc08 | |||
| f380930e9e | |||
| d15ef6f72c | |||
| 0160de78fb | |||
| 5b6925ac05 | |||
| e4efa4ddf7 | |||
| f36095dfa6 | |||
| f9fdfcda3b | |||
| 9622249e5b | |||
| 5e3acdbfa4 | |||
|
|
3754a7fae9 | ||
| 1c6fb71448 | |||
| c34695e9fb | |||
| b42de2c98f | |||
| 7fe1b9a5ad | |||
|
|
9cc8211888 | ||
| 7648b7f665 | |||
| 9ea703addb | |||
| 9ec0676a96 | |||
| 825592ee80 | |||
| 2b7d0f07dc | |||
| 5fcdd58fe5 | |||
| 4753112f89 | |||
| 90ec2d8b05 | |||
| 915f48622e | |||
| c517c048a4 | |||
| e3440e36d7 | |||
| 105d383cbd | |||
| 7041d5a121 | |||
| 1091bcea05 | |||
| 0f684400ef | |||
| c47785f6bc | |||
| 3e65ad9c74 | |||
| 8720f92bab | |||
| e24ff3c060 | |||
| 3d21afd70f | |||
|
|
db189a9d6e | ||
| c7ec9cd53c | |||
| 32fb7be05e | |||
| b108923004 | |||
|
|
0cc0e05df5 | ||
|
|
4fc85385be | ||
| f1033a3e85 | |||
|
|
4f99b75e44 | ||
|
|
4d369602c4 | ||
| c1ed1ba2b7 | |||
|
|
a78310b9c0 | ||
|
|
4ced9070d0 | ||
| f0f33df812 | |||
|
|
823e2ad1f5 | ||
|
|
09e310e275 | ||
|
|
2588a9e594 | ||
|
|
57ed110b45 | ||
|
|
70fab7666b | ||
|
|
3905fdd0ba | ||
|
|
bd5cf804db | ||
|
|
208278c6d0 | ||
|
|
3abc9aea1b | ||
|
|
51852f6f7f | ||
|
|
92d6df091f | ||
|
|
60b4d7832a | ||
| 82d41ac427 | |||
| 886c28843c | |||
| 42252234aa | |||
| 933b8f614e | |||
| 332d530522 | |||
|
|
0ff5ab6f57 | ||
|
|
01fff50626 | ||
|
|
e1324ec946 | ||
|
|
9391f419c7 | ||
|
|
6d03242a7e | ||
|
|
2787ca0e0a | ||
|
|
10e3edd9b3 | ||
|
|
460ddd62fa | ||
|
|
6fecfc5978 | ||
|
|
c5f652a053 | ||
|
|
997f8d5c2b | ||
|
|
22359e0e6e | ||
|
|
e894be998d | ||
|
|
a4f9d9a4b2 | ||
|
|
8f583fd99a | ||
|
|
854a38fd9d | ||
|
|
167c8d374a | ||
|
|
18046fbec5 | ||
|
|
5762cdaf45 | ||
|
|
02ac67c41f | ||
|
|
e32ac563b8 | ||
|
|
767e7d8ae1 | ||
|
|
7eefbf8bb7 | ||
|
|
bb630d9251 | ||
|
|
8fc8dd2efd | ||
|
|
f8244f3b8c | ||
|
|
4c7c0d2442 | ||
|
|
51c943931d | ||
|
|
9cd1fd4b50 | ||
|
|
f84b79a8fc | ||
|
|
eb40b14740 | ||
|
|
03ee5e0c53 | ||
|
|
1faa437db9 | ||
|
|
9b42e33bda | ||
|
|
73f5d5bfb7 | ||
|
|
97fa3d7fcc | ||
|
|
659eeb16b3 | ||
|
|
0d889c5c86 | ||
|
|
02833b07b6 | ||
|
|
b95002f47a | ||
|
|
bec9a96934 | ||
|
|
df9aa3dd8c | ||
|
|
cd320c8a82 | ||
|
|
27a15a2a32 | ||
|
|
a160fa0fc3 | ||
|
|
3148a16b30 | ||
|
|
0e8f3eb43f | ||
|
|
ae2dc2a27a | ||
|
|
f74e5bd9b9 | ||
|
|
20eee6cb3d |
14
.b4-config
14
.b4-config
@@ -1,14 +0,0 @@
|
|||||||
#
|
|
||||||
# Common b4 settings that can be used to send patches to QEMU upstream.
|
|
||||||
# https://b4.docs.kernel.org/
|
|
||||||
#
|
|
||||||
|
|
||||||
[b4]
|
|
||||||
send-series-to = qemu-devel@nongnu.org
|
|
||||||
send-auto-to-cmd = echo
|
|
||||||
send-auto-cc-cmd = scripts/get_maintainer.pl --noroles --norolestats --nogit --nogit-fallback
|
|
||||||
am-perpatch-check-cmd = scripts/checkpatch.pl -q --terse --no-summary --mailback -
|
|
||||||
prep-perpatch-check-cmd = scripts/checkpatch.pl -q --terse --no-summary --mailback -
|
|
||||||
searchmask = https://lore.kernel.org/qemu-devel/?x=m&t=1&q=%s
|
|
||||||
linkmask = https://lore.kernel.org/qemu-devel/%s
|
|
||||||
linktrailermask = Message-ID: <%s>
|
|
||||||
@@ -47,16 +47,3 @@ emacs_mode = glsl
|
|||||||
[*.json]
|
[*.json]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
emacs_mode = python
|
emacs_mode = python
|
||||||
|
|
||||||
# by default follow QEMU's style
|
|
||||||
[*.pl]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
emacs_mode = perl
|
|
||||||
|
|
||||||
# but user kernel "style" for imported scripts
|
|
||||||
[scripts/{kernel-doc,get_maintainer.pl,checkpatch.pl}]
|
|
||||||
indent_style = tab
|
|
||||||
indent_size = 8
|
|
||||||
emacs_mode = perl
|
|
||||||
|
|
||||||
|
|||||||
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -2,8 +2,3 @@
|
|||||||
*.h.inc diff=c
|
*.h.inc diff=c
|
||||||
*.m diff=objc
|
*.m diff=objc
|
||||||
*.py diff=python
|
*.py diff=python
|
||||||
*.rs diff=rust
|
|
||||||
*.rs.inc diff=rust
|
|
||||||
Cargo.lock diff=toml merge=binary
|
|
||||||
|
|
||||||
*.patch -text -whitespace
|
|
||||||
|
|||||||
@@ -8,11 +8,8 @@
|
|||||||
key: "$CI_JOB_NAME"
|
key: "$CI_JOB_NAME"
|
||||||
when: always
|
when: always
|
||||||
before_script:
|
before_script:
|
||||||
- source scripts/ci/gitlab-ci-section
|
|
||||||
- section_start setup "Pre-script setup"
|
|
||||||
- JOBS=$(expr $(nproc) + 1)
|
- JOBS=$(expr $(nproc) + 1)
|
||||||
- cat /packages.txt
|
- cat /packages.txt
|
||||||
- section_end setup
|
|
||||||
script:
|
script:
|
||||||
- export CCACHE_BASEDIR="$(pwd)"
|
- export CCACHE_BASEDIR="$(pwd)"
|
||||||
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
||||||
@@ -22,7 +19,6 @@
|
|||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- ccache --zero-stats
|
- ccache --zero-stats
|
||||||
- section_start configure "Running configure"
|
|
||||||
- ../configure --enable-werror --disable-docs --enable-fdt=system
|
- ../configure --enable-werror --disable-docs --enable-fdt=system
|
||||||
${TARGETS:+--target-list="$TARGETS"}
|
${TARGETS:+--target-list="$TARGETS"}
|
||||||
$CONFIGURE_ARGS ||
|
$CONFIGURE_ARGS ||
|
||||||
@@ -31,16 +27,11 @@
|
|||||||
then
|
then
|
||||||
pyvenv/bin/meson configure . -Dbackend_max_links="$LD_JOBS" ;
|
pyvenv/bin/meson configure . -Dbackend_max_links="$LD_JOBS" ;
|
||||||
fi || exit 1;
|
fi || exit 1;
|
||||||
- section_end configure
|
|
||||||
- section_start build "Building QEMU"
|
|
||||||
- $MAKE -j"$JOBS"
|
- $MAKE -j"$JOBS"
|
||||||
- section_end build
|
|
||||||
- section_start test "Running tests"
|
|
||||||
- if test -n "$MAKE_CHECK_ARGS";
|
- if test -n "$MAKE_CHECK_ARGS";
|
||||||
then
|
then
|
||||||
$MAKE -j"$JOBS" $MAKE_CHECK_ARGS ;
|
$MAKE -j"$JOBS" $MAKE_CHECK_ARGS ;
|
||||||
fi
|
fi
|
||||||
- section_end test
|
|
||||||
- ccache --show-stats
|
- ccache --show-stats
|
||||||
|
|
||||||
# We jump some hoops in common_test_job_template to avoid
|
# We jump some hoops in common_test_job_template to avoid
|
||||||
@@ -63,21 +54,12 @@
|
|||||||
stage: test
|
stage: test
|
||||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
|
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
|
||||||
script:
|
script:
|
||||||
- source scripts/ci/gitlab-ci-section
|
|
||||||
- section_start buildenv "Setting up to run tests"
|
|
||||||
- scripts/git-submodule.sh update roms/SLOF
|
- scripts/git-submodule.sh update roms/SLOF
|
||||||
- build/pyvenv/bin/meson subprojects download $(cd build/subprojects && echo *)
|
- meson subprojects download $(cd build/subprojects && echo *)
|
||||||
- cd build
|
- cd build
|
||||||
- find . -type f -exec touch {} +
|
- find . -type f -exec touch {} +
|
||||||
# Avoid recompiling by hiding ninja with NINJA=":"
|
# Avoid recompiling by hiding ninja with NINJA=":"
|
||||||
# We also have to pre-cache the functional tests manually in this case
|
|
||||||
- if [ "x${QEMU_TEST_CACHE_DIR}" != "x" ]; then
|
|
||||||
$MAKE precache-functional ;
|
|
||||||
fi
|
|
||||||
- section_end buildenv
|
|
||||||
- section_start test "Running tests"
|
|
||||||
- $MAKE NINJA=":" $MAKE_CHECK_ARGS
|
- $MAKE NINJA=":" $MAKE_CHECK_ARGS
|
||||||
- section_end test
|
|
||||||
|
|
||||||
.native_test_job_template:
|
.native_test_job_template:
|
||||||
extends: .common_test_job_template
|
extends: .common_test_job_template
|
||||||
@@ -90,13 +72,12 @@
|
|||||||
reports:
|
reports:
|
||||||
junit: build/meson-logs/testlog.junit.xml
|
junit: build/meson-logs/testlog.junit.xml
|
||||||
|
|
||||||
.functional_test_job_template:
|
.avocado_test_job_template:
|
||||||
extends: .common_test_job_template
|
extends: .common_test_job_template
|
||||||
cache:
|
cache:
|
||||||
key: "${CI_JOB_NAME}-cache"
|
key: "${CI_JOB_NAME}-cache"
|
||||||
paths:
|
paths:
|
||||||
- ${CI_PROJECT_DIR}/avocado-cache
|
- ${CI_PROJECT_DIR}/avocado-cache
|
||||||
- ${CI_PROJECT_DIR}/functional-cache
|
|
||||||
policy: pull-push
|
policy: pull-push
|
||||||
artifacts:
|
artifacts:
|
||||||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||||
@@ -105,7 +86,6 @@
|
|||||||
paths:
|
paths:
|
||||||
- build/tests/results/latest/results.xml
|
- build/tests/results/latest/results.xml
|
||||||
- build/tests/results/latest/test-results
|
- build/tests/results/latest/test-results
|
||||||
- build/tests/functional/*/*/*.log
|
|
||||||
reports:
|
reports:
|
||||||
junit: build/tests/results/latest/results.xml
|
junit: build/tests/results/latest/results.xml
|
||||||
before_script:
|
before_script:
|
||||||
@@ -116,13 +96,11 @@
|
|||||||
- echo -e '[job.output.testlogs]\nstatuses = ["FAIL", "INTERRUPT"]'
|
- echo -e '[job.output.testlogs]\nstatuses = ["FAIL", "INTERRUPT"]'
|
||||||
>> ~/.config/avocado/avocado.conf
|
>> ~/.config/avocado/avocado.conf
|
||||||
- if [ -d ${CI_PROJECT_DIR}/avocado-cache ]; then
|
- if [ -d ${CI_PROJECT_DIR}/avocado-cache ]; then
|
||||||
du -chs ${CI_PROJECT_DIR}/*-cache ;
|
du -chs ${CI_PROJECT_DIR}/avocado-cache ;
|
||||||
fi
|
fi
|
||||||
- export AVOCADO_ALLOW_UNTRUSTED_CODE=1
|
- export AVOCADO_ALLOW_UNTRUSTED_CODE=1
|
||||||
- export QEMU_TEST_ALLOW_UNTRUSTED_CODE=1
|
|
||||||
- export QEMU_TEST_CACHE_DIR=${CI_PROJECT_DIR}/functional-cache
|
|
||||||
after_script:
|
after_script:
|
||||||
- cd build
|
- cd build
|
||||||
- du -chs ${CI_PROJECT_DIR}/*-cache
|
- du -chs ${CI_PROJECT_DIR}/avocado-cache
|
||||||
variables:
|
variables:
|
||||||
QEMU_JOB_AVOCADO: 1
|
QEMU_JOB_AVOCADO: 1
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ check-system-alpine:
|
|||||||
IMAGE: alpine
|
IMAGE: alpine
|
||||||
MAKE_CHECK_ARGS: check-unit check-qtest
|
MAKE_CHECK_ARGS: check-unit check-qtest
|
||||||
|
|
||||||
functional-system-alpine:
|
avocado-system-alpine:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-system-alpine
|
- job: build-system-alpine
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: alpine
|
IMAGE: alpine
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
AVOCADO_TAGS: arch:avr arch:loongarch64 arch:mips64 arch:mipsel
|
AVOCADO_TAGS: arch:avr arch:loongarch64 arch:mips64 arch:mipsel
|
||||||
|
|
||||||
build-system-ubuntu:
|
build-system-ubuntu:
|
||||||
@@ -40,7 +40,7 @@ build-system-ubuntu:
|
|||||||
job: amd64-ubuntu2204-container
|
job: amd64-ubuntu2204-container
|
||||||
variables:
|
variables:
|
||||||
IMAGE: ubuntu2204
|
IMAGE: ubuntu2204
|
||||||
CONFIGURE_ARGS: --enable-docs --enable-rust
|
CONFIGURE_ARGS: --enable-docs
|
||||||
TARGETS: alpha-softmmu microblazeel-softmmu mips64el-softmmu
|
TARGETS: alpha-softmmu microblazeel-softmmu mips64el-softmmu
|
||||||
MAKE_CHECK_ARGS: check-build
|
MAKE_CHECK_ARGS: check-build
|
||||||
|
|
||||||
@@ -53,14 +53,14 @@ check-system-ubuntu:
|
|||||||
IMAGE: ubuntu2204
|
IMAGE: ubuntu2204
|
||||||
MAKE_CHECK_ARGS: check
|
MAKE_CHECK_ARGS: check
|
||||||
|
|
||||||
functional-system-ubuntu:
|
avocado-system-ubuntu:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-system-ubuntu
|
- job: build-system-ubuntu
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: ubuntu2204
|
IMAGE: ubuntu2204
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
AVOCADO_TAGS: arch:alpha arch:microblazeel arch:mips64el
|
AVOCADO_TAGS: arch:alpha arch:microblazeel arch:mips64el
|
||||||
|
|
||||||
build-system-debian:
|
build-system-debian:
|
||||||
@@ -71,7 +71,7 @@ build-system-debian:
|
|||||||
job: amd64-debian-container
|
job: amd64-debian-container
|
||||||
variables:
|
variables:
|
||||||
IMAGE: debian
|
IMAGE: debian
|
||||||
CONFIGURE_ARGS: --with-coroutine=sigaltstack --enable-rust
|
CONFIGURE_ARGS: --with-coroutine=sigaltstack
|
||||||
TARGETS: arm-softmmu i386-softmmu riscv64-softmmu sh4eb-softmmu
|
TARGETS: arm-softmmu i386-softmmu riscv64-softmmu sh4eb-softmmu
|
||||||
sparc-softmmu xtensa-softmmu
|
sparc-softmmu xtensa-softmmu
|
||||||
MAKE_CHECK_ARGS: check-build
|
MAKE_CHECK_ARGS: check-build
|
||||||
@@ -85,14 +85,14 @@ check-system-debian:
|
|||||||
IMAGE: debian
|
IMAGE: debian
|
||||||
MAKE_CHECK_ARGS: check
|
MAKE_CHECK_ARGS: check
|
||||||
|
|
||||||
functional-system-debian:
|
avocado-system-debian:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-system-debian
|
- job: build-system-debian
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: debian
|
IMAGE: debian
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
AVOCADO_TAGS: arch:arm arch:i386 arch:riscv64 arch:sh4 arch:sparc arch:xtensa
|
AVOCADO_TAGS: arch:arm arch:i386 arch:riscv64 arch:sh4 arch:sparc arch:xtensa
|
||||||
|
|
||||||
crash-test-debian:
|
crash-test-debian:
|
||||||
@@ -115,30 +115,11 @@ build-system-fedora:
|
|||||||
job: amd64-fedora-container
|
job: amd64-fedora-container
|
||||||
variables:
|
variables:
|
||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs --enable-crypto-afalg --enable-rust
|
CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs
|
||||||
TARGETS: microblaze-softmmu mips-softmmu
|
TARGETS: microblaze-softmmu mips-softmmu
|
||||||
xtensa-softmmu m68k-softmmu riscv32-softmmu ppc-softmmu sparc64-softmmu
|
xtensa-softmmu m68k-softmmu riscv32-softmmu ppc-softmmu sparc64-softmmu
|
||||||
MAKE_CHECK_ARGS: check-build
|
MAKE_CHECK_ARGS: check-build
|
||||||
|
|
||||||
build-system-fedora-rust-nightly:
|
|
||||||
extends:
|
|
||||||
- .native_build_job_template
|
|
||||||
- .native_build_artifact_template
|
|
||||||
needs:
|
|
||||||
job: amd64-fedora-rust-nightly-container
|
|
||||||
variables:
|
|
||||||
IMAGE: fedora-rust-nightly
|
|
||||||
CONFIGURE_ARGS: --disable-docs --enable-rust --enable-strict-rust-lints
|
|
||||||
TARGETS: aarch64-softmmu
|
|
||||||
MAKE_CHECK_ARGS: check-build
|
|
||||||
after_script:
|
|
||||||
- source scripts/ci/gitlab-ci-section
|
|
||||||
- section_start test "Running Rust doctests"
|
|
||||||
- cd build
|
|
||||||
- pyvenv/bin/meson devenv -w ../rust ${CARGO-cargo} test --doc -p qemu_api
|
|
||||||
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
check-system-fedora:
|
check-system-fedora:
|
||||||
extends: .native_test_job_template
|
extends: .native_test_job_template
|
||||||
needs:
|
needs:
|
||||||
@@ -148,14 +129,14 @@ check-system-fedora:
|
|||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
MAKE_CHECK_ARGS: check
|
MAKE_CHECK_ARGS: check
|
||||||
|
|
||||||
functional-system-fedora:
|
avocado-system-fedora:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-system-fedora
|
- job: build-system-fedora
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
AVOCADO_TAGS: arch:microblaze arch:mips arch:xtensa arch:m68k
|
AVOCADO_TAGS: arch:microblaze arch:mips arch:xtensa arch:m68k
|
||||||
arch:riscv32 arch:ppc arch:sparc64
|
arch:riscv32 arch:ppc arch:sparc64
|
||||||
|
|
||||||
@@ -207,7 +188,6 @@ build-previous-qemu:
|
|||||||
# Override the default flags as we need more to grab the old version
|
# Override the default flags as we need more to grab the old version
|
||||||
GIT_FETCH_EXTRA_FLAGS: --prune --quiet
|
GIT_FETCH_EXTRA_FLAGS: --prune --quiet
|
||||||
before_script:
|
before_script:
|
||||||
- source scripts/ci/gitlab-ci-section
|
|
||||||
- export QEMU_PREV_VERSION="$(sed 's/\([0-9.]*\)\.[0-9]*/v\1.0/' VERSION)"
|
- export QEMU_PREV_VERSION="$(sed 's/\([0-9.]*\)\.[0-9]*/v\1.0/' VERSION)"
|
||||||
- git remote add upstream https://gitlab.com/qemu-project/qemu
|
- git remote add upstream https://gitlab.com/qemu-project/qemu
|
||||||
- git fetch upstream refs/tags/$QEMU_PREV_VERSION:refs/tags/$QEMU_PREV_VERSION
|
- git fetch upstream refs/tags/$QEMU_PREV_VERSION:refs/tags/$QEMU_PREV_VERSION
|
||||||
@@ -232,14 +212,6 @@ build-previous-qemu:
|
|||||||
# testing an old QEMU against new features/tests that it is not
|
# testing an old QEMU against new features/tests that it is not
|
||||||
# compatible with.
|
# compatible with.
|
||||||
- cd build-previous
|
- cd build-previous
|
||||||
# Don't allow python-based tests to run. The
|
|
||||||
# vmstate-checker-script test has a race that causes it to fail
|
|
||||||
# sometimes. It cannot be fixed it because this job runs the test
|
|
||||||
# from the old QEMU version. The test will be removed on master,
|
|
||||||
# but this job will only see the change in the next release.
|
|
||||||
#
|
|
||||||
# TODO: remove this line after 9.2 release
|
|
||||||
- unset PYTHON
|
|
||||||
# old to new
|
# old to new
|
||||||
- QTEST_QEMU_BINARY_SRC=./qemu-system-${TARGET}
|
- QTEST_QEMU_BINARY_SRC=./qemu-system-${TARGET}
|
||||||
QTEST_QEMU_BINARY=../build/qemu-system-${TARGET} ./tests/qtest/migration-test
|
QTEST_QEMU_BINARY=../build/qemu-system-${TARGET} ./tests/qtest/migration-test
|
||||||
@@ -271,14 +243,14 @@ check-system-centos:
|
|||||||
IMAGE: centos9
|
IMAGE: centos9
|
||||||
MAKE_CHECK_ARGS: check
|
MAKE_CHECK_ARGS: check
|
||||||
|
|
||||||
functional-system-centos:
|
avocado-system-centos:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-system-centos
|
- job: build-system-centos
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: centos9
|
IMAGE: centos9
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
AVOCADO_TAGS: arch:ppc64 arch:or1k arch:s390x arch:x86_64 arch:rx
|
AVOCADO_TAGS: arch:ppc64 arch:or1k arch:s390x arch:x86_64 arch:rx
|
||||||
arch:sh4
|
arch:sh4
|
||||||
|
|
||||||
@@ -302,14 +274,14 @@ check-system-opensuse:
|
|||||||
IMAGE: opensuse-leap
|
IMAGE: opensuse-leap
|
||||||
MAKE_CHECK_ARGS: check
|
MAKE_CHECK_ARGS: check
|
||||||
|
|
||||||
functional-system-opensuse:
|
avocado-system-opensuse:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-system-opensuse
|
- job: build-system-opensuse
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: opensuse-leap
|
IMAGE: opensuse-leap
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
AVOCADO_TAGS: arch:s390x arch:x86_64 arch:aarch64
|
AVOCADO_TAGS: arch:s390x arch:x86_64 arch:aarch64
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -330,15 +302,15 @@ build-system-flaky:
|
|||||||
ppc64-softmmu rx-softmmu s390x-softmmu sh4-softmmu x86_64-softmmu
|
ppc64-softmmu rx-softmmu s390x-softmmu sh4-softmmu x86_64-softmmu
|
||||||
MAKE_CHECK_ARGS: check-build
|
MAKE_CHECK_ARGS: check-build
|
||||||
|
|
||||||
functional-system-flaky:
|
avocado-system-flaky:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-system-flaky
|
- job: build-system-flaky
|
||||||
artifacts: true
|
artifacts: true
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: debian
|
IMAGE: debian
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
QEMU_JOB_OPTIONAL: 1
|
QEMU_JOB_OPTIONAL: 1
|
||||||
QEMU_TEST_FLAKY_TESTS: 1
|
QEMU_TEST_FLAKY_TESTS: 1
|
||||||
AVOCADO_TAGS: flaky
|
AVOCADO_TAGS: flaky
|
||||||
@@ -458,8 +430,9 @@ clang-system:
|
|||||||
job: amd64-fedora-container
|
job: amd64-fedora-container
|
||||||
variables:
|
variables:
|
||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
CONFIGURE_ARGS: --cc=clang --cxx=clang++ --enable-ubsan
|
CONFIGURE_ARGS: --cc=clang --cxx=clang++
|
||||||
--extra-cflags=-fno-sanitize-recover=undefined
|
--extra-cflags=-fsanitize=undefined --extra-cflags=-fno-sanitize-recover=undefined
|
||||||
|
--extra-cflags=-fno-sanitize=function
|
||||||
TARGETS: alpha-softmmu arm-softmmu m68k-softmmu mips64-softmmu s390x-softmmu
|
TARGETS: alpha-softmmu arm-softmmu m68k-softmmu mips64-softmmu s390x-softmmu
|
||||||
MAKE_CHECK_ARGS: check-qtest check-tcg
|
MAKE_CHECK_ARGS: check-qtest check-tcg
|
||||||
|
|
||||||
@@ -470,9 +443,10 @@ clang-user:
|
|||||||
timeout: 70m
|
timeout: 70m
|
||||||
variables:
|
variables:
|
||||||
IMAGE: debian-all-test-cross
|
IMAGE: debian-all-test-cross
|
||||||
CONFIGURE_ARGS: --cc=clang --cxx=clang++ --disable-system --enable-ubsan
|
CONFIGURE_ARGS: --cc=clang --cxx=clang++ --disable-system
|
||||||
--target-list-exclude=alpha-linux-user,microblazeel-linux-user,aarch64_be-linux-user,i386-linux-user,m68k-linux-user,mipsn32el-linux-user,xtensaeb-linux-user
|
--target-list-exclude=alpha-linux-user,microblazeel-linux-user,aarch64_be-linux-user,i386-linux-user,m68k-linux-user,mipsn32el-linux-user,xtensaeb-linux-user
|
||||||
--extra-cflags=-fno-sanitize-recover=undefined
|
--extra-cflags=-fsanitize=undefined --extra-cflags=-fno-sanitize-recover=undefined
|
||||||
|
--extra-cflags=-fno-sanitize=function
|
||||||
MAKE_CHECK_ARGS: check-unit check-tcg
|
MAKE_CHECK_ARGS: check-unit check-tcg
|
||||||
|
|
||||||
# Set LD_JOBS=1 because this requires LTO and ld consumes a large amount of memory.
|
# Set LD_JOBS=1 because this requires LTO and ld consumes a large amount of memory.
|
||||||
@@ -513,14 +487,14 @@ check-cfi-aarch64:
|
|||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
MAKE_CHECK_ARGS: check
|
MAKE_CHECK_ARGS: check
|
||||||
|
|
||||||
functional-cfi-aarch64:
|
avocado-cfi-aarch64:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-cfi-aarch64
|
- job: build-cfi-aarch64
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
|
|
||||||
build-cfi-ppc64-s390x:
|
build-cfi-ppc64-s390x:
|
||||||
extends:
|
extends:
|
||||||
@@ -551,14 +525,14 @@ check-cfi-ppc64-s390x:
|
|||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
MAKE_CHECK_ARGS: check
|
MAKE_CHECK_ARGS: check
|
||||||
|
|
||||||
functional-cfi-ppc64-s390x:
|
avocado-cfi-ppc64-s390x:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-cfi-ppc64-s390x
|
- job: build-cfi-ppc64-s390x
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
|
|
||||||
build-cfi-x86_64:
|
build-cfi-x86_64:
|
||||||
extends:
|
extends:
|
||||||
@@ -585,14 +559,14 @@ check-cfi-x86_64:
|
|||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
MAKE_CHECK_ARGS: check
|
MAKE_CHECK_ARGS: check
|
||||||
|
|
||||||
functional-cfi-x86_64:
|
avocado-cfi-x86_64:
|
||||||
extends: .functional_test_job_template
|
extends: .avocado_test_job_template
|
||||||
needs:
|
needs:
|
||||||
- job: build-cfi-x86_64
|
- job: build-cfi-x86_64
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
variables:
|
||||||
IMAGE: fedora
|
IMAGE: fedora
|
||||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
MAKE_CHECK_ARGS: check-avocado
|
||||||
|
|
||||||
tsan-build:
|
tsan-build:
|
||||||
extends: .native_build_job_template
|
extends: .native_build_job_template
|
||||||
@@ -647,15 +621,12 @@ build-oss-fuzz:
|
|||||||
- CC="clang" CXX="clang++" CFLAGS="-fsanitize=address"
|
- CC="clang" CXX="clang++" CFLAGS="-fsanitize=address"
|
||||||
./scripts/oss-fuzz/build.sh
|
./scripts/oss-fuzz/build.sh
|
||||||
- export ASAN_OPTIONS="fast_unwind_on_malloc=0"
|
- export ASAN_OPTIONS="fast_unwind_on_malloc=0"
|
||||||
- failures=0
|
|
||||||
- for fuzzer in $(find ./build-oss-fuzz/DEST_DIR/ -executable -type f
|
- for fuzzer in $(find ./build-oss-fuzz/DEST_DIR/ -executable -type f
|
||||||
| grep -v slirp); do
|
| grep -v slirp); do
|
||||||
grep "LLVMFuzzerTestOneInput" ${fuzzer} > /dev/null 2>&1 || continue ;
|
grep "LLVMFuzzerTestOneInput" ${fuzzer} > /dev/null 2>&1 || continue ;
|
||||||
echo Testing ${fuzzer} ... ;
|
echo Testing ${fuzzer} ... ;
|
||||||
"${fuzzer}" -runs=1 -seed=1 || { echo "FAILED:"" ${fuzzer} exit code is $?"; failures=$(($failures+1)); };
|
"${fuzzer}" -runs=1 -seed=1 || exit 1 ;
|
||||||
done
|
done
|
||||||
- echo "Number of failures:"" $failures"
|
|
||||||
- test $failures = 0
|
|
||||||
|
|
||||||
build-tci:
|
build-tci:
|
||||||
extends: .native_build_job_template
|
extends: .native_build_job_template
|
||||||
@@ -682,6 +653,9 @@ build-tci:
|
|||||||
- make check-tcg
|
- make check-tcg
|
||||||
|
|
||||||
# Check our reduced build configurations
|
# Check our reduced build configurations
|
||||||
|
# requires libfdt: aarch64, arm, loongarch64, microblaze, microblazeel,
|
||||||
|
# or1k, ppc64, riscv32, riscv64, rx
|
||||||
|
# fails qtest without boards: i386, x86_64
|
||||||
build-without-defaults:
|
build-without-defaults:
|
||||||
extends: .native_build_job_template
|
extends: .native_build_job_template
|
||||||
needs:
|
needs:
|
||||||
@@ -695,7 +669,11 @@ build-without-defaults:
|
|||||||
--disable-pie
|
--disable-pie
|
||||||
--disable-qom-cast-debug
|
--disable-qom-cast-debug
|
||||||
--disable-strip
|
--disable-strip
|
||||||
--target-list-exclude=aarch64-softmmu,microblaze-softmmu,mips64-softmmu,mipsel-softmmu,ppc64-softmmu,sh4el-softmmu,xtensa-softmmu,x86_64-softmmu
|
TARGETS: alpha-softmmu avr-softmmu cris-softmmu hppa-softmmu m68k-softmmu
|
||||||
|
mips-softmmu mips64-softmmu mipsel-softmmu mips64el-softmmu
|
||||||
|
ppc-softmmu s390x-softmmu sh4-softmmu sh4eb-softmmu sparc-softmmu
|
||||||
|
sparc64-softmmu tricore-softmmu xtensa-softmmu xtensaeb-softmmu
|
||||||
|
hexagon-linux-user i386-linux-user s390x-linux-user
|
||||||
MAKE_CHECK_ARGS: check
|
MAKE_CHECK_ARGS: check
|
||||||
|
|
||||||
build-libvhost-user:
|
build-libvhost-user:
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ cwd = os.getcwd()
|
|||||||
reponame = os.path.basename(cwd)
|
reponame = os.path.basename(cwd)
|
||||||
repourl = "https://gitlab.com/%s/%s.git" % (namespace, reponame)
|
repourl = "https://gitlab.com/%s/%s.git" % (namespace, reponame)
|
||||||
|
|
||||||
print(f"adding upstream git repo @ {repourl}")
|
|
||||||
subprocess.check_call(["git", "remote", "add", "check-dco", repourl])
|
subprocess.check_call(["git", "remote", "add", "check-dco", repourl])
|
||||||
subprocess.check_call(["git", "fetch", "--refetch", "check-dco", "master"])
|
subprocess.check_call(["git", "fetch", "check-dco", "master"],
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
ancestor = subprocess.check_output(["git", "merge-base",
|
ancestor = subprocess.check_output(["git", "merge-base",
|
||||||
"check-dco/master", "HEAD"],
|
"check-dco/master", "HEAD"],
|
||||||
@@ -78,10 +79,7 @@ of Origin 1.1 (DCO):
|
|||||||
|
|
||||||
To indicate acceptance of the DCO every commit must have a tag
|
To indicate acceptance of the DCO every commit must have a tag
|
||||||
|
|
||||||
Signed-off-by: YOUR NAME <EMAIL>
|
Signed-off-by: REAL NAME <EMAIL>
|
||||||
|
|
||||||
where "YOUR NAME" is your commonly known identity in the context
|
|
||||||
of the community.
|
|
||||||
|
|
||||||
This can be achieved by passing the "-s" flag to the "git commit" command.
|
This can be achieved by passing the "-s" flag to the "git commit" command.
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,13 @@ cwd = os.getcwd()
|
|||||||
reponame = os.path.basename(cwd)
|
reponame = os.path.basename(cwd)
|
||||||
repourl = "https://gitlab.com/%s/%s.git" % (namespace, reponame)
|
repourl = "https://gitlab.com/%s/%s.git" % (namespace, reponame)
|
||||||
|
|
||||||
print(f"adding upstream git repo @ {repourl}")
|
|
||||||
# GitLab CI environment does not give us any direct info about the
|
# GitLab CI environment does not give us any direct info about the
|
||||||
# base for the user's branch. We thus need to figure out a common
|
# base for the user's branch. We thus need to figure out a common
|
||||||
# ancestor between the user's branch and current git master.
|
# ancestor between the user's branch and current git master.
|
||||||
subprocess.check_call(["git", "remote", "add", "check-patch", repourl])
|
subprocess.check_call(["git", "remote", "add", "check-patch", repourl])
|
||||||
subprocess.check_call(["git", "fetch", "--refetch", "check-patch", "master"])
|
subprocess.check_call(["git", "fetch", "check-patch", "master"],
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
ancestor = subprocess.check_output(["git", "merge-base",
|
ancestor = subprocess.check_output(["git", "merge-base",
|
||||||
"check-patch/master", "HEAD"],
|
"check-patch/master", "HEAD"],
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
#
|
|
||||||
# check-units.py: check the number of compilation units and identify
|
|
||||||
# those that are rebuilt multiple times
|
|
||||||
#
|
|
||||||
# Copyright (C) 2025 Linaro Ltd.
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
from os import access, R_OK, path
|
|
||||||
from sys import argv, exit
|
|
||||||
import json
|
|
||||||
from collections import Counter
|
|
||||||
|
|
||||||
|
|
||||||
def extract_build_units(cc_path):
|
|
||||||
"""
|
|
||||||
Extract the build units and their counds from compile_commands.json file.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Hash table of ["unit"] = count
|
|
||||||
"""
|
|
||||||
|
|
||||||
j = json.load(open(cc_path, 'r'))
|
|
||||||
files = [f['file'] for f in j]
|
|
||||||
build_units = Counter(files)
|
|
||||||
|
|
||||||
return build_units
|
|
||||||
|
|
||||||
|
|
||||||
def analyse_units(build_units):
|
|
||||||
"""
|
|
||||||
Analyse the build units and report stats and the top 10 rebuilds
|
|
||||||
"""
|
|
||||||
|
|
||||||
print(f"Total source files: {len(build_units.keys())}")
|
|
||||||
print(f"Total build units: {sum(units.values())}")
|
|
||||||
|
|
||||||
# Create a sorted list by number of rebuilds
|
|
||||||
sorted_build_units = sorted(build_units.items(),
|
|
||||||
key=lambda item: item[1],
|
|
||||||
reverse=True)
|
|
||||||
|
|
||||||
print("Most rebuilt units:")
|
|
||||||
for unit, count in sorted_build_units[:20]:
|
|
||||||
print(f" {unit} built {count} times")
|
|
||||||
|
|
||||||
print("Least rebuilt units:")
|
|
||||||
for unit, count in sorted_build_units[-10:]:
|
|
||||||
print(f" {unit} built {count} times")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
if len(argv) != 2:
|
|
||||||
script_name = path.basename(argv[0])
|
|
||||||
print(f"Usage: {script_name} <path_to_compile_commands.json>")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
cc_path = argv[1]
|
|
||||||
if path.isfile(cc_path) and access(cc_path, R_OK):
|
|
||||||
units = extract_build_units(cc_path)
|
|
||||||
analyse_units(units)
|
|
||||||
exit(0)
|
|
||||||
else:
|
|
||||||
print(f"{cc_path} doesn't exist or isn't readable")
|
|
||||||
exit(1)
|
|
||||||
@@ -15,29 +15,44 @@
|
|||||||
stage: build
|
stage: build
|
||||||
image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:latest
|
image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:latest
|
||||||
needs: []
|
needs: []
|
||||||
allow_failure:
|
|
||||||
exit_codes: 3
|
|
||||||
# 20 mins larger than "timeout_in" in cirrus/build.yml
|
# 20 mins larger than "timeout_in" in cirrus/build.yml
|
||||||
# as there's often a 5-10 minute delay before Cirrus CI
|
# as there's often a 5-10 minute delay before Cirrus CI
|
||||||
# actually starts the task
|
# actually starts the task
|
||||||
timeout: 80m
|
timeout: 80m
|
||||||
script:
|
script:
|
||||||
- set -o allexport
|
|
||||||
- source .gitlab-ci.d/cirrus/$NAME.vars
|
- source .gitlab-ci.d/cirrus/$NAME.vars
|
||||||
- set +o allexport
|
- sed -e "s|[@]CI_REPOSITORY_URL@|$CI_REPOSITORY_URL|g"
|
||||||
- cirrus-vars <.gitlab-ci.d/cirrus/build.yml >.gitlab-ci.d/cirrus/$NAME.yml
|
-e "s|[@]CI_COMMIT_REF_NAME@|$CI_COMMIT_REF_NAME|g"
|
||||||
|
-e "s|[@]CI_COMMIT_SHA@|$CI_COMMIT_SHA|g"
|
||||||
|
-e "s|[@]CIRRUS_VM_INSTANCE_TYPE@|$CIRRUS_VM_INSTANCE_TYPE|g"
|
||||||
|
-e "s|[@]CIRRUS_VM_IMAGE_SELECTOR@|$CIRRUS_VM_IMAGE_SELECTOR|g"
|
||||||
|
-e "s|[@]CIRRUS_VM_IMAGE_NAME@|$CIRRUS_VM_IMAGE_NAME|g"
|
||||||
|
-e "s|[@]CIRRUS_VM_CPUS@|$CIRRUS_VM_CPUS|g"
|
||||||
|
-e "s|[@]CIRRUS_VM_RAM@|$CIRRUS_VM_RAM|g"
|
||||||
|
-e "s|[@]UPDATE_COMMAND@|$UPDATE_COMMAND|g"
|
||||||
|
-e "s|[@]INSTALL_COMMAND@|$INSTALL_COMMAND|g"
|
||||||
|
-e "s|[@]PATH@|$PATH_EXTRA${PATH_EXTRA:+:}\$PATH|g"
|
||||||
|
-e "s|[@]PKG_CONFIG_PATH@|$PKG_CONFIG_PATH|g"
|
||||||
|
-e "s|[@]PKGS@|$PKGS|g"
|
||||||
|
-e "s|[@]MAKE@|$MAKE|g"
|
||||||
|
-e "s|[@]PYTHON@|$PYTHON|g"
|
||||||
|
-e "s|[@]PIP3@|$PIP3|g"
|
||||||
|
-e "s|[@]PYPI_PKGS@|$PYPI_PKGS|g"
|
||||||
|
-e "s|[@]CONFIGURE_ARGS@|$CONFIGURE_ARGS|g"
|
||||||
|
-e "s|[@]TEST_TARGETS@|$TEST_TARGETS|g"
|
||||||
|
<.gitlab-ci.d/cirrus/build.yml >.gitlab-ci.d/cirrus/$NAME.yml
|
||||||
- cat .gitlab-ci.d/cirrus/$NAME.yml
|
- cat .gitlab-ci.d/cirrus/$NAME.yml
|
||||||
- cirrus-run -v --show-build-log always .gitlab-ci.d/cirrus/$NAME.yml
|
- cirrus-run -v --show-build-log always .gitlab-ci.d/cirrus/$NAME.yml
|
||||||
variables:
|
variables:
|
||||||
QEMU_JOB_CIRRUS: 1
|
QEMU_JOB_CIRRUS: 1
|
||||||
|
|
||||||
x64-freebsd-14-build:
|
x64-freebsd-13-build:
|
||||||
extends: .cirrus_build_job
|
extends: .cirrus_build_job
|
||||||
variables:
|
variables:
|
||||||
NAME: freebsd-14
|
NAME: freebsd-13
|
||||||
CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
|
CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
|
||||||
CIRRUS_VM_IMAGE_SELECTOR: image_family
|
CIRRUS_VM_IMAGE_SELECTOR: image_family
|
||||||
CIRRUS_VM_IMAGE_NAME: freebsd-14-2
|
CIRRUS_VM_IMAGE_NAME: freebsd-13-3
|
||||||
CIRRUS_VM_CPUS: 8
|
CIRRUS_VM_CPUS: 8
|
||||||
CIRRUS_VM_RAM: 8G
|
CIRRUS_VM_RAM: 8G
|
||||||
UPDATE_COMMAND: pkg update; pkg upgrade -y
|
UPDATE_COMMAND: pkg update; pkg upgrade -y
|
||||||
@@ -45,16 +60,34 @@ x64-freebsd-14-build:
|
|||||||
CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblaze-softmmu,mips64el-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4eb-softmmu,xtensa-softmmu
|
CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblaze-softmmu,mips64el-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4eb-softmmu,xtensa-softmmu
|
||||||
TEST_TARGETS: check
|
TEST_TARGETS: check
|
||||||
|
|
||||||
aarch64-macos-build:
|
aarch64-macos-13-base-build:
|
||||||
extends: .cirrus_build_job
|
extends: .cirrus_build_job
|
||||||
variables:
|
variables:
|
||||||
NAME: macos-14
|
NAME: macos-13
|
||||||
CIRRUS_VM_INSTANCE_TYPE: macos_instance
|
CIRRUS_VM_INSTANCE_TYPE: macos_instance
|
||||||
CIRRUS_VM_IMAGE_SELECTOR: image
|
CIRRUS_VM_IMAGE_SELECTOR: image
|
||||||
CIRRUS_VM_IMAGE_NAME: ghcr.io/cirruslabs/macos-runner:sonoma
|
CIRRUS_VM_IMAGE_NAME: ghcr.io/cirruslabs/macos-ventura-base:latest
|
||||||
|
CIRRUS_VM_CPUS: 12
|
||||||
|
CIRRUS_VM_RAM: 24G
|
||||||
UPDATE_COMMAND: brew update
|
UPDATE_COMMAND: brew update
|
||||||
INSTALL_COMMAND: brew install
|
INSTALL_COMMAND: brew install
|
||||||
PATH_EXTRA: /opt/homebrew/ccache/libexec:/opt/homebrew/gettext/bin
|
PATH_EXTRA: /opt/homebrew/ccache/libexec:/opt/homebrew/gettext/bin
|
||||||
PKG_CONFIG_PATH: /opt/homebrew/curl/lib/pkgconfig:/opt/homebrew/ncurses/lib/pkgconfig:/opt/homebrew/readline/lib/pkgconfig
|
PKG_CONFIG_PATH: /opt/homebrew/curl/lib/pkgconfig:/opt/homebrew/ncurses/lib/pkgconfig:/opt/homebrew/readline/lib/pkgconfig
|
||||||
CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblazeel-softmmu,mips64-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4-softmmu,xtensaeb-softmmu
|
CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblazeel-softmmu,mips64-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4-softmmu,xtensaeb-softmmu
|
||||||
TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64
|
TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64
|
||||||
|
|
||||||
|
aarch64-macos-14-base-build:
|
||||||
|
extends: .cirrus_build_job
|
||||||
|
variables:
|
||||||
|
NAME: macos-14
|
||||||
|
CIRRUS_VM_INSTANCE_TYPE: macos_instance
|
||||||
|
CIRRUS_VM_IMAGE_SELECTOR: image
|
||||||
|
CIRRUS_VM_IMAGE_NAME: ghcr.io/cirruslabs/macos-sonoma-base:latest
|
||||||
|
CIRRUS_VM_CPUS: 12
|
||||||
|
CIRRUS_VM_RAM: 24G
|
||||||
|
UPDATE_COMMAND: brew update
|
||||||
|
INSTALL_COMMAND: brew install
|
||||||
|
PATH_EXTRA: /opt/homebrew/ccache/libexec:/opt/homebrew/gettext/bin
|
||||||
|
PKG_CONFIG_PATH: /opt/homebrew/curl/lib/pkgconfig:/opt/homebrew/ncurses/lib/pkgconfig:/opt/homebrew/readline/lib/pkgconfig
|
||||||
|
TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64
|
||||||
|
QEMU_JOB_OPTIONAL: 1
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ env:
|
|||||||
CI_REPOSITORY_URL: "@CI_REPOSITORY_URL@"
|
CI_REPOSITORY_URL: "@CI_REPOSITORY_URL@"
|
||||||
CI_COMMIT_REF_NAME: "@CI_COMMIT_REF_NAME@"
|
CI_COMMIT_REF_NAME: "@CI_COMMIT_REF_NAME@"
|
||||||
CI_COMMIT_SHA: "@CI_COMMIT_SHA@"
|
CI_COMMIT_SHA: "@CI_COMMIT_SHA@"
|
||||||
PATH: "@PATH_EXTRA@:$PATH"
|
PATH: "@PATH@"
|
||||||
PKG_CONFIG_PATH: "@PKG_CONFIG_PATH@"
|
PKG_CONFIG_PATH: "@PKG_CONFIG_PATH@"
|
||||||
PYTHON: "@PYTHON@"
|
PYTHON: "@PYTHON@"
|
||||||
MAKE: "@MAKE@"
|
MAKE: "@MAKE@"
|
||||||
|
|||||||
16
.gitlab-ci.d/cirrus/freebsd-13.vars
Normal file
16
.gitlab-ci.d/cirrus/freebsd-13.vars
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# THIS FILE WAS AUTO-GENERATED
|
||||||
|
#
|
||||||
|
# $ lcitool variables freebsd-13 qemu
|
||||||
|
#
|
||||||
|
# https://gitlab.com/libvirt/libvirt-ci
|
||||||
|
|
||||||
|
CCACHE='/usr/local/bin/ccache'
|
||||||
|
CPAN_PKGS=''
|
||||||
|
CROSS_PKGS=''
|
||||||
|
MAKE='/usr/local/bin/gmake'
|
||||||
|
NINJA='/usr/local/bin/ninja'
|
||||||
|
PACKAGING_COMMAND='pkg'
|
||||||
|
PIP3='/usr/local/bin/pip-3.8'
|
||||||
|
PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk-vnc gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja opencv pixman pkgconf png py311-numpy py311-pillow py311-pip py311-sphinx py311-sphinx_rtd_theme py311-tomli py311-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio socat spice-protocol tesseract usbredir virglrenderer vte3 xorriso zstd'
|
||||||
|
PYPI_PKGS=''
|
||||||
|
PYTHON='/usr/local/bin/python3'
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# THIS FILE WAS AUTO-GENERATED
|
|
||||||
#
|
|
||||||
# $ lcitool variables freebsd-14 qemu
|
|
||||||
#
|
|
||||||
# https://gitlab.com/libvirt/libvirt-ci
|
|
||||||
|
|
||||||
CCACHE='/usr/local/bin/ccache'
|
|
||||||
CPAN_PKGS=''
|
|
||||||
CROSS_PKGS=''
|
|
||||||
MAKE='/usr/local/bin/gmake'
|
|
||||||
NINJA='/usr/local/bin/ninja'
|
|
||||||
PACKAGING_COMMAND='pkg'
|
|
||||||
PIP3='/usr/local/bin/pip'
|
|
||||||
PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache4 cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk-vnc gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja opencv pixman pkgconf png py311-numpy py311-pillow py311-pip py311-pyyaml py311-sphinx py311-sphinx_rtd_theme py311-tomli python3 rpm2cpio rust rust-bindgen-cli sdl2 sdl2_image snappy sndio socat spice-protocol tesseract usbredir virglrenderer vte3 vulkan-tools xorriso zstd'
|
|
||||||
PYPI_PKGS=''
|
|
||||||
PYTHON='/usr/local/bin/python3'
|
|
||||||
16
.gitlab-ci.d/cirrus/macos-13.vars
Normal file
16
.gitlab-ci.d/cirrus/macos-13.vars
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# THIS FILE WAS AUTO-GENERATED
|
||||||
|
#
|
||||||
|
# $ lcitool variables macos-13 qemu
|
||||||
|
#
|
||||||
|
# https://gitlab.com/libvirt/libvirt-ci
|
||||||
|
|
||||||
|
CCACHE='/opt/homebrew/bin/ccache'
|
||||||
|
CPAN_PKGS=''
|
||||||
|
CROSS_PKGS=''
|
||||||
|
MAKE='/opt/homebrew/bin/gmake'
|
||||||
|
NINJA='/opt/homebrew/bin/ninja'
|
||||||
|
PACKAGING_COMMAND='brew'
|
||||||
|
PIP3='/opt/homebrew/bin/pip3'
|
||||||
|
PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 gtk-vnc jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd'
|
||||||
|
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
|
||||||
|
PYTHON='/opt/homebrew/bin/python3'
|
||||||
@@ -11,6 +11,6 @@ MAKE='/opt/homebrew/bin/gmake'
|
|||||||
NINJA='/opt/homebrew/bin/ninja'
|
NINJA='/opt/homebrew/bin/ninja'
|
||||||
PACKAGING_COMMAND='brew'
|
PACKAGING_COMMAND='brew'
|
||||||
PIP3='/opt/homebrew/bin/pip3'
|
PIP3='/opt/homebrew/bin/pip3'
|
||||||
PKGS='bash bc bindgen bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 gtk-vnc jemalloc jpeg-turbo json-c libcbor libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio rust sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 vulkan-tools xorriso zlib zstd'
|
PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 gtk-vnc jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd'
|
||||||
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
|
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
|
||||||
PYTHON='/opt/homebrew/bin/python3'
|
PYTHON='/opt/homebrew/bin/python3'
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ xtensa-debian-cross-container:
|
|||||||
variables:
|
variables:
|
||||||
NAME: debian-xtensa-cross
|
NAME: debian-xtensa-cross
|
||||||
|
|
||||||
|
cris-fedora-cross-container:
|
||||||
|
extends: .container_job_template
|
||||||
|
variables:
|
||||||
|
NAME: fedora-cris-cross
|
||||||
|
|
||||||
win64-fedora-cross-container:
|
win64-fedora-cross-container:
|
||||||
extends: .container_job_template
|
extends: .container_job_template
|
||||||
variables:
|
variables:
|
||||||
|
|||||||
@@ -27,9 +27,3 @@ python-container:
|
|||||||
extends: .container_job_template
|
extends: .container_job_template
|
||||||
variables:
|
variables:
|
||||||
NAME: python
|
NAME: python
|
||||||
|
|
||||||
amd64-fedora-rust-nightly-container:
|
|
||||||
extends: .container_job_template
|
|
||||||
variables:
|
|
||||||
NAME: fedora-rust-nightly
|
|
||||||
allow_failure: true
|
|
||||||
|
|||||||
@@ -9,11 +9,7 @@
|
|||||||
when: always
|
when: always
|
||||||
timeout: 80m
|
timeout: 80m
|
||||||
before_script:
|
before_script:
|
||||||
- source scripts/ci/gitlab-ci-section
|
|
||||||
- section_start setup "Pre-script setup"
|
|
||||||
- JOBS=$(expr $(nproc) + 1)
|
|
||||||
- cat /packages.txt
|
- cat /packages.txt
|
||||||
- section_end setup
|
|
||||||
script:
|
script:
|
||||||
- export CCACHE_BASEDIR="$(pwd)"
|
- export CCACHE_BASEDIR="$(pwd)"
|
||||||
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
||||||
@@ -22,30 +18,18 @@
|
|||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- ccache --zero-stats
|
- ccache --zero-stats
|
||||||
- section_start configure "Running configure"
|
|
||||||
- ../configure --enable-werror --disable-docs --enable-fdt=system
|
- ../configure --enable-werror --disable-docs --enable-fdt=system
|
||||||
--disable-user $QEMU_CONFIGURE_OPTS $EXTRA_CONFIGURE_OPTS
|
--disable-user $QEMU_CONFIGURE_OPTS $EXTRA_CONFIGURE_OPTS
|
||||||
--target-list-exclude="arm-softmmu
|
--target-list-exclude="arm-softmmu cris-softmmu
|
||||||
i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu
|
i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu
|
||||||
mips64-softmmu ppc-softmmu riscv32-softmmu sh4-softmmu
|
mips64-softmmu ppc-softmmu riscv32-softmmu sh4-softmmu
|
||||||
sparc-softmmu xtensa-softmmu $CROSS_SKIP_TARGETS"
|
sparc-softmmu xtensa-softmmu $CROSS_SKIP_TARGETS"
|
||||||
- section_end configure
|
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
|
||||||
- section_start build "Building QEMU"
|
|
||||||
- make -j"$JOBS" all check-build
|
|
||||||
- section_end build
|
|
||||||
- section_start test "Running tests"
|
|
||||||
- if test -n "$MAKE_CHECK_ARGS";
|
|
||||||
then
|
|
||||||
$MAKE -j"$JOBS" $MAKE_CHECK_ARGS ;
|
|
||||||
fi
|
|
||||||
- section_end test
|
|
||||||
- section_start installer "Building the installer"
|
|
||||||
- if grep -q "EXESUF=.exe" config-host.mak;
|
- if grep -q "EXESUF=.exe" config-host.mak;
|
||||||
then make installer;
|
then make installer;
|
||||||
version="$(git describe --match v[0-9]* 2>/dev/null || git rev-parse --short HEAD)";
|
version="$(git describe --match v[0-9]* 2>/dev/null || git rev-parse --short HEAD)";
|
||||||
mv -v qemu-setup*.exe qemu-setup-${version}.exe;
|
mv -v qemu-setup*.exe qemu-setup-${version}.exe;
|
||||||
fi
|
fi
|
||||||
- section_end installer
|
|
||||||
- ccache --show-stats
|
- ccache --show-stats
|
||||||
|
|
||||||
# Job to cross-build specific accelerators.
|
# Job to cross-build specific accelerators.
|
||||||
@@ -57,14 +41,11 @@
|
|||||||
extends: .base_job_template
|
extends: .base_job_template
|
||||||
stage: build
|
stage: build
|
||||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
|
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
|
||||||
timeout: 60m
|
timeout: 30m
|
||||||
cache:
|
cache:
|
||||||
paths:
|
paths:
|
||||||
- ccache/
|
- ccache/
|
||||||
key: "$CI_JOB_NAME"
|
key: "$CI_JOB_NAME"
|
||||||
before_script:
|
|
||||||
- source scripts/ci/gitlab-ci-section
|
|
||||||
- JOBS=$(expr $(nproc) + 1)
|
|
||||||
script:
|
script:
|
||||||
- export CCACHE_BASEDIR="$(pwd)"
|
- export CCACHE_BASEDIR="$(pwd)"
|
||||||
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
||||||
@@ -72,19 +53,9 @@
|
|||||||
- export PATH="$CCACHE_WRAPPERSDIR:$PATH"
|
- export PATH="$CCACHE_WRAPPERSDIR:$PATH"
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- section_start configure "Running configure"
|
|
||||||
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
|
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
|
||||||
--disable-tools --enable-${ACCEL:-kvm} $EXTRA_CONFIGURE_OPTS
|
--disable-tools --enable-${ACCEL:-kvm} $EXTRA_CONFIGURE_OPTS
|
||||||
- section_end configure
|
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
|
||||||
- section_start build "Building QEMU"
|
|
||||||
- make -j"$JOBS" all check-build
|
|
||||||
- section_end build
|
|
||||||
- section_start test "Running tests"
|
|
||||||
- if test -n "$MAKE_CHECK_ARGS";
|
|
||||||
then
|
|
||||||
$MAKE -j"$JOBS" $MAKE_CHECK_ARGS ;
|
|
||||||
fi
|
|
||||||
- section_end test
|
|
||||||
|
|
||||||
.cross_user_build_job:
|
.cross_user_build_job:
|
||||||
extends: .base_job_template
|
extends: .base_job_template
|
||||||
@@ -94,31 +65,18 @@
|
|||||||
paths:
|
paths:
|
||||||
- ccache/
|
- ccache/
|
||||||
key: "$CI_JOB_NAME"
|
key: "$CI_JOB_NAME"
|
||||||
before_script:
|
|
||||||
- source scripts/ci/gitlab-ci-section
|
|
||||||
- JOBS=$(expr $(nproc) + 1)
|
|
||||||
script:
|
script:
|
||||||
- export CCACHE_BASEDIR="$(pwd)"
|
- export CCACHE_BASEDIR="$(pwd)"
|
||||||
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
- export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
|
||||||
- export CCACHE_MAXSIZE="500M"
|
- export CCACHE_MAXSIZE="500M"
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- section_start configure "Running configure"
|
|
||||||
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
|
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
|
||||||
--disable-system --target-list-exclude="aarch64_be-linux-user
|
--disable-system --target-list-exclude="aarch64_be-linux-user
|
||||||
alpha-linux-user m68k-linux-user microblazeel-linux-user
|
alpha-linux-user cris-linux-user m68k-linux-user microblazeel-linux-user
|
||||||
or1k-linux-user ppc-linux-user sparc-linux-user
|
or1k-linux-user ppc-linux-user sparc-linux-user
|
||||||
xtensa-linux-user $CROSS_SKIP_TARGETS"
|
xtensa-linux-user $CROSS_SKIP_TARGETS"
|
||||||
- section_end configure
|
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
|
||||||
- section_start build "Building QEMU"
|
|
||||||
- make -j"$JOBS" all check-build
|
|
||||||
- section_end build
|
|
||||||
- section_start test "Running tests"
|
|
||||||
- if test -n "$MAKE_CHECK_ARGS";
|
|
||||||
then
|
|
||||||
$MAKE -j"$JOBS" $MAKE_CHECK_ARGS ;
|
|
||||||
fi
|
|
||||||
- section_end test
|
|
||||||
|
|
||||||
# We can still run some tests on some of our cross build jobs. They can add this
|
# We can still run some tests on some of our cross build jobs. They can add this
|
||||||
# template to their extends to save the build logs and test results
|
# template to their extends to save the build logs and test results
|
||||||
|
|||||||
@@ -61,12 +61,8 @@ cross-i686-tci:
|
|||||||
variables:
|
variables:
|
||||||
IMAGE: debian-i686-cross
|
IMAGE: debian-i686-cross
|
||||||
ACCEL: tcg-interpreter
|
ACCEL: tcg-interpreter
|
||||||
EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,arm-softmmu,arm-linux-user,ppc-softmmu,ppc-linux-user --disable-plugins --disable-kvm
|
EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user --disable-plugins --disable-kvm
|
||||||
# Force tests to run with reduced parallelism, to see whether this
|
MAKE_CHECK_ARGS: check check-tcg
|
||||||
# reduces the flakiness of this CI job. The CI
|
|
||||||
# environment by default shows us 8 CPUs and so we
|
|
||||||
# would otherwise be using a parallelism of 9.
|
|
||||||
MAKE_CHECK_ARGS: check check-tcg -j2
|
|
||||||
|
|
||||||
cross-mipsel-system:
|
cross-mipsel-system:
|
||||||
extends: .cross_system_build_job
|
extends: .cross_system_build_job
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ ubuntu-22.04-aarch64-clang:
|
|||||||
script:
|
script:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- ../configure --disable-libssh --cc=clang --cxx=clang++ --enable-ubsan
|
- ../configure --disable-libssh --cc=clang --cxx=clang++ --enable-sanitizers
|
||||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||||
- make --output-sync -j`nproc --ignore=40`
|
- make --output-sync -j`nproc --ignore=40`
|
||||||
- make --output-sync -j`nproc --ignore=40` check
|
- make --output-sync -j`nproc --ignore=40` check
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ ubuntu-22.04-s390x-clang:
|
|||||||
script:
|
script:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- ../configure --cc=clang --cxx=clang++ --enable-ubsan
|
- ../configure --cc=clang --cxx=clang++ --enable-sanitizers
|
||||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||||
- make --output-sync -j`nproc`
|
- make --output-sync -j`nproc`
|
||||||
- make --output-sync -j`nproc` check
|
- make --output-sync -j`nproc` check
|
||||||
|
|||||||
@@ -46,49 +46,3 @@ check-python-tox:
|
|||||||
QEMU_JOB_OPTIONAL: 1
|
QEMU_JOB_OPTIONAL: 1
|
||||||
needs:
|
needs:
|
||||||
job: python-container
|
job: python-container
|
||||||
|
|
||||||
check-rust-tools-nightly:
|
|
||||||
extends: .base_job_template
|
|
||||||
stage: test
|
|
||||||
image: $CI_REGISTRY_IMAGE/qemu/fedora-rust-nightly:$QEMU_CI_CONTAINER_TAG
|
|
||||||
script:
|
|
||||||
- source scripts/ci/gitlab-ci-section
|
|
||||||
- section_start test "Running Rust code checks"
|
|
||||||
- cd build
|
|
||||||
- pyvenv/bin/meson devenv -w ../rust ${CARGO-cargo} fmt --check
|
|
||||||
- make clippy
|
|
||||||
- make rustdoc
|
|
||||||
- section_end test
|
|
||||||
variables:
|
|
||||||
GIT_DEPTH: 1
|
|
||||||
allow_failure: true
|
|
||||||
needs:
|
|
||||||
- job: build-system-fedora-rust-nightly
|
|
||||||
artifacts: true
|
|
||||||
artifacts:
|
|
||||||
when: on_success
|
|
||||||
expire_in: 2 days
|
|
||||||
paths:
|
|
||||||
- rust/target/doc
|
|
||||||
|
|
||||||
check-build-units:
|
|
||||||
extends: .base_job_template
|
|
||||||
stage: build
|
|
||||||
image: $CI_REGISTRY_IMAGE/qemu/debian:$QEMU_CI_CONTAINER_TAG
|
|
||||||
needs:
|
|
||||||
job: amd64-debian-container
|
|
||||||
before_script:
|
|
||||||
- source scripts/ci/gitlab-ci-section
|
|
||||||
- section_start setup "Install Tools"
|
|
||||||
- apt install --assume-yes --no-install-recommends jq
|
|
||||||
- section_end setup
|
|
||||||
script:
|
|
||||||
- mkdir build
|
|
||||||
- cd build
|
|
||||||
- section_start configure "Running configure"
|
|
||||||
- ../configure
|
|
||||||
- cd ..
|
|
||||||
- section_end configure
|
|
||||||
- section_start analyse "Analyse"
|
|
||||||
- .gitlab-ci.d/check-units.py build/compile_commands.json
|
|
||||||
- section_end analyse
|
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ msys2-64bit:
|
|||||||
mingw-w64-x86_64-python
|
mingw-w64-x86_64-python
|
||||||
mingw-w64-x86_64-zstd"
|
mingw-w64-x86_64-zstd"
|
||||||
- Write-Output "Running build at $(Get-Date -Format u)"
|
- Write-Output "Running build at $(Get-Date -Format u)"
|
||||||
- $env:JOBS = $(.\msys64\usr\bin\bash -lc nproc)
|
|
||||||
- $env:CHERE_INVOKING = 'yes' # Preserve the current working directory
|
- $env:CHERE_INVOKING = 'yes' # Preserve the current working directory
|
||||||
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
|
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
|
||||||
- $env:CCACHE_BASEDIR = "$env:CI_PROJECT_DIR"
|
- $env:CCACHE_BASEDIR = "$env:CI_PROJECT_DIR"
|
||||||
@@ -100,7 +99,7 @@ msys2-64bit:
|
|||||||
- cd build
|
- cd build
|
||||||
- ..\msys64\usr\bin\bash -lc "ccache --zero-stats"
|
- ..\msys64\usr\bin\bash -lc "ccache --zero-stats"
|
||||||
- ..\msys64\usr\bin\bash -lc "../configure $CONFIGURE_ARGS"
|
- ..\msys64\usr\bin\bash -lc "../configure $CONFIGURE_ARGS"
|
||||||
- ..\msys64\usr\bin\bash -lc "make -j$env:JOBS"
|
- ..\msys64\usr\bin\bash -lc "make"
|
||||||
- ..\msys64\usr\bin\bash -lc "make check MTESTARGS='$TEST_ARGS' || { cat meson-logs/testlog.txt; exit 1; } ;"
|
- ..\msys64\usr\bin\bash -lc "make check MTESTARGS='$TEST_ARGS' || { cat meson-logs/testlog.txt; exit 1; } ;"
|
||||||
- ..\msys64\usr\bin\bash -lc "ccache --show-stats"
|
- ..\msys64\usr\bin\bash -lc "ccache --show-stats"
|
||||||
- Write-Output "Finished build at $(Get-Date -Format u)"
|
- Write-Output "Finished build at $(Get-Date -Format u)"
|
||||||
|
|||||||
27
.gitmodules
vendored
27
.gitmodules
vendored
@@ -1,12 +1,12 @@
|
|||||||
[submodule "roms/seabios"]
|
[submodule "roms/seabios"]
|
||||||
path = roms/seabios
|
path = roms/seabios
|
||||||
url = https://gitlab.com/qemu-project/seabios.git/
|
url = https://github.com/openSUSE/qemu-seabios.git
|
||||||
[submodule "roms/SLOF"]
|
[submodule "roms/SLOF"]
|
||||||
path = roms/SLOF
|
path = roms/SLOF
|
||||||
url = https://gitlab.com/qemu-project/SLOF.git
|
url = https://github.com/openSUSE/qemu-SLOF.git
|
||||||
[submodule "roms/ipxe"]
|
[submodule "roms/ipxe"]
|
||||||
path = roms/ipxe
|
path = roms/ipxe
|
||||||
url = https://gitlab.com/qemu-project/ipxe.git
|
url = https://github.com/openSUSE/qemu-ipxe.git
|
||||||
[submodule "roms/openbios"]
|
[submodule "roms/openbios"]
|
||||||
path = roms/openbios
|
path = roms/openbios
|
||||||
url = https://gitlab.com/qemu-project/openbios.git
|
url = https://gitlab.com/qemu-project/openbios.git
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
url = https://gitlab.com/qemu-project/u-boot.git
|
url = https://gitlab.com/qemu-project/u-boot.git
|
||||||
[submodule "roms/skiboot"]
|
[submodule "roms/skiboot"]
|
||||||
path = roms/skiboot
|
path = roms/skiboot
|
||||||
url = https://gitlab.com/qemu-project/skiboot.git
|
url = https://github.com/openSUSE/qemu-skiboot.git
|
||||||
[submodule "roms/QemuMacDrivers"]
|
[submodule "roms/QemuMacDrivers"]
|
||||||
path = roms/QemuMacDrivers
|
path = roms/QemuMacDrivers
|
||||||
url = https://gitlab.com/qemu-project/QemuMacDrivers.git
|
url = https://gitlab.com/qemu-project/QemuMacDrivers.git
|
||||||
@@ -30,16 +30,31 @@
|
|||||||
url = https://gitlab.com/qemu-project/u-boot-sam460ex.git
|
url = https://gitlab.com/qemu-project/u-boot-sam460ex.git
|
||||||
[submodule "roms/edk2"]
|
[submodule "roms/edk2"]
|
||||||
path = roms/edk2
|
path = roms/edk2
|
||||||
url = https://gitlab.com/qemu-project/edk2.git
|
url = https://github.com/openSUSE/qemu-edk2.git
|
||||||
[submodule "roms/opensbi"]
|
[submodule "roms/opensbi"]
|
||||||
path = roms/opensbi
|
path = roms/opensbi
|
||||||
url = https://gitlab.com/qemu-project/opensbi.git
|
url = https://gitlab.com/qemu-project/opensbi.git
|
||||||
[submodule "roms/qboot"]
|
[submodule "roms/qboot"]
|
||||||
path = roms/qboot
|
path = roms/qboot
|
||||||
url = https://gitlab.com/qemu-project/qboot.git
|
url = https://github.com/openSUSE/qemu-qboot.git
|
||||||
[submodule "roms/vbootrom"]
|
[submodule "roms/vbootrom"]
|
||||||
path = roms/vbootrom
|
path = roms/vbootrom
|
||||||
url = https://gitlab.com/qemu-project/vbootrom.git
|
url = https://gitlab.com/qemu-project/vbootrom.git
|
||||||
[submodule "tests/lcitool/libvirt-ci"]
|
[submodule "tests/lcitool/libvirt-ci"]
|
||||||
path = tests/lcitool/libvirt-ci
|
path = tests/lcitool/libvirt-ci
|
||||||
url = https://gitlab.com/libvirt/libvirt-ci.git
|
url = https://gitlab.com/libvirt/libvirt-ci.git
|
||||||
|
[submodule "subprojects/berkeley-softfloat-3"]
|
||||||
|
path = subprojects/berkeley-softfloat-3
|
||||||
|
url = https://gitlab.com/qemu-project/berkeley-softfloat-3
|
||||||
|
[submodule "subprojects/berkeley-testfloat-3"]
|
||||||
|
path = subprojects/berkeley-testfloat-3
|
||||||
|
url = https://gitlab.com/qemu-project/berkeley-testfloat-3
|
||||||
|
[submodule "subprojects/dtc"]
|
||||||
|
path = subprojects/dtc
|
||||||
|
url = https://gitlab.com/qemu-project/dtc.git
|
||||||
|
[submodule "subprojects/libvfio-user"]
|
||||||
|
path = subprojects/libvfio-user
|
||||||
|
url = https://gitlab.com/qemu-project/libvfio-user.git
|
||||||
|
[submodule "subprojects/keycodemapdb"]
|
||||||
|
path = subprojects/keycodemapdb
|
||||||
|
url = https://gitlab.com/qemu-project/keycodemapdb.git
|
||||||
|
|||||||
8
.mailmap
8
.mailmap
@@ -67,7 +67,6 @@ Andrey Drobyshev <andrey.drobyshev@virtuozzo.com> Andrey Drobyshev via <qemu-blo
|
|||||||
BALATON Zoltan <balaton@eik.bme.hu> BALATON Zoltan via <qemu-ppc@nongnu.org>
|
BALATON Zoltan <balaton@eik.bme.hu> BALATON Zoltan via <qemu-ppc@nongnu.org>
|
||||||
|
|
||||||
# Next, replace old addresses by a more recent one.
|
# Next, replace old addresses by a more recent one.
|
||||||
Akihiko Odaki <akihiko.odaki@daynix.com> <akihiko.odaki@gmail.com>
|
|
||||||
Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <aleksandar.markovic@mips.com>
|
Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <aleksandar.markovic@mips.com>
|
||||||
Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <aleksandar.markovic@imgtec.com>
|
Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <aleksandar.markovic@imgtec.com>
|
||||||
Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <amarkovic@wavecomp.com>
|
Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <amarkovic@wavecomp.com>
|
||||||
@@ -76,8 +75,6 @@ Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> <aleksandar.rikalo@rt-rk.com>
|
|||||||
Alexander Graf <agraf@csgraf.de> <agraf@suse.de>
|
Alexander Graf <agraf@csgraf.de> <agraf@suse.de>
|
||||||
Ani Sinha <anisinha@redhat.com> <ani@anisinha.ca>
|
Ani Sinha <anisinha@redhat.com> <ani@anisinha.ca>
|
||||||
Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com>
|
Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com>
|
||||||
Brian Cain <brian.cain@oss.qualcomm.com> <bcain@quicinc.com>
|
|
||||||
Brian Cain <brian.cain@oss.qualcomm.com> <quic_bcain@quicinc.com>
|
|
||||||
Christian Borntraeger <borntraeger@linux.ibm.com> <borntraeger@de.ibm.com>
|
Christian Borntraeger <borntraeger@linux.ibm.com> <borntraeger@de.ibm.com>
|
||||||
Damien Hedde <damien.hedde@dahe.fr> <damien.hedde@greensocs.com>
|
Damien Hedde <damien.hedde@dahe.fr> <damien.hedde@greensocs.com>
|
||||||
Filip Bozuta <filip.bozuta@syrmia.com> <filip.bozuta@rt-rk.com.com>
|
Filip Bozuta <filip.bozuta@syrmia.com> <filip.bozuta@rt-rk.com.com>
|
||||||
@@ -88,9 +85,8 @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
|
|||||||
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
|
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
|
||||||
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
|
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
|
||||||
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
|
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
|
||||||
Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
|
Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
|
||||||
Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
|
Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
|
||||||
Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
|
|
||||||
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
|
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
|
||||||
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
|
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
|
||||||
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
|
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
|
||||||
|
|||||||
47
.obs/workflows.yml
Normal file
47
.obs/workflows.yml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
pr_factory:
|
||||||
|
steps:
|
||||||
|
- branch_package:
|
||||||
|
source_project: Virtualization:Staging
|
||||||
|
source_package: qemu
|
||||||
|
target_project: Virtualization:Staging:PRs
|
||||||
|
filters:
|
||||||
|
event: pull_request
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- factory
|
||||||
|
|
||||||
|
rebuild_factory:
|
||||||
|
steps:
|
||||||
|
# Will automatically rebuild the package
|
||||||
|
- trigger_services:
|
||||||
|
project: Virtualization:Staging
|
||||||
|
package: qemu
|
||||||
|
filters:
|
||||||
|
event: push
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- factory
|
||||||
|
|
||||||
|
pr_staging_tdx:
|
||||||
|
steps:
|
||||||
|
- branch_package:
|
||||||
|
source_project: Virtualization:Staging:TDX
|
||||||
|
source_package: qemu
|
||||||
|
target_project: Virtualization:Staging:TDX:PRs
|
||||||
|
filters:
|
||||||
|
event: pull_request
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- v8.2.6-tdx
|
||||||
|
|
||||||
|
rebuild_staging_tdx:
|
||||||
|
steps:
|
||||||
|
# Will automatically rebuild the package
|
||||||
|
- trigger_services:
|
||||||
|
project: Virtualization:Staging:TDX
|
||||||
|
package: qemu
|
||||||
|
filters:
|
||||||
|
event: push
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- v8.2.6-tdx
|
||||||
1
Kconfig
1
Kconfig
@@ -4,4 +4,3 @@ source accel/Kconfig
|
|||||||
source target/Kconfig
|
source target/Kconfig
|
||||||
source hw/Kconfig
|
source hw/Kconfig
|
||||||
source semihosting/Kconfig
|
source semihosting/Kconfig
|
||||||
source rust/Kconfig
|
|
||||||
|
|||||||
12
Kconfig.host
12
Kconfig.host
@@ -5,12 +5,6 @@
|
|||||||
config LINUX
|
config LINUX
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config LIBCBOR
|
|
||||||
bool
|
|
||||||
|
|
||||||
config GNUTLS
|
|
||||||
bool
|
|
||||||
|
|
||||||
config OPENGL
|
config OPENGL
|
||||||
bool
|
bool
|
||||||
|
|
||||||
@@ -58,9 +52,3 @@ config VFIO_USER_SERVER_ALLOWED
|
|||||||
|
|
||||||
config HV_BALLOON_POSSIBLE
|
config HV_BALLOON_POSSIBLE
|
||||||
bool
|
bool
|
||||||
|
|
||||||
config HAVE_RUST
|
|
||||||
bool
|
|
||||||
|
|
||||||
config MAC_PVG
|
|
||||||
bool
|
|
||||||
|
|||||||
597
MAINTAINERS
597
MAINTAINERS
File diff suppressed because it is too large
Load Diff
16
Makefile
16
Makefile
@@ -187,6 +187,11 @@ SUBDIR_RULES=$(foreach t, all clean distclean, $(addsuffix /$(t), $(SUBDIRS)))
|
|||||||
$(SUBDIR_RULES):
|
$(SUBDIR_RULES):
|
||||||
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" TARGET_DIR="$(dir $@)" $(notdir $@),)
|
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" TARGET_DIR="$(dir $@)" $(notdir $@),)
|
||||||
|
|
||||||
|
ifneq ($(filter contrib/plugins, $(SUBDIRS)),)
|
||||||
|
.PHONY: plugins
|
||||||
|
plugins: contrib/plugins/all
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: recurse-all recurse-clean
|
.PHONY: recurse-all recurse-clean
|
||||||
recurse-all: $(addsuffix /all, $(SUBDIRS))
|
recurse-all: $(addsuffix /all, $(SUBDIRS))
|
||||||
recurse-clean: $(addsuffix /clean, $(SUBDIRS))
|
recurse-clean: $(addsuffix /clean, $(SUBDIRS))
|
||||||
@@ -207,10 +212,10 @@ clean: recurse-clean
|
|||||||
|
|
||||||
VERSION = $(shell cat $(SRC_PATH)/VERSION)
|
VERSION = $(shell cat $(SRC_PATH)/VERSION)
|
||||||
|
|
||||||
dist: qemu-$(VERSION).tar.xz
|
dist: qemu-$(VERSION).tar.bz2
|
||||||
|
|
||||||
qemu-%.tar.xz:
|
qemu-%.tar.bz2:
|
||||||
$(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.xz,%,$@)"
|
$(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst qemu-%.tar.bz2,%,$@)"
|
||||||
|
|
||||||
distclean: clean recurse-distclean
|
distclean: clean recurse-distclean
|
||||||
-$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || :
|
-$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || :
|
||||||
@@ -302,6 +307,11 @@ help:
|
|||||||
$(call print-help,cscope,Generate cscope index)
|
$(call print-help,cscope,Generate cscope index)
|
||||||
$(call print-help,sparse,Run sparse on the QEMU source)
|
$(call print-help,sparse,Run sparse on the QEMU source)
|
||||||
@echo ''
|
@echo ''
|
||||||
|
ifneq ($(filter contrib/plugins, $(SUBDIRS)),)
|
||||||
|
@echo 'Plugin targets:'
|
||||||
|
$(call print-help,plugins,Build the example TCG plugins)
|
||||||
|
@echo ''
|
||||||
|
endif
|
||||||
@echo 'Cleaning targets:'
|
@echo 'Cleaning targets:'
|
||||||
$(call print-help,clean,Remove most generated files but keep the config)
|
$(call print-help,clean,Remove most generated files but keep the config)
|
||||||
$(call print-help,distclean,Remove all generated files)
|
$(call print-help,distclean,Remove all generated files)
|
||||||
|
|||||||
@@ -16,5 +16,4 @@ config KVM
|
|||||||
config XEN
|
config XEN
|
||||||
bool
|
bool
|
||||||
select FSDEV_9P if VIRTFS
|
select FSDEV_9P if VIRTFS
|
||||||
select PCI_EXPRESS_GENERIC_BRIDGE
|
|
||||||
select XEN_BUS
|
select XEN_BUS
|
||||||
|
|||||||
@@ -25,11 +25,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/lockcnt.h"
|
|
||||||
#include "qemu/thread.h"
|
#include "qemu/thread.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
#include "system/accel-blocker.h"
|
#include "sysemu/accel-blocker.h"
|
||||||
|
|
||||||
static QemuLockCnt accel_in_ioctl_lock;
|
static QemuLockCnt accel_in_ioctl_lock;
|
||||||
static QemuEvent accel_in_ioctl_event;
|
static QemuEvent accel_in_ioctl_event;
|
||||||
|
|||||||
@@ -26,8 +26,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/accel.h"
|
#include "qemu/accel.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "system/accel-ops.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/cpus.h"
|
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "accel-system.h"
|
#include "accel-system.h"
|
||||||
|
|
||||||
@@ -74,17 +73,19 @@ void accel_system_init_ops_interfaces(AccelClass *ac)
|
|||||||
g_assert(ac_name != NULL);
|
g_assert(ac_name != NULL);
|
||||||
|
|
||||||
ops_name = g_strdup_printf("%s" ACCEL_OPS_SUFFIX, ac_name);
|
ops_name = g_strdup_printf("%s" ACCEL_OPS_SUFFIX, ac_name);
|
||||||
|
ops = ACCEL_OPS_CLASS(module_object_class_by_name(ops_name));
|
||||||
oc = module_object_class_by_name(ops_name);
|
oc = module_object_class_by_name(ops_name);
|
||||||
if (!oc) {
|
if (!oc) {
|
||||||
error_report("fatal: could not load module for type '%s'", ops_name);
|
error_report("fatal: could not load module for type '%s'", ops_name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
g_free(ops_name);
|
g_free(ops_name);
|
||||||
|
ops = ACCEL_OPS_CLASS(oc);
|
||||||
/*
|
/*
|
||||||
* all accelerators need to define ops, providing at least a mandatory
|
* all accelerators need to define ops, providing at least a mandatory
|
||||||
* non-NULL create_vcpu_thread operation.
|
* non-NULL create_vcpu_thread operation.
|
||||||
*/
|
*/
|
||||||
ops = ACCEL_OPS_CLASS(oc);
|
g_assert(ops != NULL);
|
||||||
if (ops->ops_init) {
|
if (ops->ops_init) {
|
||||||
ops->ops_init(ops);
|
ops->ops_init(ops);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#include "qemu/accel.h"
|
#include "qemu/accel.h"
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "accel/accel-cpu-target.h"
|
#include "hw/core/accel-cpu.h"
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
#include "accel-system.h"
|
#include "accel-system.h"
|
||||||
@@ -38,7 +38,6 @@ static const TypeInfo accel_type = {
|
|||||||
.parent = TYPE_OBJECT,
|
.parent = TYPE_OBJECT,
|
||||||
.class_size = sizeof(AccelClass),
|
.class_size = sizeof(AccelClass),
|
||||||
.instance_size = sizeof(AccelState),
|
.instance_size = sizeof(AccelState),
|
||||||
.abstract = true,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Lookup AccelClass from opt_name. Returns NULL if not found */
|
/* Lookup AccelClass from opt_name. Returns NULL if not found */
|
||||||
@@ -113,20 +112,22 @@ void accel_init_interfaces(AccelClass *ac)
|
|||||||
|
|
||||||
void accel_cpu_instance_init(CPUState *cpu)
|
void accel_cpu_instance_init(CPUState *cpu)
|
||||||
{
|
{
|
||||||
if (cpu->cc->accel_cpu && cpu->cc->accel_cpu->cpu_instance_init) {
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
cpu->cc->accel_cpu->cpu_instance_init(cpu);
|
|
||||||
|
if (cc->accel_cpu && cc->accel_cpu->cpu_instance_init) {
|
||||||
|
cc->accel_cpu->cpu_instance_init(cpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool accel_cpu_common_realize(CPUState *cpu, Error **errp)
|
bool accel_cpu_common_realize(CPUState *cpu, Error **errp)
|
||||||
{
|
{
|
||||||
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
AccelState *accel = current_accel();
|
AccelState *accel = current_accel();
|
||||||
AccelClass *acc = ACCEL_GET_CLASS(accel);
|
AccelClass *acc = ACCEL_GET_CLASS(accel);
|
||||||
|
|
||||||
/* target specific realization */
|
/* target specific realization */
|
||||||
if (cpu->cc->accel_cpu
|
if (cc->accel_cpu && cc->accel_cpu->cpu_target_realize
|
||||||
&& cpu->cc->accel_cpu->cpu_target_realize
|
&& !cc->accel_cpu->cpu_target_realize(cpu, errp)) {
|
||||||
&& !cpu->cc->accel_cpu->cpu_target_realize(cpu, errp)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/rcu.h"
|
#include "qemu/rcu.h"
|
||||||
#include "system/cpus.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
|
|||||||
@@ -53,16 +53,18 @@
|
|||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "gdbstub/enums.h"
|
#include "gdbstub/enums.h"
|
||||||
#include "hw/boards.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/accel-ops.h"
|
#include "sysemu/hvf.h"
|
||||||
#include "system/cpus.h"
|
#include "sysemu/hvf_int.h"
|
||||||
#include "system/hvf.h"
|
#include "sysemu/runstate.h"
|
||||||
#include "system/hvf_int.h"
|
|
||||||
#include "system/runstate.h"
|
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
|
|
||||||
HVFState *hvf_state;
|
HVFState *hvf_state;
|
||||||
|
|
||||||
|
#ifdef __aarch64__
|
||||||
|
#define HV_VM_DEFAULT NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Memory slots */
|
/* Memory slots */
|
||||||
|
|
||||||
hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
|
hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
|
||||||
@@ -321,17 +323,8 @@ static int hvf_accel_init(MachineState *ms)
|
|||||||
int x;
|
int x;
|
||||||
hv_return_t ret;
|
hv_return_t ret;
|
||||||
HVFState *s;
|
HVFState *s;
|
||||||
int pa_range = 36;
|
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
|
||||||
|
|
||||||
if (mc->hvf_get_physical_address_range) {
|
ret = hv_vm_create(HV_VM_DEFAULT);
|
||||||
pa_range = mc->hvf_get_physical_address_range(ms);
|
|
||||||
if (pa_range < 0) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = hvf_arch_vm_create(ms, (uint32_t)pa_range);
|
|
||||||
assert_hvf_ok(ret);
|
assert_hvf_ok(ret);
|
||||||
|
|
||||||
s = g_new0(HVFState, 1);
|
s = g_new0(HVFState, 1);
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "system/hvf.h"
|
#include "sysemu/hvf.h"
|
||||||
#include "system/hvf_int.h"
|
#include "sysemu/hvf_int.h"
|
||||||
|
|
||||||
const char *hvf_return_string(hv_return_t ret)
|
const char *hvf_return_string(hv_return_t ret)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,11 +16,10 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "system/accel-ops.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "system/kvm.h"
|
#include "sysemu/kvm_int.h"
|
||||||
#include "system/kvm_int.h"
|
#include "sysemu/runstate.h"
|
||||||
#include "system/runstate.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/cpus.h"
|
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,10 @@
|
|||||||
#include "hw/pci/msix.h"
|
#include "hw/pci/msix.h"
|
||||||
#include "hw/s390x/adapter.h"
|
#include "hw/s390x/adapter.h"
|
||||||
#include "gdbstub/enums.h"
|
#include "gdbstub/enums.h"
|
||||||
#include "system/kvm_int.h"
|
#include "sysemu/kvm_int.h"
|
||||||
#include "system/runstate.h"
|
#include "sysemu/runstate.h"
|
||||||
#include "system/cpus.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/accel-blocker.h"
|
#include "sysemu/accel-blocker.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
#include "exec/ram_addr.h"
|
#include "exec/ram_addr.h"
|
||||||
@@ -42,15 +42,15 @@
|
|||||||
#include "qapi/visitor.h"
|
#include "qapi/visitor.h"
|
||||||
#include "qapi/qapi-types-common.h"
|
#include "qapi/qapi-types-common.h"
|
||||||
#include "qapi/qapi-visit-common.h"
|
#include "qapi/qapi-visit-common.h"
|
||||||
#include "system/reset.h"
|
#include "sysemu/reset.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
#include "system/hw_accel.h"
|
#include "sysemu/hw_accel.h"
|
||||||
#include "kvm-cpus.h"
|
#include "kvm-cpus.h"
|
||||||
#include "system/dirtylimit.h"
|
#include "sysemu/dirtylimit.h"
|
||||||
#include "qemu/range.h"
|
#include "qemu/range.h"
|
||||||
|
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "system/stats.h"
|
#include "sysemu/stats.h"
|
||||||
|
|
||||||
/* This check must be after config-host.h is included */
|
/* This check must be after config-host.h is included */
|
||||||
#ifdef CONFIG_EVENTFD
|
#ifdef CONFIG_EVENTFD
|
||||||
@@ -69,11 +69,6 @@
|
|||||||
#define KVM_GUESTDBG_BLOCKIRQ 0
|
#define KVM_GUESTDBG_BLOCKIRQ 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Default num of memslots to be allocated when VM starts */
|
|
||||||
#define KVM_MEMSLOTS_NR_ALLOC_DEFAULT 16
|
|
||||||
/* Default max allowed memslots if kernel reported nothing */
|
|
||||||
#define KVM_MEMSLOTS_NR_MAX_DEFAULT 32
|
|
||||||
|
|
||||||
struct KVMParkedVcpu {
|
struct KVMParkedVcpu {
|
||||||
unsigned long vcpu_id;
|
unsigned long vcpu_id;
|
||||||
int kvm_fd;
|
int kvm_fd;
|
||||||
@@ -170,62 +165,11 @@ void kvm_resample_fd_notify(int gsi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* kvm_slots_grow(): Grow the slots[] array in the KVMMemoryListener
|
|
||||||
*
|
|
||||||
* @kml: The KVMMemoryListener* to grow the slots[] array
|
|
||||||
* @nr_slots_new: The new size of slots[] array
|
|
||||||
*
|
|
||||||
* Returns: True if the array grows larger, false otherwise.
|
|
||||||
*/
|
|
||||||
static bool kvm_slots_grow(KVMMemoryListener *kml, unsigned int nr_slots_new)
|
|
||||||
{
|
|
||||||
unsigned int i, cur = kml->nr_slots_allocated;
|
|
||||||
KVMSlot *slots;
|
|
||||||
|
|
||||||
if (nr_slots_new > kvm_state->nr_slots_max) {
|
|
||||||
nr_slots_new = kvm_state->nr_slots_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur >= nr_slots_new) {
|
|
||||||
/* Big enough, no need to grow, or we reached max */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur == 0) {
|
|
||||||
slots = g_new0(KVMSlot, nr_slots_new);
|
|
||||||
} else {
|
|
||||||
assert(kml->slots);
|
|
||||||
slots = g_renew(KVMSlot, kml->slots, nr_slots_new);
|
|
||||||
/*
|
|
||||||
* g_renew() doesn't initialize extended buffers, however kvm
|
|
||||||
* memslots require fields to be zero-initialized. E.g. pointers,
|
|
||||||
* memory_size field, etc.
|
|
||||||
*/
|
|
||||||
memset(&slots[cur], 0x0, sizeof(slots[0]) * (nr_slots_new - cur));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = cur; i < nr_slots_new; i++) {
|
|
||||||
slots[i].slot = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
kml->slots = slots;
|
|
||||||
kml->nr_slots_allocated = nr_slots_new;
|
|
||||||
trace_kvm_slots_grow(cur, nr_slots_new);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool kvm_slots_double(KVMMemoryListener *kml)
|
|
||||||
{
|
|
||||||
return kvm_slots_grow(kml, kml->nr_slots_allocated * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int kvm_get_max_memslots(void)
|
unsigned int kvm_get_max_memslots(void)
|
||||||
{
|
{
|
||||||
KVMState *s = KVM_STATE(current_accel());
|
KVMState *s = KVM_STATE(current_accel());
|
||||||
|
|
||||||
return s->nr_slots_max;
|
return s->nr_slots;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int kvm_get_free_memslots(void)
|
unsigned int kvm_get_free_memslots(void)
|
||||||
@@ -239,36 +183,25 @@ unsigned int kvm_get_free_memslots(void)
|
|||||||
if (!s->as[i].ml) {
|
if (!s->as[i].ml) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
used_slots = MAX(used_slots, s->as[i].ml->nr_slots_used);
|
used_slots = MAX(used_slots, s->as[i].ml->nr_used_slots);
|
||||||
}
|
}
|
||||||
kvm_slots_unlock();
|
kvm_slots_unlock();
|
||||||
|
|
||||||
return s->nr_slots_max - used_slots;
|
return s->nr_slots - used_slots;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called with KVMMemoryListener.slots_lock held */
|
/* Called with KVMMemoryListener.slots_lock held */
|
||||||
static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
|
static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
|
||||||
{
|
{
|
||||||
unsigned int n;
|
KVMState *s = kvm_state;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < kml->nr_slots_allocated; i++) {
|
for (i = 0; i < s->nr_slots; i++) {
|
||||||
if (kml->slots[i].memory_size == 0) {
|
if (kml->slots[i].memory_size == 0) {
|
||||||
return &kml->slots[i];
|
return &kml->slots[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If no free slots, try to grow first by doubling. Cache the old size
|
|
||||||
* here to avoid another round of search: if the grow succeeded, it
|
|
||||||
* means slots[] now must have the existing "n" slots occupied,
|
|
||||||
* followed by one or more free slots starting from slots[n].
|
|
||||||
*/
|
|
||||||
n = kml->nr_slots_allocated;
|
|
||||||
if (kvm_slots_double(kml)) {
|
|
||||||
return &kml->slots[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,9 +222,10 @@ static KVMSlot *kvm_lookup_matching_slot(KVMMemoryListener *kml,
|
|||||||
hwaddr start_addr,
|
hwaddr start_addr,
|
||||||
hwaddr size)
|
hwaddr size)
|
||||||
{
|
{
|
||||||
|
KVMState *s = kvm_state;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < kml->nr_slots_allocated; i++) {
|
for (i = 0; i < s->nr_slots; i++) {
|
||||||
KVMSlot *mem = &kml->slots[i];
|
KVMSlot *mem = &kml->slots[i];
|
||||||
|
|
||||||
if (start_addr == mem->start_addr && size == mem->memory_size) {
|
if (start_addr == mem->start_addr && size == mem->memory_size) {
|
||||||
@@ -333,7 +267,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram,
|
|||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
kvm_slots_lock();
|
kvm_slots_lock();
|
||||||
for (i = 0; i < kml->nr_slots_allocated; i++) {
|
for (i = 0; i < s->nr_slots; i++) {
|
||||||
KVMSlot *mem = &kml->slots[i];
|
KVMSlot *mem = &kml->slots[i];
|
||||||
|
|
||||||
if (ram >= mem->ram && ram < mem->ram + mem->memory_size) {
|
if (ram >= mem->ram && ram < mem->ram + mem->memory_size) {
|
||||||
@@ -437,16 +371,6 @@ int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
|
|||||||
return kvm_fd;
|
return kvm_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvm_reset_parked_vcpus(void *param)
|
|
||||||
{
|
|
||||||
KVMState *s = param;
|
|
||||||
struct KVMParkedVcpu *cpu;
|
|
||||||
|
|
||||||
QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
|
|
||||||
kvm_arch_reset_parked_vcpu(cpu->vcpu_id, cpu->kvm_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int kvm_create_vcpu(CPUState *cpu)
|
int kvm_create_vcpu(CPUState *cpu)
|
||||||
{
|
{
|
||||||
unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
|
unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
|
||||||
@@ -490,7 +414,7 @@ int kvm_create_and_park_vcpu(CPUState *cpu)
|
|||||||
static int do_kvm_destroy_vcpu(CPUState *cpu)
|
static int do_kvm_destroy_vcpu(CPUState *cpu)
|
||||||
{
|
{
|
||||||
KVMState *s = kvm_state;
|
KVMState *s = kvm_state;
|
||||||
int mmap_size;
|
long mmap_size;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
|
trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
|
||||||
@@ -535,7 +459,7 @@ void kvm_destroy_vcpu(CPUState *cpu)
|
|||||||
int kvm_init_vcpu(CPUState *cpu, Error **errp)
|
int kvm_init_vcpu(CPUState *cpu, Error **errp)
|
||||||
{
|
{
|
||||||
KVMState *s = kvm_state;
|
KVMState *s = kvm_state;
|
||||||
int mmap_size;
|
long mmap_size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
|
trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
|
||||||
@@ -1147,7 +1071,7 @@ static int kvm_physical_log_clear(KVMMemoryListener *kml,
|
|||||||
|
|
||||||
kvm_slots_lock();
|
kvm_slots_lock();
|
||||||
|
|
||||||
for (i = 0; i < kml->nr_slots_allocated; i++) {
|
for (i = 0; i < s->nr_slots; i++) {
|
||||||
mem = &kml->slots[i];
|
mem = &kml->slots[i];
|
||||||
/* Discard slots that are empty or do not overlap the section */
|
/* Discard slots that are empty or do not overlap the section */
|
||||||
if (!mem->memory_size ||
|
if (!mem->memory_size ||
|
||||||
@@ -1288,7 +1212,7 @@ static void kvm_unpoison_all(void *param)
|
|||||||
|
|
||||||
QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) {
|
QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) {
|
||||||
QLIST_REMOVE(page, list);
|
QLIST_REMOVE(page, list);
|
||||||
qemu_ram_remap(page->ram_addr);
|
qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
|
||||||
g_free(page);
|
g_free(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1526,7 +1450,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
|||||||
}
|
}
|
||||||
start_addr += slot_size;
|
start_addr += slot_size;
|
||||||
size -= slot_size;
|
size -= slot_size;
|
||||||
kml->nr_slots_used--;
|
kml->nr_used_slots--;
|
||||||
} while (size);
|
} while (size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1565,7 +1489,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
|||||||
ram_start_offset += slot_size;
|
ram_start_offset += slot_size;
|
||||||
ram += slot_size;
|
ram += slot_size;
|
||||||
size -= slot_size;
|
size -= slot_size;
|
||||||
kml->nr_slots_used++;
|
kml->nr_used_slots++;
|
||||||
} while (size);
|
} while (size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1601,7 +1525,11 @@ static void *kvm_dirty_ring_reaper_thread(void *data)
|
|||||||
r->reaper_iteration++;
|
r->reaper_iteration++;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert_not_reached();
|
trace_kvm_dirty_ring_reaper("exit");
|
||||||
|
|
||||||
|
rcu_unregister_thread();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kvm_dirty_ring_reaper_init(KVMState *s)
|
static void kvm_dirty_ring_reaper_init(KVMState *s)
|
||||||
@@ -1791,8 +1719,12 @@ static void kvm_log_sync_global(MemoryListener *l, bool last_stage)
|
|||||||
/* Flush all kernel dirty addresses into KVMSlot dirty bitmap */
|
/* Flush all kernel dirty addresses into KVMSlot dirty bitmap */
|
||||||
kvm_dirty_ring_flush();
|
kvm_dirty_ring_flush();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: make this faster when nr_slots is big while there are
|
||||||
|
* only a few used slots (small VMs).
|
||||||
|
*/
|
||||||
kvm_slots_lock();
|
kvm_slots_lock();
|
||||||
for (i = 0; i < kml->nr_slots_allocated; i++) {
|
for (i = 0; i < s->nr_slots; i++) {
|
||||||
mem = &kml->slots[i];
|
mem = &kml->slots[i];
|
||||||
if (mem->memory_size && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
|
if (mem->memory_size && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
|
||||||
kvm_slot_sync_dirty_pages(mem);
|
kvm_slot_sync_dirty_pages(mem);
|
||||||
@@ -1907,9 +1839,12 @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
kml->slots = g_new0(KVMSlot, s->nr_slots);
|
||||||
kml->as_id = as_id;
|
kml->as_id = as_id;
|
||||||
|
|
||||||
kvm_slots_grow(kml, KVM_MEMSLOTS_NR_ALLOC_DEFAULT);
|
for (i = 0; i < s->nr_slots; i++) {
|
||||||
|
kml->slots[i].slot = i;
|
||||||
|
}
|
||||||
|
|
||||||
QSIMPLEQ_INIT(&kml->transaction_add);
|
QSIMPLEQ_INIT(&kml->transaction_add);
|
||||||
QSIMPLEQ_INIT(&kml->transaction_del);
|
QSIMPLEQ_INIT(&kml->transaction_del);
|
||||||
@@ -2450,64 +2385,171 @@ uint32_t kvm_dirty_ring_size(void)
|
|||||||
return kvm_state->kvm_dirty_ring_size;
|
return kvm_state->kvm_dirty_ring_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_kvm_create_vm(MachineState *ms, int type)
|
static int kvm_init(MachineState *ms)
|
||||||
{
|
{
|
||||||
|
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||||
|
static const char upgrade_note[] =
|
||||||
|
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
|
||||||
|
"(see http://sourceforge.net/projects/kvm).\n";
|
||||||
|
const struct {
|
||||||
|
const char *name;
|
||||||
|
int num;
|
||||||
|
} num_cpus[] = {
|
||||||
|
{ "SMP", ms->smp.cpus },
|
||||||
|
{ "hotpluggable", ms->smp.max_cpus },
|
||||||
|
{ /* end of list */ }
|
||||||
|
}, *nc = num_cpus;
|
||||||
|
int soft_vcpus_limit, hard_vcpus_limit;
|
||||||
KVMState *s;
|
KVMState *s;
|
||||||
|
const KVMCapabilityInfo *missing_cap;
|
||||||
int ret;
|
int ret;
|
||||||
|
int type;
|
||||||
|
uint64_t dirty_log_manual_caps;
|
||||||
|
|
||||||
|
qemu_mutex_init(&kml_slots_lock);
|
||||||
|
|
||||||
s = KVM_STATE(ms->accelerator);
|
s = KVM_STATE(ms->accelerator);
|
||||||
|
|
||||||
do {
|
/*
|
||||||
ret = kvm_ioctl(s, KVM_CREATE_VM, type);
|
* On systems where the kernel can support different base page
|
||||||
} while (ret == -EINTR);
|
* sizes, host page size may be different from TARGET_PAGE_SIZE,
|
||||||
|
* even with KVM. TARGET_PAGE_SIZE is assumed to be the minimum
|
||||||
|
* page size for the system though.
|
||||||
|
*/
|
||||||
|
assert(TARGET_PAGE_SIZE <= qemu_real_host_page_size());
|
||||||
|
|
||||||
if (ret < 0) {
|
s->sigmask_len = 8;
|
||||||
error_report("ioctl(KVM_CREATE_VM) failed: %s", strerror(-ret));
|
accel_blocker_init();
|
||||||
|
|
||||||
#ifdef TARGET_S390X
|
#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
|
||||||
if (ret == -EINVAL) {
|
QTAILQ_INIT(&s->kvm_sw_breakpoints);
|
||||||
error_printf("Host kernel setup problem detected."
|
|
||||||
" Please verify:\n");
|
|
||||||
error_printf("- for kernels supporting the"
|
|
||||||
" switch_amode or user_mode parameters, whether");
|
|
||||||
error_printf(" user space is running in primary address space\n");
|
|
||||||
error_printf("- for kernels supporting the vm.allocate_pgste"
|
|
||||||
" sysctl, whether it is enabled\n");
|
|
||||||
}
|
|
||||||
#elif defined(TARGET_PPC)
|
|
||||||
if (ret == -EINVAL) {
|
|
||||||
error_printf("PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
|
|
||||||
(type == 2) ? "pr" : "hv");
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
QLIST_INIT(&s->kvm_parked_vcpus);
|
||||||
|
s->fd = qemu_open_old(s->device ?: "/dev/kvm", O_RDWR);
|
||||||
|
if (s->fd == -1) {
|
||||||
|
fprintf(stderr, "Could not access KVM kernel module: %m\n");
|
||||||
|
ret = -errno;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
ret = kvm_ioctl(s, KVM_GET_API_VERSION, 0);
|
||||||
}
|
if (ret < KVM_API_VERSION) {
|
||||||
|
if (ret >= 0) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "kvm version too old\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
static int find_kvm_machine_type(MachineState *ms)
|
if (ret > KVM_API_VERSION) {
|
||||||
{
|
ret = -EINVAL;
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
fprintf(stderr, "kvm version not supported\n");
|
||||||
int type;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
kvm_supported_memory_attributes = kvm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES);
|
||||||
|
kvm_guest_memfd_supported =
|
||||||
|
kvm_check_extension(s, KVM_CAP_GUEST_MEMFD) &&
|
||||||
|
kvm_check_extension(s, KVM_CAP_USER_MEMORY2) &&
|
||||||
|
(kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
|
||||||
|
|
||||||
|
kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT);
|
||||||
|
s->nr_slots = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
|
||||||
|
|
||||||
|
/* If unspecified, use the default value */
|
||||||
|
if (!s->nr_slots) {
|
||||||
|
s->nr_slots = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE);
|
||||||
|
if (s->nr_as <= 1) {
|
||||||
|
s->nr_as = 1;
|
||||||
|
}
|
||||||
|
s->as = g_new0(struct KVMAs, s->nr_as);
|
||||||
|
|
||||||
if (object_property_find(OBJECT(current_machine), "kvm-type")) {
|
if (object_property_find(OBJECT(current_machine), "kvm-type")) {
|
||||||
g_autofree char *kvm_type;
|
g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
|
||||||
kvm_type = object_property_get_str(OBJECT(current_machine),
|
"kvm-type",
|
||||||
"kvm-type",
|
&error_abort);
|
||||||
&error_abort);
|
|
||||||
type = mc->kvm_type(ms, kvm_type);
|
type = mc->kvm_type(ms, kvm_type);
|
||||||
} else if (mc->kvm_type) {
|
} else if (mc->kvm_type) {
|
||||||
type = mc->kvm_type(ms, NULL);
|
type = mc->kvm_type(ms, NULL);
|
||||||
} else {
|
} else {
|
||||||
type = kvm_arch_get_default_type(ms);
|
type = kvm_arch_get_default_type(ms);
|
||||||
}
|
}
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int kvm_setup_dirty_ring(KVMState *s)
|
if (type < 0) {
|
||||||
{
|
ret = -EINVAL;
|
||||||
uint64_t dirty_log_manual_caps;
|
goto err;
|
||||||
int ret;
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = kvm_ioctl(s, KVM_CREATE_VM, type);
|
||||||
|
} while (ret == -EINTR);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "ioctl(KVM_CREATE_VM) failed: %d %s\n", -ret,
|
||||||
|
strerror(-ret));
|
||||||
|
|
||||||
|
#ifdef TARGET_S390X
|
||||||
|
if (ret == -EINVAL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Host kernel setup problem detected. Please verify:\n");
|
||||||
|
fprintf(stderr, "- for kernels supporting the switch_amode or"
|
||||||
|
" user_mode parameters, whether\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" user space is running in primary address space\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"- for kernels supporting the vm.allocate_pgste sysctl, "
|
||||||
|
"whether it is enabled\n");
|
||||||
|
}
|
||||||
|
#elif defined(TARGET_PPC)
|
||||||
|
if (ret == -EINVAL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"PPC KVM module is not loaded. Try modprobe kvm_%s.\n",
|
||||||
|
(type == 2) ? "pr" : "hv");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->vmfd = ret;
|
||||||
|
|
||||||
|
/* check the vcpu limits */
|
||||||
|
soft_vcpus_limit = kvm_recommended_vcpus(s);
|
||||||
|
hard_vcpus_limit = kvm_max_vcpus(s);
|
||||||
|
|
||||||
|
while (nc->name) {
|
||||||
|
if (nc->num > soft_vcpus_limit) {
|
||||||
|
warn_report("Number of %s cpus requested (%d) exceeds "
|
||||||
|
"the recommended cpus supported by KVM (%d)",
|
||||||
|
nc->name, nc->num, soft_vcpus_limit);
|
||||||
|
|
||||||
|
if (nc->num > hard_vcpus_limit) {
|
||||||
|
fprintf(stderr, "Number of %s cpus requested (%d) exceeds "
|
||||||
|
"the maximum cpus supported by KVM (%d)\n",
|
||||||
|
nc->name, nc->num, hard_vcpus_limit);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
missing_cap = kvm_check_extension_list(s, kvm_required_capabilites);
|
||||||
|
if (!missing_cap) {
|
||||||
|
missing_cap =
|
||||||
|
kvm_check_extension_list(s, kvm_arch_required_capabilities);
|
||||||
|
}
|
||||||
|
if (missing_cap) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
fprintf(stderr, "kvm does not support %s\n%s",
|
||||||
|
missing_cap->name, upgrade_note);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
|
||||||
|
s->coalesced_pio = s->coalesced_mmio &&
|
||||||
|
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable KVM dirty ring if supported, otherwise fall back to
|
* Enable KVM dirty ring if supported, otherwise fall back to
|
||||||
@@ -2515,7 +2557,7 @@ static int kvm_setup_dirty_ring(KVMState *s)
|
|||||||
*/
|
*/
|
||||||
ret = kvm_dirty_ring_init(s);
|
ret = kvm_dirty_ring_init(s);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2550,138 +2592,6 @@ static int kvm_setup_dirty_ring(KVMState *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int kvm_init(MachineState *ms)
|
|
||||||
{
|
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
|
||||||
static const char upgrade_note[] =
|
|
||||||
"Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
|
|
||||||
"(see http://sourceforge.net/projects/kvm).\n";
|
|
||||||
const struct {
|
|
||||||
const char *name;
|
|
||||||
int num;
|
|
||||||
} num_cpus[] = {
|
|
||||||
{ "SMP", ms->smp.cpus },
|
|
||||||
{ "hotpluggable", ms->smp.max_cpus },
|
|
||||||
{ /* end of list */ }
|
|
||||||
}, *nc = num_cpus;
|
|
||||||
int soft_vcpus_limit, hard_vcpus_limit;
|
|
||||||
KVMState *s;
|
|
||||||
const KVMCapabilityInfo *missing_cap;
|
|
||||||
int ret;
|
|
||||||
int type;
|
|
||||||
|
|
||||||
qemu_mutex_init(&kml_slots_lock);
|
|
||||||
|
|
||||||
s = KVM_STATE(ms->accelerator);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* On systems where the kernel can support different base page
|
|
||||||
* sizes, host page size may be different from TARGET_PAGE_SIZE,
|
|
||||||
* even with KVM. TARGET_PAGE_SIZE is assumed to be the minimum
|
|
||||||
* page size for the system though.
|
|
||||||
*/
|
|
||||||
assert(TARGET_PAGE_SIZE <= qemu_real_host_page_size());
|
|
||||||
|
|
||||||
s->sigmask_len = 8;
|
|
||||||
accel_blocker_init();
|
|
||||||
|
|
||||||
#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
|
|
||||||
QTAILQ_INIT(&s->kvm_sw_breakpoints);
|
|
||||||
#endif
|
|
||||||
QLIST_INIT(&s->kvm_parked_vcpus);
|
|
||||||
s->fd = qemu_open_old(s->device ?: "/dev/kvm", O_RDWR);
|
|
||||||
if (s->fd == -1) {
|
|
||||||
error_report("Could not access KVM kernel module: %m");
|
|
||||||
ret = -errno;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = kvm_ioctl(s, KVM_GET_API_VERSION, 0);
|
|
||||||
if (ret < KVM_API_VERSION) {
|
|
||||||
if (ret >= 0) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
}
|
|
||||||
error_report("kvm version too old");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret > KVM_API_VERSION) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
error_report("kvm version not supported");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
kvm_immediate_exit = kvm_check_extension(s, KVM_CAP_IMMEDIATE_EXIT);
|
|
||||||
s->nr_slots_max = kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
|
|
||||||
|
|
||||||
/* If unspecified, use the default value */
|
|
||||||
if (!s->nr_slots_max) {
|
|
||||||
s->nr_slots_max = KVM_MEMSLOTS_NR_MAX_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = find_kvm_machine_type(ms);
|
|
||||||
if (type < 0) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = do_kvm_create_vm(ms, type);
|
|
||||||
if (ret < 0) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->vmfd = ret;
|
|
||||||
|
|
||||||
s->nr_as = kvm_vm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE);
|
|
||||||
if (s->nr_as <= 1) {
|
|
||||||
s->nr_as = 1;
|
|
||||||
}
|
|
||||||
s->as = g_new0(struct KVMAs, s->nr_as);
|
|
||||||
|
|
||||||
/* check the vcpu limits */
|
|
||||||
soft_vcpus_limit = kvm_recommended_vcpus(s);
|
|
||||||
hard_vcpus_limit = kvm_max_vcpus(s);
|
|
||||||
|
|
||||||
while (nc->name) {
|
|
||||||
if (nc->num > soft_vcpus_limit) {
|
|
||||||
warn_report("Number of %s cpus requested (%d) exceeds "
|
|
||||||
"the recommended cpus supported by KVM (%d)",
|
|
||||||
nc->name, nc->num, soft_vcpus_limit);
|
|
||||||
|
|
||||||
if (nc->num > hard_vcpus_limit) {
|
|
||||||
error_report("Number of %s cpus requested (%d) exceeds "
|
|
||||||
"the maximum cpus supported by KVM (%d)",
|
|
||||||
nc->name, nc->num, hard_vcpus_limit);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
missing_cap = kvm_check_extension_list(s, kvm_required_capabilites);
|
|
||||||
if (!missing_cap) {
|
|
||||||
missing_cap =
|
|
||||||
kvm_check_extension_list(s, kvm_arch_required_capabilities);
|
|
||||||
}
|
|
||||||
if (missing_cap) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
error_report("kvm does not support %s", missing_cap->name);
|
|
||||||
error_printf("%s", upgrade_note);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
|
|
||||||
s->coalesced_pio = s->coalesced_mmio &&
|
|
||||||
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
|
|
||||||
|
|
||||||
ret = kvm_setup_dirty_ring(s);
|
|
||||||
if (ret < 0) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef KVM_CAP_VCPU_EVENTS
|
#ifdef KVM_CAP_VCPU_EVENTS
|
||||||
s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);
|
s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);
|
||||||
#endif
|
#endif
|
||||||
@@ -2727,18 +2637,11 @@ static int kvm_init(MachineState *ms)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
kvm_supported_memory_attributes = kvm_vm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES);
|
|
||||||
kvm_guest_memfd_supported =
|
|
||||||
kvm_check_extension(s, KVM_CAP_GUEST_MEMFD) &&
|
|
||||||
kvm_check_extension(s, KVM_CAP_USER_MEMORY2) &&
|
|
||||||
(kvm_supported_memory_attributes & KVM_MEMORY_ATTRIBUTE_PRIVATE);
|
|
||||||
|
|
||||||
if (s->kernel_irqchip_split == ON_OFF_AUTO_AUTO) {
|
if (s->kernel_irqchip_split == ON_OFF_AUTO_AUTO) {
|
||||||
s->kernel_irqchip_split = mc->default_kernel_irqchip_split ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
|
s->kernel_irqchip_split = mc->default_kernel_irqchip_split ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_register_reset(kvm_unpoison_all, NULL);
|
qemu_register_reset(kvm_unpoison_all, NULL);
|
||||||
qemu_register_reset(kvm_reset_parked_vcpus, s);
|
|
||||||
|
|
||||||
if (s->kernel_irqchip_allowed) {
|
if (s->kernel_irqchip_allowed) {
|
||||||
kvm_irqchip_create(s);
|
kvm_irqchip_create(s);
|
||||||
@@ -2863,15 +2766,9 @@ void kvm_flush_coalesced_mmio_buffer(void)
|
|||||||
static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
|
static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
|
||||||
{
|
{
|
||||||
if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) {
|
if (!cpu->vcpu_dirty && !kvm_state->guest_state_protected) {
|
||||||
Error *err = NULL;
|
int ret = kvm_arch_get_registers(cpu);
|
||||||
int ret = kvm_arch_get_registers(cpu, &err);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (err) {
|
error_report("Failed to get registers: %s", strerror(-ret));
|
||||||
error_reportf_err(err, "Failed to synchronize CPU state: ");
|
|
||||||
} else {
|
|
||||||
error_report("Failed to get registers: %s", strerror(-ret));
|
|
||||||
}
|
|
||||||
|
|
||||||
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
|
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
|
||||||
vm_stop(RUN_STATE_INTERNAL_ERROR);
|
vm_stop(RUN_STATE_INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
@@ -2889,15 +2786,9 @@ void kvm_cpu_synchronize_state(CPUState *cpu)
|
|||||||
|
|
||||||
static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
|
static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
|
||||||
{
|
{
|
||||||
Error *err = NULL;
|
int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
|
||||||
int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE, &err);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (err) {
|
error_report("Failed to put registers after reset: %s", strerror(-ret));
|
||||||
error_reportf_err(err, "Restoring resisters after reset: ");
|
|
||||||
} else {
|
|
||||||
error_report("Failed to put registers after reset: %s",
|
|
||||||
strerror(-ret));
|
|
||||||
}
|
|
||||||
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
|
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
|
||||||
vm_stop(RUN_STATE_INTERNAL_ERROR);
|
vm_stop(RUN_STATE_INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
@@ -2912,15 +2803,9 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu)
|
|||||||
|
|
||||||
static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
|
static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
|
||||||
{
|
{
|
||||||
Error *err = NULL;
|
int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
|
||||||
int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE, &err);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (err) {
|
error_report("Failed to put registers after init: %s", strerror(-ret));
|
||||||
error_reportf_err(err, "Putting registers after init: ");
|
|
||||||
} else {
|
|
||||||
error_report("Failed to put registers after init: %s",
|
|
||||||
strerror(-ret));
|
|
||||||
}
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3010,17 +2895,17 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private)
|
|||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
RAMBlock *rb;
|
RAMBlock *rb;
|
||||||
void *addr;
|
void *addr;
|
||||||
int ret = -EINVAL;
|
int ret = -1;
|
||||||
|
|
||||||
trace_kvm_convert_memory(start, size, to_private ? "shared_to_private" : "private_to_shared");
|
trace_kvm_convert_memory(start, size, to_private ? "shared_to_private" : "private_to_shared");
|
||||||
|
|
||||||
if (!QEMU_PTR_IS_ALIGNED(start, qemu_real_host_page_size()) ||
|
if (!QEMU_PTR_IS_ALIGNED(start, qemu_real_host_page_size()) ||
|
||||||
!QEMU_PTR_IS_ALIGNED(size, qemu_real_host_page_size())) {
|
!QEMU_PTR_IS_ALIGNED(size, qemu_real_host_page_size())) {
|
||||||
return ret;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!size) {
|
if (!size) {
|
||||||
return ret;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
section = memory_region_find(get_system_memory(), start, size);
|
section = memory_region_find(get_system_memory(), start, size);
|
||||||
@@ -3038,7 +2923,7 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private)
|
|||||||
if (!to_private) {
|
if (!to_private) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ret;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!memory_region_has_guest_memfd(mr)) {
|
if (!memory_region_has_guest_memfd(mr)) {
|
||||||
@@ -3110,15 +2995,10 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||||||
MemTxAttrs attrs;
|
MemTxAttrs attrs;
|
||||||
|
|
||||||
if (cpu->vcpu_dirty) {
|
if (cpu->vcpu_dirty) {
|
||||||
Error *err = NULL;
|
ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
|
||||||
ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE, &err);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (err) {
|
error_report("Failed to put registers after init: %s",
|
||||||
error_reportf_err(err, "Putting registers after init: ");
|
strerror(-ret));
|
||||||
} else {
|
|
||||||
error_report("Failed to put registers after init: %s",
|
|
||||||
strerror(-ret));
|
|
||||||
}
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3290,7 +3170,7 @@ int kvm_cpu_exec(CPUState *cpu)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_ioctl(KVMState *s, unsigned long type, ...)
|
int kvm_ioctl(KVMState *s, int type, ...)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
void *arg;
|
void *arg;
|
||||||
@@ -3308,7 +3188,7 @@ int kvm_ioctl(KVMState *s, unsigned long type, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_vm_ioctl(KVMState *s, unsigned long type, ...)
|
int kvm_vm_ioctl(KVMState *s, int type, ...)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
void *arg;
|
void *arg;
|
||||||
@@ -3328,7 +3208,7 @@ int kvm_vm_ioctl(KVMState *s, unsigned long type, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_vcpu_ioctl(CPUState *cpu, unsigned long type, ...)
|
int kvm_vcpu_ioctl(CPUState *cpu, int type, ...)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
void *arg;
|
void *arg;
|
||||||
@@ -3348,7 +3228,7 @@ int kvm_vcpu_ioctl(CPUState *cpu, unsigned long type, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_device_ioctl(int fd, unsigned long type, ...)
|
int kvm_device_ioctl(int fd, int type, ...)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
void *arg;
|
void *arg;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#ifndef KVM_CPUS_H
|
#ifndef KVM_CPUS_H
|
||||||
#define KVM_CPUS_H
|
#define KVM_CPUS_H
|
||||||
|
|
||||||
|
#include "sysemu/cpus.h"
|
||||||
|
|
||||||
int kvm_init_vcpu(CPUState *cpu, Error **errp);
|
int kvm_init_vcpu(CPUState *cpu, Error **errp);
|
||||||
int kvm_cpu_exec(CPUState *cpu);
|
int kvm_cpu_exec(CPUState *cpu);
|
||||||
void kvm_destroy_vcpu(CPUState *cpu);
|
void kvm_destroy_vcpu(CPUState *cpu);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# See docs/devel/tracing.rst for syntax documentation.
|
# See docs/devel/tracing.rst for syntax documentation.
|
||||||
|
|
||||||
# kvm-all.c
|
# kvm-all.c
|
||||||
kvm_ioctl(unsigned long type, void *arg) "type 0x%lx, arg %p"
|
kvm_ioctl(int type, void *arg) "type 0x%x, arg %p"
|
||||||
kvm_vm_ioctl(unsigned long type, void *arg) "type 0x%lx, arg %p"
|
kvm_vm_ioctl(int type, void *arg) "type 0x%x, arg %p"
|
||||||
kvm_vcpu_ioctl(int cpu_index, unsigned long type, void *arg) "cpu_index %d, type 0x%lx, arg %p"
|
kvm_vcpu_ioctl(int cpu_index, int type, void *arg) "cpu_index %d, type 0x%x, arg %p"
|
||||||
kvm_run_exit(int cpu_index, uint32_t reason) "cpu_index %d, reason %d"
|
kvm_run_exit(int cpu_index, uint32_t reason) "cpu_index %d, reason %d"
|
||||||
kvm_device_ioctl(int fd, unsigned long type, void *arg) "dev fd %d, type 0x%lx, arg %p"
|
kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 0x%x, arg %p"
|
||||||
kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s"
|
kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s"
|
||||||
kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s"
|
kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s"
|
||||||
kvm_init_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu"
|
kvm_init_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu"
|
||||||
@@ -36,4 +36,3 @@ kvm_io_window_exit(void) ""
|
|||||||
kvm_run_exit_system_event(int cpu_index, uint32_t event_type) "cpu_index %d, system_even_type %"PRIu32
|
kvm_run_exit_system_event(int cpu_index, uint32_t event_type) "cpu_index %d, system_even_type %"PRIu32
|
||||||
kvm_convert_memory(uint64_t start, uint64_t size, const char *msg) "start 0x%" PRIx64 " size 0x%" PRIx64 " %s"
|
kvm_convert_memory(uint64_t start, uint64_t size, const char *msg) "start 0x%" PRIx64 " size 0x%" PRIx64 " %s"
|
||||||
kvm_memory_fault(uint64_t start, uint64_t size, uint64_t flags) "start 0x%" PRIx64 " size 0x%" PRIx64 " flags 0x%" PRIx64
|
kvm_memory_fault(uint64_t start, uint64_t size, uint64_t flags) "start 0x%" PRIx64 " size 0x%" PRIx64 " flags 0x%" PRIx64
|
||||||
kvm_slots_grow(unsigned int old, unsigned int new) "%u -> %u"
|
|
||||||
|
|||||||
@@ -18,9 +18,8 @@
|
|||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
#include "qemu/accel.h"
|
#include "qemu/accel.h"
|
||||||
#include "system/accel-ops.h"
|
#include "sysemu/qtest.h"
|
||||||
#include "system/qtest.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/cpus.h"
|
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "hw/pci/msi.h"
|
#include "hw/pci/msi.h"
|
||||||
|
|
||||||
KVMState *kvm_state;
|
KVMState *kvm_state;
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
#include "exec/tb-flush.h"
|
#include "exec/tb-flush.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
|
void tb_flush(CPUState *cpu)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
G_NORETURN void cpu_loop_exit(CPUState *cpu)
|
G_NORETURN void cpu_loop_exit(CPUState *cpu)
|
||||||
{
|
{
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/xen.h"
|
#include "sysemu/xen.h"
|
||||||
#include "qapi/qapi-commands-migration.h"
|
#include "qapi/qapi-commands-migration.h"
|
||||||
|
|
||||||
bool xen_allowed;
|
bool xen_allowed;
|
||||||
|
|||||||
@@ -14,20 +14,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void atomic_trace_rmw_post(CPUArchState *env, uint64_t addr,
|
static void atomic_trace_rmw_post(CPUArchState *env, uint64_t addr,
|
||||||
uint64_t read_value_low,
|
|
||||||
uint64_t read_value_high,
|
|
||||||
uint64_t write_value_low,
|
|
||||||
uint64_t write_value_high,
|
|
||||||
MemOpIdx oi)
|
MemOpIdx oi)
|
||||||
{
|
{
|
||||||
if (cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_RW);
|
||||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr,
|
|
||||||
read_value_low, read_value_high,
|
|
||||||
oi, QEMU_PLUGIN_MEM_R);
|
|
||||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr,
|
|
||||||
write_value_low, write_value_high,
|
|
||||||
oi, QEMU_PLUGIN_MEM_W);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -53,14 +53,6 @@
|
|||||||
# error unsupported data size
|
# error unsupported data size
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DATA_SIZE == 16
|
|
||||||
# define VALUE_LOW(val) int128_getlo(val)
|
|
||||||
# define VALUE_HIGH(val) int128_gethi(val)
|
|
||||||
#else
|
|
||||||
# define VALUE_LOW(val) val
|
|
||||||
# define VALUE_HIGH(val) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DATA_SIZE >= 4
|
#if DATA_SIZE >= 4
|
||||||
# define ABI_TYPE DATA_TYPE
|
# define ABI_TYPE DATA_TYPE
|
||||||
#else
|
#else
|
||||||
@@ -91,12 +83,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
|
|||||||
ret = qatomic_cmpxchg__nocheck(haddr, cmpv, newv);
|
ret = qatomic_cmpxchg__nocheck(haddr, cmpv, newv);
|
||||||
#endif
|
#endif
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
atomic_trace_rmw_post(env, addr,
|
atomic_trace_rmw_post(env, addr, oi);
|
||||||
VALUE_LOW(ret),
|
|
||||||
VALUE_HIGH(ret),
|
|
||||||
VALUE_LOW(newv),
|
|
||||||
VALUE_HIGH(newv),
|
|
||||||
oi);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,12 +97,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
|
|||||||
|
|
||||||
ret = qatomic_xchg__nocheck(haddr, val);
|
ret = qatomic_xchg__nocheck(haddr, val);
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
atomic_trace_rmw_post(env, addr,
|
atomic_trace_rmw_post(env, addr, oi);
|
||||||
VALUE_LOW(ret),
|
|
||||||
VALUE_HIGH(ret),
|
|
||||||
VALUE_LOW(val),
|
|
||||||
VALUE_HIGH(val),
|
|
||||||
oi);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,12 +109,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
|
|||||||
haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr); \
|
haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr); \
|
||||||
ret = qatomic_##X(haddr, val); \
|
ret = qatomic_##X(haddr, val); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
atomic_trace_rmw_post(env, addr, \
|
atomic_trace_rmw_post(env, addr, oi); \
|
||||||
VALUE_LOW(ret), \
|
|
||||||
VALUE_HIGH(ret), \
|
|
||||||
VALUE_LOW(val), \
|
|
||||||
VALUE_HIGH(val), \
|
|
||||||
oi); \
|
|
||||||
return ret; \
|
return ret; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,12 +145,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
|
|||||||
cmp = qatomic_cmpxchg__nocheck(haddr, old, new); \
|
cmp = qatomic_cmpxchg__nocheck(haddr, old, new); \
|
||||||
} while (cmp != old); \
|
} while (cmp != old); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
atomic_trace_rmw_post(env, addr, \
|
atomic_trace_rmw_post(env, addr, oi); \
|
||||||
VALUE_LOW(old), \
|
|
||||||
VALUE_HIGH(old), \
|
|
||||||
VALUE_LOW(xval), \
|
|
||||||
VALUE_HIGH(xval), \
|
|
||||||
oi); \
|
|
||||||
return RET; \
|
return RET; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,12 +188,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, abi_ptr addr,
|
|||||||
ret = qatomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
|
ret = qatomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv));
|
||||||
#endif
|
#endif
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
atomic_trace_rmw_post(env, addr,
|
atomic_trace_rmw_post(env, addr, oi);
|
||||||
VALUE_LOW(ret),
|
|
||||||
VALUE_HIGH(ret),
|
|
||||||
VALUE_LOW(newv),
|
|
||||||
VALUE_HIGH(newv),
|
|
||||||
oi);
|
|
||||||
return BSWAP(ret);
|
return BSWAP(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,12 +202,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, abi_ptr addr, ABI_TYPE val,
|
|||||||
|
|
||||||
ret = qatomic_xchg__nocheck(haddr, BSWAP(val));
|
ret = qatomic_xchg__nocheck(haddr, BSWAP(val));
|
||||||
ATOMIC_MMU_CLEANUP;
|
ATOMIC_MMU_CLEANUP;
|
||||||
atomic_trace_rmw_post(env, addr,
|
atomic_trace_rmw_post(env, addr, oi);
|
||||||
VALUE_LOW(ret),
|
|
||||||
VALUE_HIGH(ret),
|
|
||||||
VALUE_LOW(val),
|
|
||||||
VALUE_HIGH(val),
|
|
||||||
oi);
|
|
||||||
return BSWAP(ret);
|
return BSWAP(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,12 +214,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
|
|||||||
haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr); \
|
haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, DATA_SIZE, retaddr); \
|
||||||
ret = qatomic_##X(haddr, BSWAP(val)); \
|
ret = qatomic_##X(haddr, BSWAP(val)); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
atomic_trace_rmw_post(env, addr, \
|
atomic_trace_rmw_post(env, addr, oi); \
|
||||||
VALUE_LOW(ret), \
|
|
||||||
VALUE_HIGH(ret), \
|
|
||||||
VALUE_LOW(val), \
|
|
||||||
VALUE_HIGH(val), \
|
|
||||||
oi); \
|
|
||||||
return BSWAP(ret); \
|
return BSWAP(ret); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,12 +247,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, abi_ptr addr, \
|
|||||||
ldn = qatomic_cmpxchg__nocheck(haddr, ldo, BSWAP(new)); \
|
ldn = qatomic_cmpxchg__nocheck(haddr, ldo, BSWAP(new)); \
|
||||||
} while (ldo != ldn); \
|
} while (ldo != ldn); \
|
||||||
ATOMIC_MMU_CLEANUP; \
|
ATOMIC_MMU_CLEANUP; \
|
||||||
atomic_trace_rmw_post(env, addr, \
|
atomic_trace_rmw_post(env, addr, oi); \
|
||||||
VALUE_LOW(old), \
|
|
||||||
VALUE_HIGH(old), \
|
|
||||||
VALUE_LOW(xval), \
|
|
||||||
VALUE_HIGH(xval), \
|
|
||||||
oi); \
|
|
||||||
return RET; \
|
return RET; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,5 +281,3 @@ GEN_ATOMIC_HELPER_FN(add_fetch, ADD, DATA_TYPE, new)
|
|||||||
#undef SUFFIX
|
#undef SUFFIX
|
||||||
#undef DATA_SIZE
|
#undef DATA_SIZE
|
||||||
#undef SHIFT
|
#undef SHIFT
|
||||||
#undef VALUE_LOW
|
|
||||||
#undef VALUE_HIGH
|
|
||||||
|
|||||||
@@ -18,45 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "exec/log.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "qemu/plugin.h"
|
#include "qemu/plugin.h"
|
||||||
#include "internal-common.h"
|
#include "internal-common.h"
|
||||||
|
|
||||||
bool tcg_allowed;
|
bool tcg_allowed;
|
||||||
|
|
||||||
bool tcg_cflags_has(CPUState *cpu, uint32_t flags)
|
|
||||||
{
|
|
||||||
return cpu->tcg_cflags & flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tcg_cflags_set(CPUState *cpu, uint32_t flags)
|
|
||||||
{
|
|
||||||
cpu->tcg_cflags |= flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t curr_cflags(CPUState *cpu)
|
|
||||||
{
|
|
||||||
uint32_t cflags = cpu->tcg_cflags;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Record gdb single-step. We should be exiting the TB by raising
|
|
||||||
* EXCP_DEBUG, but to simplify other tests, disable chaining too.
|
|
||||||
*
|
|
||||||
* For singlestep and -d nochain, suppress goto_tb so that
|
|
||||||
* we can log -d cpu,exec after every TB.
|
|
||||||
*/
|
|
||||||
if (unlikely(cpu->singlestep_enabled)) {
|
|
||||||
cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR | CF_SINGLE_STEP | 1;
|
|
||||||
} else if (qatomic_read(&one_insn_per_tb)) {
|
|
||||||
cflags |= CF_NO_GOTO_TB | 1;
|
|
||||||
} else if (qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
|
|
||||||
cflags |= CF_NO_GOTO_TB;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cflags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* exit the current TB, but without causing any exception to be raised */
|
/* exit the current TB, but without causing any exception to be raised */
|
||||||
void cpu_loop_exit_noexc(CPUState *cpu)
|
void cpu_loop_exit_noexc(CPUState *cpu)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,27 +21,24 @@
|
|||||||
#include "qemu/qemu-print.h"
|
#include "qemu/qemu-print.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/type-helpers.h"
|
#include "qapi/type-helpers.h"
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/tcg-cpu-ops.h"
|
||||||
#include "accel/tcg/cpu-ops.h"
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "disas/disas.h"
|
#include "disas/disas.h"
|
||||||
#include "exec/cpu-common.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/page-protection.h"
|
|
||||||
#include "exec/translation-block.h"
|
|
||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
#include "qemu/atomic.h"
|
#include "qemu/atomic.h"
|
||||||
#include "qemu/rcu.h"
|
#include "qemu/rcu.h"
|
||||||
#include "exec/log.h"
|
#include "exec/log.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
|
#include "sysemu/cpus.h"
|
||||||
#include "exec/cpu-all.h"
|
#include "exec/cpu-all.h"
|
||||||
#include "system/cpu-timers.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
#include "exec/replay-core.h"
|
#include "exec/replay-core.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "exec/helper-proto-common.h"
|
#include "exec/helper-proto-common.h"
|
||||||
#include "tb-jmp-cache.h"
|
#include "tb-jmp-cache.h"
|
||||||
#include "tb-hash.h"
|
#include "tb-hash.h"
|
||||||
#include "tb-context.h"
|
#include "tb-context.h"
|
||||||
#include "tb-internal.h"
|
|
||||||
#include "internal-common.h"
|
#include "internal-common.h"
|
||||||
#include "internal-target.h"
|
#include "internal-target.h"
|
||||||
|
|
||||||
@@ -147,6 +144,38 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG USER ONLY */
|
#endif /* CONFIG USER ONLY */
|
||||||
|
|
||||||
|
bool tcg_cflags_has(CPUState *cpu, uint32_t flags)
|
||||||
|
{
|
||||||
|
return cpu->tcg_cflags & flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tcg_cflags_set(CPUState *cpu, uint32_t flags)
|
||||||
|
{
|
||||||
|
cpu->tcg_cflags |= flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t curr_cflags(CPUState *cpu)
|
||||||
|
{
|
||||||
|
uint32_t cflags = cpu->tcg_cflags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record gdb single-step. We should be exiting the TB by raising
|
||||||
|
* EXCP_DEBUG, but to simplify other tests, disable chaining too.
|
||||||
|
*
|
||||||
|
* For singlestep and -d nochain, suppress goto_tb so that
|
||||||
|
* we can log -d cpu,exec after every TB.
|
||||||
|
*/
|
||||||
|
if (unlikely(cpu->singlestep_enabled)) {
|
||||||
|
cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR | CF_SINGLE_STEP | 1;
|
||||||
|
} else if (qatomic_read(&one_insn_per_tb)) {
|
||||||
|
cflags |= CF_NO_GOTO_TB | 1;
|
||||||
|
} else if (qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
|
||||||
|
cflags |= CF_NO_GOTO_TB;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cflags;
|
||||||
|
}
|
||||||
|
|
||||||
struct tb_desc {
|
struct tb_desc {
|
||||||
vaddr pc;
|
vaddr pc;
|
||||||
uint64_t cs_base;
|
uint64_t cs_base;
|
||||||
@@ -216,20 +245,7 @@ static TranslationBlock *tb_htable_lookup(CPUState *cpu, vaddr pc,
|
|||||||
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
|
return qht_lookup_custom(&tb_ctx.htable, &desc, h, tb_lookup_cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Might cause an exception, so have a longjmp destination ready */
|
||||||
* tb_lookup:
|
|
||||||
* @cpu: CPU that will execute the returned translation block
|
|
||||||
* @pc: guest PC
|
|
||||||
* @cs_base: arch-specific value associated with translation block
|
|
||||||
* @flags: arch-specific translation block flags
|
|
||||||
* @cflags: CF_* flags
|
|
||||||
*
|
|
||||||
* Look up a translation block inside the QHT using @pc, @cs_base, @flags and
|
|
||||||
* @cflags. Uses @cpu's tb_jmp_cache. Might cause an exception, so have a
|
|
||||||
* longjmp destination ready.
|
|
||||||
*
|
|
||||||
* Returns: an existing translation block or NULL.
|
|
||||||
*/
|
|
||||||
static inline TranslationBlock *tb_lookup(CPUState *cpu, vaddr pc,
|
static inline TranslationBlock *tb_lookup(CPUState *cpu, vaddr pc,
|
||||||
uint64_t cs_base, uint32_t flags,
|
uint64_t cs_base, uint32_t flags,
|
||||||
uint32_t cflags)
|
uint32_t cflags)
|
||||||
@@ -417,16 +433,6 @@ const void *HELPER(lookup_tb_ptr)(CPUArchState *env)
|
|||||||
return tb->tc.ptr;
|
return tb->tc.ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the current PC from CPU, which may be cached in TB. */
|
|
||||||
static vaddr log_pc(CPUState *cpu, const TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
if (tb_cflags(tb) & CF_PCREL) {
|
|
||||||
return cpu->cc->get_pc(cpu);
|
|
||||||
} else {
|
|
||||||
return tb->pc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Execute a TB, and fix up the CPU state afterwards if necessary */
|
/* Execute a TB, and fix up the CPU state afterwards if necessary */
|
||||||
/*
|
/*
|
||||||
* Disable CFI checks.
|
* Disable CFI checks.
|
||||||
@@ -1068,13 +1074,11 @@ bool tcg_exec_realizefn(CPUState *cpu, Error **errp)
|
|||||||
|
|
||||||
if (!tcg_target_initialized) {
|
if (!tcg_target_initialized) {
|
||||||
/* Check mandatory TCGCPUOps handlers */
|
/* Check mandatory TCGCPUOps handlers */
|
||||||
const TCGCPUOps *tcg_ops = cpu->cc->tcg_ops;
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
assert(tcg_ops->cpu_exec_halt);
|
assert(cpu->cc->tcg_ops->cpu_exec_halt);
|
||||||
assert(tcg_ops->cpu_exec_interrupt);
|
assert(cpu->cc->tcg_ops->cpu_exec_interrupt);
|
||||||
#endif /* !CONFIG_USER_ONLY */
|
#endif /* !CONFIG_USER_ONLY */
|
||||||
assert(tcg_ops->translate_code);
|
cpu->cc->tcg_ops->initialize();
|
||||||
tcg_ops->initialize();
|
|
||||||
tcg_target_initialized = true;
|
tcg_target_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "accel/tcg/cpu-ops.h"
|
#include "hw/core/tcg-cpu-ops.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/page-protection.h"
|
#include "exec/page-protection.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
@@ -37,16 +37,16 @@
|
|||||||
#include "exec/helper-proto-common.h"
|
#include "exec/helper-proto-common.h"
|
||||||
#include "qemu/atomic.h"
|
#include "qemu/atomic.h"
|
||||||
#include "qemu/atomic128.h"
|
#include "qemu/atomic128.h"
|
||||||
#include "tb-internal.h"
|
#include "exec/translate-all.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "tb-hash.h"
|
#include "tb-hash.h"
|
||||||
#include "tb-internal.h"
|
|
||||||
#include "internal-common.h"
|
#include "internal-common.h"
|
||||||
#include "internal-target.h"
|
#include "internal-target.h"
|
||||||
#ifdef CONFIG_PLUGIN
|
#ifdef CONFIG_PLUGIN
|
||||||
#include "qemu/plugin-memory.h"
|
#include "qemu/plugin-memory.h"
|
||||||
#endif
|
#endif
|
||||||
#include "tcg/tcg-ldst.h"
|
#include "tcg/tcg-ldst.h"
|
||||||
|
#include "tcg/oversized-guest.h"
|
||||||
|
|
||||||
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
|
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
|
||||||
/* #define DEBUG_TLB */
|
/* #define DEBUG_TLB */
|
||||||
@@ -104,15 +104,26 @@ static inline uint64_t tlb_read_idx(const CPUTLBEntry *entry,
|
|||||||
{
|
{
|
||||||
/* Do not rearrange the CPUTLBEntry structure members. */
|
/* Do not rearrange the CPUTLBEntry structure members. */
|
||||||
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_read) !=
|
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_read) !=
|
||||||
MMU_DATA_LOAD * sizeof(uintptr_t));
|
MMU_DATA_LOAD * sizeof(uint64_t));
|
||||||
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_write) !=
|
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_write) !=
|
||||||
MMU_DATA_STORE * sizeof(uintptr_t));
|
MMU_DATA_STORE * sizeof(uint64_t));
|
||||||
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_code) !=
|
QEMU_BUILD_BUG_ON(offsetof(CPUTLBEntry, addr_code) !=
|
||||||
MMU_INST_FETCH * sizeof(uintptr_t));
|
MMU_INST_FETCH * sizeof(uint64_t));
|
||||||
|
|
||||||
const uintptr_t *ptr = &entry->addr_idx[access_type];
|
#if TARGET_LONG_BITS == 32
|
||||||
|
/* Use qatomic_read, in case of addr_write; only care about low bits. */
|
||||||
|
const uint32_t *ptr = (uint32_t *)&entry->addr_idx[access_type];
|
||||||
|
ptr += HOST_BIG_ENDIAN;
|
||||||
|
return qatomic_read(ptr);
|
||||||
|
#else
|
||||||
|
const uint64_t *ptr = &entry->addr_idx[access_type];
|
||||||
|
# if TCG_OVERSIZED_GUEST
|
||||||
|
return *ptr;
|
||||||
|
# else
|
||||||
/* ofs might correspond to .addr_write, so use qatomic_read */
|
/* ofs might correspond to .addr_write, so use qatomic_read */
|
||||||
return qatomic_read(ptr);
|
return qatomic_read(ptr);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t tlb_addr_write(const CPUTLBEntry *entry)
|
static inline uint64_t tlb_addr_write(const CPUTLBEntry *entry)
|
||||||
@@ -892,8 +903,16 @@ static void tlb_reset_dirty_range_locked(CPUTLBEntry *tlb_entry,
|
|||||||
addr &= TARGET_PAGE_MASK;
|
addr &= TARGET_PAGE_MASK;
|
||||||
addr += tlb_entry->addend;
|
addr += tlb_entry->addend;
|
||||||
if ((addr - start) < length) {
|
if ((addr - start) < length) {
|
||||||
|
#if TARGET_LONG_BITS == 32
|
||||||
|
uint32_t *ptr_write = (uint32_t *)&tlb_entry->addr_write;
|
||||||
|
ptr_write += HOST_BIG_ENDIAN;
|
||||||
|
qatomic_set(ptr_write, *ptr_write | TLB_NOTDIRTY);
|
||||||
|
#elif TCG_OVERSIZED_GUEST
|
||||||
|
tlb_entry->addr_write |= TLB_NOTDIRTY;
|
||||||
|
#else
|
||||||
qatomic_set(&tlb_entry->addr_write,
|
qatomic_set(&tlb_entry->addr_write,
|
||||||
tlb_entry->addr_write | TLB_NOTDIRTY);
|
tlb_entry->addr_write | TLB_NOTDIRTY);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1180,7 +1199,7 @@ void tlb_set_page_full(CPUState *cpu, int mmu_idx,
|
|||||||
|
|
||||||
void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
|
void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
|
||||||
hwaddr paddr, MemTxAttrs attrs, int prot,
|
hwaddr paddr, MemTxAttrs attrs, int prot,
|
||||||
int mmu_idx, vaddr size)
|
int mmu_idx, uint64_t size)
|
||||||
{
|
{
|
||||||
CPUTLBEntryFull full = {
|
CPUTLBEntryFull full = {
|
||||||
.phys_addr = paddr,
|
.phys_addr = paddr,
|
||||||
@@ -1195,65 +1214,29 @@ void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
|
|||||||
|
|
||||||
void tlb_set_page(CPUState *cpu, vaddr addr,
|
void tlb_set_page(CPUState *cpu, vaddr addr,
|
||||||
hwaddr paddr, int prot,
|
hwaddr paddr, int prot,
|
||||||
int mmu_idx, vaddr size)
|
int mmu_idx, uint64_t size)
|
||||||
{
|
{
|
||||||
tlb_set_page_with_attrs(cpu, addr, paddr, MEMTXATTRS_UNSPECIFIED,
|
tlb_set_page_with_attrs(cpu, addr, paddr, MEMTXATTRS_UNSPECIFIED,
|
||||||
prot, mmu_idx, size);
|
prot, mmu_idx, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* tlb_hit_page: return true if page aligned @addr is a hit against the
|
|
||||||
* TLB entry @tlb_addr
|
|
||||||
*
|
|
||||||
* @addr: virtual address to test (must be page aligned)
|
|
||||||
* @tlb_addr: TLB entry address (a CPUTLBEntry addr_read/write/code value)
|
|
||||||
*/
|
|
||||||
static inline bool tlb_hit_page(uint64_t tlb_addr, vaddr addr)
|
|
||||||
{
|
|
||||||
return addr == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tlb_hit: return true if @addr is a hit against the TLB entry @tlb_addr
|
|
||||||
*
|
|
||||||
* @addr: virtual address to test (need not be page aligned)
|
|
||||||
* @tlb_addr: TLB entry address (a CPUTLBEntry addr_read/write/code value)
|
|
||||||
*/
|
|
||||||
static inline bool tlb_hit(uint64_t tlb_addr, vaddr addr)
|
|
||||||
{
|
|
||||||
return tlb_hit_page(tlb_addr, addr & TARGET_PAGE_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note: tlb_fill_align() can trigger a resize of the TLB.
|
* Note: tlb_fill() can trigger a resize of the TLB. This means that all of the
|
||||||
* This means that all of the caller's prior references to the TLB table
|
* caller's prior references to the TLB table (e.g. CPUTLBEntry pointers) must
|
||||||
* (e.g. CPUTLBEntry pointers) must be discarded and looked up again
|
* be discarded and looked up again (e.g. via tlb_entry()).
|
||||||
* (e.g. via tlb_entry()).
|
|
||||||
*/
|
*/
|
||||||
static bool tlb_fill_align(CPUState *cpu, vaddr addr, MMUAccessType type,
|
static void tlb_fill(CPUState *cpu, vaddr addr, int size,
|
||||||
int mmu_idx, MemOp memop, int size,
|
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
|
||||||
bool probe, uintptr_t ra)
|
|
||||||
{
|
{
|
||||||
const TCGCPUOps *ops = cpu->cc->tcg_ops;
|
bool ok;
|
||||||
CPUTLBEntryFull full;
|
|
||||||
|
|
||||||
if (ops->tlb_fill_align) {
|
/*
|
||||||
if (ops->tlb_fill_align(cpu, &full, addr, type, mmu_idx,
|
* This is not a probe, so only valid return is success; failure
|
||||||
memop, size, probe, ra)) {
|
* should result in exception + longjmp to the cpu loop.
|
||||||
tlb_set_page_full(cpu, mmu_idx, addr, &full);
|
*/
|
||||||
return true;
|
ok = cpu->cc->tcg_ops->tlb_fill(cpu, addr, size,
|
||||||
}
|
access_type, mmu_idx, false, retaddr);
|
||||||
} else {
|
assert(ok);
|
||||||
/* Legacy behaviour is alignment before paging. */
|
|
||||||
if (addr & ((1u << memop_alignment_bits(memop)) - 1)) {
|
|
||||||
ops->do_unaligned_access(cpu, addr, type, mmu_idx, ra);
|
|
||||||
}
|
|
||||||
if (ops->tlb_fill(cpu, addr, size, type, mmu_idx, probe, ra)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(probe);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
|
static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
|
||||||
@@ -1368,22 +1351,22 @@ static int probe_access_internal(CPUState *cpu, vaddr addr,
|
|||||||
|
|
||||||
if (!tlb_hit_page(tlb_addr, page_addr)) {
|
if (!tlb_hit_page(tlb_addr, page_addr)) {
|
||||||
if (!victim_tlb_hit(cpu, mmu_idx, index, access_type, page_addr)) {
|
if (!victim_tlb_hit(cpu, mmu_idx, index, access_type, page_addr)) {
|
||||||
if (!tlb_fill_align(cpu, addr, access_type, mmu_idx,
|
if (!cpu->cc->tcg_ops->tlb_fill(cpu, addr, fault_size, access_type,
|
||||||
0, fault_size, nonfault, retaddr)) {
|
mmu_idx, nonfault, retaddr)) {
|
||||||
/* Non-faulting page table read failed. */
|
/* Non-faulting page table read failed. */
|
||||||
*phost = NULL;
|
*phost = NULL;
|
||||||
*pfull = NULL;
|
*pfull = NULL;
|
||||||
return TLB_INVALID_MASK;
|
return TLB_INVALID_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TLB resize via tlb_fill_align may have moved the entry. */
|
/* TLB resize via tlb_fill may have moved the entry. */
|
||||||
index = tlb_index(cpu, mmu_idx, addr);
|
index = tlb_index(cpu, mmu_idx, addr);
|
||||||
entry = tlb_entry(cpu, mmu_idx, addr);
|
entry = tlb_entry(cpu, mmu_idx, addr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* With PAGE_WRITE_INV, we set TLB_INVALID_MASK immediately,
|
* With PAGE_WRITE_INV, we set TLB_INVALID_MASK immediately,
|
||||||
* to force the next access through tlb_fill_align. We've just
|
* to force the next access through tlb_fill. We've just
|
||||||
* called tlb_fill_align, so we know that this entry *is* valid.
|
* called tlb_fill, so we know that this entry *is* valid.
|
||||||
*/
|
*/
|
||||||
flags &= ~TLB_INVALID_MASK;
|
flags &= ~TLB_INVALID_MASK;
|
||||||
}
|
}
|
||||||
@@ -1508,7 +1491,7 @@ void *probe_access(CPUArchState *env, vaddr addr, int size,
|
|||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *tlb_vaddr_to_host(CPUArchState *env, vaddr addr,
|
void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
|
||||||
MMUAccessType access_type, int mmu_idx)
|
MMUAccessType access_type, int mmu_idx)
|
||||||
{
|
{
|
||||||
CPUTLBEntryFull *full;
|
CPUTLBEntryFull *full;
|
||||||
@@ -1624,17 +1607,16 @@ typedef struct MMULookupLocals {
|
|||||||
* mmu_lookup1: translate one page
|
* mmu_lookup1: translate one page
|
||||||
* @cpu: generic cpu state
|
* @cpu: generic cpu state
|
||||||
* @data: lookup parameters
|
* @data: lookup parameters
|
||||||
* @memop: memory operation for the access, or 0
|
|
||||||
* @mmu_idx: virtual address context
|
* @mmu_idx: virtual address context
|
||||||
* @access_type: load/store/code
|
* @access_type: load/store/code
|
||||||
* @ra: return address into tcg generated code, or 0
|
* @ra: return address into tcg generated code, or 0
|
||||||
*
|
*
|
||||||
* Resolve the translation for the one page at @data.addr, filling in
|
* Resolve the translation for the one page at @data.addr, filling in
|
||||||
* the rest of @data with the results. If the translation fails,
|
* the rest of @data with the results. If the translation fails,
|
||||||
* tlb_fill_align will longjmp out. Return true if the softmmu tlb for
|
* tlb_fill will longjmp out. Return true if the softmmu tlb for
|
||||||
* @mmu_idx may have resized.
|
* @mmu_idx may have resized.
|
||||||
*/
|
*/
|
||||||
static bool mmu_lookup1(CPUState *cpu, MMULookupPageData *data, MemOp memop,
|
static bool mmu_lookup1(CPUState *cpu, MMULookupPageData *data,
|
||||||
int mmu_idx, MMUAccessType access_type, uintptr_t ra)
|
int mmu_idx, MMUAccessType access_type, uintptr_t ra)
|
||||||
{
|
{
|
||||||
vaddr addr = data->addr;
|
vaddr addr = data->addr;
|
||||||
@@ -1649,8 +1631,7 @@ static bool mmu_lookup1(CPUState *cpu, MMULookupPageData *data, MemOp memop,
|
|||||||
if (!tlb_hit(tlb_addr, addr)) {
|
if (!tlb_hit(tlb_addr, addr)) {
|
||||||
if (!victim_tlb_hit(cpu, mmu_idx, index, access_type,
|
if (!victim_tlb_hit(cpu, mmu_idx, index, access_type,
|
||||||
addr & TARGET_PAGE_MASK)) {
|
addr & TARGET_PAGE_MASK)) {
|
||||||
tlb_fill_align(cpu, addr, access_type, mmu_idx,
|
tlb_fill(cpu, addr, data->size, access_type, mmu_idx, ra);
|
||||||
memop, data->size, false, ra);
|
|
||||||
maybe_resized = true;
|
maybe_resized = true;
|
||||||
index = tlb_index(cpu, mmu_idx, addr);
|
index = tlb_index(cpu, mmu_idx, addr);
|
||||||
entry = tlb_entry(cpu, mmu_idx, addr);
|
entry = tlb_entry(cpu, mmu_idx, addr);
|
||||||
@@ -1662,25 +1643,6 @@ static bool mmu_lookup1(CPUState *cpu, MMULookupPageData *data, MemOp memop,
|
|||||||
flags = tlb_addr & (TLB_FLAGS_MASK & ~TLB_FORCE_SLOW);
|
flags = tlb_addr & (TLB_FLAGS_MASK & ~TLB_FORCE_SLOW);
|
||||||
flags |= full->slow_flags[access_type];
|
flags |= full->slow_flags[access_type];
|
||||||
|
|
||||||
if (likely(!maybe_resized)) {
|
|
||||||
/* Alignment has not been checked by tlb_fill_align. */
|
|
||||||
int a_bits = memop_alignment_bits(memop);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This alignment check differs from the one above, in that this is
|
|
||||||
* based on the atomicity of the operation. The intended use case is
|
|
||||||
* the ARM memory type field of each PTE, where access to pages with
|
|
||||||
* Device memory type require alignment.
|
|
||||||
*/
|
|
||||||
if (unlikely(flags & TLB_CHECK_ALIGNED)) {
|
|
||||||
int at_bits = memop_atomicity_bits(memop);
|
|
||||||
a_bits = MAX(a_bits, at_bits);
|
|
||||||
}
|
|
||||||
if (unlikely(addr & ((1 << a_bits) - 1))) {
|
|
||||||
cpu_unaligned_access(cpu, addr, access_type, mmu_idx, ra);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data->full = full;
|
data->full = full;
|
||||||
data->flags = flags;
|
data->flags = flags;
|
||||||
/* Compute haddr speculatively; depending on flags it might be invalid. */
|
/* Compute haddr speculatively; depending on flags it might be invalid. */
|
||||||
@@ -1737,6 +1699,7 @@ static void mmu_watch_or_dirty(CPUState *cpu, MMULookupPageData *data,
|
|||||||
static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
||||||
uintptr_t ra, MMUAccessType type, MMULookupLocals *l)
|
uintptr_t ra, MMUAccessType type, MMULookupLocals *l)
|
||||||
{
|
{
|
||||||
|
unsigned a_bits;
|
||||||
bool crosspage;
|
bool crosspage;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
@@ -1745,6 +1708,12 @@ static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
|||||||
|
|
||||||
tcg_debug_assert(l->mmu_idx < NB_MMU_MODES);
|
tcg_debug_assert(l->mmu_idx < NB_MMU_MODES);
|
||||||
|
|
||||||
|
/* Handle CPU specific unaligned behaviour */
|
||||||
|
a_bits = get_alignment_bits(l->memop);
|
||||||
|
if (addr & ((1 << a_bits) - 1)) {
|
||||||
|
cpu_unaligned_access(cpu, addr, type, l->mmu_idx, ra);
|
||||||
|
}
|
||||||
|
|
||||||
l->page[0].addr = addr;
|
l->page[0].addr = addr;
|
||||||
l->page[0].size = memop_size(l->memop);
|
l->page[0].size = memop_size(l->memop);
|
||||||
l->page[1].addr = (addr + l->page[0].size - 1) & TARGET_PAGE_MASK;
|
l->page[1].addr = (addr + l->page[0].size - 1) & TARGET_PAGE_MASK;
|
||||||
@@ -1752,7 +1721,7 @@ static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
|||||||
crosspage = (addr ^ l->page[1].addr) & TARGET_PAGE_MASK;
|
crosspage = (addr ^ l->page[1].addr) & TARGET_PAGE_MASK;
|
||||||
|
|
||||||
if (likely(!crosspage)) {
|
if (likely(!crosspage)) {
|
||||||
mmu_lookup1(cpu, &l->page[0], l->memop, l->mmu_idx, type, ra);
|
mmu_lookup1(cpu, &l->page[0], l->mmu_idx, type, ra);
|
||||||
|
|
||||||
flags = l->page[0].flags;
|
flags = l->page[0].flags;
|
||||||
if (unlikely(flags & (TLB_WATCHPOINT | TLB_NOTDIRTY))) {
|
if (unlikely(flags & (TLB_WATCHPOINT | TLB_NOTDIRTY))) {
|
||||||
@@ -1771,8 +1740,8 @@ static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
|||||||
* Lookup both pages, recognizing exceptions from either. If the
|
* Lookup both pages, recognizing exceptions from either. If the
|
||||||
* second lookup potentially resized, refresh first CPUTLBEntryFull.
|
* second lookup potentially resized, refresh first CPUTLBEntryFull.
|
||||||
*/
|
*/
|
||||||
mmu_lookup1(cpu, &l->page[0], l->memop, l->mmu_idx, type, ra);
|
mmu_lookup1(cpu, &l->page[0], l->mmu_idx, type, ra);
|
||||||
if (mmu_lookup1(cpu, &l->page[1], 0, l->mmu_idx, type, ra)) {
|
if (mmu_lookup1(cpu, &l->page[1], l->mmu_idx, type, ra)) {
|
||||||
uintptr_t index = tlb_index(cpu, l->mmu_idx, addr);
|
uintptr_t index = tlb_index(cpu, l->mmu_idx, addr);
|
||||||
l->page[0].full = &cpu->neg.tlb.d[l->mmu_idx].fulltlb[index];
|
l->page[0].full = &cpu->neg.tlb.d[l->mmu_idx].fulltlb[index];
|
||||||
}
|
}
|
||||||
@@ -1791,6 +1760,31 @@ static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
|||||||
tcg_debug_assert((flags & TLB_BSWAP) == 0);
|
tcg_debug_assert((flags & TLB_BSWAP) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This alignment check differs from the one above, in that this is
|
||||||
|
* based on the atomicity of the operation. The intended use case is
|
||||||
|
* the ARM memory type field of each PTE, where access to pages with
|
||||||
|
* Device memory type require alignment.
|
||||||
|
*/
|
||||||
|
if (unlikely(flags & TLB_CHECK_ALIGNED)) {
|
||||||
|
MemOp size = l->memop & MO_SIZE;
|
||||||
|
|
||||||
|
switch (l->memop & MO_ATOM_MASK) {
|
||||||
|
case MO_ATOM_NONE:
|
||||||
|
size = MO_8;
|
||||||
|
break;
|
||||||
|
case MO_ATOM_IFALIGN_PAIR:
|
||||||
|
case MO_ATOM_WITHIN16_PAIR:
|
||||||
|
size = size ? size - 1 : 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (addr & ((1 << size) - 1)) {
|
||||||
|
cpu_unaligned_access(cpu, addr, type, l->mmu_idx, ra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return crosspage;
|
return crosspage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1803,18 +1797,34 @@ static void *atomic_mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
|||||||
{
|
{
|
||||||
uintptr_t mmu_idx = get_mmuidx(oi);
|
uintptr_t mmu_idx = get_mmuidx(oi);
|
||||||
MemOp mop = get_memop(oi);
|
MemOp mop = get_memop(oi);
|
||||||
|
int a_bits = get_alignment_bits(mop);
|
||||||
uintptr_t index;
|
uintptr_t index;
|
||||||
CPUTLBEntry *tlbe;
|
CPUTLBEntry *tlbe;
|
||||||
vaddr tlb_addr;
|
vaddr tlb_addr;
|
||||||
void *hostaddr;
|
void *hostaddr;
|
||||||
CPUTLBEntryFull *full;
|
CPUTLBEntryFull *full;
|
||||||
bool did_tlb_fill = false;
|
|
||||||
|
|
||||||
tcg_debug_assert(mmu_idx < NB_MMU_MODES);
|
tcg_debug_assert(mmu_idx < NB_MMU_MODES);
|
||||||
|
|
||||||
/* Adjust the given return address. */
|
/* Adjust the given return address. */
|
||||||
retaddr -= GETPC_ADJ;
|
retaddr -= GETPC_ADJ;
|
||||||
|
|
||||||
|
/* Enforce guest required alignment. */
|
||||||
|
if (unlikely(a_bits > 0 && (addr & ((1 << a_bits) - 1)))) {
|
||||||
|
/* ??? Maybe indicate atomic op to cpu_unaligned_access */
|
||||||
|
cpu_unaligned_access(cpu, addr, MMU_DATA_STORE,
|
||||||
|
mmu_idx, retaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enforce qemu required alignment. */
|
||||||
|
if (unlikely(addr & (size - 1))) {
|
||||||
|
/* We get here if guest alignment was not requested,
|
||||||
|
or was not enforced by cpu_unaligned_access above.
|
||||||
|
We might widen the access and emulate, but for now
|
||||||
|
mark an exception and exit the cpu loop. */
|
||||||
|
goto stop_the_world;
|
||||||
|
}
|
||||||
|
|
||||||
index = tlb_index(cpu, mmu_idx, addr);
|
index = tlb_index(cpu, mmu_idx, addr);
|
||||||
tlbe = tlb_entry(cpu, mmu_idx, addr);
|
tlbe = tlb_entry(cpu, mmu_idx, addr);
|
||||||
|
|
||||||
@@ -1823,9 +1833,8 @@ static void *atomic_mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
|||||||
if (!tlb_hit(tlb_addr, addr)) {
|
if (!tlb_hit(tlb_addr, addr)) {
|
||||||
if (!victim_tlb_hit(cpu, mmu_idx, index, MMU_DATA_STORE,
|
if (!victim_tlb_hit(cpu, mmu_idx, index, MMU_DATA_STORE,
|
||||||
addr & TARGET_PAGE_MASK)) {
|
addr & TARGET_PAGE_MASK)) {
|
||||||
tlb_fill_align(cpu, addr, MMU_DATA_STORE, mmu_idx,
|
tlb_fill(cpu, addr, size,
|
||||||
mop, size, false, retaddr);
|
MMU_DATA_STORE, mmu_idx, retaddr);
|
||||||
did_tlb_fill = true;
|
|
||||||
index = tlb_index(cpu, mmu_idx, addr);
|
index = tlb_index(cpu, mmu_idx, addr);
|
||||||
tlbe = tlb_entry(cpu, mmu_idx, addr);
|
tlbe = tlb_entry(cpu, mmu_idx, addr);
|
||||||
}
|
}
|
||||||
@@ -1839,32 +1848,15 @@ static void *atomic_mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
|||||||
* but addr_read will only be -1 if PAGE_READ was unset.
|
* but addr_read will only be -1 if PAGE_READ was unset.
|
||||||
*/
|
*/
|
||||||
if (unlikely(tlbe->addr_read == -1)) {
|
if (unlikely(tlbe->addr_read == -1)) {
|
||||||
tlb_fill_align(cpu, addr, MMU_DATA_LOAD, mmu_idx,
|
tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
|
||||||
0, size, false, retaddr);
|
|
||||||
/*
|
/*
|
||||||
* Since we don't support reads and writes to different
|
* Since we don't support reads and writes to different
|
||||||
* addresses, and we do have the proper page loaded for
|
* addresses, and we do have the proper page loaded for
|
||||||
* write, this shouldn't ever return.
|
* write, this shouldn't ever return. But just in case,
|
||||||
*/
|
* handle via stop-the-world.
|
||||||
g_assert_not_reached();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enforce guest required alignment, if not handled by tlb_fill_align. */
|
|
||||||
if (!did_tlb_fill && (addr & ((1 << memop_alignment_bits(mop)) - 1))) {
|
|
||||||
cpu_unaligned_access(cpu, addr, MMU_DATA_STORE, mmu_idx, retaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enforce qemu required alignment. */
|
|
||||||
if (unlikely(addr & (size - 1))) {
|
|
||||||
/*
|
|
||||||
* We get here if guest alignment was not requested, or was not
|
|
||||||
* enforced by cpu_unaligned_access or tlb_fill_align above.
|
|
||||||
* We might widen the access and emulate, but for now
|
|
||||||
* mark an exception and exit the cpu loop.
|
|
||||||
*/
|
*/
|
||||||
goto stop_the_world;
|
goto stop_the_world;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Collect tlb flags for read. */
|
/* Collect tlb flags for read. */
|
||||||
tlb_addr |= tlbe->addr_read;
|
tlb_addr |= tlbe->addr_read;
|
||||||
|
|
||||||
|
|||||||
@@ -27,16 +27,17 @@
|
|||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "system/cpus.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/qtest.h"
|
#include "sysemu/qtest.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "qemu/seqlock.h"
|
#include "qemu/seqlock.h"
|
||||||
#include "system/replay.h"
|
#include "sysemu/replay.h"
|
||||||
#include "system/runstate.h"
|
#include "sysemu/runstate.h"
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
#include "system/cpu-timers.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
#include "system/cpu-timers-internal.h"
|
#include "sysemu/cpu-throttle.h"
|
||||||
|
#include "sysemu/cpu-timers-internal.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ICOUNT: Instruction Counter
|
* ICOUNT: Instruction Counter
|
||||||
@@ -48,8 +49,6 @@ static bool icount_sleep = true;
|
|||||||
/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
|
/* Arbitrarily pick 1MIPS as the minimum allowable speed. */
|
||||||
#define MAX_ICOUNT_SHIFT 10
|
#define MAX_ICOUNT_SHIFT 10
|
||||||
|
|
||||||
bool icount_align_option;
|
|
||||||
|
|
||||||
/* Do not count executed instructions */
|
/* Do not count executed instructions */
|
||||||
ICountMode use_icount = ICOUNT_DISABLED;
|
ICountMode use_icount = ICOUNT_DISABLED;
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ extern int64_t max_advance;
|
|||||||
|
|
||||||
extern bool one_insn_per_tb;
|
extern bool one_insn_per_tb;
|
||||||
|
|
||||||
extern bool icount_align_option;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return true if CS is not running in parallel with other cpus, either
|
* Return true if CS is not running in parallel with other cpus, either
|
||||||
* because there are no other cpus or we are within an exclusive context.
|
* because there are no other cpus or we are within an exclusive context.
|
||||||
@@ -55,23 +53,7 @@ TranslationBlock *tb_link_page(TranslationBlock *tb);
|
|||||||
void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
|
void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
|
||||||
uintptr_t host_pc);
|
uintptr_t host_pc);
|
||||||
|
|
||||||
/**
|
|
||||||
* tlb_init - initialize a CPU's TLB
|
|
||||||
* @cpu: CPU whose TLB should be initialized
|
|
||||||
*/
|
|
||||||
void tlb_init(CPUState *cpu);
|
|
||||||
/**
|
|
||||||
* tlb_destroy - destroy a CPU's TLB
|
|
||||||
* @cpu: CPU whose TLB should be destroyed
|
|
||||||
*/
|
|
||||||
void tlb_destroy(CPUState *cpu);
|
|
||||||
|
|
||||||
bool tcg_exec_realizefn(CPUState *cpu, Error **errp);
|
bool tcg_exec_realizefn(CPUState *cpu, Error **errp);
|
||||||
void tcg_exec_unrealizefn(CPUState *cpu);
|
void tcg_exec_unrealizefn(CPUState *cpu);
|
||||||
|
|
||||||
/* current cflags for hashing/comparison */
|
|
||||||
uint32_t curr_cflags(CPUState *cpu);
|
|
||||||
|
|
||||||
void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,9 +10,7 @@
|
|||||||
#define ACCEL_TCG_INTERNAL_TARGET_H
|
#define ACCEL_TCG_INTERNAL_TARGET_H
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/translation-block.h"
|
#include "exec/translate-all.h"
|
||||||
#include "tb-internal.h"
|
|
||||||
#include "tcg-target-mo.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access to the various translations structures need to be serialised
|
* Access to the various translations structures need to be serialised
|
||||||
@@ -38,9 +36,50 @@ static inline void page_table_config_init(void) { }
|
|||||||
void page_table_config_init(void);
|
void page_table_config_init(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
/*
|
||||||
|
* For user-only, page_protect sets the page read-only.
|
||||||
|
* Since most execution is already on read-only pages, and we'd need to
|
||||||
|
* account for other TBs on the same page, defer undoing any page protection
|
||||||
|
* until we receive the write fault.
|
||||||
|
*/
|
||||||
|
static inline void tb_lock_page0(tb_page_addr_t p0)
|
||||||
|
{
|
||||||
|
page_protect(p0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void tb_lock_page1(tb_page_addr_t p0, tb_page_addr_t p1)
|
||||||
|
{
|
||||||
|
page_protect(p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void tb_unlock_page1(tb_page_addr_t p0, tb_page_addr_t p1) { }
|
||||||
|
static inline void tb_unlock_pages(TranslationBlock *tb) { }
|
||||||
|
#else
|
||||||
|
void tb_lock_page0(tb_page_addr_t);
|
||||||
|
void tb_lock_page1(tb_page_addr_t, tb_page_addr_t);
|
||||||
|
void tb_unlock_page1(tb_page_addr_t, tb_page_addr_t);
|
||||||
|
void tb_unlock_pages(TranslationBlock *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SOFTMMU
|
||||||
|
void tb_invalidate_phys_range_fast(ram_addr_t ram_addr,
|
||||||
|
unsigned size,
|
||||||
|
uintptr_t retaddr);
|
||||||
G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
|
G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
|
||||||
#endif /* CONFIG_USER_ONLY */
|
#endif /* CONFIG_SOFTMMU */
|
||||||
|
|
||||||
|
bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
|
||||||
|
|
||||||
|
/* Return the current PC from CPU, which may be cached in TB. */
|
||||||
|
static inline vaddr log_pc(CPUState *cpu, const TranslationBlock *tb)
|
||||||
|
{
|
||||||
|
if (tb_cflags(tb) & CF_PCREL) {
|
||||||
|
return cpu->cc->get_pc(cpu);
|
||||||
|
} else {
|
||||||
|
return tb->pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tcg_req_mo:
|
* tcg_req_mo:
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ static uint64_t load_atomic8_or_exit(CPUState *cpu, uintptr_t ra, void *pv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Ultimate fallback: re-execute in serial context. */
|
/* Ultimate fallback: re-execute in serial context. */
|
||||||
trace_load_atom8_or_exit_fallback(ra);
|
|
||||||
cpu_loop_exit_atomic(cpu, ra);
|
cpu_loop_exit_atomic(cpu, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +212,6 @@ static Int128 load_atomic16_or_exit(CPUState *cpu, uintptr_t ra, void *pv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Ultimate fallback: re-execute in serial context. */
|
/* Ultimate fallback: re-execute in serial context. */
|
||||||
trace_load_atom16_or_exit_fallback(ra);
|
|
||||||
cpu_loop_exit_atomic(cpu, ra);
|
cpu_loop_exit_atomic(cpu, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +519,6 @@ static uint64_t load_atom_8(CPUState *cpu, uintptr_t ra,
|
|||||||
if (HAVE_al8) {
|
if (HAVE_al8) {
|
||||||
return load_atom_extract_al8x2(pv);
|
return load_atom_extract_al8x2(pv);
|
||||||
}
|
}
|
||||||
trace_load_atom8_fallback(memop, ra);
|
|
||||||
cpu_loop_exit_atomic(cpu, ra);
|
cpu_loop_exit_atomic(cpu, ra);
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
@@ -566,7 +563,6 @@ static Int128 load_atom_16(CPUState *cpu, uintptr_t ra,
|
|||||||
break;
|
break;
|
||||||
case MO_64:
|
case MO_64:
|
||||||
if (!HAVE_al8) {
|
if (!HAVE_al8) {
|
||||||
trace_load_atom16_fallback(memop, ra);
|
|
||||||
cpu_loop_exit_atomic(cpu, ra);
|
cpu_loop_exit_atomic(cpu, ra);
|
||||||
}
|
}
|
||||||
a = load_atomic8(pv);
|
a = load_atomic8(pv);
|
||||||
@@ -574,7 +570,6 @@ static Int128 load_atom_16(CPUState *cpu, uintptr_t ra,
|
|||||||
break;
|
break;
|
||||||
case -MO_64:
|
case -MO_64:
|
||||||
if (!HAVE_al8) {
|
if (!HAVE_al8) {
|
||||||
trace_load_atom16_fallback(memop, ra);
|
|
||||||
cpu_loop_exit_atomic(cpu, ra);
|
cpu_loop_exit_atomic(cpu, ra);
|
||||||
}
|
}
|
||||||
a = load_atom_extract_al8x2(pv);
|
a = load_atom_extract_al8x2(pv);
|
||||||
@@ -902,7 +897,6 @@ static void store_atom_2(CPUState *cpu, uintptr_t ra,
|
|||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_store_atom2_fallback(memop, ra);
|
|
||||||
cpu_loop_exit_atomic(cpu, ra);
|
cpu_loop_exit_atomic(cpu, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,7 +961,6 @@ static void store_atom_4(CPUState *cpu, uintptr_t ra,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trace_store_atom4_fallback(memop, ra);
|
|
||||||
cpu_loop_exit_atomic(cpu, ra);
|
cpu_loop_exit_atomic(cpu, ra);
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
@@ -1036,7 +1029,6 @@ static void store_atom_8(CPUState *cpu, uintptr_t ra,
|
|||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
trace_store_atom8_fallback(memop, ra);
|
|
||||||
cpu_loop_exit_atomic(cpu, ra);
|
cpu_loop_exit_atomic(cpu, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1115,6 +1107,5 @@ static void store_atom_16(CPUState *cpu, uintptr_t ra,
|
|||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
trace_store_atom16_fallback(memop, ra);
|
|
||||||
cpu_loop_exit_atomic(cpu, ra);
|
cpu_loop_exit_atomic(cpu, ra);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,15 +123,10 @@ void helper_st_i128(CPUArchState *env, uint64_t addr, Int128 val, MemOpIdx oi)
|
|||||||
* Load helpers for cpu_ldst.h
|
* Load helpers for cpu_ldst.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void plugin_load_cb(CPUArchState *env, abi_ptr addr,
|
static void plugin_load_cb(CPUArchState *env, abi_ptr addr, MemOpIdx oi)
|
||||||
uint64_t value_low,
|
|
||||||
uint64_t value_high,
|
|
||||||
MemOpIdx oi)
|
|
||||||
{
|
{
|
||||||
if (cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
if (cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
||||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr,
|
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
|
||||||
value_low, value_high,
|
|
||||||
oi, QEMU_PLUGIN_MEM_R);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +136,7 @@ uint8_t cpu_ldb_mmu(CPUArchState *env, abi_ptr addr, MemOpIdx oi, uintptr_t ra)
|
|||||||
|
|
||||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_UB);
|
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_UB);
|
||||||
ret = do_ld1_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
|
ret = do_ld1_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
|
||||||
plugin_load_cb(env, addr, ret, 0, oi);
|
plugin_load_cb(env, addr, oi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +147,7 @@ uint16_t cpu_ldw_mmu(CPUArchState *env, abi_ptr addr,
|
|||||||
|
|
||||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
|
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
|
||||||
ret = do_ld2_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
|
ret = do_ld2_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
|
||||||
plugin_load_cb(env, addr, ret, 0, oi);
|
plugin_load_cb(env, addr, oi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +158,7 @@ uint32_t cpu_ldl_mmu(CPUArchState *env, abi_ptr addr,
|
|||||||
|
|
||||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
|
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
|
||||||
ret = do_ld4_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
|
ret = do_ld4_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
|
||||||
plugin_load_cb(env, addr, ret, 0, oi);
|
plugin_load_cb(env, addr, oi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +169,7 @@ uint64_t cpu_ldq_mmu(CPUArchState *env, abi_ptr addr,
|
|||||||
|
|
||||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
|
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
|
||||||
ret = do_ld8_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
|
ret = do_ld8_mmu(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
|
||||||
plugin_load_cb(env, addr, ret, 0, oi);
|
plugin_load_cb(env, addr, oi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +180,7 @@ Int128 cpu_ld16_mmu(CPUArchState *env, abi_ptr addr,
|
|||||||
|
|
||||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
|
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
|
||||||
ret = do_ld16_mmu(env_cpu(env), addr, oi, ra);
|
ret = do_ld16_mmu(env_cpu(env), addr, oi, ra);
|
||||||
plugin_load_cb(env, addr, int128_getlo(ret), int128_gethi(ret), oi);
|
plugin_load_cb(env, addr, oi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,15 +188,10 @@ Int128 cpu_ld16_mmu(CPUArchState *env, abi_ptr addr,
|
|||||||
* Store helpers for cpu_ldst.h
|
* Store helpers for cpu_ldst.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void plugin_store_cb(CPUArchState *env, abi_ptr addr,
|
static void plugin_store_cb(CPUArchState *env, abi_ptr addr, MemOpIdx oi)
|
||||||
uint64_t value_low,
|
|
||||||
uint64_t value_high,
|
|
||||||
MemOpIdx oi)
|
|
||||||
{
|
{
|
||||||
if (cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
if (cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
||||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr,
|
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
|
||||||
value_low, value_high,
|
|
||||||
oi, QEMU_PLUGIN_MEM_W);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +199,7 @@ void cpu_stb_mmu(CPUArchState *env, abi_ptr addr, uint8_t val,
|
|||||||
MemOpIdx oi, uintptr_t retaddr)
|
MemOpIdx oi, uintptr_t retaddr)
|
||||||
{
|
{
|
||||||
helper_stb_mmu(env, addr, val, oi, retaddr);
|
helper_stb_mmu(env, addr, val, oi, retaddr);
|
||||||
plugin_store_cb(env, addr, val, 0, oi);
|
plugin_store_cb(env, addr, oi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_stw_mmu(CPUArchState *env, abi_ptr addr, uint16_t val,
|
void cpu_stw_mmu(CPUArchState *env, abi_ptr addr, uint16_t val,
|
||||||
@@ -217,7 +207,7 @@ void cpu_stw_mmu(CPUArchState *env, abi_ptr addr, uint16_t val,
|
|||||||
{
|
{
|
||||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
|
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_16);
|
||||||
do_st2_mmu(env_cpu(env), addr, val, oi, retaddr);
|
do_st2_mmu(env_cpu(env), addr, val, oi, retaddr);
|
||||||
plugin_store_cb(env, addr, val, 0, oi);
|
plugin_store_cb(env, addr, oi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_stl_mmu(CPUArchState *env, abi_ptr addr, uint32_t val,
|
void cpu_stl_mmu(CPUArchState *env, abi_ptr addr, uint32_t val,
|
||||||
@@ -225,7 +215,7 @@ void cpu_stl_mmu(CPUArchState *env, abi_ptr addr, uint32_t val,
|
|||||||
{
|
{
|
||||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
|
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_32);
|
||||||
do_st4_mmu(env_cpu(env), addr, val, oi, retaddr);
|
do_st4_mmu(env_cpu(env), addr, val, oi, retaddr);
|
||||||
plugin_store_cb(env, addr, val, 0, oi);
|
plugin_store_cb(env, addr, oi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_stq_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
void cpu_stq_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||||
@@ -233,7 +223,7 @@ void cpu_stq_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
|||||||
{
|
{
|
||||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
|
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_64);
|
||||||
do_st8_mmu(env_cpu(env), addr, val, oi, retaddr);
|
do_st8_mmu(env_cpu(env), addr, val, oi, retaddr);
|
||||||
plugin_store_cb(env, addr, val, 0, oi);
|
plugin_store_cb(env, addr, oi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_st16_mmu(CPUArchState *env, abi_ptr addr, Int128 val,
|
void cpu_st16_mmu(CPUArchState *env, abi_ptr addr, Int128 val,
|
||||||
@@ -241,7 +231,7 @@ void cpu_st16_mmu(CPUArchState *env, abi_ptr addr, Int128 val,
|
|||||||
{
|
{
|
||||||
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
|
tcg_debug_assert((get_memop(oi) & MO_SIZE) == MO_128);
|
||||||
do_st16_mmu(env_cpu(env), addr, val, oi, retaddr);
|
do_st16_mmu(env_cpu(env), addr, val, oi, retaddr);
|
||||||
plugin_store_cb(env, addr, int128_getlo(val), int128_gethi(val), oi);
|
plugin_store_cb(env, addr, oi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
common_ss.add(when: 'CONFIG_TCG', if_true: files(
|
common_ss.add(when: 'CONFIG_TCG', if_true: files(
|
||||||
'cpu-exec-common.c',
|
'cpu-exec-common.c',
|
||||||
'tcg-runtime.c',
|
|
||||||
'tcg-runtime-gvec.c',
|
|
||||||
))
|
))
|
||||||
tcg_specific_ss = ss.source_set()
|
tcg_specific_ss = ss.source_set()
|
||||||
tcg_specific_ss.add(files(
|
tcg_specific_ss.add(files(
|
||||||
'tcg-all.c',
|
'tcg-all.c',
|
||||||
'cpu-exec.c',
|
'cpu-exec.c',
|
||||||
'tb-maint.c',
|
'tb-maint.c',
|
||||||
|
'tcg-runtime-gvec.c',
|
||||||
|
'tcg-runtime.c',
|
||||||
'translate-all.c',
|
'translate-all.c',
|
||||||
'translator.c',
|
'translator.c',
|
||||||
))
|
))
|
||||||
@@ -20,14 +20,17 @@ specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_specific_ss)
|
|||||||
|
|
||||||
specific_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files(
|
specific_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files(
|
||||||
'cputlb.c',
|
'cputlb.c',
|
||||||
|
'watchpoint.c',
|
||||||
))
|
))
|
||||||
|
|
||||||
system_ss.add(when: ['CONFIG_TCG'], if_true: files(
|
system_ss.add(when: ['CONFIG_TCG'], if_true: files(
|
||||||
'icount-common.c',
|
'icount-common.c',
|
||||||
'monitor.c',
|
'monitor.c',
|
||||||
'tcg-accel-ops.c',
|
))
|
||||||
'tcg-accel-ops-icount.c',
|
|
||||||
'tcg-accel-ops-mttcg.c',
|
tcg_module_ss.add(when: ['CONFIG_SYSTEM_ONLY', 'CONFIG_TCG'], if_true: files(
|
||||||
'tcg-accel-ops-rr.c',
|
'tcg-accel-ops.c',
|
||||||
'watchpoint.c',
|
'tcg-accel-ops-mttcg.c',
|
||||||
|
'tcg-accel-ops-icount.c',
|
||||||
|
'tcg-accel-ops-rr.c',
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -13,8 +13,9 @@
|
|||||||
#include "qapi/type-helpers.h"
|
#include "qapi/type-helpers.h"
|
||||||
#include "qapi/qapi-commands-machine.h"
|
#include "qapi/qapi-commands-machine.h"
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
#include "system/cpu-timers.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
|
#include "sysemu/tcg.h"
|
||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
#include "internal-common.h"
|
#include "internal-common.h"
|
||||||
#include "tb-context.h"
|
#include "tb-context.h"
|
||||||
|
|||||||
@@ -102,15 +102,6 @@ static void gen_disable_mem_helper(void)
|
|||||||
|
|
||||||
static TCGv_i32 gen_cpu_index(void)
|
static TCGv_i32 gen_cpu_index(void)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Optimize when we run with a single vcpu. All values using cpu_index,
|
|
||||||
* including scoreboard index, will be optimized out.
|
|
||||||
* User-mode calls tb_flush when setting this flag. In system-mode, all
|
|
||||||
* vcpus are created before generating code.
|
|
||||||
*/
|
|
||||||
if (!tcg_cflags_has(current_cpu, CF_PARALLEL)) {
|
|
||||||
return tcg_constant_i32(current_cpu->cpu_index);
|
|
||||||
}
|
|
||||||
TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
|
TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
|
||||||
tcg_gen_ld_i32(cpu_index, tcg_env,
|
tcg_gen_ld_i32(cpu_index, tcg_env,
|
||||||
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
|
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
|
||||||
@@ -260,6 +251,7 @@ static void inject_mem_cb(struct qemu_plugin_dyn_cb *cb,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +276,7 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
|
|||||||
* that might be live within the existing opcode stream.
|
* that might be live within the existing opcode stream.
|
||||||
* The simplest solution is to release them all and create new.
|
* The simplest solution is to release them all and create new.
|
||||||
*/
|
*/
|
||||||
tcg_temp_ebb_reset_freed(tcg_ctx);
|
memset(tcg_ctx->free_temps, 0, sizeof(tcg_ctx->free_temps));
|
||||||
|
|
||||||
QTAILQ_FOREACH_SAFE(op, &tcg_ctx->ops, link, next) {
|
QTAILQ_FOREACH_SAFE(op, &tcg_ctx->ops, link, next) {
|
||||||
switch (op->opc) {
|
switch (op->opc) {
|
||||||
@@ -476,8 +468,4 @@ void plugin_gen_tb_end(CPUState *cpu, size_t num_insns)
|
|||||||
|
|
||||||
/* inject the instrumentation at the appropriate places */
|
/* inject the instrumentation at the appropriate places */
|
||||||
plugin_gen_inject(ptb);
|
plugin_gen_inject(ptb);
|
||||||
|
|
||||||
/* reset plugin translation state (plugin_tb is reused between blocks) */
|
|
||||||
tcg_ctx->plugin_db = NULL;
|
|
||||||
tcg_ctx->plugin_insn = NULL;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include "exec/cpu-defs.h"
|
#include "exec/cpu-defs.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/translation-block.h"
|
|
||||||
#include "qemu/xxhash.h"
|
#include "qemu/xxhash.h"
|
||||||
#include "tb-jmp-cache.h"
|
#include "tb-jmp-cache.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* TranslationBlock internal declarations (target specific)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ACCEL_TCG_TB_INTERNAL_TARGET_H
|
|
||||||
#define ACCEL_TCG_TB_INTERNAL_TARGET_H
|
|
||||||
|
|
||||||
#include "exec/cpu-all.h"
|
|
||||||
#include "exec/exec-all.h"
|
|
||||||
#include "exec/translation-block.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The true return address will often point to a host insn that is part of
|
|
||||||
* the next translated guest insn. Adjust the address backward to point to
|
|
||||||
* the middle of the call insn. Subtracting one would do the job except for
|
|
||||||
* several compressed mode architectures (arm, mips) which set the low bit
|
|
||||||
* to indicate the compressed mode; subtracting two works around that. It
|
|
||||||
* is also the case that there are no host isas that contain a call insn
|
|
||||||
* smaller than 4 bytes, so we don't worry about special-casing this.
|
|
||||||
*/
|
|
||||||
#define GETPC_ADJ 2
|
|
||||||
|
|
||||||
#ifdef CONFIG_SOFTMMU
|
|
||||||
|
|
||||||
#define CPU_TLB_DYN_MIN_BITS 6
|
|
||||||
#define CPU_TLB_DYN_DEFAULT_BITS 8
|
|
||||||
|
|
||||||
# if HOST_LONG_BITS == 32
|
|
||||||
/* Make sure we do not require a double-word shift for the TLB load */
|
|
||||||
# define CPU_TLB_DYN_MAX_BITS (32 - TARGET_PAGE_BITS)
|
|
||||||
# else /* HOST_LONG_BITS == 64 */
|
|
||||||
/*
|
|
||||||
* Assuming TARGET_PAGE_BITS==12, with 2**22 entries we can cover 2**(22+12) ==
|
|
||||||
* 2**34 == 16G of address space. This is roughly what one would expect a
|
|
||||||
* TLB to cover in a modern (as of 2018) x86_64 CPU. For instance, Intel
|
|
||||||
* Skylake's Level-2 STLB has 16 1G entries.
|
|
||||||
* Also, make sure we do not size the TLB past the guest's address space.
|
|
||||||
*/
|
|
||||||
# ifdef TARGET_PAGE_BITS_VARY
|
|
||||||
# define CPU_TLB_DYN_MAX_BITS \
|
|
||||||
MIN(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS)
|
|
||||||
# else
|
|
||||||
# define CPU_TLB_DYN_MAX_BITS \
|
|
||||||
MIN_CONST(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif /* CONFIG_SOFTMMU */
|
|
||||||
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
|
||||||
#include "user/page-protection.h"
|
|
||||||
/*
|
|
||||||
* For user-only, page_protect sets the page read-only.
|
|
||||||
* Since most execution is already on read-only pages, and we'd need to
|
|
||||||
* account for other TBs on the same page, defer undoing any page protection
|
|
||||||
* until we receive the write fault.
|
|
||||||
*/
|
|
||||||
static inline void tb_lock_page0(tb_page_addr_t p0)
|
|
||||||
{
|
|
||||||
page_protect(p0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void tb_lock_page1(tb_page_addr_t p0, tb_page_addr_t p1)
|
|
||||||
{
|
|
||||||
page_protect(p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void tb_unlock_page1(tb_page_addr_t p0, tb_page_addr_t p1) { }
|
|
||||||
static inline void tb_unlock_pages(TranslationBlock *tb) { }
|
|
||||||
#else
|
|
||||||
void tb_lock_page0(tb_page_addr_t);
|
|
||||||
void tb_lock_page1(tb_page_addr_t, tb_page_addr_t);
|
|
||||||
void tb_unlock_page1(tb_page_addr_t, tb_page_addr_t);
|
|
||||||
void tb_unlock_pages(TranslationBlock *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_SOFTMMU
|
|
||||||
void tb_invalidate_phys_range_fast(ram_addr_t ram_addr,
|
|
||||||
unsigned size,
|
|
||||||
uintptr_t retaddr);
|
|
||||||
#endif /* CONFIG_SOFTMMU */
|
|
||||||
|
|
||||||
bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -25,17 +25,13 @@
|
|||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/page-protection.h"
|
#include "exec/page-protection.h"
|
||||||
#include "exec/tb-flush.h"
|
#include "exec/tb-flush.h"
|
||||||
#include "tb-internal.h"
|
#include "exec/translate-all.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
#include "tb-hash.h"
|
#include "tb-hash.h"
|
||||||
#include "tb-context.h"
|
#include "tb-context.h"
|
||||||
#include "tb-internal.h"
|
|
||||||
#include "internal-common.h"
|
#include "internal-common.h"
|
||||||
#include "internal-target.h"
|
#include "internal-target.h"
|
||||||
#ifdef CONFIG_USER_ONLY
|
|
||||||
#include "user/page-protection.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* List iterators for lists of tagged pointers in TranslationBlock. */
|
/* List iterators for lists of tagged pointers in TranslationBlock. */
|
||||||
|
|||||||
@@ -24,11 +24,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/replay.h"
|
#include "sysemu/replay.h"
|
||||||
#include "system/cpu-timers.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
#include "hw/core/cpu.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
#include "tcg-accel-ops.h"
|
#include "tcg-accel-ops.h"
|
||||||
#include "tcg-accel-ops-icount.h"
|
#include "tcg-accel-ops-icount.h"
|
||||||
|
|||||||
@@ -24,12 +24,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "system/replay.h"
|
#include "sysemu/replay.h"
|
||||||
#include "system/cpu-timers.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/notify.h"
|
#include "qemu/notify.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
|
#include "exec/exec-all.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "tcg/startup.h"
|
#include "tcg/startup.h"
|
||||||
#include "tcg-accel-ops.h"
|
#include "tcg-accel-ops.h"
|
||||||
|
|||||||
@@ -25,13 +25,13 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/lockable.h"
|
#include "qemu/lockable.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "system/replay.h"
|
#include "sysemu/replay.h"
|
||||||
#include "system/cpu-timers.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/notify.h"
|
#include "qemu/notify.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
#include "exec/cpu-common.h"
|
#include "exec/exec-all.h"
|
||||||
#include "tcg/startup.h"
|
#include "tcg/startup.h"
|
||||||
#include "tcg-accel-ops.h"
|
#include "tcg-accel-ops.h"
|
||||||
#include "tcg-accel-ops-rr.h"
|
#include "tcg-accel-ops-rr.h"
|
||||||
@@ -302,7 +302,9 @@ static void *rr_cpu_thread_fn(void *arg)
|
|||||||
rr_deal_with_unplugged_cpus();
|
rr_deal_with_unplugged_cpus();
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert_not_reached();
|
rcu_remove_force_rcu_notifier(&force_rcu);
|
||||||
|
rcu_unregister_thread();
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rr_start_vcpu_thread(CPUState *cpu)
|
void rr_start_vcpu_thread(CPUState *cpu)
|
||||||
|
|||||||
@@ -26,17 +26,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/accel-ops.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/replay.h"
|
||||||
#include "system/replay.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
#include "system/cpu-timers.h"
|
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "exec/cputlb.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/hwaddr.h"
|
#include "exec/hwaddr.h"
|
||||||
#include "exec/tb-flush.h"
|
#include "exec/tb-flush.h"
|
||||||
#include "exec/translation-block.h"
|
|
||||||
#include "gdbstub/enums.h"
|
#include "gdbstub/enums.h"
|
||||||
|
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
@@ -121,9 +119,10 @@ static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
|
|||||||
[GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
|
[GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
int cputype = xlat[gdbtype];
|
int cputype = xlat[gdbtype];
|
||||||
|
|
||||||
if (cpu->cc->gdb_stop_before_watchpoint) {
|
if (cc->gdb_stop_before_watchpoint) {
|
||||||
cputype |= BP_STOP_BEFORE_ACCESS;
|
cputype |= BP_STOP_BEFORE_ACCESS;
|
||||||
}
|
}
|
||||||
return cputype;
|
return cputype;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#ifndef TCG_ACCEL_OPS_H
|
#ifndef TCG_ACCEL_OPS_H
|
||||||
#define TCG_ACCEL_OPS_H
|
#define TCG_ACCEL_OPS_H
|
||||||
|
|
||||||
#include "system/cpus.h"
|
#include "sysemu/cpus.h"
|
||||||
|
|
||||||
void tcg_cpu_destroy(CPUState *cpu);
|
void tcg_cpu_destroy(CPUState *cpu);
|
||||||
int tcg_cpu_exec(CPUState *cpu);
|
int tcg_cpu_exec(CPUState *cpu);
|
||||||
|
|||||||
@@ -24,24 +24,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "exec/replay-core.h"
|
#include "exec/replay-core.h"
|
||||||
#include "system/cpu-timers.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
#include "tcg/startup.h"
|
#include "tcg/startup.h"
|
||||||
|
#include "tcg/oversized-guest.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/accel.h"
|
#include "qemu/accel.h"
|
||||||
#include "qemu/atomic.h"
|
#include "qemu/atomic.h"
|
||||||
#include "qapi/qapi-builtin-visit.h"
|
#include "qapi/qapi-builtin-visit.h"
|
||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
#include "hw/qdev-core.h"
|
|
||||||
#else
|
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#endif
|
#endif
|
||||||
#include "internal-common.h"
|
#include "internal-common.h"
|
||||||
#include "cpu-param.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct TCGState {
|
struct TCGState {
|
||||||
AccelState parent_obj;
|
AccelState parent_obj;
|
||||||
@@ -73,7 +70,7 @@ DECLARE_INSTANCE_CHECKER(TCGState, TCG_STATE,
|
|||||||
|
|
||||||
static bool default_mttcg_enabled(void)
|
static bool default_mttcg_enabled(void)
|
||||||
{
|
{
|
||||||
if (icount_enabled()) {
|
if (icount_enabled() || TCG_OVERSIZED_GUEST) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef TARGET_SUPPORTS_MTTCG
|
#ifdef TARGET_SUPPORTS_MTTCG
|
||||||
@@ -127,10 +124,6 @@ static int tcg_init_machine(MachineState *ms)
|
|||||||
tcg_prologue_init();
|
tcg_prologue_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_USER_ONLY
|
|
||||||
qdev_create_fake_machine();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +139,9 @@ static void tcg_set_thread(Object *obj, const char *value, Error **errp)
|
|||||||
TCGState *s = TCG_STATE(obj);
|
TCGState *s = TCG_STATE(obj);
|
||||||
|
|
||||||
if (strcmp(value, "multi") == 0) {
|
if (strcmp(value, "multi") == 0) {
|
||||||
if (icount_enabled()) {
|
if (TCG_OVERSIZED_GUEST) {
|
||||||
|
error_setg(errp, "No MTTCG when guest word size > hosts");
|
||||||
|
} else if (icount_enabled()) {
|
||||||
error_setg(errp, "No MTTCG when icount is enabled");
|
error_setg(errp, "No MTTCG when icount is enabled");
|
||||||
} else {
|
} else {
|
||||||
#ifndef TARGET_SUPPORTS_MTTCG
|
#ifndef TARGET_SUPPORTS_MTTCG
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/host-utils.h"
|
#include "qemu/host-utils.h"
|
||||||
|
#include "cpu.h"
|
||||||
#include "exec/helper-proto-common.h"
|
#include "exec/helper-proto-common.h"
|
||||||
#include "tcg/tcg-gvec-desc.h"
|
#include "tcg/tcg-gvec-desc.h"
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,13 @@
|
|||||||
*/
|
*/
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/host-utils.h"
|
#include "qemu/host-utils.h"
|
||||||
#include "exec/cpu-common.h"
|
#include "cpu.h"
|
||||||
#include "exec/helper-proto-common.h"
|
#include "exec/helper-proto-common.h"
|
||||||
#include "accel/tcg/getpc.h"
|
#include "exec/cpu_ldst.h"
|
||||||
|
#include "exec/exec-all.h"
|
||||||
|
#include "disas/disas.h"
|
||||||
|
#include "exec/log.h"
|
||||||
|
#include "tcg/tcg.h"
|
||||||
|
|
||||||
#define HELPER_H "accel/tcg/tcg-runtime.h"
|
#define HELPER_H "accel/tcg/tcg-runtime.h"
|
||||||
#include "exec/helper-info.c.inc"
|
#include "exec/helper-info.c.inc"
|
||||||
|
|||||||
@@ -12,15 +12,3 @@ memory_notdirty_set_dirty(uint64_t vaddr) "0x%" PRIx64
|
|||||||
|
|
||||||
# translate-all.c
|
# translate-all.c
|
||||||
translate_block(void *tb, uintptr_t pc, const void *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
|
translate_block(void *tb, uintptr_t pc, const void *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
|
||||||
|
|
||||||
# ldst_atomicity
|
|
||||||
load_atom2_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
|
|
||||||
load_atom4_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
|
|
||||||
load_atom8_or_exit_fallback(uintptr_t ra) "ra:0x%"PRIxPTR""
|
|
||||||
load_atom8_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
|
|
||||||
load_atom16_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
|
|
||||||
load_atom16_or_exit_fallback(uintptr_t ra) "ra:0x%"PRIxPTR""
|
|
||||||
store_atom2_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
|
|
||||||
store_atom4_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
|
|
||||||
store_atom8_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
|
|
||||||
store_atom16_fallback(uint32_t memop, uintptr_t ra) "mop:0x%"PRIx32", ra:0x%"PRIxPTR""
|
|
||||||
|
|||||||
@@ -44,8 +44,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "exec/cputlb.h"
|
#include "exec/cputlb.h"
|
||||||
#include "exec/page-protection.h"
|
#include "exec/translate-all.h"
|
||||||
#include "tb-internal.h"
|
|
||||||
#include "exec/translator.h"
|
#include "exec/translator.h"
|
||||||
#include "exec/tb-flush.h"
|
#include "exec/tb-flush.h"
|
||||||
#include "qemu/bitmap.h"
|
#include "qemu/bitmap.h"
|
||||||
@@ -54,14 +53,14 @@
|
|||||||
#include "qemu/cacheinfo.h"
|
#include "qemu/cacheinfo.h"
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "exec/log.h"
|
#include "exec/log.h"
|
||||||
#include "system/cpu-timers.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/cpu-timers.h"
|
||||||
|
#include "sysemu/tcg.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "accel/tcg/cpu-ops.h"
|
#include "hw/core/tcg-cpu-ops.h"
|
||||||
#include "tb-jmp-cache.h"
|
#include "tb-jmp-cache.h"
|
||||||
#include "tb-hash.h"
|
#include "tb-hash.h"
|
||||||
#include "tb-context.h"
|
#include "tb-context.h"
|
||||||
#include "tb-internal.h"
|
|
||||||
#include "internal-common.h"
|
#include "internal-common.h"
|
||||||
#include "internal-target.h"
|
#include "internal-target.h"
|
||||||
#include "tcg/perf.h"
|
#include "tcg/perf.h"
|
||||||
@@ -275,10 +274,8 @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
|
|||||||
|
|
||||||
tcg_func_start(tcg_ctx);
|
tcg_func_start(tcg_ctx);
|
||||||
|
|
||||||
CPUState *cs = env_cpu(env);
|
tcg_ctx->cpu = env_cpu(env);
|
||||||
tcg_ctx->cpu = cs;
|
gen_intermediate_code(env_cpu(env), tb, max_insns, pc, host_pc);
|
||||||
cs->cc->tcg_ops->translate_code(cs, tb, max_insns, pc, host_pc);
|
|
||||||
|
|
||||||
assert(tb->size != 0);
|
assert(tb->size != 0);
|
||||||
tcg_ctx->cpu = NULL;
|
tcg_ctx->cpu = NULL;
|
||||||
*max_insns = tb->icount;
|
*max_insns = tb->icount;
|
||||||
@@ -365,7 +362,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
|||||||
/*
|
/*
|
||||||
* Overflow of code_gen_buffer, or the current slice of it.
|
* Overflow of code_gen_buffer, or the current slice of it.
|
||||||
*
|
*
|
||||||
* TODO: We don't need to re-do tcg_ops->translate_code, nor
|
* TODO: We don't need to re-do gen_intermediate_code, nor
|
||||||
* should we re-do the tcg optimization currently hidden
|
* should we re-do the tcg optimization currently hidden
|
||||||
* inside tcg_gen_code. All that should be required is to
|
* inside tcg_gen_code. All that should be required is to
|
||||||
* flush the TBs, allocate a new TB, re-initialize it per
|
* flush the TBs, allocate a new TB, re-initialize it per
|
||||||
@@ -530,32 +527,23 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
|||||||
tb_reset_jump(tb, 1);
|
tb_reset_jump(tb, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Insert TB into the corresponding region tree before publishing it
|
|
||||||
* through QHT. Otherwise rewinding happened in the TB might fail to
|
|
||||||
* lookup itself using host PC.
|
|
||||||
*/
|
|
||||||
tcg_tb_insert(tb);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the TB is not associated with a physical RAM page then it must be
|
* If the TB is not associated with a physical RAM page then it must be
|
||||||
* a temporary one-insn TB.
|
* a temporary one-insn TB, and we have nothing left to do. Return early
|
||||||
*
|
* before attempting to link to other TBs or add to the lookup table.
|
||||||
* Such TBs must be added to region trees in order to make sure that
|
|
||||||
* restore_state_to_opc() - which on some architectures is not limited to
|
|
||||||
* rewinding, but also affects exception handling! - is called when such a
|
|
||||||
* TB causes an exception.
|
|
||||||
*
|
|
||||||
* At the same time, temporary one-insn TBs must be executed at most once,
|
|
||||||
* because subsequent reads from, e.g., I/O memory may return different
|
|
||||||
* values. So return early before attempting to link to other TBs or add
|
|
||||||
* to the QHT.
|
|
||||||
*/
|
*/
|
||||||
if (tb_page_addr0(tb) == -1) {
|
if (tb_page_addr0(tb) == -1) {
|
||||||
assert_no_pages_locked();
|
assert_no_pages_locked();
|
||||||
return tb;
|
return tb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert TB into the corresponding region tree before publishing it
|
||||||
|
* through QHT. Otherwise rewinding happened in the TB might fail to
|
||||||
|
* lookup itself using host PC.
|
||||||
|
*/
|
||||||
|
tcg_tb_insert(tb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No explicit memory barrier is required -- tb_link_page() makes the
|
* No explicit memory barrier is required -- tb_link_page() makes the
|
||||||
* TB visible in a consistent state.
|
* TB visible in a consistent state.
|
||||||
@@ -630,7 +618,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
|
|||||||
* to account for the re-execution of the branch.
|
* to account for the re-execution of the branch.
|
||||||
*/
|
*/
|
||||||
n = 1;
|
n = 1;
|
||||||
cc = cpu->cc;
|
cc = CPU_GET_CLASS(cpu);
|
||||||
if (cc->tcg_ops->io_recompile_replay_branch &&
|
if (cc->tcg_ops->io_recompile_replay_branch &&
|
||||||
cc->tcg_ops->io_recompile_replay_branch(cpu, tb)) {
|
cc->tcg_ops->io_recompile_replay_branch(cpu, tb)) {
|
||||||
cpu->neg.icount_decr.u16.low++;
|
cpu->neg.icount_decr.u16.low++;
|
||||||
@@ -641,10 +629,9 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
|
|||||||
* Exit the loop and potentially generate a new TB executing the
|
* Exit the loop and potentially generate a new TB executing the
|
||||||
* just the I/O insns. We also limit instrumentation to memory
|
* just the I/O insns. We also limit instrumentation to memory
|
||||||
* operations only (which execute after completion) so we don't
|
* operations only (which execute after completion) so we don't
|
||||||
* double instrument the instruction. Also don't let an IRQ sneak
|
* double instrument the instruction.
|
||||||
* in before we execute it.
|
|
||||||
*/
|
*/
|
||||||
cpu->cflags_next_tb = curr_cflags(cpu) | CF_MEMI_ONLY | CF_NOIRQ | n;
|
cpu->cflags_next_tb = curr_cflags(cpu) | CF_MEMI_ONLY | n;
|
||||||
|
|
||||||
if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
|
if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
|
||||||
vaddr pc = cpu->cc->get_pc(cpu);
|
vaddr pc = cpu->cc->get_pc(cpu);
|
||||||
|
|||||||
@@ -15,11 +15,9 @@
|
|||||||
#include "exec/cpu_ldst.h"
|
#include "exec/cpu_ldst.h"
|
||||||
#include "exec/plugin-gen.h"
|
#include "exec/plugin-gen.h"
|
||||||
#include "exec/cpu_ldst.h"
|
#include "exec/cpu_ldst.h"
|
||||||
#include "exec/tswap.h"
|
|
||||||
#include "tcg/tcg-op-common.h"
|
#include "tcg/tcg-op-common.h"
|
||||||
#include "internal-target.h"
|
#include "internal-target.h"
|
||||||
#include "disas/disas.h"
|
#include "disas/disas.h"
|
||||||
#include "tb-internal.h"
|
|
||||||
|
|
||||||
static void set_can_do_io(DisasContextBase *db, bool val)
|
static void set_can_do_io(DisasContextBase *db, bool val)
|
||||||
{
|
{
|
||||||
@@ -104,11 +102,6 @@ static void gen_tb_end(const TranslationBlock *tb, uint32_t cflags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool translator_is_same_page(const DisasContextBase *db, vaddr addr)
|
|
||||||
{
|
|
||||||
return ((addr ^ db->pc_first) & TARGET_PAGE_MASK) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool translator_use_goto_tb(DisasContextBase *db, vaddr dest)
|
bool translator_use_goto_tb(DisasContextBase *db, vaddr dest)
|
||||||
{
|
{
|
||||||
/* Suppress goto_tb if requested. */
|
/* Suppress goto_tb if requested. */
|
||||||
@@ -117,7 +110,7 @@ bool translator_use_goto_tb(DisasContextBase *db, vaddr dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for the dest on the same page as the start of the TB. */
|
/* Check for the dest on the same page as the start of the TB. */
|
||||||
return translator_is_same_page(db, dest);
|
return ((db->pc_first ^ dest) & TARGET_PAGE_MASK) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
|
void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
|
||||||
@@ -136,6 +129,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
|
|||||||
db->is_jmp = DISAS_NEXT;
|
db->is_jmp = DISAS_NEXT;
|
||||||
db->num_insns = 0;
|
db->num_insns = 0;
|
||||||
db->max_insns = *max_insns;
|
db->max_insns = *max_insns;
|
||||||
|
db->singlestep_enabled = cflags & CF_SINGLE_STEP;
|
||||||
db->insn_start = NULL;
|
db->insn_start = NULL;
|
||||||
db->fake_insn = false;
|
db->fake_insn = false;
|
||||||
db->host_addr[0] = host_pc;
|
db->host_addr[0] = host_pc;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
#include "exec/replay-core.h"
|
#include "exec/replay-core.h"
|
||||||
#include "internal-common.h"
|
|
||||||
|
|
||||||
void cpu_resume(CPUState *cpu)
|
void cpu_resume(CPUState *cpu)
|
||||||
{
|
{
|
||||||
@@ -19,16 +18,6 @@ void cpu_exec_reset_hold(CPUState *cpu)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User mode emulation does not support softmmu yet. */
|
|
||||||
|
|
||||||
void tlb_init(CPUState *cpu)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void tlb_destroy(CPUState *cpu)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* User mode emulation does not support record/replay yet. */
|
/* User mode emulation does not support record/replay yet. */
|
||||||
|
|
||||||
bool replay_exception(void)
|
bool replay_exception(void)
|
||||||
|
|||||||
@@ -17,27 +17,22 @@
|
|||||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "accel/tcg/cpu-ops.h"
|
#include "hw/core/tcg-cpu-ops.h"
|
||||||
#include "disas/disas.h"
|
#include "disas/disas.h"
|
||||||
#include "exec/vaddr.h"
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
#include "qemu/bitops.h"
|
#include "qemu/bitops.h"
|
||||||
#include "qemu/rcu.h"
|
#include "qemu/rcu.h"
|
||||||
#include "exec/cpu_ldst.h"
|
#include "exec/cpu_ldst.h"
|
||||||
#include "user/cpu_loop.h"
|
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "user/page-protection.h"
|
#include "exec/translate-all.h"
|
||||||
#include "exec/page-protection.h"
|
#include "exec/page-protection.h"
|
||||||
#include "exec/helper-proto.h"
|
#include "exec/helper-proto.h"
|
||||||
#include "qemu/atomic128.h"
|
#include "qemu/atomic128.h"
|
||||||
#include "qemu/bswap.h"
|
#include "trace/trace-root.h"
|
||||||
#include "qemu/int128.h"
|
|
||||||
#include "trace.h"
|
|
||||||
#include "tcg/tcg-ldst.h"
|
#include "tcg/tcg-ldst.h"
|
||||||
#include "internal-common.h"
|
#include "internal-common.h"
|
||||||
#include "internal-target.h"
|
#include "internal-target.h"
|
||||||
#include "tb-internal.h"
|
|
||||||
|
|
||||||
__thread uintptr_t helper_retaddr;
|
__thread uintptr_t helper_retaddr;
|
||||||
|
|
||||||
@@ -490,6 +485,11 @@ static bool pageflags_set_clear(target_ulong start, target_ulong last,
|
|||||||
return inval_tb;
|
return inval_tb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modify the flags of a page and invalidate the code if necessary.
|
||||||
|
* The flag PAGE_WRITE_ORG is positioned automatically depending
|
||||||
|
* on PAGE_WRITE. The mmap_lock should already be held.
|
||||||
|
*/
|
||||||
void page_set_flags(target_ulong start, target_ulong last, int flags)
|
void page_set_flags(target_ulong start, target_ulong last, int flags)
|
||||||
{
|
{
|
||||||
bool reset = false;
|
bool reset = false;
|
||||||
@@ -701,7 +701,7 @@ void page_protect(tb_page_addr_t address)
|
|||||||
* immediately exited. (We can only return 2 if the 'pc' argument is
|
* immediately exited. (We can only return 2 if the 'pc' argument is
|
||||||
* non-zero.)
|
* non-zero.)
|
||||||
*/
|
*/
|
||||||
int page_unprotect(tb_page_addr_t address, uintptr_t pc)
|
int page_unprotect(target_ulong address, uintptr_t pc)
|
||||||
{
|
{
|
||||||
PageFlagsNode *p;
|
PageFlagsNode *p;
|
||||||
bool current_tb_invalidated;
|
bool current_tb_invalidated;
|
||||||
@@ -805,7 +805,7 @@ static int probe_access_internal(CPUArchState *env, vaddr addr,
|
|||||||
if (guest_addr_valid_untagged(addr)) {
|
if (guest_addr_valid_untagged(addr)) {
|
||||||
int page_flags = page_get_flags(addr);
|
int page_flags = page_get_flags(addr);
|
||||||
if (page_flags & acc_flag) {
|
if (page_flags & acc_flag) {
|
||||||
if (access_type != MMU_INST_FETCH
|
if ((acc_flag == PAGE_READ || acc_flag == PAGE_WRITE)
|
||||||
&& cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
&& cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
||||||
return TLB_MMIO;
|
return TLB_MMIO;
|
||||||
}
|
}
|
||||||
@@ -959,7 +959,7 @@ void page_reset_target_data(target_ulong start, target_ulong last) { }
|
|||||||
static void *cpu_mmu_lookup(CPUState *cpu, vaddr addr,
|
static void *cpu_mmu_lookup(CPUState *cpu, vaddr addr,
|
||||||
MemOp mop, uintptr_t ra, MMUAccessType type)
|
MemOp mop, uintptr_t ra, MMUAccessType type)
|
||||||
{
|
{
|
||||||
int a_bits = memop_alignment_bits(mop);
|
int a_bits = get_alignment_bits(mop);
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
/* Enforce guest required alignment. */
|
/* Enforce guest required alignment. */
|
||||||
@@ -972,85 +972,6 @@ static void *cpu_mmu_lookup(CPUState *cpu, vaddr addr,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* physical memory access (slow version, mainly for debug) */
|
|
||||||
int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
|
|
||||||
void *ptr, size_t len, bool is_write)
|
|
||||||
{
|
|
||||||
int flags;
|
|
||||||
vaddr l, page;
|
|
||||||
uint8_t *buf = ptr;
|
|
||||||
ssize_t written;
|
|
||||||
int ret = -1;
|
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
mmap_lock();
|
|
||||||
|
|
||||||
while (len > 0) {
|
|
||||||
page = addr & TARGET_PAGE_MASK;
|
|
||||||
l = (page + TARGET_PAGE_SIZE) - addr;
|
|
||||||
if (l > len) {
|
|
||||||
l = len;
|
|
||||||
}
|
|
||||||
flags = page_get_flags(page);
|
|
||||||
if (!(flags & PAGE_VALID)) {
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
if (is_write) {
|
|
||||||
if (flags & PAGE_WRITE) {
|
|
||||||
memcpy(g2h(cpu, addr), buf, l);
|
|
||||||
} else {
|
|
||||||
/* Bypass the host page protection using ptrace. */
|
|
||||||
if (fd == -1) {
|
|
||||||
fd = open("/proc/self/mem", O_WRONLY);
|
|
||||||
if (fd == -1) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* If there is a TranslationBlock and we weren't bypassing the
|
|
||||||
* host page protection, the memcpy() above would SEGV,
|
|
||||||
* ultimately leading to page_unprotect(). So invalidate the
|
|
||||||
* translations manually. Both invalidation and pwrite() must
|
|
||||||
* be under mmap_lock() in order to prevent the creation of
|
|
||||||
* another TranslationBlock in between.
|
|
||||||
*/
|
|
||||||
tb_invalidate_phys_range(addr, addr + l - 1);
|
|
||||||
written = pwrite(fd, buf, l,
|
|
||||||
(off_t)(uintptr_t)g2h_untagged(addr));
|
|
||||||
if (written != l) {
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (flags & PAGE_READ) {
|
|
||||||
memcpy(buf, g2h(cpu, addr), l);
|
|
||||||
} else {
|
|
||||||
/* Bypass the host page protection using ptrace. */
|
|
||||||
if (fd == -1) {
|
|
||||||
fd = open("/proc/self/mem", O_RDONLY);
|
|
||||||
if (fd == -1) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pread(fd, buf, l,
|
|
||||||
(off_t)(uintptr_t)g2h_untagged(addr)) != l) {
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
len -= l;
|
|
||||||
buf += l;
|
|
||||||
addr += l;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
out_close:
|
|
||||||
if (fd != -1) {
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
mmap_unlock();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "ldst_atomicity.c.inc"
|
#include "ldst_atomicity.c.inc"
|
||||||
|
|
||||||
static uint8_t do_ld1_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
static uint8_t do_ld1_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
||||||
@@ -1320,7 +1241,7 @@ static void *atomic_mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
|
|||||||
int size, uintptr_t retaddr)
|
int size, uintptr_t retaddr)
|
||||||
{
|
{
|
||||||
MemOp mop = get_memop(oi);
|
MemOp mop = get_memop(oi);
|
||||||
int a_bits = memop_alignment_bits(mop);
|
int a_bits = get_alignment_bits(mop);
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
/* Enforce guest required alignment. */
|
/* Enforce guest required alignment. */
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* TaskState helpers for QEMU
|
* SPDX-FileContributor: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||||
*
|
* SPDX-FileCopyrightText: 2023 Linaro Ltd.
|
||||||
* Copyright (c) 2023 Linaro Ltd.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Philippe Mathieu-Daudé
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
#ifndef ACCEL_TCG_VCPU_STATE_H
|
#ifndef ACCEL_TCG_VCPU_STATE_H
|
||||||
|
|||||||
@@ -19,15 +19,13 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "exec/breakpoint.h"
|
#include "qemu/error-report.h"
|
||||||
#include "exec/cpu-interrupt.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/page-protection.h"
|
#include "exec/translate-all.h"
|
||||||
#include "exec/translation-block.h"
|
#include "sysemu/tcg.h"
|
||||||
#include "system/tcg.h"
|
#include "sysemu/replay.h"
|
||||||
#include "system/replay.h"
|
#include "hw/core/tcg-cpu-ops.h"
|
||||||
#include "accel/tcg/cpu-ops.h"
|
|
||||||
#include "hw/core/cpu.h"
|
#include "hw/core/cpu.h"
|
||||||
#include "internal-common.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return true if this watchpoint address matches the specified
|
* Return true if this watchpoint address matches the specified
|
||||||
@@ -68,6 +66,7 @@ int cpu_watchpoint_address_matches(CPUState *cpu, vaddr addr, vaddr len)
|
|||||||
void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
||||||
MemTxAttrs attrs, int flags, uintptr_t ra)
|
MemTxAttrs attrs, int flags, uintptr_t ra)
|
||||||
{
|
{
|
||||||
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
CPUWatchpoint *wp;
|
CPUWatchpoint *wp;
|
||||||
|
|
||||||
assert(tcg_enabled());
|
assert(tcg_enabled());
|
||||||
@@ -83,9 +82,9 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpu->cc->tcg_ops->adjust_watchpoint_address) {
|
if (cc->tcg_ops->adjust_watchpoint_address) {
|
||||||
/* this is currently used only by ARM BE32 */
|
/* this is currently used only by ARM BE32 */
|
||||||
addr = cpu->cc->tcg_ops->adjust_watchpoint_address(cpu, addr, len);
|
addr = cc->tcg_ops->adjust_watchpoint_address(cpu, addr, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((flags & ~BP_MEM_ACCESS) == 0);
|
assert((flags & ~BP_MEM_ACCESS) == 0);
|
||||||
@@ -117,8 +116,8 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
|||||||
wp->hitattrs = attrs;
|
wp->hitattrs = attrs;
|
||||||
|
|
||||||
if (wp->flags & BP_CPU
|
if (wp->flags & BP_CPU
|
||||||
&& cpu->cc->tcg_ops->debug_check_watchpoint
|
&& cc->tcg_ops->debug_check_watchpoint
|
||||||
&& !cpu->cc->tcg_ops->debug_check_watchpoint(cpu, wp)) {
|
&& !cc->tcg_ops->debug_check_watchpoint(cpu, wp)) {
|
||||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,9 @@
|
|||||||
#include "hw/xen/xen_igd.h"
|
#include "hw/xen/xen_igd.h"
|
||||||
#include "chardev/char.h"
|
#include "chardev/char.h"
|
||||||
#include "qemu/accel.h"
|
#include "qemu/accel.h"
|
||||||
#include "system/accel-ops.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "system/cpus.h"
|
#include "sysemu/xen.h"
|
||||||
#include "system/xen.h"
|
#include "sysemu/runstate.h"
|
||||||
#include "system/runstate.h"
|
|
||||||
#include "migration/misc.h"
|
#include "migration/misc.h"
|
||||||
#include "migration/global_state.h"
|
#include "migration/global_state.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#include "monitor/hmp.h"
|
#include "monitor/hmp.h"
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qobject/qdict.h"
|
#include "qapi/qmp/qdict.h"
|
||||||
|
|
||||||
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
|
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
|
||||||
|
|
||||||
|
|||||||
@@ -32,15 +32,15 @@
|
|||||||
#include "qapi/qobject-input-visitor.h"
|
#include "qapi/qobject-input-visitor.h"
|
||||||
#include "qapi/qapi-visit-audio.h"
|
#include "qapi/qapi-visit-audio.h"
|
||||||
#include "qapi/qapi-commands-audio.h"
|
#include "qapi/qapi-commands-audio.h"
|
||||||
#include "qobject/qdict.h"
|
#include "qapi/qmp/qdict.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu/help_option.h"
|
#include "qemu/help_option.h"
|
||||||
#include "system/system.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "system/replay.h"
|
#include "sysemu/replay.h"
|
||||||
#include "system/runstate.h"
|
#include "sysemu/runstate.h"
|
||||||
#include "ui/qemu-spice.h"
|
#include "ui/qemu-spice.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,9 @@
|
|||||||
|
|
||||||
#define DBUS_DISPLAY1_AUDIO_PATH DBUS_DISPLAY1_ROOT "/Audio"
|
#define DBUS_DISPLAY1_AUDIO_PATH DBUS_DISPLAY1_ROOT "/Audio"
|
||||||
|
|
||||||
#define DBUS_DEFAULT_AUDIO_NSAMPLES 480
|
#define DBUS_AUDIO_NSAMPLES 1024 /* could be configured? */
|
||||||
|
|
||||||
typedef struct DBusAudio {
|
typedef struct DBusAudio {
|
||||||
Audiodev *dev;
|
|
||||||
GDBusObjectManagerServer *server;
|
GDBusObjectManagerServer *server;
|
||||||
bool p2p;
|
bool p2p;
|
||||||
GDBusObjectSkeleton *audio;
|
GDBusObjectSkeleton *audio;
|
||||||
@@ -152,18 +151,6 @@ dbus_init_out_listener(QemuDBusDisplay1AudioOutListener *listener,
|
|||||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
|
||||||
dbus_audio_get_nsamples(DBusAudio *da)
|
|
||||||
{
|
|
||||||
AudiodevDBusOptions *opts = &da->dev->u.dbus;
|
|
||||||
|
|
||||||
if (opts->has_nsamples && opts->nsamples) {
|
|
||||||
return opts->nsamples;
|
|
||||||
} else {
|
|
||||||
return DBUS_DEFAULT_AUDIO_NSAMPLES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dbus_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
|
dbus_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
|
||||||
{
|
{
|
||||||
@@ -173,7 +160,7 @@ dbus_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
|
|||||||
QemuDBusDisplay1AudioOutListener *listener = NULL;
|
QemuDBusDisplay1AudioOutListener *listener = NULL;
|
||||||
|
|
||||||
audio_pcm_init_info(&hw->info, as);
|
audio_pcm_init_info(&hw->info, as);
|
||||||
hw->samples = dbus_audio_get_nsamples(da);
|
hw->samples = DBUS_AUDIO_NSAMPLES;
|
||||||
audio_rate_start(&vo->rate);
|
audio_rate_start(&vo->rate);
|
||||||
|
|
||||||
g_hash_table_iter_init(&iter, da->out_listeners);
|
g_hash_table_iter_init(&iter, da->out_listeners);
|
||||||
@@ -287,7 +274,7 @@ dbus_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
|
|||||||
QemuDBusDisplay1AudioInListener *listener = NULL;
|
QemuDBusDisplay1AudioInListener *listener = NULL;
|
||||||
|
|
||||||
audio_pcm_init_info(&hw->info, as);
|
audio_pcm_init_info(&hw->info, as);
|
||||||
hw->samples = dbus_audio_get_nsamples(da);
|
hw->samples = DBUS_AUDIO_NSAMPLES;
|
||||||
audio_rate_start(&vo->rate);
|
audio_rate_start(&vo->rate);
|
||||||
|
|
||||||
g_hash_table_iter_init(&iter, da->in_listeners);
|
g_hash_table_iter_init(&iter, da->in_listeners);
|
||||||
@@ -412,7 +399,6 @@ dbus_audio_init(Audiodev *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
DBusAudio *da = g_new0(DBusAudio, 1);
|
DBusAudio *da = g_new0(DBusAudio, 1);
|
||||||
|
|
||||||
da->dev = dev;
|
|
||||||
da->out_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
|
da->out_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||||
g_free, g_object_unref);
|
g_free, g_object_unref);
|
||||||
da->in_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
|
da->in_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||||
@@ -538,17 +524,11 @@ dbus_audio_register_listener(AudioState *s,
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
GDBusConnectionFlags flags =
|
|
||||||
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER;
|
|
||||||
#ifdef WIN32
|
|
||||||
flags |= G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
listener_conn =
|
listener_conn =
|
||||||
g_dbus_connection_new_sync(
|
g_dbus_connection_new_sync(
|
||||||
G_IO_STREAM(socket_conn),
|
G_IO_STREAM(socket_conn),
|
||||||
guid,
|
guid,
|
||||||
flags,
|
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER,
|
||||||
NULL, NULL, &err);
|
NULL, NULL, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
error_report("Failed to setup peer connection: %s", err->message);
|
error_report("Failed to setup peer connection: %s", err->message);
|
||||||
@@ -666,7 +646,6 @@ dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server, bool p2p)
|
|||||||
"swapped-signal::handle-register-out-listener",
|
"swapped-signal::handle-register-out-listener",
|
||||||
dbus_audio_register_out_listener, s,
|
dbus_audio_register_out_listener, s,
|
||||||
NULL);
|
NULL);
|
||||||
qemu_dbus_display1_audio_set_nsamples(da->iface, dbus_audio_get_nsamples(da));
|
|
||||||
|
|
||||||
g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(da->audio),
|
g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(da->audio),
|
||||||
G_DBUS_INTERFACE_SKELETON(da->iface));
|
G_DBUS_INTERFACE_SKELETON(da->iface));
|
||||||
|
|||||||
@@ -769,15 +769,13 @@ qpw_audio_init(Audiodev *dev, Error **errp)
|
|||||||
pw->core = pw_context_connect(pw->context, NULL, 0);
|
pw->core = pw_context_connect(pw->context, NULL, 0);
|
||||||
if (pw->core == NULL) {
|
if (pw->core == NULL) {
|
||||||
pw_thread_loop_unlock(pw->thread_loop);
|
pw_thread_loop_unlock(pw->thread_loop);
|
||||||
error_setg_errno(errp, errno, "Failed to connect to PipeWire instance");
|
goto fail_error;
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pw_core_add_listener(pw->core, &pw->core_listener,
|
if (pw_core_add_listener(pw->core, &pw->core_listener,
|
||||||
&core_events, pw) < 0) {
|
&core_events, pw) < 0) {
|
||||||
pw_thread_loop_unlock(pw->thread_loop);
|
pw_thread_loop_unlock(pw->thread_loop);
|
||||||
error_setg(errp, "Failed to add PipeWire listener");
|
goto fail_error;
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
if (wait_resync(pw) < 0) {
|
if (wait_resync(pw) < 0) {
|
||||||
pw_thread_loop_unlock(pw->thread_loop);
|
pw_thread_loop_unlock(pw->thread_loop);
|
||||||
@@ -787,6 +785,8 @@ qpw_audio_init(Audiodev *dev, Error **errp)
|
|||||||
|
|
||||||
return g_steal_pointer(&pw);
|
return g_steal_pointer(&pw);
|
||||||
|
|
||||||
|
fail_error:
|
||||||
|
error_setg(errp, "Failed to initialize PW context");
|
||||||
fail:
|
fail:
|
||||||
if (pw->thread_loop) {
|
if (pw->thread_loop) {
|
||||||
pw_thread_loop_stop(pw->thread_loop);
|
pw_thread_loop_stop(pw->thread_loop);
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
#include "qemu/filemonitor.h"
|
#include "qemu/filemonitor.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include "qapi/qapi-visit-authz.h"
|
#include "qapi/qapi-visit-authz.h"
|
||||||
#include "qobject/qjson.h"
|
#include "qapi/qmp/qjson.h"
|
||||||
#include "qobject/qobject.h"
|
#include "qapi/qmp/qobject.h"
|
||||||
#include "qapi/qobject-input-visitor.h"
|
#include "qapi/qobject-input-visitor.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
|
||||||
#include "system/confidential-guest-support.h"
|
#include "exec/confidential-guest-support.h"
|
||||||
|
|
||||||
OBJECT_DEFINE_ABSTRACT_TYPE(ConfidentialGuestSupport,
|
OBJECT_DEFINE_ABSTRACT_TYPE(ConfidentialGuestSupport,
|
||||||
confidential_guest_support,
|
confidential_guest_support,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/cryptodev.h"
|
#include "sysemu/cryptodev.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "standard-headers/linux/virtio_crypto.h"
|
#include "standard-headers/linux/virtio_crypto.h"
|
||||||
@@ -64,11 +64,11 @@ static void cryptodev_builtin_init_akcipher(CryptoDevBackend *backend)
|
|||||||
{
|
{
|
||||||
QCryptoAkCipherOptions opts;
|
QCryptoAkCipherOptions opts;
|
||||||
|
|
||||||
opts.alg = QCRYPTO_AK_CIPHER_ALGO_RSA;
|
opts.alg = QCRYPTO_AKCIPHER_ALG_RSA;
|
||||||
opts.u.rsa.padding_alg = QCRYPTO_RSA_PADDING_ALGO_RAW;
|
opts.u.rsa.padding_alg = QCRYPTO_RSA_PADDING_ALG_RAW;
|
||||||
if (qcrypto_akcipher_supports(&opts)) {
|
if (qcrypto_akcipher_supports(&opts)) {
|
||||||
backend->conf.crypto_services |=
|
backend->conf.crypto_services |=
|
||||||
(1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_AKCIPHER);
|
(1u << QCRYPTODEV_BACKEND_SERVICE_AKCIPHER);
|
||||||
backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA;
|
backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,9 +93,9 @@ static void cryptodev_builtin_init(
|
|||||||
backend->conf.peers.ccs[0] = cc;
|
backend->conf.peers.ccs[0] = cc;
|
||||||
|
|
||||||
backend->conf.crypto_services =
|
backend->conf.crypto_services =
|
||||||
1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_CIPHER |
|
1u << QCRYPTODEV_BACKEND_SERVICE_CIPHER |
|
||||||
1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_HASH |
|
1u << QCRYPTODEV_BACKEND_SERVICE_HASH |
|
||||||
1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_MAC;
|
1u << QCRYPTODEV_BACKEND_SERVICE_MAC;
|
||||||
backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
|
backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
|
||||||
backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
|
backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
|
||||||
/*
|
/*
|
||||||
@@ -138,18 +138,18 @@ cryptodev_builtin_get_aes_algo(uint32_t key_len, int mode, Error **errp)
|
|||||||
int algo;
|
int algo;
|
||||||
|
|
||||||
if (key_len == AES_KEYSIZE_128) {
|
if (key_len == AES_KEYSIZE_128) {
|
||||||
algo = QCRYPTO_CIPHER_ALGO_AES_128;
|
algo = QCRYPTO_CIPHER_ALG_AES_128;
|
||||||
} else if (key_len == AES_KEYSIZE_192) {
|
} else if (key_len == AES_KEYSIZE_192) {
|
||||||
algo = QCRYPTO_CIPHER_ALGO_AES_192;
|
algo = QCRYPTO_CIPHER_ALG_AES_192;
|
||||||
} else if (key_len == AES_KEYSIZE_256) { /* equals AES_KEYSIZE_128_XTS */
|
} else if (key_len == AES_KEYSIZE_256) { /* equals AES_KEYSIZE_128_XTS */
|
||||||
if (mode == QCRYPTO_CIPHER_MODE_XTS) {
|
if (mode == QCRYPTO_CIPHER_MODE_XTS) {
|
||||||
algo = QCRYPTO_CIPHER_ALGO_AES_128;
|
algo = QCRYPTO_CIPHER_ALG_AES_128;
|
||||||
} else {
|
} else {
|
||||||
algo = QCRYPTO_CIPHER_ALGO_AES_256;
|
algo = QCRYPTO_CIPHER_ALG_AES_256;
|
||||||
}
|
}
|
||||||
} else if (key_len == AES_KEYSIZE_256_XTS) {
|
} else if (key_len == AES_KEYSIZE_256_XTS) {
|
||||||
if (mode == QCRYPTO_CIPHER_MODE_XTS) {
|
if (mode == QCRYPTO_CIPHER_MODE_XTS) {
|
||||||
algo = QCRYPTO_CIPHER_ALGO_AES_256;
|
algo = QCRYPTO_CIPHER_ALG_AES_256;
|
||||||
} else {
|
} else {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -169,16 +169,16 @@ static int cryptodev_builtin_get_rsa_hash_algo(
|
|||||||
{
|
{
|
||||||
switch (virtio_rsa_hash) {
|
switch (virtio_rsa_hash) {
|
||||||
case VIRTIO_CRYPTO_RSA_MD5:
|
case VIRTIO_CRYPTO_RSA_MD5:
|
||||||
return QCRYPTO_HASH_ALGO_MD5;
|
return QCRYPTO_HASH_ALG_MD5;
|
||||||
|
|
||||||
case VIRTIO_CRYPTO_RSA_SHA1:
|
case VIRTIO_CRYPTO_RSA_SHA1:
|
||||||
return QCRYPTO_HASH_ALGO_SHA1;
|
return QCRYPTO_HASH_ALG_SHA1;
|
||||||
|
|
||||||
case VIRTIO_CRYPTO_RSA_SHA256:
|
case VIRTIO_CRYPTO_RSA_SHA256:
|
||||||
return QCRYPTO_HASH_ALGO_SHA256;
|
return QCRYPTO_HASH_ALG_SHA256;
|
||||||
|
|
||||||
case VIRTIO_CRYPTO_RSA_SHA512:
|
case VIRTIO_CRYPTO_RSA_SHA512:
|
||||||
return QCRYPTO_HASH_ALGO_SHA512;
|
return QCRYPTO_HASH_ALG_SHA512;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error_setg(errp, "Unsupported rsa hash algo: %d", virtio_rsa_hash);
|
error_setg(errp, "Unsupported rsa hash algo: %d", virtio_rsa_hash);
|
||||||
@@ -200,12 +200,12 @@ static int cryptodev_builtin_set_rsa_options(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
opt->hash_alg = hash_alg;
|
opt->hash_alg = hash_alg;
|
||||||
opt->padding_alg = QCRYPTO_RSA_PADDING_ALGO_PKCS1;
|
opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_PKCS1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virtio_padding_algo == VIRTIO_CRYPTO_RSA_RAW_PADDING) {
|
if (virtio_padding_algo == VIRTIO_CRYPTO_RSA_RAW_PADDING) {
|
||||||
opt->padding_alg = QCRYPTO_RSA_PADDING_ALGO_RAW;
|
opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_RAW;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,15 +271,15 @@ static int cryptodev_builtin_create_cipher_session(
|
|||||||
break;
|
break;
|
||||||
case VIRTIO_CRYPTO_CIPHER_3DES_ECB:
|
case VIRTIO_CRYPTO_CIPHER_3DES_ECB:
|
||||||
mode = QCRYPTO_CIPHER_MODE_ECB;
|
mode = QCRYPTO_CIPHER_MODE_ECB;
|
||||||
algo = QCRYPTO_CIPHER_ALGO_3DES;
|
algo = QCRYPTO_CIPHER_ALG_3DES;
|
||||||
break;
|
break;
|
||||||
case VIRTIO_CRYPTO_CIPHER_3DES_CBC:
|
case VIRTIO_CRYPTO_CIPHER_3DES_CBC:
|
||||||
mode = QCRYPTO_CIPHER_MODE_CBC;
|
mode = QCRYPTO_CIPHER_MODE_CBC;
|
||||||
algo = QCRYPTO_CIPHER_ALGO_3DES;
|
algo = QCRYPTO_CIPHER_ALG_3DES;
|
||||||
break;
|
break;
|
||||||
case VIRTIO_CRYPTO_CIPHER_3DES_CTR:
|
case VIRTIO_CRYPTO_CIPHER_3DES_CTR:
|
||||||
mode = QCRYPTO_CIPHER_MODE_CTR;
|
mode = QCRYPTO_CIPHER_MODE_CTR;
|
||||||
algo = QCRYPTO_CIPHER_ALGO_3DES;
|
algo = QCRYPTO_CIPHER_ALG_3DES;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error_setg(errp, "Unsupported cipher alg :%u",
|
error_setg(errp, "Unsupported cipher alg :%u",
|
||||||
@@ -318,7 +318,7 @@ static int cryptodev_builtin_create_akcipher_session(
|
|||||||
|
|
||||||
switch (sess_info->algo) {
|
switch (sess_info->algo) {
|
||||||
case VIRTIO_CRYPTO_AKCIPHER_RSA:
|
case VIRTIO_CRYPTO_AKCIPHER_RSA:
|
||||||
opts.alg = QCRYPTO_AK_CIPHER_ALGO_RSA;
|
opts.alg = QCRYPTO_AKCIPHER_ALG_RSA;
|
||||||
if (cryptodev_builtin_set_rsa_options(sess_info->u.rsa.padding_algo,
|
if (cryptodev_builtin_set_rsa_options(sess_info->u.rsa.padding_algo,
|
||||||
sess_info->u.rsa.hash_algo, &opts.u.rsa, errp) != 0) {
|
sess_info->u.rsa.hash_algo, &opts.u.rsa, errp) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -334,11 +334,11 @@ static int cryptodev_builtin_create_akcipher_session(
|
|||||||
|
|
||||||
switch (sess_info->keytype) {
|
switch (sess_info->keytype) {
|
||||||
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
|
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
|
||||||
type = QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC;
|
type = QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
|
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
|
||||||
type = QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE;
|
type = QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -549,7 +549,7 @@ static int cryptodev_builtin_operation(
|
|||||||
CryptoDevBackendBuiltinSession *sess;
|
CryptoDevBackendBuiltinSession *sess;
|
||||||
CryptoDevBackendSymOpInfo *sym_op_info;
|
CryptoDevBackendSymOpInfo *sym_op_info;
|
||||||
CryptoDevBackendAsymOpInfo *asym_op_info;
|
CryptoDevBackendAsymOpInfo *asym_op_info;
|
||||||
QCryptodevBackendAlgoType algtype = op_info->algtype;
|
QCryptodevBackendAlgType algtype = op_info->algtype;
|
||||||
int status = -VIRTIO_CRYPTO_ERR;
|
int status = -VIRTIO_CRYPTO_ERR;
|
||||||
Error *local_error = NULL;
|
Error *local_error = NULL;
|
||||||
|
|
||||||
@@ -561,11 +561,11 @@ static int cryptodev_builtin_operation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sess = builtin->sessions[op_info->session_id];
|
sess = builtin->sessions[op_info->session_id];
|
||||||
if (algtype == QCRYPTODEV_BACKEND_ALGO_TYPE_SYM) {
|
if (algtype == QCRYPTODEV_BACKEND_ALG_SYM) {
|
||||||
sym_op_info = op_info->u.sym_op_info;
|
sym_op_info = op_info->u.sym_op_info;
|
||||||
status = cryptodev_builtin_sym_operation(sess, sym_op_info,
|
status = cryptodev_builtin_sym_operation(sess, sym_op_info,
|
||||||
&local_error);
|
&local_error);
|
||||||
} else if (algtype == QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM) {
|
} else if (algtype == QCRYPTODEV_BACKEND_ALG_ASYM) {
|
||||||
asym_op_info = op_info->u.asym_op_info;
|
asym_op_info = op_info->u.asym_op_info;
|
||||||
status = cryptodev_builtin_asym_operation(sess, op_info->op_code,
|
status = cryptodev_builtin_asym_operation(sess, op_info->op_code,
|
||||||
asym_op_info, &local_error);
|
asym_op_info, &local_error);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include "monitor/hmp.h"
|
#include "monitor/hmp.h"
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
#include "qapi/qapi-commands-cryptodev.h"
|
#include "qapi/qapi-commands-cryptodev.h"
|
||||||
#include "qobject/qdict.h"
|
#include "qapi/qmp/qdict.h"
|
||||||
|
|
||||||
|
|
||||||
void hmp_info_cryptodev(Monitor *mon, const QDict *qdict)
|
void hmp_info_cryptodev(Monitor *mon, const QDict *qdict)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
#include "system/cryptodev.h"
|
#include "sysemu/cryptodev.h"
|
||||||
#include "standard-headers/linux/virtio_crypto.h"
|
#include "standard-headers/linux/virtio_crypto.h"
|
||||||
|
|
||||||
#include <keyutils.h>
|
#include <keyutils.h>
|
||||||
@@ -133,20 +133,20 @@ static int cryptodev_lkcf_set_op_desc(QCryptoAkCipherOptions *opts,
|
|||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
QCryptoAkCipherOptionsRSA *rsa_opt;
|
QCryptoAkCipherOptionsRSA *rsa_opt;
|
||||||
if (opts->alg != QCRYPTO_AK_CIPHER_ALGO_RSA) {
|
if (opts->alg != QCRYPTO_AKCIPHER_ALG_RSA) {
|
||||||
error_setg(errp, "Unsupported alg: %u", opts->alg);
|
error_setg(errp, "Unsupported alg: %u", opts->alg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsa_opt = &opts->u.rsa;
|
rsa_opt = &opts->u.rsa;
|
||||||
if (rsa_opt->padding_alg == QCRYPTO_RSA_PADDING_ALGO_PKCS1) {
|
if (rsa_opt->padding_alg == QCRYPTO_RSA_PADDING_ALG_PKCS1) {
|
||||||
snprintf(key_desc, desc_len, "enc=%s hash=%s",
|
snprintf(key_desc, desc_len, "enc=%s hash=%s",
|
||||||
QCryptoRSAPaddingAlgo_str(rsa_opt->padding_alg),
|
QCryptoRSAPaddingAlgorithm_str(rsa_opt->padding_alg),
|
||||||
QCryptoHashAlgo_str(rsa_opt->hash_alg));
|
QCryptoHashAlgorithm_str(rsa_opt->hash_alg));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
snprintf(key_desc, desc_len, "enc=%s",
|
snprintf(key_desc, desc_len, "enc=%s",
|
||||||
QCryptoRSAPaddingAlgo_str(rsa_opt->padding_alg));
|
QCryptoRSAPaddingAlgorithm_str(rsa_opt->padding_alg));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -157,23 +157,23 @@ static int cryptodev_lkcf_set_rsa_opt(int virtio_padding_alg,
|
|||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
if (virtio_padding_alg == VIRTIO_CRYPTO_RSA_PKCS1_PADDING) {
|
if (virtio_padding_alg == VIRTIO_CRYPTO_RSA_PKCS1_PADDING) {
|
||||||
opt->padding_alg = QCRYPTO_RSA_PADDING_ALGO_PKCS1;
|
opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_PKCS1;
|
||||||
|
|
||||||
switch (virtio_hash_alg) {
|
switch (virtio_hash_alg) {
|
||||||
case VIRTIO_CRYPTO_RSA_MD5:
|
case VIRTIO_CRYPTO_RSA_MD5:
|
||||||
opt->hash_alg = QCRYPTO_HASH_ALGO_MD5;
|
opt->hash_alg = QCRYPTO_HASH_ALG_MD5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIRTIO_CRYPTO_RSA_SHA1:
|
case VIRTIO_CRYPTO_RSA_SHA1:
|
||||||
opt->hash_alg = QCRYPTO_HASH_ALGO_SHA1;
|
opt->hash_alg = QCRYPTO_HASH_ALG_SHA1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIRTIO_CRYPTO_RSA_SHA256:
|
case VIRTIO_CRYPTO_RSA_SHA256:
|
||||||
opt->hash_alg = QCRYPTO_HASH_ALGO_SHA256;
|
opt->hash_alg = QCRYPTO_HASH_ALG_SHA256;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIRTIO_CRYPTO_RSA_SHA512:
|
case VIRTIO_CRYPTO_RSA_SHA512:
|
||||||
opt->hash_alg = QCRYPTO_HASH_ALGO_SHA512;
|
opt->hash_alg = QCRYPTO_HASH_ALG_SHA512;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -184,7 +184,7 @@ static int cryptodev_lkcf_set_rsa_opt(int virtio_padding_alg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (virtio_padding_alg == VIRTIO_CRYPTO_RSA_RAW_PADDING) {
|
if (virtio_padding_alg == VIRTIO_CRYPTO_RSA_RAW_PADDING) {
|
||||||
opt->padding_alg = QCRYPTO_RSA_PADDING_ALGO_RAW;
|
opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_RAW;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ static void cryptodev_lkcf_init(CryptoDevBackend *backend, Error **errp)
|
|||||||
backend->conf.peers.ccs[0] = cc;
|
backend->conf.peers.ccs[0] = cc;
|
||||||
|
|
||||||
backend->conf.crypto_services =
|
backend->conf.crypto_services =
|
||||||
1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_AKCIPHER;
|
1u << QCRYPTODEV_BACKEND_SERVICE_AKCIPHER;
|
||||||
backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA;
|
backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA;
|
||||||
lkcf->running = true;
|
lkcf->running = true;
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ static void cryptodev_lkcf_execute_task(CryptoDevLKCFTask *task)
|
|||||||
* 2. generally, public key related compution is fast, just compute it with
|
* 2. generally, public key related compution is fast, just compute it with
|
||||||
* thread-pool.
|
* thread-pool.
|
||||||
*/
|
*/
|
||||||
if (session->keytype == QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE) {
|
if (session->keytype == QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE) {
|
||||||
if (qcrypto_akcipher_export_p8info(&session->akcipher_opts,
|
if (qcrypto_akcipher_export_p8info(&session->akcipher_opts,
|
||||||
session->key, session->keylen,
|
session->key, session->keylen,
|
||||||
&p8info, &p8info_len,
|
&p8info, &p8info_len,
|
||||||
@@ -330,8 +330,6 @@ static void cryptodev_lkcf_execute_task(CryptoDevLKCFTask *task)
|
|||||||
cryptodev_lkcf_set_op_desc(&session->akcipher_opts, op_desc,
|
cryptodev_lkcf_set_op_desc(&session->akcipher_opts, op_desc,
|
||||||
sizeof(op_desc), &local_error) != 0) {
|
sizeof(op_desc), &local_error) != 0) {
|
||||||
error_report_err(local_error);
|
error_report_err(local_error);
|
||||||
status = -VIRTIO_CRYPTO_ERR;
|
|
||||||
goto out;
|
|
||||||
} else {
|
} else {
|
||||||
key_id = add_key(KCTL_KEY_TYPE_PKEY, "lkcf-backend-priv-key",
|
key_id = add_key(KCTL_KEY_TYPE_PKEY, "lkcf-backend-priv-key",
|
||||||
p8info, p8info_len, KCTL_KEY_RING);
|
p8info, p8info_len, KCTL_KEY_RING);
|
||||||
@@ -348,7 +346,6 @@ static void cryptodev_lkcf_execute_task(CryptoDevLKCFTask *task)
|
|||||||
session->key, session->keylen,
|
session->key, session->keylen,
|
||||||
&local_error);
|
&local_error);
|
||||||
if (!akcipher) {
|
if (!akcipher) {
|
||||||
error_report_err(local_error);
|
|
||||||
status = -VIRTIO_CRYPTO_ERR;
|
status = -VIRTIO_CRYPTO_ERR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -477,7 +474,7 @@ static int cryptodev_lkcf_operation(
|
|||||||
CryptoDevBackendLKCF *lkcf =
|
CryptoDevBackendLKCF *lkcf =
|
||||||
CRYPTODEV_BACKEND_LKCF(backend);
|
CRYPTODEV_BACKEND_LKCF(backend);
|
||||||
CryptoDevBackendLKCFSession *sess;
|
CryptoDevBackendLKCFSession *sess;
|
||||||
QCryptodevBackendAlgoType algtype = op_info->algtype;
|
QCryptodevBackendAlgType algtype = op_info->algtype;
|
||||||
CryptoDevLKCFTask *task;
|
CryptoDevLKCFTask *task;
|
||||||
|
|
||||||
if (op_info->session_id >= MAX_SESSIONS ||
|
if (op_info->session_id >= MAX_SESSIONS ||
|
||||||
@@ -488,7 +485,7 @@ static int cryptodev_lkcf_operation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
sess = lkcf->sess[op_info->session_id];
|
sess = lkcf->sess[op_info->session_id];
|
||||||
if (algtype != QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM) {
|
if (algtype != QCRYPTODEV_BACKEND_ALG_ASYM) {
|
||||||
error_report("algtype not supported: %u", algtype);
|
error_report("algtype not supported: %u", algtype);
|
||||||
return -VIRTIO_CRYPTO_NOTSUPP;
|
return -VIRTIO_CRYPTO_NOTSUPP;
|
||||||
}
|
}
|
||||||
@@ -521,7 +518,7 @@ static int cryptodev_lkcf_create_asym_session(
|
|||||||
|
|
||||||
switch (sess_info->algo) {
|
switch (sess_info->algo) {
|
||||||
case VIRTIO_CRYPTO_AKCIPHER_RSA:
|
case VIRTIO_CRYPTO_AKCIPHER_RSA:
|
||||||
sess->akcipher_opts.alg = QCRYPTO_AK_CIPHER_ALGO_RSA;
|
sess->akcipher_opts.alg = QCRYPTO_AKCIPHER_ALG_RSA;
|
||||||
if (cryptodev_lkcf_set_rsa_opt(
|
if (cryptodev_lkcf_set_rsa_opt(
|
||||||
sess_info->u.rsa.padding_algo, sess_info->u.rsa.hash_algo,
|
sess_info->u.rsa.padding_algo, sess_info->u.rsa.hash_algo,
|
||||||
&sess->akcipher_opts.u.rsa, &local_error) != 0) {
|
&sess->akcipher_opts.u.rsa, &local_error) != 0) {
|
||||||
@@ -537,11 +534,11 @@ static int cryptodev_lkcf_create_asym_session(
|
|||||||
|
|
||||||
switch (sess_info->keytype) {
|
switch (sess_info->keytype) {
|
||||||
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
|
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
|
||||||
sess->keytype = QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC;
|
sess->keytype = QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
|
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
|
||||||
sess->keytype = QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE;
|
sess->keytype = QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -27,9 +27,9 @@
|
|||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "hw/virtio/vhost-user.h"
|
#include "hw/virtio/vhost-user.h"
|
||||||
#include "standard-headers/linux/virtio_crypto.h"
|
#include "standard-headers/linux/virtio_crypto.h"
|
||||||
#include "system/cryptodev-vhost.h"
|
#include "sysemu/cryptodev-vhost.h"
|
||||||
#include "chardev/char-fe.h"
|
#include "chardev/char-fe.h"
|
||||||
#include "system/cryptodev-vhost-user.h"
|
#include "sysemu/cryptodev-vhost-user.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -221,9 +221,9 @@ static void cryptodev_vhost_user_init(
|
|||||||
cryptodev_vhost_user_event, NULL, s, NULL, true);
|
cryptodev_vhost_user_event, NULL, s, NULL, true);
|
||||||
|
|
||||||
backend->conf.crypto_services =
|
backend->conf.crypto_services =
|
||||||
1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_CIPHER |
|
1u << QCRYPTODEV_BACKEND_SERVICE_CIPHER |
|
||||||
1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_HASH |
|
1u << QCRYPTODEV_BACKEND_SERVICE_HASH |
|
||||||
1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_MAC;
|
1u << QCRYPTODEV_BACKEND_SERVICE_MAC;
|
||||||
backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
|
backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
|
||||||
backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
|
backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
|
||||||
|
|
||||||
@@ -281,7 +281,8 @@ static int cryptodev_vhost_user_create_session(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error_report("Unsupported opcode :%" PRIu32 "", sess_info->op_code);
|
error_setg(&local_error, "Unsupported opcode :%" PRIu32 "",
|
||||||
|
sess_info->op_code);
|
||||||
return -VIRTIO_CRYPTO_NOTSUPP;
|
return -VIRTIO_CRYPTO_NOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,13 +24,13 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/virtio/virtio-bus.h"
|
#include "hw/virtio/virtio-bus.h"
|
||||||
#include "system/cryptodev-vhost.h"
|
#include "sysemu/cryptodev-vhost.h"
|
||||||
|
|
||||||
#ifdef CONFIG_VHOST_CRYPTO
|
#ifdef CONFIG_VHOST_CRYPTO
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "hw/virtio/virtio-crypto.h"
|
#include "hw/virtio/virtio-crypto.h"
|
||||||
#include "system/cryptodev-vhost-user.h"
|
#include "sysemu/cryptodev-vhost-user.h"
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
cryptodev_vhost_get_max_queues(
|
cryptodev_vhost_get_max_queues(
|
||||||
@@ -53,7 +53,7 @@ cryptodev_vhost_init(
|
|||||||
CryptoDevBackendVhost *crypto;
|
CryptoDevBackendVhost *crypto;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
crypto = g_new0(CryptoDevBackendVhost, 1);
|
crypto = g_new(CryptoDevBackendVhost, 1);
|
||||||
crypto->dev.max_queues = 1;
|
crypto->dev.max_queues = 1;
|
||||||
crypto->dev.nvqs = 1;
|
crypto->dev.nvqs = 1;
|
||||||
crypto->dev.vqs = crypto->vqs;
|
crypto->dev.vqs = crypto->vqs;
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/cryptodev.h"
|
#include "sysemu/cryptodev.h"
|
||||||
#include "system/stats.h"
|
#include "sysemu/stats.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qapi-commands-cryptodev.h"
|
#include "qapi/qapi-commands-cryptodev.h"
|
||||||
#include "qapi/qapi-types-stats.h"
|
#include "qapi/qapi-types-stats.h"
|
||||||
@@ -74,7 +74,7 @@ static int qmp_query_cryptodev_foreach(Object *obj, void *data)
|
|||||||
|
|
||||||
backend = CRYPTODEV_BACKEND(obj);
|
backend = CRYPTODEV_BACKEND(obj);
|
||||||
services = backend->conf.crypto_services;
|
services = backend->conf.crypto_services;
|
||||||
for (i = 0; i < QCRYPTODEV_BACKEND_SERVICE_TYPE__MAX; i++) {
|
for (i = 0; i < QCRYPTODEV_BACKEND_SERVICE__MAX; i++) {
|
||||||
if (services & (1 << i)) {
|
if (services & (1 << i)) {
|
||||||
QAPI_LIST_PREPEND(info->service, i);
|
QAPI_LIST_PREPEND(info->service, i);
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ static int qmp_query_cryptodev_foreach(Object *obj, void *data)
|
|||||||
QCryptodevInfoList *qmp_query_cryptodev(Error **errp)
|
QCryptodevInfoList *qmp_query_cryptodev(Error **errp)
|
||||||
{
|
{
|
||||||
QCryptodevInfoList *list = NULL;
|
QCryptodevInfoList *list = NULL;
|
||||||
Object *objs = object_get_container("objects");
|
Object *objs = container_get(object_get_root(), "/objects");
|
||||||
|
|
||||||
object_child_foreach(objs, qmp_query_cryptodev_foreach, &list);
|
object_child_foreach(objs, qmp_query_cryptodev_foreach, &list);
|
||||||
|
|
||||||
@@ -185,10 +185,10 @@ static int cryptodev_backend_operation(
|
|||||||
static int cryptodev_backend_account(CryptoDevBackend *backend,
|
static int cryptodev_backend_account(CryptoDevBackend *backend,
|
||||||
CryptoDevBackendOpInfo *op_info)
|
CryptoDevBackendOpInfo *op_info)
|
||||||
{
|
{
|
||||||
enum QCryptodevBackendAlgoType algtype = op_info->algtype;
|
enum QCryptodevBackendAlgType algtype = op_info->algtype;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (algtype == QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM) {
|
if (algtype == QCRYPTODEV_BACKEND_ALG_ASYM) {
|
||||||
CryptoDevBackendAsymOpInfo *asym_op_info = op_info->u.asym_op_info;
|
CryptoDevBackendAsymOpInfo *asym_op_info = op_info->u.asym_op_info;
|
||||||
len = asym_op_info->src_len;
|
len = asym_op_info->src_len;
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ static int cryptodev_backend_account(CryptoDevBackend *backend,
|
|||||||
default:
|
default:
|
||||||
return -VIRTIO_CRYPTO_NOTSUPP;
|
return -VIRTIO_CRYPTO_NOTSUPP;
|
||||||
}
|
}
|
||||||
} else if (algtype == QCRYPTODEV_BACKEND_ALGO_TYPE_SYM) {
|
} else if (algtype == QCRYPTODEV_BACKEND_ALG_SYM) {
|
||||||
CryptoDevBackendSymOpInfo *sym_op_info = op_info->u.sym_op_info;
|
CryptoDevBackendSymOpInfo *sym_op_info = op_info->u.sym_op_info;
|
||||||
len = sym_op_info->src_len;
|
len = sym_op_info->src_len;
|
||||||
|
|
||||||
@@ -424,11 +424,11 @@ cryptodev_backend_complete(UserCreatable *uc, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
services = backend->conf.crypto_services;
|
services = backend->conf.crypto_services;
|
||||||
if (services & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_CIPHER)) {
|
if (services & (1 << QCRYPTODEV_BACKEND_SERVICE_CIPHER)) {
|
||||||
backend->sym_stat = g_new0(CryptodevBackendSymStat, 1);
|
backend->sym_stat = g_new0(CryptodevBackendSymStat, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (services & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_AKCIPHER)) {
|
if (services & (1 << QCRYPTODEV_BACKEND_SERVICE_AKCIPHER)) {
|
||||||
backend->asym_stat = g_new0(CryptodevBackendAsymStat, 1);
|
backend->asym_stat = g_new0(CryptodevBackendAsymStat, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -557,7 +557,7 @@ static void cryptodev_backend_stats_cb(StatsResultList **result,
|
|||||||
switch (target) {
|
switch (target) {
|
||||||
case STATS_TARGET_CRYPTODEV:
|
case STATS_TARGET_CRYPTODEV:
|
||||||
{
|
{
|
||||||
Object *objs = object_get_container("objects");
|
Object *objs = container_get(object_get_root(), "/objects");
|
||||||
StatsArgs stats_args;
|
StatsArgs stats_args;
|
||||||
stats_args.result.stats = result;
|
stats_args.result.stats = result;
|
||||||
stats_args.names = names;
|
stats_args.names = names;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/host_iommu_device.h"
|
#include "sysemu/host_iommu_device.h"
|
||||||
|
|
||||||
OBJECT_DEFINE_ABSTRACT_TYPE(HostIOMMUDevice,
|
OBJECT_DEFINE_ABSTRACT_TYPE(HostIOMMUDevice,
|
||||||
host_iommu_device,
|
host_iommu_device,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "system/hostmem.h"
|
#include "sysemu/hostmem.h"
|
||||||
#include "hw/i386/hostmem-epc.h"
|
#include "hw/i386/hostmem-epc.h"
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -36,7 +36,7 @@ sgx_epc_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
|
|
||||||
backend->aligned = true;
|
backend->aligned = true;
|
||||||
name = object_get_canonical_path(OBJECT(backend));
|
name = object_get_canonical_path(OBJECT(backend));
|
||||||
ram_flags = (backend->share ? RAM_SHARED : RAM_PRIVATE) | RAM_PROTECTED;
|
ram_flags = (backend->share ? RAM_SHARED : 0) | RAM_PROTECTED;
|
||||||
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
|
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
|
||||||
backend->size, ram_flags, fd, 0, errp);
|
backend->size, ram_flags, fd, 0, errp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu/madvise.h"
|
#include "qemu/madvise.h"
|
||||||
#include "system/hostmem.h"
|
#include "sysemu/hostmem.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
#include "qapi/visitor.h"
|
#include "qapi/visitor.h"
|
||||||
@@ -82,7 +82,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
|
|
||||||
backend->aligned = true;
|
backend->aligned = true;
|
||||||
name = host_memory_backend_get_name(backend);
|
name = host_memory_backend_get_name(backend);
|
||||||
ram_flags = backend->share ? RAM_SHARED : RAM_PRIVATE;
|
ram_flags = backend->share ? RAM_SHARED : 0;
|
||||||
ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
|
ram_flags |= fb->readonly ? RAM_READONLY_FD : 0;
|
||||||
ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0;
|
ram_flags |= fb->rom == ON_OFF_AUTO_ON ? RAM_READONLY : 0;
|
||||||
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
||||||
|
|||||||
@@ -11,13 +11,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/hostmem.h"
|
#include "sysemu/hostmem.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include "qemu/memfd.h"
|
#include "qemu/memfd.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
#include "migration/cpr.h"
|
|
||||||
|
#define TYPE_MEMORY_BACKEND_MEMFD "memory-backend-memfd"
|
||||||
|
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendMemfd, MEMORY_BACKEND_MEMFD)
|
OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendMemfd, MEMORY_BACKEND_MEMFD)
|
||||||
|
|
||||||
@@ -34,19 +35,15 @@ static bool
|
|||||||
memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
||||||
{
|
{
|
||||||
HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(backend);
|
HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(backend);
|
||||||
g_autofree char *name = host_memory_backend_get_name(backend);
|
g_autofree char *name = NULL;
|
||||||
int fd = cpr_find_fd(name, 0);
|
|
||||||
uint32_t ram_flags;
|
uint32_t ram_flags;
|
||||||
|
int fd;
|
||||||
|
|
||||||
if (!backend->size) {
|
if (!backend->size) {
|
||||||
error_setg(errp, "can't create backend with size 0");
|
error_setg(errp, "can't create backend with size 0");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd >= 0) {
|
|
||||||
goto have_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
|
fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
|
||||||
m->hugetlb, m->hugetlbsize, m->seal ?
|
m->hugetlb, m->hugetlbsize, m->seal ?
|
||||||
F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
|
F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
|
||||||
@@ -54,11 +51,10 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cpr_save_fd(name, 0, fd);
|
|
||||||
|
|
||||||
have_fd:
|
|
||||||
backend->aligned = true;
|
backend->aligned = true;
|
||||||
ram_flags = backend->share ? RAM_SHARED : RAM_PRIVATE;
|
name = host_memory_backend_get_name(backend);
|
||||||
|
ram_flags = backend->share ? RAM_SHARED : 0;
|
||||||
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
||||||
ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
|
ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
|
||||||
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
|
return memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/hostmem.h"
|
#include "sysemu/hostmem.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
@@ -28,7 +28,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
name = host_memory_backend_get_name(backend);
|
name = host_memory_backend_get_name(backend);
|
||||||
ram_flags = backend->share ? RAM_SHARED : RAM_PRIVATE;
|
ram_flags = backend->share ? RAM_SHARED : 0;
|
||||||
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
||||||
ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
|
ram_flags |= backend->guest_memfd ? RAM_GUEST_MEMFD : 0;
|
||||||
return memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend),
|
return memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend),
|
||||||
|
|||||||
@@ -11,9 +11,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/hostmem.h"
|
#include "sysemu/hostmem.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "migration/cpr.h"
|
|
||||||
|
|
||||||
#define TYPE_MEMORY_BACKEND_SHM "memory-backend-shm"
|
#define TYPE_MEMORY_BACKEND_SHM "memory-backend-shm"
|
||||||
|
|
||||||
@@ -26,9 +25,11 @@ struct HostMemoryBackendShm {
|
|||||||
static bool
|
static bool
|
||||||
shm_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
shm_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
||||||
{
|
{
|
||||||
g_autofree char *backend_name = host_memory_backend_get_name(backend);
|
g_autoptr(GString) shm_name = g_string_new(NULL);
|
||||||
|
g_autofree char *backend_name = NULL;
|
||||||
uint32_t ram_flags;
|
uint32_t ram_flags;
|
||||||
int fd = cpr_find_fd(backend_name, 0);
|
int fd, oflag;
|
||||||
|
mode_t mode;
|
||||||
|
|
||||||
if (!backend->size) {
|
if (!backend->size) {
|
||||||
error_setg(errp, "can't create shm backend with size 0");
|
error_setg(errp, "can't create shm backend with size 0");
|
||||||
@@ -40,18 +41,48 @@ shm_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd >= 0) {
|
/*
|
||||||
goto have_fd;
|
* Let's use `mode = 0` because we don't want other processes to open our
|
||||||
}
|
* memory unless we share the file descriptor with them.
|
||||||
|
*/
|
||||||
|
mode = 0;
|
||||||
|
oflag = O_RDWR | O_CREAT | O_EXCL;
|
||||||
|
backend_name = host_memory_backend_get_name(backend);
|
||||||
|
|
||||||
fd = qemu_shm_alloc(backend->size, errp);
|
/*
|
||||||
|
* Some operating systems allow creating anonymous POSIX shared memory
|
||||||
|
* objects (e.g. FreeBSD provides the SHM_ANON constant), but this is not
|
||||||
|
* defined by POSIX, so let's create a unique name.
|
||||||
|
*
|
||||||
|
* From Linux's shm_open(3) man-page:
|
||||||
|
* For portable use, a shared memory object should be identified
|
||||||
|
* by a name of the form /somename;"
|
||||||
|
*/
|
||||||
|
g_string_printf(shm_name, "/qemu-" FMT_pid "-shm-%s", getpid(),
|
||||||
|
backend_name);
|
||||||
|
|
||||||
|
fd = shm_open(shm_name->str, oflag, mode);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
error_setg_errno(errp, errno,
|
||||||
|
"failed to create POSIX shared memory");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have the file descriptor, so we no longer need to expose the
|
||||||
|
* POSIX shared memory object. However it will remain allocated as long as
|
||||||
|
* there are file descriptors pointing to it.
|
||||||
|
*/
|
||||||
|
shm_unlink(shm_name->str);
|
||||||
|
|
||||||
|
if (ftruncate(fd, backend->size) == -1) {
|
||||||
|
error_setg_errno(errp, errno,
|
||||||
|
"failed to resize POSIX shared memory to %" PRIu64,
|
||||||
|
backend->size);
|
||||||
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cpr_save_fd(backend_name, 0, fd);
|
|
||||||
|
|
||||||
have_fd:
|
|
||||||
/* Let's do the same as memory-backend-ram,share=on would do. */
|
|
||||||
ram_flags = RAM_SHARED;
|
ram_flags = RAM_SHARED;
|
||||||
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/hostmem.h"
|
#include "sysemu/hostmem.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qapi-builtin-visit.h"
|
#include "qapi/qapi-builtin-visit.h"
|
||||||
@@ -178,7 +178,7 @@ static void host_memory_backend_set_merge(Object *obj, bool value, Error **errp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (host_memory_backend_mr_inited(backend) &&
|
if (!host_memory_backend_mr_inited(backend) &&
|
||||||
value != backend->merge) {
|
value != backend->merge) {
|
||||||
void *ptr = memory_region_get_ram_ptr(&backend->mr);
|
void *ptr = memory_region_get_ram_ptr(&backend->mr);
|
||||||
uint64_t sz = memory_region_size(&backend->mr);
|
uint64_t sz = memory_region_size(&backend->mr);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/iommufd.h"
|
#include "sysemu/iommufd.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
@@ -167,6 +167,8 @@ int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
|
|||||||
/* TODO: Not support mapping hardware PCI BAR region for now. */
|
/* TODO: Not support mapping hardware PCI BAR region for now. */
|
||||||
if (errno == EFAULT) {
|
if (errno == EFAULT) {
|
||||||
warn_report("IOMMU_IOAS_MAP failed: %m, PCI BAR?");
|
warn_report("IOMMU_IOAS_MAP failed: %m, PCI BAR?");
|
||||||
|
} else {
|
||||||
|
error_report("IOMMU_IOAS_MAP failed: %m");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -201,6 +203,7 @@ int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id,
|
|||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
|
error_report("IOMMU_IOAS_UNMAP failed: %m");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/rng.h"
|
#include "sysemu/rng.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
#include "system/replay.h"
|
#include "sysemu/replay.h"
|
||||||
|
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(RngBuiltin, RNG_BUILTIN)
|
OBJECT_DECLARE_SIMPLE_TYPE(RngBuiltin, RNG_BUILTIN)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/rng.h"
|
#include "sysemu/rng.h"
|
||||||
#include "chardev/char-fe.h"
|
#include "chardev/char-fe.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "system/rng-random.h"
|
#include "sysemu/rng-random.h"
|
||||||
#include "system/rng.h"
|
#include "sysemu/rng.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user