Compare commits
49 Commits
v7.1-sle15
...
opensuse-6
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b372abd35 | |||
|
|
8b09f319f0 | ||
|
|
f2f010c9ee | ||
|
|
e8af65f4b4 | ||
|
|
3005c18f9f | ||
|
|
ae84b2f70f | ||
|
|
537ae213de | ||
|
|
4ef6dd8d68 | ||
|
|
4be3d93708 | ||
|
|
b833e1aac3 | ||
|
|
b6679c724b | ||
|
|
7783d86de9 | ||
|
|
d128665557 | ||
|
|
5e4567c98b | ||
|
|
b55775e091 | ||
|
|
5140df1daf | ||
|
|
3c448cad68 | ||
|
|
3b7837c67a | ||
|
|
e413bf95b1 | ||
|
|
15a95a2fe1 | ||
|
|
41ec88ff62 | ||
|
|
f155101f62 | ||
|
|
d21c0a9bde | ||
|
|
d89e12a685 | ||
|
|
00a3bc6073 | ||
|
|
71b57ee924 | ||
|
|
6260aa41c0 | ||
|
|
11418db98d | ||
|
|
633a2f9f72 | ||
|
|
8edc4fb5f0 | ||
|
|
76b1ac2dfc | ||
|
|
e712d2fa40 | ||
|
|
9b92359f17 | ||
| 14e6d9e59c | |||
|
|
6a6abf5e09 | ||
|
|
a056ee84f2 | ||
|
|
ecfcff7f81 | ||
|
|
c22d206c7f | ||
|
|
1a796cd199 | ||
|
|
7ff23cc3f1 | ||
|
|
a4770fd7b5 | ||
|
|
a00acf92cb | ||
|
|
f7f676f6dd | ||
|
|
331d3ac2cb | ||
|
|
ef9b9c6f4f | ||
|
|
63de9b65ad | ||
|
|
437b9b2f8c | ||
|
|
03a9121985 | ||
|
|
8c2842cecc |
@@ -10,9 +10,9 @@ windows_msys2_task:
|
||||
memory: 8G
|
||||
env:
|
||||
CIRRUS_SHELL: powershell
|
||||
MSYS: winsymlinks:native
|
||||
MSYS: winsymlinks:nativestrict
|
||||
MSYSTEM: MINGW64
|
||||
MSYS2_URL: https://github.com/msys2/msys2-installer/releases/download/2022-06-03/msys2-base-x86_64-20220603.sfx.exe
|
||||
MSYS2_URL: https://github.com/msys2/msys2-installer/releases/download/2021-04-19/msys2-base-x86_64-20210419.sfx.exe
|
||||
MSYS2_FINGERPRINT: 0
|
||||
MSYS2_PACKAGES: "
|
||||
diffutils git grep make pkg-config sed
|
||||
@@ -32,6 +32,7 @@ windows_msys2_task:
|
||||
mingw-w64-x86_64-libgcrypt
|
||||
mingw-w64-x86_64-libpng
|
||||
mingw-w64-x86_64-libssh
|
||||
mingw-w64-x86_64-libxml2
|
||||
mingw-w64-x86_64-snappy
|
||||
mingw-w64-x86_64-libusb
|
||||
mingw-w64-x86_64-usbredir
|
||||
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,4 +1,3 @@
|
||||
*.c.inc diff=c
|
||||
*.h.inc diff=c
|
||||
*.m diff=objc
|
||||
*.py diff=python
|
||||
|
||||
6
.github/workflows/lockdown.yml
vendored
6
.github/workflows/lockdown.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
steps:
|
||||
- uses: dessant/repo-lockdown@v2
|
||||
with:
|
||||
pr-comment: |
|
||||
pull-comment: |
|
||||
Thank you for your interest in the QEMU project.
|
||||
|
||||
This repository is a read-only mirror of the project's repostories hosted
|
||||
@@ -26,5 +26,5 @@ jobs:
|
||||
functionality). However, we get a lot of patches, and so we have some
|
||||
guidelines about contributing on the project website:
|
||||
https://www.qemu.org/contribute/
|
||||
lock-pr: true
|
||||
close-pr: true
|
||||
lock-pull: true
|
||||
close-pull: true
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,4 +15,3 @@ GTAGS
|
||||
*.depend_raw
|
||||
*.swp
|
||||
*.patch
|
||||
*.gcov
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
|
||||
# The order of rules defined here is critically important.
|
||||
# They are evaluated in order and first match wins.
|
||||
#
|
||||
# Thus we group them into a number of stages, ordered from
|
||||
# most restrictive to least restrictive
|
||||
#
|
||||
.base_job_template:
|
||||
rules:
|
||||
#############################################################
|
||||
# Stage 1: exclude scenarios where we definitely don't
|
||||
# want jobs to run
|
||||
#############################################################
|
||||
|
||||
# Cirrus jobs can't run unless the creds / target repo are set
|
||||
- if: '$QEMU_JOB_CIRRUS && ($CIRRUS_GITHUB_REPO == null || $CIRRUS_API_TOKEN == null)'
|
||||
when: never
|
||||
|
||||
# Publishing jobs should only run on the default branch in upstream
|
||||
- if: '$QEMU_JOB_PUBLISH == "1" && $CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH'
|
||||
when: never
|
||||
|
||||
# Non-publishing jobs should only run on staging branches in upstream
|
||||
- if: '$QEMU_JOB_PUBLISH != "1" && $CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH !~ /staging/'
|
||||
when: never
|
||||
|
||||
# Jobs only intended for forks should always be skipped on upstream
|
||||
- if: '$QEMU_JOB_ONLY_FORKS == "1" && $CI_PROJECT_NAMESPACE == "qemu-project"'
|
||||
when: never
|
||||
|
||||
# Forks don't get pipelines unless QEMU_CI=1 or QEMU_CI=2 is set
|
||||
- if: '$QEMU_CI != "1" && $QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != "qemu-project"'
|
||||
when: never
|
||||
|
||||
# Avocado jobs don't run in forks unless $QEMU_CI_AVOCADO_TESTING is set
|
||||
- if: '$QEMU_JOB_AVOCADO && $QEMU_CI_AVOCADO_TESTING != "1" && $CI_PROJECT_NAMESPACE != "qemu-project"'
|
||||
when: never
|
||||
|
||||
|
||||
#############################################################
|
||||
# Stage 2: fine tune execution of jobs in specific scenarios
|
||||
# where the catch all logic is inapprorpaite
|
||||
#############################################################
|
||||
|
||||
# Optional jobs should not be run unless manually triggered
|
||||
- if: '$QEMU_JOB_OPTIONAL'
|
||||
when: manual
|
||||
allow_failure: true
|
||||
|
||||
# Skipped jobs should not be run unless manually triggered
|
||||
- if: '$QEMU_JOB_SKIPPED'
|
||||
when: manual
|
||||
allow_failure: true
|
||||
|
||||
# Avocado jobs can be manually start in forks if $QEMU_CI_AVOCADO_TESTING is unset
|
||||
- if: '$QEMU_JOB_AVOCADO && $CI_PROJECT_NAMESPACE != "qemu-project"'
|
||||
when: manual
|
||||
allow_failure: true
|
||||
|
||||
|
||||
#############################################################
|
||||
# Stage 3: catch all logic applying to any job not matching
|
||||
# an earlier criteria
|
||||
#############################################################
|
||||
|
||||
# Forks pipeline jobs don't start automatically unless
|
||||
# QEMU_CI=2 is set
|
||||
- if: '$QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != "qemu-project"'
|
||||
when: manual
|
||||
|
||||
# Jobs can run if any jobs they depend on were successfull
|
||||
- when: on_success
|
||||
@@ -1,5 +1,4 @@
|
||||
.native_build_job_template:
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
|
||||
before_script:
|
||||
@@ -27,8 +26,7 @@
|
||||
make -j"$JOBS" $MAKE_CHECK_ARGS ;
|
||||
fi
|
||||
|
||||
.common_test_job_template:
|
||||
extends: .base_job_template
|
||||
.native_test_job_template:
|
||||
stage: test
|
||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
|
||||
script:
|
||||
@@ -39,18 +37,8 @@
|
||||
# Avoid recompiling by hiding ninja with NINJA=":"
|
||||
- make NINJA=":" $MAKE_CHECK_ARGS
|
||||
|
||||
.native_test_job_template:
|
||||
extends: .common_test_job_template
|
||||
artifacts:
|
||||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
expire_in: 7 days
|
||||
paths:
|
||||
- build/meson-logs/testlog.txt
|
||||
reports:
|
||||
junit: build/meson-logs/testlog.junit.xml
|
||||
|
||||
.avocado_test_job_template:
|
||||
extends: .common_test_job_template
|
||||
extends: .native_test_job_template
|
||||
cache:
|
||||
key: "${CI_JOB_NAME}-cache"
|
||||
paths:
|
||||
@@ -79,5 +67,15 @@
|
||||
after_script:
|
||||
- cd build
|
||||
- du -chs ${CI_PROJECT_DIR}/avocado-cache
|
||||
variables:
|
||||
QEMU_JOB_AVOCADO: 1
|
||||
rules:
|
||||
# Only run these jobs if running on the mainstream namespace,
|
||||
# or if the user set the QEMU_CI_AVOCADO_TESTING variable (either
|
||||
# in its namespace setting or via git-push option, see documentation
|
||||
# in /.gitlab-ci.yml of this repository).
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project"'
|
||||
when: on_success
|
||||
- if: '$QEMU_CI_AVOCADO_TESTING'
|
||||
when: on_success
|
||||
# Otherwise, set to manual (the jobs are created but not run).
|
||||
- when: manual
|
||||
allow_failure: true
|
||||
|
||||
@@ -24,7 +24,7 @@ check-system-alpine:
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: alpine
|
||||
MAKE_CHECK_ARGS: check-unit check-qtest
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
avocado-system-alpine:
|
||||
extends: .avocado_test_job_template
|
||||
@@ -42,7 +42,6 @@ build-system-ubuntu:
|
||||
variables:
|
||||
IMAGE: ubuntu2004
|
||||
CONFIGURE_ARGS: --enable-docs --enable-fdt=system --enable-slirp=system
|
||||
--enable-capstone
|
||||
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu
|
||||
microblazeel-softmmu mips64el-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
@@ -101,18 +100,6 @@ avocado-system-debian:
|
||||
IMAGE: debian-amd64
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
|
||||
crash-test-debian:
|
||||
extends: .native_test_job_template
|
||||
needs:
|
||||
- job: build-system-debian
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: debian-amd64
|
||||
script:
|
||||
- cd build
|
||||
- make check-venv
|
||||
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-i386
|
||||
|
||||
build-system-fedora:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
@@ -120,7 +107,7 @@ build-system-fedora:
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
CONFIGURE_ARGS: --disable-gcrypt --enable-nettle --enable-docs
|
||||
--enable-fdt=system --enable-slirp=system --enable-capstone
|
||||
--enable-fdt=system --enable-slirp=system --enable-capstone=system
|
||||
TARGETS: tricore-softmmu microblaze-softmmu mips-softmmu
|
||||
xtensa-softmmu m68k-softmmu riscv32-softmmu ppc-softmmu sparc64-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
@@ -147,19 +134,6 @@ avocado-system-fedora:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
|
||||
crash-test-fedora:
|
||||
extends: .native_test_job_template
|
||||
needs:
|
||||
- job: build-system-fedora
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
script:
|
||||
- cd build
|
||||
- make check-venv
|
||||
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-ppc
|
||||
- tests/venv/bin/python3 scripts/device-crash-test -q ./qemu-system-riscv32
|
||||
|
||||
build-system-centos:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
@@ -167,8 +141,7 @@ build-system-centos:
|
||||
variables:
|
||||
IMAGE: centos8
|
||||
CONFIGURE_ARGS: --disable-nettle --enable-gcrypt --enable-fdt=system
|
||||
--enable-modules --enable-trace-backends=dtrace --enable-docs
|
||||
--enable-vfio-user-server
|
||||
--enable-modules --enable-trace-backends=dtrace
|
||||
TARGETS: ppc64-softmmu or1k-softmmu s390x-softmmu
|
||||
x86_64-softmmu rx-softmmu sh4-softmmu nios2-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
@@ -358,15 +331,17 @@ build-cfi-aarch64:
|
||||
--enable-safe-stack --enable-slirp=git
|
||||
TARGETS: aarch64-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
# FIXME: This job is often failing, likely due to out-of-memory problems in
|
||||
# the constrained containers of the shared runners. Thus this is marked as
|
||||
# skipped until the situation has been solved.
|
||||
QEMU_JOB_SKIPPED: 1
|
||||
timeout: 90m
|
||||
timeout: 70m
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- build
|
||||
rules:
|
||||
# FIXME: This job is often failing, likely due to out-of-memory problems in
|
||||
# the constrained containers of the shared runners. Thus this is marked as
|
||||
# manual until the situation has been solved.
|
||||
- when: manual
|
||||
allow_failure: true
|
||||
|
||||
check-cfi-aarch64:
|
||||
extends: .native_test_job_template
|
||||
@@ -398,15 +373,17 @@ build-cfi-ppc64-s390x:
|
||||
--enable-safe-stack --enable-slirp=git
|
||||
TARGETS: ppc64-softmmu s390x-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
# FIXME: This job is often failing, likely due to out-of-memory problems in
|
||||
# the constrained containers of the shared runners. Thus this is marked as
|
||||
# skipped until the situation has been solved.
|
||||
QEMU_JOB_SKIPPED: 1
|
||||
timeout: 80m
|
||||
timeout: 70m
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- build
|
||||
rules:
|
||||
# FIXME: This job is often failing, likely due to out-of-memory problems in
|
||||
# the constrained containers of the shared runners. Thus this is marked as
|
||||
# manual until the situation has been solved.
|
||||
- when: manual
|
||||
allow_failure: true
|
||||
|
||||
check-cfi-ppc64-s390x:
|
||||
extends: .native_test_job_template
|
||||
@@ -473,6 +450,33 @@ tsan-build:
|
||||
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
|
||||
MAKE_CHECK_ARGS: bench V=1
|
||||
|
||||
# These targets are on the way out
|
||||
build-deprecated:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
job: amd64-debian-user-cross-container
|
||||
variables:
|
||||
IMAGE: debian-all-test-cross
|
||||
CONFIGURE_ARGS: --disable-tools
|
||||
MAKE_CHECK_ARGS: build-tcg
|
||||
TARGETS: ppc64abi32-linux-user
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- build
|
||||
|
||||
# We split the check-tcg step as test failures are expected but we still
|
||||
# want to catch the build breaking.
|
||||
check-deprecated:
|
||||
extends: .native_test_job_template
|
||||
needs:
|
||||
- job: build-deprecated
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: debian-all-test-cross
|
||||
MAKE_CHECK_ARGS: check-tcg
|
||||
allow_failure: true
|
||||
|
||||
# gprof/gcov are GCC features
|
||||
build-gprof-gcov:
|
||||
extends: .native_build_job_template
|
||||
@@ -515,6 +519,8 @@ build-oss-fuzz:
|
||||
echo Testing ${fuzzer} ... ;
|
||||
"${fuzzer}" -runs=1 -seed=1 || exit 1 ;
|
||||
done
|
||||
# Unrelated to fuzzer: run some tests with -fsanitize=address
|
||||
- cd build-oss-fuzz && make check-qtest-i386 check-unit
|
||||
|
||||
build-tci:
|
||||
extends: .native_build_job_template
|
||||
@@ -578,7 +584,6 @@ build-without-default-features:
|
||||
MAKE_CHECK_ARGS: check-unit check-qtest SPEED=slow
|
||||
|
||||
build-libvhost-user:
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: $CI_REGISTRY_IMAGE/qemu/fedora:latest
|
||||
needs:
|
||||
@@ -595,13 +600,10 @@ build-tools-and-docs-debian:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
job: amd64-debian-container
|
||||
# when running on 'master' we use pre-existing container
|
||||
optional: true
|
||||
variables:
|
||||
IMAGE: debian-amd64
|
||||
MAKE_CHECK_ARGS: check-unit ctags TAGS cscope
|
||||
MAKE_CHECK_ARGS: check-unit check-softfloat ctags TAGS cscope
|
||||
CONFIGURE_ARGS: --disable-system --disable-user --enable-docs --enable-tools
|
||||
QEMU_JOB_PUBLISH: 1
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
@@ -621,7 +623,6 @@ build-tools-and-docs-debian:
|
||||
# that users can see the results of their commits, regardless
|
||||
# of what topic branch they're currently using
|
||||
pages:
|
||||
extends: .base_job_template
|
||||
image: $CI_REGISTRY_IMAGE/qemu/debian-amd64:latest
|
||||
stage: test
|
||||
needs:
|
||||
@@ -639,5 +640,10 @@ pages:
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
variables:
|
||||
QEMU_JOB_PUBLISH: 1
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||
when: on_success
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project"'
|
||||
when: never
|
||||
- if: '$CI_PROJECT_NAMESPACE != "qemu-project"'
|
||||
when: on_success
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
# special care, because we can't just override it at the GitLab CI job
|
||||
# definition level or we risk breaking it completely.
|
||||
.cirrus_build_job:
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:master
|
||||
needs: []
|
||||
@@ -41,8 +40,11 @@
|
||||
<.gitlab-ci.d/cirrus/build.yml >.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
|
||||
variables:
|
||||
QEMU_JOB_CIRRUS: 1
|
||||
rules:
|
||||
# Allow on 'staging' branch and 'stable-X.Y-staging' branches only
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH !~ /staging/'
|
||||
when: never
|
||||
- if: "$CIRRUS_GITHUB_REPO && $CIRRUS_API_TOKEN"
|
||||
|
||||
x64-freebsd-12-build:
|
||||
extends: .cirrus_build_job
|
||||
@@ -50,11 +52,14 @@ x64-freebsd-12-build:
|
||||
NAME: freebsd-12
|
||||
CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
|
||||
CIRRUS_VM_IMAGE_SELECTOR: image_family
|
||||
CIRRUS_VM_IMAGE_NAME: freebsd-12-3
|
||||
CIRRUS_VM_IMAGE_NAME: freebsd-12-2
|
||||
CIRRUS_VM_CPUS: 8
|
||||
CIRRUS_VM_RAM: 8G
|
||||
UPDATE_COMMAND: pkg update
|
||||
INSTALL_COMMAND: pkg install -y
|
||||
# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
|
||||
# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
|
||||
CONFIGURE_ARGS: --disable-gnutls
|
||||
TEST_TARGETS: check
|
||||
|
||||
x64-freebsd-13-build:
|
||||
@@ -84,40 +89,3 @@ x64-macos-11-base-build:
|
||||
PATH_EXTRA: /usr/local/opt/ccache/libexec:/usr/local/opt/gettext/bin
|
||||
PKG_CONFIG_PATH: /usr/local/opt/curl/lib/pkgconfig:/usr/local/opt/ncurses/lib/pkgconfig:/usr/local/opt/readline/lib/pkgconfig
|
||||
TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64
|
||||
|
||||
|
||||
# The following jobs run VM-based tests via KVM on a Linux-based Cirrus-CI job
|
||||
.cirrus_kvm_job:
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:master
|
||||
needs: []
|
||||
timeout: 80m
|
||||
script:
|
||||
- sed -e "s|[@]CI_REPOSITORY_URL@|$CI_REPOSITORY_URL|g"
|
||||
-e "s|[@]CI_COMMIT_REF_NAME@|$CI_COMMIT_REF_NAME|g"
|
||||
-e "s|[@]CI_COMMIT_SHA@|$CI_COMMIT_SHA|g"
|
||||
-e "s|[@]NAME@|$NAME|g"
|
||||
-e "s|[@]CONFIGURE_ARGS@|$CONFIGURE_ARGS|g"
|
||||
-e "s|[@]TEST_TARGETS@|$TEST_TARGETS|g"
|
||||
<.gitlab-ci.d/cirrus/kvm-build.yml >.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
|
||||
variables:
|
||||
QEMU_JOB_CIRRUS: 1
|
||||
QEMU_JOB_OPTIONAL: 1
|
||||
|
||||
|
||||
x86-netbsd:
|
||||
extends: .cirrus_kvm_job
|
||||
variables:
|
||||
NAME: netbsd
|
||||
CONFIGURE_ARGS: --target-list=x86_64-softmmu,ppc64-softmmu,aarch64-softmmu
|
||||
TEST_TARGETS: check
|
||||
|
||||
x86-openbsd:
|
||||
extends: .cirrus_kvm_job
|
||||
variables:
|
||||
NAME: openbsd
|
||||
CONFIGURE_ARGS: --target-list=i386-softmmu,riscv64-softmmu,mips64-softmmu
|
||||
TEST_TARGETS: check
|
||||
|
||||
@@ -32,6 +32,5 @@ build_task:
|
||||
- $MAKE -j$(sysctl -n hw.ncpu)
|
||||
- for TARGET in $TEST_TARGETS ;
|
||||
do
|
||||
$MAKE -j$(sysctl -n hw.ncpu) $TARGET V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
$MAKE -j$(sysctl -n hw.ncpu) $TARGET V=1 ;
|
||||
done
|
||||
|
||||
@@ -2,15 +2,12 @@
|
||||
#
|
||||
# $ lcitool variables freebsd-12 qemu
|
||||
#
|
||||
# https://gitlab.com/libvirt/libvirt-ci
|
||||
# https://gitlab.com/libvirt/libvirt-ci/-/commit/c7e275ab27ac0dcd09da290817b9adeea1fd1eb1
|
||||
|
||||
PACKAGING_COMMAND='pkg'
|
||||
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 bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
|
||||
PYPI_PKGS=''
|
||||
PYTHON='/usr/local/bin/python3'
|
||||
PIP3='/usr/local/bin/pip-3.8'
|
||||
PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage ctags curl cyrus-sasl dbus diffutils gettext git glib gmake gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh libtasn1 libxml2 llvm lttng-ust lzo2 meson ncurses nettle ninja opencv p5-Test-Harness perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
|
||||
|
||||
@@ -2,15 +2,12 @@
|
||||
#
|
||||
# $ lcitool variables freebsd-13 qemu
|
||||
#
|
||||
# https://gitlab.com/libvirt/libvirt-ci
|
||||
# https://gitlab.com/libvirt/libvirt-ci/-/commit/c7e275ab27ac0dcd09da290817b9adeea1fd1eb1
|
||||
|
||||
PACKAGING_COMMAND='pkg'
|
||||
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 bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
|
||||
PYPI_PKGS=''
|
||||
PYTHON='/usr/local/bin/python3'
|
||||
PIP3='/usr/local/bin/pip-3.8'
|
||||
PKGS='alsa-lib bash bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage ctags curl cyrus-sasl dbus diffutils gettext git glib gmake gnutls gsed gtk3 libepoxy libffi libgcrypt libjpeg-turbo libnfs libspice-server libssh libtasn1 libxml2 llvm lttng-ust lzo2 meson ncurses nettle ninja opencv p5-Test-Harness perl5 pixman pkgconf png py38-numpy py38-pillow py38-pip py38-sphinx py38-sphinx_rtd_theme py38-virtualenv py38-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd'
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
container:
|
||||
image: fedora:35
|
||||
cpu: 4
|
||||
memory: 8Gb
|
||||
kvm: true
|
||||
|
||||
env:
|
||||
CIRRUS_CLONE_DEPTH: 1
|
||||
CI_REPOSITORY_URL: "@CI_REPOSITORY_URL@"
|
||||
CI_COMMIT_REF_NAME: "@CI_COMMIT_REF_NAME@"
|
||||
CI_COMMIT_SHA: "@CI_COMMIT_SHA@"
|
||||
|
||||
@NAME@_task:
|
||||
@NAME@_vm_cache:
|
||||
folder: $HOME/.cache/qemu-vm
|
||||
install_script:
|
||||
- dnf update -y
|
||||
- dnf install -y git make openssh-clients qemu-img qemu-system-x86 wget
|
||||
clone_script:
|
||||
- git clone --depth 100 "$CI_REPOSITORY_URL" .
|
||||
- git fetch origin "$CI_COMMIT_REF_NAME"
|
||||
- git reset --hard "$CI_COMMIT_SHA"
|
||||
build_script:
|
||||
- if [ -f $HOME/.cache/qemu-vm/images/@NAME@.img ]; then
|
||||
make vm-build-@NAME@ J=$(getconf _NPROCESSORS_ONLN)
|
||||
EXTRA_CONFIGURE_OPTS="@CONFIGURE_ARGS@"
|
||||
BUILD_TARGET="@TEST_TARGETS@" ;
|
||||
else
|
||||
make vm-build-@NAME@ J=$(getconf _NPROCESSORS_ONLN) BUILD_TARGET=help
|
||||
EXTRA_CONFIGURE_OPTS="--disable-system --disable-user --disable-tools" ;
|
||||
fi
|
||||
@@ -2,15 +2,14 @@
|
||||
#
|
||||
# $ lcitool variables macos-11 qemu
|
||||
#
|
||||
# https://gitlab.com/libvirt/libvirt-ci
|
||||
# https://gitlab.com/libvirt/libvirt-ci/-/commit/c7e275ab27ac0dcd09da290817b9adeea1fd1eb1
|
||||
|
||||
PACKAGING_COMMAND='brew'
|
||||
CCACHE='/usr/local/bin/ccache'
|
||||
CPAN_PKGS=''
|
||||
CROSS_PKGS=''
|
||||
MAKE='/usr/local/bin/gmake'
|
||||
NINJA='/usr/local/bin/ninja'
|
||||
PACKAGING_COMMAND='brew'
|
||||
PIP3='/usr/local/bin/pip3'
|
||||
PKGS='bash bc bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson ncurses nettle ninja perl pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy sparse spice-protocol tesseract texinfo usbredir vde vte3 zlib zstd'
|
||||
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme'
|
||||
PYTHON='/usr/local/bin/python3'
|
||||
PIP3='/usr/local/bin/pip3'
|
||||
PKGS='bash bc bzip2 capstone ccache cpanminus ctags curl dbus diffutils gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb libxml2 llvm lzo make meson ncurses nettle ninja perl pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy sparse spice-protocol tesseract texinfo usbredir vde vte3 zlib zstd'
|
||||
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme virtualenv'
|
||||
CPAN_PKGS='Test::Harness'
|
||||
|
||||
@@ -1,52 +1,64 @@
|
||||
alpha-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-alpha-cross
|
||||
|
||||
amd64-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-amd64-cross
|
||||
|
||||
amd64-debian-user-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-all-test-cross
|
||||
|
||||
arm64-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-arm64-cross
|
||||
|
||||
arm64-test-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian11-container']
|
||||
variables:
|
||||
NAME: debian-arm64-test-cross
|
||||
|
||||
armel-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-armel-cross
|
||||
|
||||
armhf-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-armhf-cross
|
||||
|
||||
# We never want to build hexagon in the CI system and by default we
|
||||
# always want to refer to the master registry where it lives.
|
||||
hexagon-cross-container:
|
||||
extends: .base_job_template
|
||||
image: docker:stable
|
||||
stage: containers
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project"'
|
||||
when: never
|
||||
- when: always
|
||||
variables:
|
||||
NAME: debian-hexagon-cross
|
||||
GIT_DEPTH: 1
|
||||
QEMU_JOB_ONLY_FORKS: 1
|
||||
services:
|
||||
- docker:dind
|
||||
before_script:
|
||||
@@ -65,96 +77,92 @@ hexagon-cross-container:
|
||||
|
||||
hppa-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-hppa-cross
|
||||
|
||||
m68k-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-m68k-cross
|
||||
|
||||
mips64-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-mips64-cross
|
||||
|
||||
mips64el-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-mips64el-cross
|
||||
|
||||
mips-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-mips-cross
|
||||
|
||||
mipsel-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-mipsel-cross
|
||||
|
||||
powerpc-test-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian11-container']
|
||||
variables:
|
||||
NAME: debian-powerpc-test-cross
|
||||
|
||||
ppc64el-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-ppc64el-cross
|
||||
|
||||
riscv64-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
# as we are currently based on 'sid/unstable' we may break so...
|
||||
allow_failure: true
|
||||
variables:
|
||||
NAME: debian-riscv64-cross
|
||||
|
||||
# we can however build TCG tests using a non-sid base
|
||||
riscv64-debian-test-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
needs: ['amd64-debian11-container']
|
||||
variables:
|
||||
NAME: debian-riscv64-test-cross
|
||||
|
||||
s390x-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-s390x-cross
|
||||
|
||||
sh4-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-sh4-cross
|
||||
|
||||
sparc64-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-sparc64-cross
|
||||
|
||||
tricore-debian-cross-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-tricore-cross
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.container_job_template:
|
||||
extends: .base_job_template
|
||||
image: docker:stable
|
||||
stage: containers
|
||||
services:
|
||||
|
||||
@@ -14,15 +14,26 @@ amd64-debian11-container:
|
||||
|
||||
amd64-debian-container:
|
||||
extends: .container_job_template
|
||||
stage: containers
|
||||
stage: containers-layer2
|
||||
needs: ['amd64-debian10-container']
|
||||
variables:
|
||||
NAME: debian-amd64
|
||||
|
||||
amd64-ubuntu1804-container:
|
||||
extends: .container_job_template
|
||||
variables:
|
||||
NAME: ubuntu1804
|
||||
|
||||
amd64-ubuntu2004-container:
|
||||
extends: .container_job_template
|
||||
variables:
|
||||
NAME: ubuntu2004
|
||||
|
||||
amd64-ubuntu-container:
|
||||
extends: .container_job_template
|
||||
variables:
|
||||
NAME: ubuntu
|
||||
|
||||
amd64-opensuse-leap-container:
|
||||
extends: .container_job_template
|
||||
variables:
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.cross_system_build_job:
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
|
||||
timeout: 80m
|
||||
@@ -15,7 +14,7 @@
|
||||
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
|
||||
- if grep -q "EXESUF=.exe" config-host.mak;
|
||||
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]*)";
|
||||
mv -v qemu-setup*.exe qemu-setup-${version}.exe;
|
||||
fi
|
||||
|
||||
@@ -25,7 +24,6 @@
|
||||
# KVM), and set extra options (such disabling other accelerators) via the
|
||||
# $EXTRA_CONFIGURE_OPTS variable.
|
||||
.cross_accel_build_job:
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
|
||||
timeout: 30m
|
||||
@@ -38,7 +36,6 @@
|
||||
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
|
||||
|
||||
.cross_user_build_job:
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
|
||||
script:
|
||||
|
||||
@@ -62,8 +62,6 @@ cross-i386-user:
|
||||
cross-i386-tci:
|
||||
extends: .cross_accel_build_job
|
||||
timeout: 60m
|
||||
needs:
|
||||
job: i386-fedora-cross-container
|
||||
variables:
|
||||
IMAGE: fedora-i386-cross
|
||||
ACCEL: tcg-interpreter
|
||||
|
||||
@@ -14,7 +14,6 @@ variables:
|
||||
GIT_STRATEGY: clone
|
||||
|
||||
include:
|
||||
- local: '/.gitlab-ci.d/custom-runners/ubuntu-20.04-s390x.yml'
|
||||
- local: '/.gitlab-ci.d/custom-runners/ubuntu-18.04-s390x.yml'
|
||||
- local: '/.gitlab-ci.d/custom-runners/ubuntu-20.04-aarch64.yml'
|
||||
- local: '/.gitlab-ci.d/custom-runners/ubuntu-20.04-aarch32.yml'
|
||||
- local: '/.gitlab-ci.d/custom-runners/centos-stream-8-x86_64.yml'
|
||||
|
||||
@@ -23,8 +23,6 @@ centos-stream-8-x86_64:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../scripts/ci/org.centos/stream/8/x86_64/configure
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make -j"$JOBS"
|
||||
- make NINJA=":" check
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- ../scripts/ci/org.centos/stream/8/x86_64/test-avocado
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# All ubuntu-20.04 jobs should run successfully in an environment
|
||||
# All ubuntu-18.04 jobs should run successfully in an environment
|
||||
# setup by the scripts/ci/setup/build-environment.yml task
|
||||
# "Install basic packages to build QEMU on Ubuntu 20.04/20.04"
|
||||
# "Install basic packages to build QEMU on Ubuntu 18.04/20.04"
|
||||
|
||||
ubuntu-20.04-s390x-all-linux-static:
|
||||
ubuntu-18.04-s390x-all-linux-static:
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
- ubuntu_20.04
|
||||
- ubuntu_18.04
|
||||
- s390x
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/'
|
||||
@@ -17,20 +17,16 @@ ubuntu-20.04-s390x-all-linux-static:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --enable-debug --static --disable-system --disable-glusterfs --disable-libssh
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- make --output-sync -j`nproc` check-tcg V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-20.04-s390x-all:
|
||||
ubuntu-18.04-s390x-all:
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
- ubuntu_20.04
|
||||
- ubuntu_18.04
|
||||
- s390x
|
||||
timeout: 75m
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/'
|
||||
- if: "$S390X_RUNNER_AVAILABLE"
|
||||
@@ -38,16 +34,14 @@ ubuntu-20.04-s390x-all:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --disable-libssh
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-20.04-s390x-alldbg:
|
||||
ubuntu-18.04-s390x-alldbg:
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
- ubuntu_20.04
|
||||
- ubuntu_18.04
|
||||
- s390x
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/'
|
||||
@@ -60,17 +54,15 @@ ubuntu-20.04-s390x-alldbg:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --enable-debug --disable-libssh
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make clean
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-20.04-s390x-clang:
|
||||
ubuntu-18.04-s390x-clang:
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
- ubuntu_20.04
|
||||
- ubuntu_18.04
|
||||
- s390x
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/'
|
||||
@@ -83,16 +75,14 @@ ubuntu-20.04-s390x-clang:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --disable-libssh --cc=clang --cxx=clang++ --enable-sanitizers
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
|
||||
ubuntu-20.04-s390x-tci:
|
||||
ubuntu-18.04-s390x-tci:
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
- ubuntu_20.04
|
||||
- ubuntu_18.04
|
||||
- s390x
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/'
|
||||
@@ -105,14 +95,13 @@ ubuntu-20.04-s390x-tci:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --disable-libssh --enable-tcg-interpreter
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc`
|
||||
|
||||
ubuntu-20.04-s390x-notcg:
|
||||
ubuntu-18.04-s390x-notcg:
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
- ubuntu_20.04
|
||||
- ubuntu_18.04
|
||||
- s390x
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/'
|
||||
@@ -125,7 +114,5 @@ ubuntu-20.04-s390x-notcg:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --disable-libssh --disable-tcg
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
@@ -1,25 +0,0 @@
|
||||
# All ubuntu-20.04 jobs should run successfully in an environment
|
||||
# setup by the scripts/ci/setup/qemu/build-environment.yml task
|
||||
# "Install basic packages to build QEMU on Ubuntu 20.04"
|
||||
|
||||
ubuntu-20.04-aarch32-all:
|
||||
needs: []
|
||||
stage: build
|
||||
tags:
|
||||
- ubuntu_20.04
|
||||
- aarch32
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/'
|
||||
when: manual
|
||||
allow_failure: true
|
||||
- if: "$AARCH32_RUNNER_AVAILABLE"
|
||||
when: manual
|
||||
allow_failure: true
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --cross-prefix=arm-linux-gnueabihf-
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
@@ -1,6 +1,6 @@
|
||||
# All ubuntu-20.04 jobs should run successfully in an environment
|
||||
# setup by the scripts/ci/setup/qemu/build-environment.yml task
|
||||
# "Install basic packages to build QEMU on Ubuntu 20.04"
|
||||
# "Install basic packages to build QEMU on Ubuntu 18.04/20.04"
|
||||
|
||||
ubuntu-20.04-aarch64-all-linux-static:
|
||||
needs: []
|
||||
@@ -17,12 +17,9 @@ ubuntu-20.04-aarch64-all-linux-static:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --enable-debug --static --disable-system --disable-glusterfs --disable-libssh
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- make --output-sync -j`nproc --ignore=40` check-tcg V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
- make --output-sync -j`nproc` check-tcg V=1
|
||||
|
||||
ubuntu-20.04-aarch64-all:
|
||||
needs: []
|
||||
@@ -41,10 +38,8 @@ ubuntu-20.04-aarch64-all:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --disable-libssh
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
|
||||
ubuntu-20.04-aarch64-alldbg:
|
||||
needs: []
|
||||
@@ -59,11 +54,9 @@ ubuntu-20.04-aarch64-alldbg:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --enable-debug --disable-libssh
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make clean
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
|
||||
ubuntu-20.04-aarch64-clang:
|
||||
needs: []
|
||||
@@ -82,10 +75,8 @@ ubuntu-20.04-aarch64-clang:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --disable-libssh --cc=clang-10 --cxx=clang++-10 --enable-sanitizers
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
|
||||
ubuntu-20.04-aarch64-tci:
|
||||
needs: []
|
||||
@@ -104,8 +95,7 @@ ubuntu-20.04-aarch64-tci:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --disable-libssh --enable-tcg-interpreter
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc`
|
||||
|
||||
ubuntu-20.04-aarch64-notcg:
|
||||
needs: []
|
||||
@@ -124,7 +114,5 @@ ubuntu-20.04-aarch64-notcg:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../configure --disable-libssh --disable-tcg
|
||||
|| { cat config.log meson-logs/meson-log.txt; exit 1; }
|
||||
- make --output-sync -j`nproc --ignore=40`
|
||||
- make --output-sync -j`nproc --ignore=40` check V=1
|
||||
|| { cat meson-logs/testlog.txt; exit 1; } ;
|
||||
- make --output-sync -j`nproc`
|
||||
- make --output-sync -j`nproc` check V=1
|
||||
|
||||
@@ -1,85 +1,60 @@
|
||||
# All jobs needing docker-edk2 must use the same rules it uses.
|
||||
.edk2_job_rules:
|
||||
rules:
|
||||
# Forks don't get pipelines unless QEMU_CI=1 or QEMU_CI=2 is set
|
||||
- if: '$QEMU_CI != "1" && $QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != "qemu-project"'
|
||||
when: never
|
||||
|
||||
# In forks, if QEMU_CI=1 is set, then create manual job
|
||||
# if any of the files affecting the build are touched
|
||||
- if: '$QEMU_CI == "1" && $CI_PROJECT_NAMESPACE != "qemu-project"'
|
||||
changes:
|
||||
- .gitlab-ci.d/edk2.yml
|
||||
- .gitlab-ci.d/edk2/Dockerfile
|
||||
- roms/edk2/*
|
||||
when: manual
|
||||
|
||||
# In forks, if QEMU_CI=1 is set, then create manual job
|
||||
# if the branch/tag starts with 'edk2'
|
||||
- if: '$QEMU_CI == "1" && $CI_PROJECT_NAMESPACE != "qemu-project" && $CI_COMMIT_REF_NAME =~ /^edk2/'
|
||||
when: manual
|
||||
|
||||
# In forks, if QEMU_CI=1 is set, then create manual job
|
||||
# if last commit msg contains 'EDK2' (case insensitive)
|
||||
- if: '$QEMU_CI == "1" && $CI_PROJECT_NAMESPACE != "qemu-project" && $CI_COMMIT_MESSAGE =~ /edk2/i'
|
||||
when: manual
|
||||
|
||||
# Run if any files affecting the build output are touched
|
||||
- changes:
|
||||
- .gitlab-ci.d/edk2.yml
|
||||
- .gitlab-ci.d/edk2/Dockerfile
|
||||
- roms/edk2/*
|
||||
when: on_success
|
||||
|
||||
# Run if the branch/tag starts with 'edk2'
|
||||
- if: '$CI_COMMIT_REF_NAME =~ /^edk2/'
|
||||
when: on_success
|
||||
|
||||
# Run if last commit msg contains 'EDK2' (case insensitive)
|
||||
- if: '$CI_COMMIT_MESSAGE =~ /edk2/i'
|
||||
when: on_success
|
||||
rules: # Only run this job when ...
|
||||
- changes:
|
||||
# this file is modified
|
||||
- .gitlab-ci.d/edk2.yml
|
||||
# or the Dockerfile is modified
|
||||
- .gitlab-ci.d/edk2/Dockerfile
|
||||
# or roms/edk2/ is modified (submodule updated)
|
||||
- roms/edk2/*
|
||||
when: on_success
|
||||
- if: '$CI_COMMIT_REF_NAME =~ /^edk2/' # or the branch/tag starts with 'edk2'
|
||||
when: on_success
|
||||
- if: '$CI_COMMIT_MESSAGE =~ /edk2/i' # or last commit description contains 'EDK2'
|
||||
when: on_success
|
||||
|
||||
docker-edk2:
|
||||
extends: .edk2_job_rules
|
||||
stage: containers
|
||||
image: docker:19.03.1
|
||||
services:
|
||||
- docker:19.03.1-dind
|
||||
variables:
|
||||
GIT_DEPTH: 3
|
||||
IMAGE_TAG: $CI_REGISTRY_IMAGE:edk2-cross-build
|
||||
# We don't use TLS
|
||||
DOCKER_HOST: tcp://docker:2375
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
before_script:
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
script:
|
||||
- docker pull $IMAGE_TAG || true
|
||||
- docker build --cache-from $IMAGE_TAG --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
--tag $IMAGE_TAG .gitlab-ci.d/edk2
|
||||
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
- docker push $IMAGE_TAG
|
||||
extends: .edk2_job_rules
|
||||
stage: containers
|
||||
image: docker:19.03.1
|
||||
services:
|
||||
- docker:19.03.1-dind
|
||||
variables:
|
||||
GIT_DEPTH: 3
|
||||
IMAGE_TAG: $CI_REGISTRY_IMAGE:edk2-cross-build
|
||||
# We don't use TLS
|
||||
DOCKER_HOST: tcp://docker:2375
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
before_script:
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
script:
|
||||
- docker pull $IMAGE_TAG || true
|
||||
- docker build --cache-from $IMAGE_TAG --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
--tag $IMAGE_TAG .gitlab-ci.d/edk2
|
||||
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
- docker push $IMAGE_TAG
|
||||
|
||||
build-edk2:
|
||||
extends: .edk2_job_rules
|
||||
stage: build
|
||||
needs: ['docker-edk2']
|
||||
artifacts:
|
||||
paths: # 'artifacts.zip' will contains the following files:
|
||||
- pc-bios/edk2*bz2
|
||||
- pc-bios/edk2-licenses.txt
|
||||
- edk2-stdout.log
|
||||
- edk2-stderr.log
|
||||
image: $CI_REGISTRY_IMAGE:edk2-cross-build
|
||||
variables:
|
||||
GIT_DEPTH: 3
|
||||
script: # Clone the required submodules and build EDK2
|
||||
- git submodule update --init roms/edk2
|
||||
- git -C roms/edk2 submodule update --init --
|
||||
ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
|
||||
BaseTools/Source/C/BrotliCompress/brotli
|
||||
CryptoPkg/Library/OpensslLib/openssl
|
||||
MdeModulePkg/Library/BrotliCustomDecompressLib/brotli
|
||||
- export JOBS=$(($(getconf _NPROCESSORS_ONLN) + 1))
|
||||
- echo "=== Using ${JOBS} simultaneous jobs ==="
|
||||
- make -j${JOBS} -C roms efi 2>&1 1>edk2-stdout.log | tee -a edk2-stderr.log >&2
|
||||
extends: .edk2_job_rules
|
||||
stage: build
|
||||
needs: ['docker-edk2']
|
||||
artifacts:
|
||||
paths: # 'artifacts.zip' will contains the following files:
|
||||
- pc-bios/edk2*bz2
|
||||
- pc-bios/edk2-licenses.txt
|
||||
- edk2-stdout.log
|
||||
- edk2-stderr.log
|
||||
image: $CI_REGISTRY_IMAGE:edk2-cross-build
|
||||
variables:
|
||||
GIT_DEPTH: 3
|
||||
script: # Clone the required submodules and build EDK2
|
||||
- git submodule update --init roms/edk2
|
||||
- git -C roms/edk2 submodule update --init --
|
||||
ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
|
||||
BaseTools/Source/C/BrotliCompress/brotli
|
||||
CryptoPkg/Library/OpensslLib/openssl
|
||||
MdeModulePkg/Library/BrotliCustomDecompressLib/brotli
|
||||
- export JOBS=$(($(getconf _NPROCESSORS_ONLN) + 1))
|
||||
- echo "=== Using ${JOBS} simultaneous jobs ==="
|
||||
- make -j${JOBS} -C roms efi 2>&1 1>edk2-stdout.log | tee -a edk2-stderr.log >&2
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#
|
||||
# Docker image to cross-compile EDK2 firmware binaries
|
||||
#
|
||||
FROM ubuntu:18.04
|
||||
FROM ubuntu:16.04
|
||||
|
||||
MAINTAINER Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
MAINTAINER Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
|
||||
# Install packages required to build EDK2
|
||||
RUN apt update \
|
||||
@@ -20,7 +20,7 @@ RUN apt update \
|
||||
iasl \
|
||||
make \
|
||||
nasm \
|
||||
python3 \
|
||||
python \
|
||||
uuid-dev \
|
||||
&& \
|
||||
\
|
||||
|
||||
@@ -1,85 +1,63 @@
|
||||
# All jobs needing docker-opensbi must use the same rules it uses.
|
||||
.opensbi_job_rules:
|
||||
rules:
|
||||
# Forks don't get pipelines unless QEMU_CI=1 or QEMU_CI=2 is set
|
||||
- if: '$QEMU_CI != "1" && $QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != "qemu-project"'
|
||||
when: never
|
||||
|
||||
# In forks, if QEMU_CI=1 is set, then create manual job
|
||||
# if any files affecting the build output are touched
|
||||
- if: '$QEMU_CI == "1" && $CI_PROJECT_NAMESPACE != "qemu-project"'
|
||||
changes:
|
||||
- .gitlab-ci.d/opensbi.yml
|
||||
- .gitlab-ci.d/opensbi/Dockerfile
|
||||
- roms/opensbi/*
|
||||
when: manual
|
||||
|
||||
# In forks, if QEMU_CI=1 is set, then create manual job
|
||||
# if the branch/tag starts with 'opensbi'
|
||||
- if: '$QEMU_CI == "1" && $CI_PROJECT_NAMESPACE != "qemu-project" && $CI_COMMIT_REF_NAME =~ /^opensbi/'
|
||||
when: manual
|
||||
|
||||
# In forks, if QEMU_CI=1 is set, then create manual job
|
||||
# if the last commit msg contains 'OpenSBI' (case insensitive)
|
||||
- if: '$QEMU_CI == "1" && $CI_PROJECT_NAMESPACE != "qemu-project" && $CI_COMMIT_MESSAGE =~ /opensbi/i'
|
||||
when: manual
|
||||
|
||||
# Run if any files affecting the build output are touched
|
||||
- changes:
|
||||
- .gitlab-ci.d/opensbi.yml
|
||||
- .gitlab-ci.d/opensbi/Dockerfile
|
||||
- roms/opensbi/*
|
||||
when: on_success
|
||||
|
||||
# Run if the branch/tag starts with 'opensbi'
|
||||
- if: '$CI_COMMIT_REF_NAME =~ /^opensbi/'
|
||||
when: on_success
|
||||
|
||||
# Run if the last commit msg contains 'OpenSBI' (case insensitive)
|
||||
- if: '$CI_COMMIT_MESSAGE =~ /opensbi/i'
|
||||
when: on_success
|
||||
rules: # Only run this job when ...
|
||||
- changes:
|
||||
# this file is modified
|
||||
- .gitlab-ci.d/opensbi.yml
|
||||
# or the Dockerfile is modified
|
||||
- .gitlab-ci.d/opensbi/Dockerfile
|
||||
when: on_success
|
||||
- changes: # or roms/opensbi/ is modified (submodule updated)
|
||||
- roms/opensbi/*
|
||||
when: on_success
|
||||
- if: '$CI_COMMIT_REF_NAME =~ /^opensbi/' # or the branch/tag starts with 'opensbi'
|
||||
when: on_success
|
||||
- if: '$CI_COMMIT_MESSAGE =~ /opensbi/i' # or last commit description contains 'OpenSBI'
|
||||
when: on_success
|
||||
|
||||
docker-opensbi:
|
||||
extends: .opensbi_job_rules
|
||||
stage: containers
|
||||
image: docker:19.03.1
|
||||
services:
|
||||
- docker:19.03.1-dind
|
||||
variables:
|
||||
GIT_DEPTH: 3
|
||||
IMAGE_TAG: $CI_REGISTRY_IMAGE:opensbi-cross-build
|
||||
# We don't use TLS
|
||||
DOCKER_HOST: tcp://docker:2375
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
before_script:
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
script:
|
||||
- docker pull $IMAGE_TAG || true
|
||||
- docker build --cache-from $IMAGE_TAG --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
--tag $IMAGE_TAG .gitlab-ci.d/opensbi
|
||||
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
- docker push $IMAGE_TAG
|
||||
extends: .opensbi_job_rules
|
||||
stage: containers
|
||||
image: docker:19.03.1
|
||||
services:
|
||||
- docker:19.03.1-dind
|
||||
variables:
|
||||
GIT_DEPTH: 3
|
||||
IMAGE_TAG: $CI_REGISTRY_IMAGE:opensbi-cross-build
|
||||
# We don't use TLS
|
||||
DOCKER_HOST: tcp://docker:2375
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
before_script:
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
script:
|
||||
- docker pull $IMAGE_TAG || true
|
||||
- docker build --cache-from $IMAGE_TAG --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
--tag $IMAGE_TAG .gitlab-ci.d/opensbi
|
||||
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
- docker push $IMAGE_TAG
|
||||
|
||||
build-opensbi:
|
||||
extends: .opensbi_job_rules
|
||||
stage: build
|
||||
needs: ['docker-opensbi']
|
||||
artifacts:
|
||||
paths: # 'artifacts.zip' will contains the following files:
|
||||
- pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
|
||||
- pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
|
||||
- opensbi32-generic-stdout.log
|
||||
- opensbi32-generic-stderr.log
|
||||
- opensbi64-generic-stdout.log
|
||||
- opensbi64-generic-stderr.log
|
||||
image: $CI_REGISTRY_IMAGE:opensbi-cross-build
|
||||
variables:
|
||||
GIT_DEPTH: 3
|
||||
script: # Clone the required submodules and build OpenSBI
|
||||
- git submodule update --init roms/opensbi
|
||||
- export JOBS=$(($(getconf _NPROCESSORS_ONLN) + 1))
|
||||
- echo "=== Using ${JOBS} simultaneous jobs ==="
|
||||
- make -j${JOBS} -C roms/opensbi clean
|
||||
- make -j${JOBS} -C roms opensbi32-generic 2>&1 1>opensbi32-generic-stdout.log | tee -a opensbi32-generic-stderr.log >&2
|
||||
- make -j${JOBS} -C roms/opensbi clean
|
||||
- make -j${JOBS} -C roms opensbi64-generic 2>&1 1>opensbi64-generic-stdout.log | tee -a opensbi64-generic-stderr.log >&2
|
||||
extends: .opensbi_job_rules
|
||||
stage: build
|
||||
needs: ['docker-opensbi']
|
||||
artifacts:
|
||||
paths: # 'artifacts.zip' will contains the following files:
|
||||
- pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
|
||||
- pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
|
||||
- pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
|
||||
- pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
|
||||
- opensbi32-generic-stdout.log
|
||||
- opensbi32-generic-stderr.log
|
||||
- opensbi64-generic-stdout.log
|
||||
- opensbi64-generic-stderr.log
|
||||
image: $CI_REGISTRY_IMAGE:opensbi-cross-build
|
||||
variables:
|
||||
GIT_DEPTH: 3
|
||||
script: # Clone the required submodules and build OpenSBI
|
||||
- git submodule update --init roms/opensbi
|
||||
- export JOBS=$(($(getconf _NPROCESSORS_ONLN) + 1))
|
||||
- echo "=== Using ${JOBS} simultaneous jobs ==="
|
||||
- make -j${JOBS} -C roms/opensbi clean
|
||||
- make -j${JOBS} -C roms opensbi32-generic 2>&1 1>opensbi32-generic-stdout.log | tee -a opensbi32-generic-stderr.log >&2
|
||||
- make -j${JOBS} -C roms/opensbi clean
|
||||
- make -j${JOBS} -C roms opensbi64-generic 2>&1 1>opensbi64-generic-stdout.log | tee -a opensbi64-generic-stderr.log >&2
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# https://gitlab.com/qemu-project/qemu/-/pipelines
|
||||
|
||||
include:
|
||||
- local: '/.gitlab-ci.d/base.yml'
|
||||
- local: '/.gitlab-ci.d/stages.yml'
|
||||
- local: '/.gitlab-ci.d/edk2.yml'
|
||||
- local: '/.gitlab-ci.d/opensbi.yml'
|
||||
@@ -12,4 +11,3 @@ include:
|
||||
- local: '/.gitlab-ci.d/static_checks.yml'
|
||||
- local: '/.gitlab-ci.d/custom-runners.yml'
|
||||
- local: '/.gitlab-ci.d/cirrus.yml'
|
||||
- local: '/.gitlab-ci.d/windows.yml'
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
# - test (for test stages, using build artefacts from a build stage)
|
||||
stages:
|
||||
- containers
|
||||
- containers-layer2
|
||||
- build
|
||||
- test
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
check-patch:
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: python:3.10-alpine
|
||||
needs: []
|
||||
image: $CI_REGISTRY_IMAGE/qemu/centos8:latest
|
||||
needs:
|
||||
job: amd64-centos8-container
|
||||
script:
|
||||
- .gitlab-ci.d/check-patch.py
|
||||
variables:
|
||||
GIT_DEPTH: 1000
|
||||
QEMU_JOB_ONLY_FORKS: 1
|
||||
before_script:
|
||||
- apk -U add git perl
|
||||
allow_failure: true
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project"'
|
||||
when: never
|
||||
- when: on_success
|
||||
allow_failure: true
|
||||
|
||||
check-dco:
|
||||
extends: .base_job_template
|
||||
stage: build
|
||||
image: python:3.10-alpine
|
||||
needs: []
|
||||
image: $CI_REGISTRY_IMAGE/qemu/centos8:latest
|
||||
needs:
|
||||
job: amd64-centos8-container
|
||||
script: .gitlab-ci.d/check-dco.py
|
||||
variables:
|
||||
GIT_DEPTH: 1000
|
||||
before_script:
|
||||
- apk -U add git
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||
when: never
|
||||
- when: on_success
|
||||
|
||||
check-python-pipenv:
|
||||
extends: .base_job_template
|
||||
stage: test
|
||||
image: $CI_REGISTRY_IMAGE/qemu/python:latest
|
||||
script:
|
||||
@@ -35,7 +37,6 @@ check-python-pipenv:
|
||||
job: python-container
|
||||
|
||||
check-python-tox:
|
||||
extends: .base_job_template
|
||||
stage: test
|
||||
image: $CI_REGISTRY_IMAGE/qemu/python:latest
|
||||
script:
|
||||
@@ -43,6 +44,6 @@ check-python-tox:
|
||||
variables:
|
||||
GIT_DEPTH: 1
|
||||
QEMU_TOX_EXTRA_ARGS: --skip-missing-interpreters=false
|
||||
QEMU_JOB_OPTIONAL: 1
|
||||
needs:
|
||||
job: python-container
|
||||
allow_failure: true
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
.shared_msys2_builder:
|
||||
extends: .base_job_template
|
||||
tags:
|
||||
- shared-windows
|
||||
- windows
|
||||
- windows-1809
|
||||
cache:
|
||||
key: "${CI_JOB_NAME}-cache"
|
||||
paths:
|
||||
- ${CI_PROJECT_DIR}/msys64/var/cache
|
||||
needs: []
|
||||
stage: build
|
||||
timeout: 70m
|
||||
before_script:
|
||||
- If ( !(Test-Path -Path msys64\var\cache ) ) {
|
||||
mkdir msys64\var\cache
|
||||
}
|
||||
- If ( !(Test-Path -Path msys64\var\cache\msys2.exe ) ) {
|
||||
Invoke-WebRequest
|
||||
"https://github.com/msys2/msys2-installer/releases/download/2022-06-03/msys2-base-x86_64-20220603.sfx.exe"
|
||||
-outfile "msys64\var\cache\msys2.exe"
|
||||
}
|
||||
- msys64\var\cache\msys2.exe -y
|
||||
- ((Get-Content -path .\msys64\etc\\post-install\\07-pacman-key.post -Raw)
|
||||
-replace '--refresh-keys', '--version') |
|
||||
Set-Content -Path ${CI_PROJECT_DIR}\msys64\etc\\post-install\\07-pacman-key.post
|
||||
- .\msys64\usr\bin\bash -lc "sed -i 's/^CheckSpace/#CheckSpace/g' /etc/pacman.conf"
|
||||
- .\msys64\usr\bin\bash -lc 'pacman --noconfirm -Syuu' # Core update
|
||||
- .\msys64\usr\bin\bash -lc 'pacman --noconfirm -Syuu' # Normal update
|
||||
- taskkill /F /FI "MODULES eq msys-2.0.dll"
|
||||
|
||||
msys2-64bit:
|
||||
extends: .shared_msys2_builder
|
||||
script:
|
||||
- .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed
|
||||
diffutils git grep make sed
|
||||
mingw-w64-x86_64-capstone
|
||||
mingw-w64-x86_64-curl
|
||||
mingw-w64-x86_64-cyrus-sasl
|
||||
mingw-w64-x86_64-gcc
|
||||
mingw-w64-x86_64-glib2
|
||||
mingw-w64-x86_64-gnutls
|
||||
mingw-w64-x86_64-libnfs
|
||||
mingw-w64-x86_64-libpng
|
||||
mingw-w64-x86_64-libssh
|
||||
mingw-w64-x86_64-libtasn1
|
||||
mingw-w64-x86_64-libusb
|
||||
mingw-w64-x86_64-nettle
|
||||
mingw-w64-x86_64-ninja
|
||||
mingw-w64-x86_64-pixman
|
||||
mingw-w64-x86_64-pkgconf
|
||||
mingw-w64-x86_64-python
|
||||
mingw-w64-x86_64-SDL2
|
||||
mingw-w64-x86_64-SDL2_image
|
||||
mingw-w64-x86_64-snappy
|
||||
mingw-w64-x86_64-usbredir
|
||||
mingw-w64-x86_64-zstd "
|
||||
- $env:CHERE_INVOKING = 'yes' # Preserve the current working directory
|
||||
- $env:MSYSTEM = 'MINGW64' # Start a 64 bit Mingw environment
|
||||
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
|
||||
- .\msys64\usr\bin\bash -lc './configure --target-list=x86_64-softmmu
|
||||
--enable-capstone --without-default-devices'
|
||||
- .\msys64\usr\bin\bash -lc "sed -i '/^ROMS=/d' build/config-host.mak"
|
||||
- .\msys64\usr\bin\bash -lc 'make -j2'
|
||||
- .\msys64\usr\bin\bash -lc 'make check'
|
||||
|
||||
msys2-32bit:
|
||||
extends: .shared_msys2_builder
|
||||
script:
|
||||
- .\msys64\usr\bin\bash -lc "pacman -Sy --noconfirm --needed
|
||||
diffutils git grep make sed
|
||||
mingw-w64-i686-capstone
|
||||
mingw-w64-i686-curl
|
||||
mingw-w64-i686-cyrus-sasl
|
||||
mingw-w64-i686-gcc
|
||||
mingw-w64-i686-glib2
|
||||
mingw-w64-i686-gnutls
|
||||
mingw-w64-i686-gtk3
|
||||
mingw-w64-i686-libgcrypt
|
||||
mingw-w64-i686-libjpeg-turbo
|
||||
mingw-w64-i686-libssh
|
||||
mingw-w64-i686-libtasn1
|
||||
mingw-w64-i686-libusb
|
||||
mingw-w64-i686-lzo2
|
||||
mingw-w64-i686-ninja
|
||||
mingw-w64-i686-pixman
|
||||
mingw-w64-i686-pkgconf
|
||||
mingw-w64-i686-python
|
||||
mingw-w64-i686-snappy
|
||||
mingw-w64-i686-usbredir "
|
||||
- $env:CHERE_INVOKING = 'yes' # Preserve the current working directory
|
||||
- $env:MSYSTEM = 'MINGW32' # Start a 32-bit MinG environment
|
||||
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
|
||||
- mkdir output
|
||||
- cd output
|
||||
- ..\msys64\usr\bin\bash -lc "../configure --target-list=ppc64-softmmu"
|
||||
- ..\msys64\usr\bin\bash -lc 'make -j2'
|
||||
- ..\msys64\usr\bin\bash -lc 'make check'
|
||||
23
.gitmodules
vendored
23
.gitmodules
vendored
@@ -1,12 +1,12 @@
|
||||
[submodule "roms/seabios"]
|
||||
path = roms/seabios
|
||||
url = https://gitlab.suse.de/virtualization/qemu-seabios.git
|
||||
url = https://gitlab.com/qemu-project/seabios.git/
|
||||
[submodule "roms/SLOF"]
|
||||
path = roms/SLOF
|
||||
url = https://gitlab.com/qemu-project/SLOF.git
|
||||
[submodule "roms/ipxe"]
|
||||
path = roms/ipxe
|
||||
url = https://gitlab.suse.de/virtualization/qemu-ipxe.git
|
||||
url = https://gitlab.com/qemu-project/ipxe.git
|
||||
[submodule "roms/openbios"]
|
||||
path = roms/openbios
|
||||
url = https://gitlab.com/qemu-project/openbios.git
|
||||
@@ -15,7 +15,7 @@
|
||||
url = https://gitlab.com/qemu-project/qemu-palcode.git
|
||||
[submodule "roms/sgabios"]
|
||||
path = roms/sgabios
|
||||
url = https://gitlab.suse.de/virtualization/qemu-sgabios.git
|
||||
url = https://gitlab.com/qemu-project/sgabios.git
|
||||
[submodule "dtc"]
|
||||
path = dtc
|
||||
url = https://gitlab.com/qemu-project/dtc.git
|
||||
@@ -24,13 +24,16 @@
|
||||
url = https://gitlab.com/qemu-project/u-boot.git
|
||||
[submodule "roms/skiboot"]
|
||||
path = roms/skiboot
|
||||
url = https://gitlab.suse.de/virtualization/qemu-skiboot.git
|
||||
url = https://gitlab.com/qemu-project/skiboot.git
|
||||
[submodule "roms/QemuMacDrivers"]
|
||||
path = roms/QemuMacDrivers
|
||||
url = https://gitlab.com/qemu-project/QemuMacDrivers.git
|
||||
[submodule "ui/keycodemapdb"]
|
||||
path = ui/keycodemapdb
|
||||
url = https://gitlab.com/qemu-project/keycodemapdb.git
|
||||
[submodule "capstone"]
|
||||
path = capstone
|
||||
url = https://gitlab.com/qemu-project/capstone.git
|
||||
[submodule "roms/seabios-hppa"]
|
||||
path = roms/seabios-hppa
|
||||
url = https://gitlab.com/qemu-project/seabios-hppa.git
|
||||
@@ -45,25 +48,19 @@
|
||||
url = https://gitlab.com/qemu-project/berkeley-softfloat-3.git
|
||||
[submodule "roms/edk2"]
|
||||
path = roms/edk2
|
||||
url = https://gitlab.suse.de/virtualization/qemu-edk2.git
|
||||
url = https://gitlab.com/qemu-project/edk2.git
|
||||
[submodule "slirp"]
|
||||
path = slirp
|
||||
url = https://gitlab.com/qemu-project/libslirp.git
|
||||
[submodule "roms/opensbi"]
|
||||
path = roms/opensbi
|
||||
url = https://gitlab.suse.de/virtualization/qemu-opensbi.git
|
||||
url = https://gitlab.com/qemu-project/opensbi.git
|
||||
[submodule "roms/qboot"]
|
||||
path = roms/qboot
|
||||
url = https://gitlab.suse.de/virtualization/qemu-qboot.git
|
||||
url = https://gitlab.com/qemu-project/qboot.git
|
||||
[submodule "meson"]
|
||||
path = meson
|
||||
url = https://gitlab.com/qemu-project/meson.git
|
||||
[submodule "roms/vbootrom"]
|
||||
path = roms/vbootrom
|
||||
url = https://gitlab.com/qemu-project/vbootrom.git
|
||||
[submodule "tests/lcitool/libvirt-ci"]
|
||||
path = tests/lcitool/libvirt-ci
|
||||
url = https://gitlab.com/libvirt/libvirt-ci.git
|
||||
[submodule "subprojects/libvfio-user"]
|
||||
path = subprojects/libvfio-user
|
||||
url = https://gitlab.com/qemu-project/libvfio-user.git
|
||||
|
||||
14
.mailmap
14
.mailmap
@@ -28,11 +28,7 @@ Thiemo Seufer <ths@networkno.de> ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
|
||||
malc <av1474@comtv.ru> malc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>
|
||||
|
||||
# Corrupted Author fields
|
||||
Aaron Larson <alarson@ddci.com> alarson@ddci.com
|
||||
Andreas Färber <andreas.faerber@web.de> Andreas Färber <andreas.faerber>
|
||||
Jason Wang <jasowang@redhat.com> Jason Wang <jasowang>
|
||||
Marek Dolata <mkdolata@us.ibm.com> mkdolata@us.ibm.com <mkdolata@us.ibm.com>
|
||||
Michael Ellerman <mpe@ellerman.id.au> michael@ozlabs.org <michael@ozlabs.org>
|
||||
Nick Hudson <hnick@vmware.com> hnick@vmware.com <hnick@vmware.com>
|
||||
|
||||
# There is also a:
|
||||
@@ -54,29 +50,24 @@ Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> <arikalo@wavecomp.com>
|
||||
Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> <aleksandar.rikalo@rt-rk.com>
|
||||
Alexander Graf <agraf@csgraf.de> <agraf@suse.de>
|
||||
Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com>
|
||||
Christian Borntraeger <borntraeger@linux.ibm.com> <borntraeger@de.ibm.com>
|
||||
Filip Bozuta <filip.bozuta@syrmia.com> <filip.bozuta@rt-rk.com.com>
|
||||
Frederic Konrad <konrad.frederic@yahoo.fr> <fred.konrad@greensocs.com>
|
||||
Frederic Konrad <konrad.frederic@yahoo.fr> <konrad@adacore.com>
|
||||
Frederic Konrad <konrad@adacore.com> <fred.konrad@greensocs.com>
|
||||
Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
|
||||
Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
|
||||
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
|
||||
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
|
||||
Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
|
||||
Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
|
||||
Leif Lindholm <leif@nuviainc.com> <leif.lindholm@linaro.org>
|
||||
Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org>
|
||||
Paul Burton <paulburton@kernel.org> <paul.burton@mips.com>
|
||||
Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com>
|
||||
Paul Burton <paulburton@kernel.org> <paul@archlinuxmips.org>
|
||||
Paul Burton <paulburton@kernel.org> <pburton@wavecomp.com>
|
||||
Philippe Mathieu-Daudé <f4bug@amsat.org> <philmd@redhat.com>
|
||||
Stefan Brankovic <stefan.brankovic@syrmia.com> <stefan.brankovic@rt-rk.com.com>
|
||||
Yongbok Kim <yongbok.kim@mips.com> <yongbok.kim@imgtec.com>
|
||||
|
||||
# Also list preferred name forms where people have changed their
|
||||
# git author config, or had utf8/latin1 encoding issues.
|
||||
Aaron Lindsay <aaron@os.amperecomputing.com>
|
||||
Aaron Larson <alarson@ddci.com>
|
||||
Alexey Gerasimenko <x1917x@gmail.com>
|
||||
Alex Chen <alex.chen@huawei.com>
|
||||
Alex Ivanov <void@aleksoft.net>
|
||||
@@ -151,7 +142,6 @@ Pan Nengyuan <pannengyuan@huawei.com>
|
||||
Pavel Dovgaluk <dovgaluk@ispras.ru>
|
||||
Pavel Dovgaluk <pavel.dovgaluk@gmail.com>
|
||||
Pavel Dovgaluk <Pavel.Dovgaluk@ispras.ru>
|
||||
Peter Chubb <peter.chubb@nicta.com.au>
|
||||
Peter Crosthwaite <crosthwaite.peter@gmail.com>
|
||||
Peter Crosthwaite <peter.crosthwaite@petalogix.com>
|
||||
Peter Crosthwaite <peter.crosthwaite@xilinx.com>
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
pr_15sp5_workflow:
|
||||
steps:
|
||||
- branch_package:
|
||||
source_project: Devel:Virt:SLE-15-SP5:Staging
|
||||
source_package: qemu
|
||||
target_project: Devel:Virt:SLE-15-SP5:Staging:PRs
|
||||
filters:
|
||||
event: pull_request
|
||||
branches:
|
||||
only:
|
||||
- v7.1.0-sle15sp5
|
||||
rebuild_15sp5_workflow:
|
||||
steps:
|
||||
# Will automatically rebuild the package
|
||||
- trigger_services:
|
||||
project: Devel:Virt:SLE-15-SP5:Staging
|
||||
package: qemu
|
||||
filters:
|
||||
event: push
|
||||
branches:
|
||||
only:
|
||||
- v7.1.0-sle15sp4
|
||||
14
.travis.yml
14
.travis.yml
@@ -1,3 +1,6 @@
|
||||
# The current Travis default is a VM based 16.04 Xenial on GCE
|
||||
# Additional builds with specific requirements for a full VM need to
|
||||
# be added as additional matrix: entries later on
|
||||
os: linux
|
||||
dist: focal
|
||||
language: c
|
||||
@@ -187,7 +190,7 @@ jobs:
|
||||
|
||||
- name: "[s390x] GCC check-tcg"
|
||||
arch: s390x
|
||||
dist: focal
|
||||
dist: bionic
|
||||
addons:
|
||||
apt_packages:
|
||||
- libaio-dev
|
||||
@@ -222,7 +225,7 @@ jobs:
|
||||
- BUILD_RC=0 && make -j${JOBS} || BUILD_RC=$?
|
||||
- |
|
||||
if [ "$BUILD_RC" -eq 0 ] ; then
|
||||
mv pc-bios/s390-ccw/*.img qemu-bundle/usr/local/share/qemu ;
|
||||
mv pc-bios/s390-ccw/*.img pc-bios/ ;
|
||||
${TEST_CMD} ;
|
||||
else
|
||||
$(exit $BUILD_RC);
|
||||
@@ -230,7 +233,7 @@ jobs:
|
||||
|
||||
- name: "[s390x] GCC (other-softmmu)"
|
||||
arch: s390x
|
||||
dist: focal
|
||||
dist: bionic
|
||||
addons:
|
||||
apt_packages:
|
||||
- libaio-dev
|
||||
@@ -260,11 +263,10 @@ jobs:
|
||||
|
||||
- name: "[s390x] GCC (user)"
|
||||
arch: s390x
|
||||
dist: focal
|
||||
dist: bionic
|
||||
addons:
|
||||
apt_packages:
|
||||
- libgcrypt20-dev
|
||||
- libglib2.0-dev
|
||||
- libgnutls28-dev
|
||||
- ninja-build
|
||||
env:
|
||||
@@ -272,7 +274,7 @@ jobs:
|
||||
|
||||
- name: "[s390x] Clang (disable-tcg)"
|
||||
arch: s390x
|
||||
dist: focal
|
||||
dist: bionic
|
||||
compiler: clang
|
||||
addons:
|
||||
apt_packages:
|
||||
|
||||
@@ -22,12 +22,15 @@ config TPM
|
||||
|
||||
config VHOST_USER
|
||||
bool
|
||||
select VHOST
|
||||
|
||||
config VHOST_VDPA
|
||||
bool
|
||||
select VHOST
|
||||
|
||||
config VHOST_KERNEL
|
||||
bool
|
||||
select VHOST
|
||||
|
||||
config VIRTFS
|
||||
bool
|
||||
@@ -42,7 +45,3 @@ config MULTIPROCESS_ALLOWED
|
||||
config FUZZ
|
||||
bool
|
||||
select SPARSE_MEM
|
||||
|
||||
config VFIO_USER_SERVER_ALLOWED
|
||||
bool
|
||||
imply VFIO_USER_SERVER
|
||||
|
||||
371
MAINTAINERS
371
MAINTAINERS
@@ -165,6 +165,9 @@ F: tests/qtest/arm-cpu-features.c
|
||||
F: hw/arm/
|
||||
F: hw/cpu/a*mpcore.c
|
||||
F: include/hw/cpu/a*mpcore.h
|
||||
F: disas/arm.c
|
||||
F: disas/arm-a64.cc
|
||||
F: disas/libvixl/
|
||||
F: docs/system/target-arm.rst
|
||||
F: docs/system/arm/cpu-features.rst
|
||||
|
||||
@@ -210,13 +213,6 @@ S: Maintained
|
||||
F: target/hppa/
|
||||
F: disas/hppa.c
|
||||
|
||||
LoongArch TCG CPUs
|
||||
M: Song Gao <gaosong@loongson.cn>
|
||||
M: Xiaojuan Yang <yangxiaojuan@loongson.cn>
|
||||
S: Maintained
|
||||
F: target/loongarch/
|
||||
F: tests/tcg/loongarch64/
|
||||
|
||||
M68K TCG CPUs
|
||||
M: Laurent Vivier <laurent@vivier.eu>
|
||||
S: Maintained
|
||||
@@ -244,8 +240,7 @@ F: docs/system/cpu-models-mips.rst.inc
|
||||
F: tests/tcg/mips/
|
||||
|
||||
MIPS TCG CPUs (nanoMIPS ISA)
|
||||
M: Stefan Pejic <stefan.pejic@syrmia.com>
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: disas/nanomips.*
|
||||
F: target/mips/tcg/*nanomips*
|
||||
|
||||
@@ -277,6 +272,7 @@ F: target/ppc/
|
||||
F: hw/ppc/ppc.c
|
||||
F: hw/ppc/ppc_booke.c
|
||||
F: include/hw/ppc/ppc.h
|
||||
F: disas/ppc.c
|
||||
|
||||
RISC-V TCG CPUs
|
||||
M: Palmer Dabbelt <palmer@dabbelt.com>
|
||||
@@ -290,13 +286,6 @@ F: include/hw/riscv/
|
||||
F: linux-user/host/riscv32/
|
||||
F: linux-user/host/riscv64/
|
||||
|
||||
RISC-V XVentanaCondOps extension
|
||||
M: Philipp Tomsich <philipp.tomsich@vrull.eu>
|
||||
L: qemu-riscv@nongnu.org
|
||||
S: Supported
|
||||
F: target/riscv/XVentanaCondOps.decode
|
||||
F: target/riscv/insn_trans/trans_xventanacondops.c.inc
|
||||
|
||||
RENESAS RX CPUs
|
||||
R: Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
S: Orphan
|
||||
@@ -308,7 +297,9 @@ M: David Hildenbrand <david@redhat.com>
|
||||
S: Maintained
|
||||
F: target/s390x/
|
||||
F: target/s390x/tcg
|
||||
F: target/s390x/cpu_models_*.[ch]
|
||||
F: hw/s390x/
|
||||
F: disas/s390.c
|
||||
F: tests/tcg/s390x/
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
@@ -339,6 +330,7 @@ F: target/i386/tcg/
|
||||
F: tests/tcg/i386/
|
||||
F: tests/tcg/x86_64/
|
||||
F: hw/i386/
|
||||
F: disas/i386.c
|
||||
F: docs/system/cpu-models-x86*
|
||||
T: git https://gitlab.com/ehabkost/qemu.git x86-next
|
||||
|
||||
@@ -401,13 +393,19 @@ F: target/ppc/kvm.c
|
||||
|
||||
S390 KVM CPUs
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
S: Supported
|
||||
F: target/s390x/kvm/
|
||||
F: target/s390x/ioinst.[ch]
|
||||
F: target/s390x/machine.c
|
||||
F: target/s390x/sigp.c
|
||||
F: target/s390x/cpu_features*.[ch]
|
||||
F: target/s390x/cpu_models.[ch]
|
||||
F: hw/s390x/pv.c
|
||||
F: include/hw/s390x/pv.h
|
||||
F: hw/intc/s390_flic.c
|
||||
F: hw/intc/s390_flic_kvm.c
|
||||
F: include/hw/s390x/s390_flic.h
|
||||
F: gdb-xml/s390*.xml
|
||||
T: git https://github.com/borntraeger/qemu.git s390-next
|
||||
L: qemu-s390x@nongnu.org
|
||||
@@ -417,7 +415,7 @@ M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
M: Marcelo Tosatti <mtosatti@redhat.com>
|
||||
L: kvm@vger.kernel.org
|
||||
S: Supported
|
||||
F: docs/system/i386/amd-memory-encryption.rst
|
||||
F: docs/amd-memory-encryption.txt
|
||||
F: docs/system/i386/sgx.rst
|
||||
F: target/i386/kvm/
|
||||
F: target/i386/sev*
|
||||
@@ -494,6 +492,7 @@ Guest CPU Cores (HAXM)
|
||||
---------------------
|
||||
X86 HAXM CPUs
|
||||
M: Wenchao Wang <wenchao.wang@intel.com>
|
||||
M: Colin Xu <colin.xu@intel.com>
|
||||
L: haxm-team@intel.com
|
||||
W: https://github.com/intel/haxm/issues
|
||||
S: Maintained
|
||||
@@ -549,12 +548,6 @@ F: include/*/*win32*
|
||||
X: qga/*win32*
|
||||
F: qemu.nsi
|
||||
|
||||
Darwin (macOS, iOS)
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
S: Odd Fixes
|
||||
F: .gitlab-ci.d/cirrus/macos-*
|
||||
F: */*.m
|
||||
|
||||
Alpha Machines
|
||||
--------------
|
||||
M: Richard Henderson <richard.henderson@linaro.org>
|
||||
@@ -649,7 +642,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/*/exynos*
|
||||
F: include/hw/*/exynos*
|
||||
F: include/hw/arm/exynos4210.h
|
||||
|
||||
Calxeda Highbank
|
||||
M: Rob Herring <robh@kernel.org>
|
||||
@@ -788,8 +781,6 @@ M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/arm/musicpal.c
|
||||
F: hw/net/mv88w8618_eth.c
|
||||
F: include/hw/net/mv88w8618_eth.h
|
||||
F: docs/system/arm/musicpal.rst
|
||||
|
||||
Nuvoton NPCM7xx
|
||||
@@ -832,6 +823,7 @@ F: docs/system/arm/palm.rst
|
||||
|
||||
Raspberry Pi
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Andrew Baumann <Andrew.Baumann@microsoft.com>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Odd Fixes
|
||||
@@ -891,7 +883,7 @@ F: include/hw/ssi/imx_spi.h
|
||||
SBSA-REF
|
||||
M: Radoslaw Biernacki <rad@semihalf.com>
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Leif Lindholm <quic_llindhol@quicinc.com>
|
||||
R: Leif Lindholm <leif@nuviainc.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/sbsa-ref.c
|
||||
@@ -943,7 +935,6 @@ S: Maintained
|
||||
F: hw/arm/virt*
|
||||
F: include/hw/arm/virt.h
|
||||
F: docs/system/arm/virt.rst
|
||||
F: tests/avocado/machine_aarch64_virt.py
|
||||
|
||||
Xilinx Zynq
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
@@ -972,12 +963,6 @@ F: hw/display/dpcd.c
|
||||
F: include/hw/display/dpcd.h
|
||||
F: docs/system/arm/xlnx-versal-virt.rst
|
||||
|
||||
Xilinx Versal OSPI
|
||||
M: Francisco Iglesias <francisco.iglesias@xilinx.com>
|
||||
S: Maintained
|
||||
F: hw/ssi/xlnx-versal-ospi.c
|
||||
F: include/hw/ssi/xlnx-versal-ospi.h
|
||||
|
||||
ARM ACPI Subsystem
|
||||
M: Shannon Zhao <shannon.zhaosl@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
@@ -1065,7 +1050,6 @@ F: hw/net/ftgmac100.c
|
||||
F: include/hw/net/ftgmac100.h
|
||||
F: docs/system/arm/aspeed.rst
|
||||
F: tests/qtest/*aspeed*
|
||||
F: hw/arm/fby35.c
|
||||
|
||||
NRF51
|
||||
M: Joel Stanley <joel@jms.id.au>
|
||||
@@ -1116,30 +1100,9 @@ S: Odd Fixes
|
||||
F: configs/devices/hppa-softmmu/default.mak
|
||||
F: hw/hppa/
|
||||
F: hw/net/*i82596*
|
||||
F: hw/misc/lasi.c
|
||||
F: hw/pci-host/dino.c
|
||||
F: include/hw/misc/lasi.h
|
||||
F: include/hw/net/lasi_82596.h
|
||||
F: include/hw/pci-host/dino.h
|
||||
F: pc-bios/hppa-firmware.img
|
||||
|
||||
LoongArch Machines
|
||||
------------------
|
||||
Virt
|
||||
M: Xiaojuan Yang <yangxiaojuan@loongson.cn>
|
||||
M: Song Gao <gaosong@loongson.cn>
|
||||
S: Maintained
|
||||
F: docs/system/loongarch/virt.rst
|
||||
F: configs/targets/loongarch64-softmmu.mak
|
||||
F: configs/devices/loongarch64-softmmu/default.mak
|
||||
F: hw/loongarch/
|
||||
F: include/hw/loongarch/virt.h
|
||||
F: include/hw/intc/loongarch_*.h
|
||||
F: hw/intc/loongarch_*.c
|
||||
F: include/hw/pci-host/ls7a.h
|
||||
F: hw/rtc/ls7a_rtc.c
|
||||
F: gdb-xml/loongarch*.xml
|
||||
|
||||
M68K Machines
|
||||
-------------
|
||||
an5206
|
||||
@@ -1282,7 +1245,7 @@ F: hw/openrisc/openrisc_sim.c
|
||||
|
||||
PowerPC Machines
|
||||
----------------
|
||||
405 (ref405ep and taihu)
|
||||
405
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Orphan
|
||||
F: hw/ppc/ppc405_boards.c
|
||||
@@ -1318,7 +1281,6 @@ New World (mac99)
|
||||
M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: docs/system/ppc/powermac.rst
|
||||
F: hw/ppc/mac_newworld.c
|
||||
F: hw/pci-host/uninorth.c
|
||||
F: hw/pci-bridge/dec.[hc]
|
||||
@@ -1337,7 +1299,6 @@ Old World (g3beige)
|
||||
M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: docs/system/ppc/powermac.rst
|
||||
F: hw/ppc/mac_oldworld.c
|
||||
F: hw/pci-host/grackle.c
|
||||
F: hw/misc/macio/
|
||||
@@ -1351,7 +1312,6 @@ PReP
|
||||
M: Hervé Poussineau <hpoussin@reactos.org>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Maintained
|
||||
F: docs/system/ppc/prep.rst
|
||||
F: hw/ppc/prep.c
|
||||
F: hw/ppc/prep_systemio.c
|
||||
F: hw/ppc/rs6000_mc.c
|
||||
@@ -1364,7 +1324,7 @@ F: include/hw/isa/pc87312.h
|
||||
F: include/hw/rtc/m48t59.h
|
||||
F: tests/avocado/ppc_prep_40p.py
|
||||
|
||||
sPAPR (pseries)
|
||||
sPAPR
|
||||
M: Cédric Le Goater <clg@kaod.org>
|
||||
M: Daniel Henrique Barboza <danielhb413@gmail.com>
|
||||
R: David Gibson <david@gibson.dropbear.id.au>
|
||||
@@ -1376,8 +1336,8 @@ F: include/hw/*/spapr*
|
||||
F: hw/*/xics*
|
||||
F: include/hw/*/xics*
|
||||
F: pc-bios/slof.bin
|
||||
F: docs/system/ppc/pseries.rst
|
||||
F: docs/specs/ppc-spapr-*
|
||||
F: docs/specs/ppc-spapr-hcalls.txt
|
||||
F: docs/specs/ppc-spapr-hotplug.txt
|
||||
F: tests/qtest/spapr*
|
||||
F: tests/qtest/libqos/*spapr*
|
||||
F: tests/qtest/rtas*
|
||||
@@ -1388,7 +1348,6 @@ PowerNV (Non-Virtualized)
|
||||
M: Cédric Le Goater <clg@kaod.org>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Maintained
|
||||
F: docs/system/ppc/powernv.rst
|
||||
F: hw/ppc/pnv*
|
||||
F: hw/intc/pnv*
|
||||
F: hw/intc/xics_pnv.c
|
||||
@@ -1557,7 +1516,7 @@ F: include/hw/rtc/sun4v-rtc.h
|
||||
|
||||
Leon3
|
||||
M: Fabien Chouteau <chouteau@adacore.com>
|
||||
M: Frederic Konrad <konrad.frederic@yahoo.fr>
|
||||
M: KONRAD Frederic <frederic.konrad@adacore.com>
|
||||
S: Maintained
|
||||
F: hw/sparc/leon3.c
|
||||
F: hw/*/grlib*
|
||||
@@ -1568,18 +1527,21 @@ S390 Machines
|
||||
-------------
|
||||
S390 Virtio-ccw
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
M: Eric Farman <farman@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
S: Supported
|
||||
F: hw/char/sclp*.[hc]
|
||||
F: hw/char/terminal3270.c
|
||||
F: hw/s390x/
|
||||
F: include/hw/s390x/
|
||||
F: hw/watchdog/wdt_diag288.c
|
||||
F: include/hw/watchdog/wdt_diag288.h
|
||||
F: configs/devices/s390x-softmmu/default.mak
|
||||
F: tests/avocado/machine_s390_ccw_virtio.py
|
||||
T: git https://github.com/borntraeger/qemu.git s390-next
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
S390-ccw boot
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
M: Thomas Huth <thuth@redhat.com>
|
||||
S: Supported
|
||||
F: hw/s390x/ipl.*
|
||||
@@ -1597,38 +1559,6 @@ F: hw/s390x/s390-pci*
|
||||
F: include/hw/s390x/s390-pci*
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
S390 channel subsystem
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
M: Eric Farman <farman@linux.ibm.com>
|
||||
S: Supported
|
||||
F: hw/s390x/ccw-device.[ch]
|
||||
F: hw/s390x/css.c
|
||||
F: hw/s390x/css-bridge.c
|
||||
F: include/hw/s390x/css.h
|
||||
F: include/hw/s390x/css-bridge.h
|
||||
F: include/hw/s390x/ioinst.h
|
||||
F: target/s390x/ioinst.c
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
S390 CPU models
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
S: Maintained
|
||||
F: target/s390x/cpu_features*.[ch]
|
||||
F: target/s390x/cpu_models.[ch]
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
S390 SCLP-backed devices
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
S: Supported
|
||||
F: include/hw/s390x/event-facility.h
|
||||
F: include/hw/s390x/sclp.h
|
||||
F: hw/char/sclp*.[hc]
|
||||
F: hw/s390x/event-facility.c
|
||||
F: hw/s390x/sclp*.c
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
X86 Machines
|
||||
------------
|
||||
PC
|
||||
@@ -1700,8 +1630,7 @@ F: pc-bios/bios-microvm.bin
|
||||
Machine core
|
||||
M: Eduardo Habkost <eduardo@habkost.net>
|
||||
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
R: Yanan Wang <wangyanan55@huawei.com>
|
||||
R: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
S: Supported
|
||||
F: cpu.c
|
||||
F: hw/core/cpu.c
|
||||
@@ -1800,12 +1729,6 @@ F: include/hw/block/fdc.h
|
||||
F: tests/qtest/fdc-test.c
|
||||
T: git https://gitlab.com/jsnow/qemu.git ide
|
||||
|
||||
Hyper-V VMBus
|
||||
M: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
|
||||
S: Odd Fixes
|
||||
F: hw/hyperv/vmbus.c
|
||||
F: include/hw/hyperv/vmbus*.h
|
||||
|
||||
OMAP
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
L: qemu-arm@nongnu.org
|
||||
@@ -1839,6 +1762,7 @@ R: Ani Sinha <ani@anisinha.ca>
|
||||
S: Supported
|
||||
F: include/hw/acpi/*
|
||||
F: include/hw/firmware/smbios.h
|
||||
F: hw/mem/*
|
||||
F: hw/acpi/*
|
||||
F: hw/smbios/*
|
||||
F: hw/i386/acpi-build.[hc]
|
||||
@@ -1849,16 +1773,9 @@ F: tests/qtest/acpi-utils.[hc]
|
||||
F: tests/data/acpi/
|
||||
F: docs/specs/acpi_cpu_hotplug.rst
|
||||
F: docs/specs/acpi_mem_hotplug.rst
|
||||
F: docs/specs/acpi_nvdimm.rst
|
||||
F: docs/specs/acpi_pci_hotplug.rst
|
||||
F: docs/specs/acpi_hw_reduced_hotplug.rst
|
||||
|
||||
ACPI/VIOT
|
||||
M: Jean-Philippe Brucker <jean-philippe@linaro.org>
|
||||
S: Supported
|
||||
F: hw/acpi/viot.c
|
||||
F: hw/acpi/viot.h
|
||||
|
||||
ACPI/HEST/GHES
|
||||
R: Dongjiu Geng <gengdongjiu1@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
@@ -1893,7 +1810,7 @@ F: docs/virtio-net-failover.rst
|
||||
T: git https://github.com/jasowang/qemu.git net
|
||||
|
||||
Parallel NOR Flash devices
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
M: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
T: git https://gitlab.com/philmd/qemu.git pflash-next
|
||||
S: Maintained
|
||||
F: hw/block/pflash_cfi*.c
|
||||
@@ -1908,7 +1825,6 @@ F: hw/scsi/*
|
||||
F: tests/qtest/virtio-scsi-test.c
|
||||
F: tests/qtest/fuzz-virtio-scsi-test.c
|
||||
F: tests/qtest/am53c974-test.c
|
||||
F: tests/qtest/fuzz-lsi53c895a-test.c
|
||||
T: git https://github.com/bonzini/qemu.git scsi-next
|
||||
|
||||
SSI
|
||||
@@ -2007,7 +1923,6 @@ virtio-balloon
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
S: Maintained
|
||||
F: docs/interop/virtio-balloon-stats.rst
|
||||
F: hw/virtio/virtio-balloon*.c
|
||||
F: include/hw/virtio/virtio-balloon.h
|
||||
F: softmmu/balloon.c
|
||||
@@ -2038,10 +1953,9 @@ T: git https://github.com/stefanha/qemu.git block
|
||||
virtio-ccw
|
||||
M: Cornelia Huck <cohuck@redhat.com>
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Eric Farman <farman@linux.ibm.com>
|
||||
S: Supported
|
||||
F: hw/s390x/virtio-ccw*.[hc]
|
||||
F: hw/s390x/vhost-*-ccw.c
|
||||
F: hw/s390x/vhost-vsock-ccw.c
|
||||
T: git https://gitlab.com/cohuck/qemu.git s390-next
|
||||
T: git https://github.com/borntraeger/qemu.git s390-next
|
||||
L: qemu-s390x@nongnu.org
|
||||
@@ -2157,6 +2071,15 @@ F: qapi/rocker.json
|
||||
F: tests/rocker/
|
||||
F: docs/specs/rocker.txt
|
||||
|
||||
NVDIMM
|
||||
M: Xiao Guangrong <xiaoguangrong.eric@gmail.com>
|
||||
S: Maintained
|
||||
F: hw/acpi/nvdimm.c
|
||||
F: hw/mem/nvdimm.c
|
||||
F: include/hw/mem/nvdimm.h
|
||||
F: docs/nvdimm.txt
|
||||
F: docs/specs/acpi_nvdimm.rst
|
||||
|
||||
e1000x
|
||||
M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
|
||||
S: Maintained
|
||||
@@ -2189,7 +2112,6 @@ Generic Loader
|
||||
M: Alistair Francis <alistair@alistair23.me>
|
||||
S: Maintained
|
||||
F: hw/core/generic-loader.c
|
||||
F: hw/core/uboot_image.h
|
||||
F: include/hw/core/generic-loader.h
|
||||
F: docs/system/generic-loader.rst
|
||||
|
||||
@@ -2215,7 +2137,6 @@ F: tests/qtest/prom-env-test.c
|
||||
|
||||
VM Generation ID
|
||||
S: Orphan
|
||||
R: Ani Sinha <ani@anisinha.ca>
|
||||
F: hw/acpi/vmgenid.c
|
||||
F: include/hw/acpi/vmgenid.h
|
||||
F: docs/specs/vmgenid.txt
|
||||
@@ -2231,7 +2152,6 @@ F: hw/misc/led.c
|
||||
Unimplemented device
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
R: Ani Sinha <ani@anisinha.ca>
|
||||
S: Maintained
|
||||
F: include/hw/misc/unimp.h
|
||||
F: hw/misc/unimp.c
|
||||
@@ -2239,7 +2159,6 @@ F: hw/misc/unimp.c
|
||||
Empty slot
|
||||
M: Artyom Tarasenko <atar4qemu@gmail.com>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
R: Ani Sinha <ani@anisinha.ca>
|
||||
S: Maintained
|
||||
F: include/hw/misc/empty_slot.h
|
||||
F: hw/misc/empty_slot.c
|
||||
@@ -2306,7 +2225,7 @@ F: hw/isa/piix4.c
|
||||
F: include/hw/southbridge/piix.h
|
||||
|
||||
Firmware configuration (fw_cfg)
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
M: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
R: Gerd Hoffmann <kraxel@redhat.com>
|
||||
S: Supported
|
||||
F: docs/specs/fw_cfg.txt
|
||||
@@ -2375,56 +2294,6 @@ F: hw/timer/mips_gictimer.c
|
||||
F: include/hw/intc/mips_gic.h
|
||||
F: include/hw/timer/mips_gictimer.h
|
||||
|
||||
S390 3270 device
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
S: Odd fixes
|
||||
F: include/hw/s390x/3270-ccw.h
|
||||
F: hw/char/terminal3270.c
|
||||
F: hw/s390x/3270-ccw.c
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
S390 diag 288 watchdog
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
S: Supported
|
||||
F: hw/watchdog/wdt_diag288.c
|
||||
F: include/hw/watchdog/wdt_diag288.h
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
S390 storage key device
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
S: Supported
|
||||
F: hw/s390x/storage-keys.h
|
||||
F: hw/390x/s390-skeys*.c
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
S390 storage attribute device
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
S: Supported
|
||||
F: hw/s390x/storage-attributes.h
|
||||
F: hw/s390/s390-stattrib*.c
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
S390 floating interrupt controller
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
S: Supported
|
||||
F: hw/intc/s390_flic*.c
|
||||
F: include/hw/s390x/s390_flic.h
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
CanoKey
|
||||
M: Hongren (Zenithal) Zheng <i@zenithal.me>
|
||||
S: Maintained
|
||||
R: Canokeys.org <contact@canokeys.org>
|
||||
F: hw/usb/canokey.c
|
||||
F: hw/usb/canokey.h
|
||||
F: docs/system/devices/canokey.rst
|
||||
|
||||
Subsystems
|
||||
----------
|
||||
Overall Audio backends
|
||||
@@ -2449,9 +2318,7 @@ F: audio/alsaaudio.c
|
||||
|
||||
Core Audio framework backend
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
R: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
R: Akihiko Odaki <akihiko.odaki@gmail.com>
|
||||
S: Odd Fixes
|
||||
F: audio/coreaudio.c
|
||||
|
||||
@@ -2536,7 +2403,7 @@ F: scsi/*
|
||||
|
||||
Block Jobs
|
||||
M: John Snow <jsnow@redhat.com>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: blockjob.c
|
||||
@@ -2550,18 +2417,15 @@ F: block/stream.c
|
||||
F: block/mirror.c
|
||||
F: qapi/job.json
|
||||
F: block/block-copy.c
|
||||
F: include/block/block-copy.h
|
||||
F: block/reqlist.c
|
||||
F: include/block/reqlist.h
|
||||
F: include/block/block-copy.c
|
||||
F: block/copy-before-write.h
|
||||
F: block/copy-before-write.c
|
||||
F: block/snapshot-access.c
|
||||
F: include/block/aio_task.h
|
||||
F: block/aio_task.c
|
||||
F: util/qemu-co-shared-resource.c
|
||||
F: include/qemu/co-shared-resource.h
|
||||
T: git https://gitlab.com/jsnow/qemu.git jobs
|
||||
T: git https://gitlab.com/vsementsov/qemu.git block
|
||||
T: git https://src.openvz.org/scm/~vsementsov/qemu.git jobs
|
||||
|
||||
Block QAPI, monitor, command line
|
||||
M: Markus Armbruster <armbru@redhat.com>
|
||||
@@ -2573,17 +2437,9 @@ F: qapi/block*.json
|
||||
F: qapi/transaction.json
|
||||
T: git https://repo.or.cz/qemu/armbru.git block-next
|
||||
|
||||
Compute Express Link
|
||||
M: Ben Widawsky <ben.widawsky@intel.com>
|
||||
M: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
S: Supported
|
||||
F: hw/cxl/
|
||||
F: hw/mem/cxl_type3.c
|
||||
F: include/hw/cxl/
|
||||
|
||||
Dirty Bitmaps
|
||||
M: Eric Blake <eblake@redhat.com>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
R: John Snow <jsnow@redhat.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
@@ -2597,7 +2453,6 @@ F: util/hbitmap.c
|
||||
F: tests/unit/test-hbitmap.c
|
||||
F: docs/interop/bitmaps.rst
|
||||
T: git https://repo.or.cz/qemu/ericb.git bitmaps
|
||||
T: git https://gitlab.com/vsementsov/qemu.git block
|
||||
|
||||
Character device backends
|
||||
M: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
@@ -2668,7 +2523,7 @@ F: scripts/coccinelle/errp-guard.cocci
|
||||
|
||||
GDB stub
|
||||
M: Alex Bennée <alex.bennee@linaro.org>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
R: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
S: Maintained
|
||||
F: gdbstub*
|
||||
F: include/exec/gdbstub.h
|
||||
@@ -2679,7 +2534,7 @@ Memory API
|
||||
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
M: Peter Xu <peterx@redhat.com>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
R: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
S: Supported
|
||||
F: include/exec/ioport.h
|
||||
F: include/exec/memop.h
|
||||
@@ -2695,19 +2550,6 @@ F: softmmu/physmem.c
|
||||
F: include/exec/memory-internal.h
|
||||
F: scripts/coccinelle/memory-region-housekeeping.cocci
|
||||
|
||||
Memory devices
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
M: Igor Mammedov <imammedo@redhat.com>
|
||||
R: Xiao Guangrong <xiaoguangrong.eric@gmail.com>
|
||||
S: Supported
|
||||
F: hw/mem/memory-device.c
|
||||
F: hw/mem/nvdimm.c
|
||||
F: hw/mem/pc-dimm.c
|
||||
F: include/hw/mem/memory-device.h
|
||||
F: include/hw/mem/nvdimm.h
|
||||
F: include/hw/mem/pc-dimm.h
|
||||
F: docs/nvdimm.txt
|
||||
|
||||
SPICE
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
S: Odd Fixes
|
||||
@@ -2729,8 +2571,6 @@ F: util/drm.c
|
||||
|
||||
Cocoa graphics
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
R: Akihiko Odaki <akihiko.odaki@gmail.com>
|
||||
S: Odd Fixes
|
||||
F: ui/cocoa.m
|
||||
|
||||
@@ -2750,7 +2590,6 @@ F: softmmu/cpu-throttle.c
|
||||
F: softmmu/cpu-timers.c
|
||||
F: softmmu/icount.c
|
||||
F: softmmu/runstate-action.c
|
||||
F: softmmu/runstate.c
|
||||
F: qapi/run-state.json
|
||||
|
||||
Read, Copy, Update (RCU)
|
||||
@@ -2809,30 +2648,29 @@ F: backends/cryptodev*.c
|
||||
Python library
|
||||
M: John Snow <jsnow@redhat.com>
|
||||
M: Cleber Rosa <crosa@redhat.com>
|
||||
R: Beraldo Leal <bleal@redhat.com>
|
||||
R: Eduardo Habkost <eduardo@habkost.net>
|
||||
S: Maintained
|
||||
F: python/
|
||||
T: git https://gitlab.com/jsnow/qemu.git python
|
||||
|
||||
Python scripts
|
||||
M: John Snow <jsnow@redhat.com>
|
||||
M: Eduardo Habkost <eduardo@habkost.net>
|
||||
M: Cleber Rosa <crosa@redhat.com>
|
||||
S: Odd Fixes
|
||||
F: scripts/*.py
|
||||
F: tests/*.py
|
||||
|
||||
Benchmark util
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
S: Maintained
|
||||
F: scripts/simplebench/
|
||||
T: git https://gitlab.com/vsementsov/qemu.git simplebench
|
||||
T: git https://src.openvz.org/scm/~vsementsov/qemu.git simplebench
|
||||
|
||||
Transactions helper
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
S: Maintained
|
||||
F: include/qemu/transactions.h
|
||||
F: util/transactions.c
|
||||
T: git https://gitlab.com/vsementsov/qemu.git block
|
||||
|
||||
QAPI
|
||||
M: Markus Armbruster <armbru@redhat.com>
|
||||
@@ -2881,7 +2719,6 @@ T: git https://repo.or.cz/qemu/armbru.git qapi-next
|
||||
|
||||
QEMU Guest Agent
|
||||
M: Michael Roth <michael.roth@amd.com>
|
||||
M: Konstantin Kostiuk <kkostiuk@redhat.com>
|
||||
S: Maintained
|
||||
F: qga/
|
||||
F: docs/interop/qemu-ga.rst
|
||||
@@ -2890,14 +2727,6 @@ F: scripts/qemu-guest-agent/
|
||||
F: tests/unit/test-qga.c
|
||||
T: git https://github.com/mdroth/qemu.git qga
|
||||
|
||||
QEMU Guest Agent Win32
|
||||
M: Konstantin Kostiuk <kkostiuk@redhat.com>
|
||||
S: Maintained
|
||||
F: qga/*win32*
|
||||
F: qga/vss-win32/
|
||||
F: qga/installer/
|
||||
T: git https://github.com/kostyanf14/qemu.git qga-win32
|
||||
|
||||
QOM
|
||||
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
R: Daniel P. Berrange <berrange@redhat.com>
|
||||
@@ -3043,22 +2872,17 @@ D-Bus
|
||||
M: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
S: Maintained
|
||||
F: backends/dbus-vmstate.c
|
||||
F: ui/dbus*
|
||||
F: audio/dbus*
|
||||
F: tests/dbus-vmstate*
|
||||
F: util/dbus.c
|
||||
F: include/ui/dbus*
|
||||
F: include/qemu/dbus.h
|
||||
F: docs/interop/dbus*
|
||||
F: docs/sphinx/dbus*
|
||||
F: docs/sphinx/fakedbusdoc.py
|
||||
F: tests/qtest/dbus*
|
||||
F: docs/interop/dbus.rst
|
||||
F: docs/interop/dbus-vmstate.rst
|
||||
|
||||
Seccomp
|
||||
M: Daniel P. Berrange <berrange@redhat.com>
|
||||
S: Odd Fixes
|
||||
M: Eduardo Otubo <otubo@redhat.com>
|
||||
S: Supported
|
||||
F: softmmu/qemu-seccomp.c
|
||||
F: include/sysemu/seccomp.h
|
||||
F: tests/unit/test-seccomp.c
|
||||
|
||||
Cryptography
|
||||
M: Daniel P. Berrange <berrange@redhat.com>
|
||||
@@ -3143,7 +2967,7 @@ F: include/qemu/yank.h
|
||||
F: qapi/yank.json
|
||||
|
||||
COLO Framework
|
||||
M: Hailiang Zhang <zhanghailiang@xfusion.com>
|
||||
M: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
||||
S: Maintained
|
||||
F: migration/colo*
|
||||
F: include/migration/colo.h
|
||||
@@ -3152,13 +2976,12 @@ F: docs/COLO-FT.txt
|
||||
|
||||
COLO Proxy
|
||||
M: Zhang Chen <chen.zhang@intel.com>
|
||||
M: Li Zhijian <lizhijian@fujitsu.com>
|
||||
M: Li Zhijian <lizhijian@cn.fujitsu.com>
|
||||
S: Supported
|
||||
F: docs/colo-proxy.txt
|
||||
F: net/colo*
|
||||
F: net/filter-rewriter.c
|
||||
F: net/filter-mirror.c
|
||||
F: tests/qtest/test-filter*
|
||||
|
||||
Record/replay
|
||||
M: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
|
||||
@@ -3199,29 +3022,16 @@ F: include/hw/i2c/smbus_master.h
|
||||
F: include/hw/i2c/smbus_slave.h
|
||||
F: include/hw/i2c/smbus_eeprom.h
|
||||
|
||||
PMBus
|
||||
M: Titus Rwantare <titusr@google.com>
|
||||
S: Maintained
|
||||
F: hw/i2c/pmbus_device.c
|
||||
F: hw/sensor/adm1272.c
|
||||
F: hw/sensor/isl_pmbus_vr.c
|
||||
F: hw/sensor/max34451.c
|
||||
F: include/hw/i2c/pmbus_device.h
|
||||
F: include/hw/sensor/isl_pmbus_vr.h
|
||||
F: tests/qtest/adm1272-test.c
|
||||
F: tests/qtest/max34451-test.c
|
||||
F: tests/qtest/isl_pmbus_vr-test.c
|
||||
|
||||
Firmware schema specifications
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
M: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
R: Daniel P. Berrange <berrange@redhat.com>
|
||||
R: Kashyap Chamarthy <kchamart@redhat.com>
|
||||
S: Maintained
|
||||
F: docs/interop/firmware.json
|
||||
|
||||
EDK2 Firmware
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
M: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
R: Gerd Hoffmann <kraxel@redhat.com>
|
||||
S: Supported
|
||||
F: hw/i386/*ovmf*
|
||||
F: pc-bios/descriptors/??-edk2-*.json
|
||||
@@ -3266,9 +3076,8 @@ Usermode Emulation
|
||||
Overall usermode emulation
|
||||
M: Riku Voipio <riku.voipio@iki.fi>
|
||||
S: Maintained
|
||||
F: thunk.c
|
||||
F: accel/tcg/user-exec*.c
|
||||
F: include/user/
|
||||
F: common-user/
|
||||
|
||||
BSD user
|
||||
M: Warner Losh <imp@bsdimp.com>
|
||||
@@ -3276,7 +3085,6 @@ R: Kyle Evans <kevans@freebsd.org>
|
||||
S: Maintained
|
||||
F: bsd-user/
|
||||
F: configs/targets/*-bsd-user.mak
|
||||
F: tests/vm/*bsd
|
||||
T: git https://github.com/qemu-bsd-user/qemu-bsd-user bsd-user-rebase-3.1
|
||||
|
||||
Linux user
|
||||
@@ -3313,22 +3121,21 @@ M: Richard Henderson <richard.henderson@linaro.org>
|
||||
S: Maintained
|
||||
L: qemu-arm@nongnu.org
|
||||
F: tcg/aarch64/
|
||||
F: disas/arm-a64.cc
|
||||
F: disas/libvixl/
|
||||
|
||||
ARM TCG target
|
||||
M: Richard Henderson <richard.henderson@linaro.org>
|
||||
S: Maintained
|
||||
L: qemu-arm@nongnu.org
|
||||
F: tcg/arm/
|
||||
F: disas/arm.c
|
||||
|
||||
i386 TCG target
|
||||
M: Richard Henderson <richard.henderson@linaro.org>
|
||||
S: Maintained
|
||||
F: tcg/i386/
|
||||
|
||||
LoongArch64 TCG target
|
||||
M: WANG Xuerui <git@xen0n.name>
|
||||
S: Maintained
|
||||
F: tcg/loongarch64/
|
||||
F: disas/i386.c
|
||||
|
||||
MIPS TCG target
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
@@ -3343,6 +3150,7 @@ PPC TCG target
|
||||
M: Richard Henderson <richard.henderson@linaro.org>
|
||||
S: Odd Fixes
|
||||
F: tcg/ppc/
|
||||
F: disas/ppc.c
|
||||
|
||||
RISC-V TCG target
|
||||
M: Palmer Dabbelt <palmer@dabbelt.com>
|
||||
@@ -3356,6 +3164,7 @@ S390 TCG target
|
||||
M: Richard Henderson <richard.henderson@linaro.org>
|
||||
S: Maintained
|
||||
F: tcg/s390/
|
||||
F: disas/s390.c
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
SPARC TCG target
|
||||
@@ -3408,7 +3217,7 @@ F: block/iscsi-opts.c
|
||||
|
||||
Network Block Device (NBD)
|
||||
M: Eric Blake <eblake@redhat.com>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Maintained
|
||||
F: block/nbd*
|
||||
@@ -3418,9 +3227,8 @@ F: qemu-nbd.*
|
||||
F: blockdev-nbd.c
|
||||
F: docs/interop/nbd.txt
|
||||
F: docs/tools/qemu-nbd.rst
|
||||
F: tests/qemu-iotests/tests/*nbd*
|
||||
T: git https://repo.or.cz/qemu/ericb.git nbd
|
||||
T: git https://gitlab.com/vsementsov/qemu.git block
|
||||
T: git https://src.openvz.org/scm/~vsementsov/qemu.git nbd
|
||||
|
||||
NFS
|
||||
M: Peter Lieven <pl@kamp.de>
|
||||
@@ -3454,7 +3262,7 @@ F: block/null.c
|
||||
NVMe Block Driver
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
R: Fam Zheng <fam@euphon.net>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
R: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/nvme*
|
||||
@@ -3505,13 +3313,13 @@ F: block/dmg.c
|
||||
parallels
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
M: Denis V. Lunev <den@openvz.org>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
M: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/parallels.c
|
||||
F: block/parallels-ext.c
|
||||
F: docs/interop/parallels.txt
|
||||
T: git https://gitlab.com/vsementsov/qemu.git block
|
||||
T: git https://src.openvz.org/scm/~vsementsov/qemu.git parallels
|
||||
|
||||
qed
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
@@ -3584,8 +3392,6 @@ M: Coiby Xu <Coiby.Xu@gmail.com>
|
||||
S: Maintained
|
||||
F: block/export/vhost-user-blk-server.c
|
||||
F: block/export/vhost-user-blk-server.h
|
||||
F: block/export/virtio-blk-handler.c
|
||||
F: block/export/virtio-blk-handler.h
|
||||
F: include/qemu/vhost-user-server.h
|
||||
F: tests/qtest/libqos/vhost-user-blk.c
|
||||
F: tests/qtest/libqos/vhost-user-blk.h
|
||||
@@ -3598,13 +3404,6 @@ L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/export/fuse.c
|
||||
|
||||
VDUSE library and block device exports
|
||||
M: Xie Yongji <xieyongji@bytedance.com>
|
||||
S: Maintained
|
||||
F: subprojects/libvduse/
|
||||
F: block/export/vduse-blk.c
|
||||
F: block/export/vduse-blk.h
|
||||
|
||||
Replication
|
||||
M: Wen Congyang <wencongyang2@huawei.com>
|
||||
M: Xie Changlong <xiechanglong.d@gmail.com>
|
||||
@@ -3630,7 +3429,6 @@ S: Maintained
|
||||
F: semihosting/
|
||||
F: include/semihosting/
|
||||
F: tests/tcg/multiarch/arm-compat-semi/
|
||||
F: tests/tcg/aarch64/system/semiheap.c
|
||||
|
||||
Multi-process QEMU
|
||||
M: Elena Ufimtseva <elena.ufimtseva@oracle.com>
|
||||
@@ -3655,11 +3453,6 @@ F: hw/remote/proxy-memory-listener.c
|
||||
F: include/hw/remote/proxy-memory-listener.h
|
||||
F: hw/remote/iohub.c
|
||||
F: include/hw/remote/iohub.h
|
||||
F: subprojects/libvfio-user
|
||||
F: hw/remote/vfio-user-obj.c
|
||||
F: include/hw/remote/vfio-user-obj.h
|
||||
F: hw/remote/iommu.c
|
||||
F: include/hw/remote/iommu.h
|
||||
|
||||
EBPF:
|
||||
M: Jason Wang <jasowang@redhat.com>
|
||||
@@ -3678,14 +3471,13 @@ M: Thomas Huth <thuth@redhat.com>
|
||||
R: Wainer dos Santos Moschetta <wainersm@redhat.com>
|
||||
R: Beraldo Leal <bleal@redhat.com>
|
||||
S: Maintained
|
||||
F: .github/workflows/lockdown.yml
|
||||
F: .github/lockdown.yml
|
||||
F: .gitlab-ci.yml
|
||||
F: .gitlab-ci.d/
|
||||
F: .travis.yml
|
||||
F: scripts/ci/
|
||||
F: tests/docker/
|
||||
F: tests/vm/
|
||||
F: tests/lcitool/
|
||||
F: scripts/archive-source.sh
|
||||
W: https://gitlab.com/qemu-project/qemu/pipelines
|
||||
W: https://travis-ci.org/qemu/qemu
|
||||
@@ -3694,8 +3486,7 @@ FreeBSD Hosted Continuous Integration
|
||||
M: Ed Maste <emaste@freebsd.org>
|
||||
M: Li-Wen Hsu <lwhsu@freebsd.org>
|
||||
S: Maintained
|
||||
F: .gitlab-ci.d/cirrus/freebsd*
|
||||
F: tests/vm/freebsd
|
||||
F: .cirrus.yml
|
||||
W: https://cirrus-ci.com/github/qemu/qemu
|
||||
|
||||
Windows Hosted Continuous Integration
|
||||
@@ -3714,7 +3505,7 @@ F: tests/tcg/Makefile.include
|
||||
Integration Testing with the Avocado framework
|
||||
W: https://trello.com/b/6Qi1pxVn/avocado-qemu
|
||||
R: Cleber Rosa <crosa@redhat.com>
|
||||
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
R: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
R: Wainer dos Santos Moschetta <wainersm@redhat.com>
|
||||
R: Beraldo Leal <bleal@redhat.com>
|
||||
S: Odd Fixes
|
||||
|
||||
39
Makefile
39
Makefile
@@ -143,9 +143,9 @@ MAKE.q = $(findstring q,$(firstword $(filter-out --%,$(MAKEFLAGS))))
|
||||
MAKE.nq = $(if $(word 2, $(MAKE.n) $(MAKE.q)),nq)
|
||||
NINJAFLAGS = $(if $V,-v) $(if $(MAKE.n), -n) $(if $(MAKE.k), -k0) \
|
||||
$(filter-out -j, $(lastword -j1 $(filter -l% -j%, $(MAKEFLAGS)))) \
|
||||
-d keepdepfile
|
||||
|
||||
ninja-cmd-goals = $(or $(MAKECMDGOALS), all)
|
||||
ninja-cmd-goals += $(foreach g, $(MAKECMDGOALS), $(.ninja-goals.$g))))
|
||||
ninja-cmd-goals += $(foreach t, $(.tests), $(.test.deps.$t))
|
||||
|
||||
makefile-targets := build.ninja ctags TAGS cscope dist clean uninstall
|
||||
# "ninja -t targets" also lists all prerequisites. If build system
|
||||
@@ -159,12 +159,15 @@ $(ninja-targets): run-ninja
|
||||
# --output-sync line.
|
||||
run-ninja: config-host.mak
|
||||
ifneq ($(filter $(ninja-targets), $(ninja-cmd-goals)),)
|
||||
+$(if $(MAKE.nq),@:,$(quiet-@)$(NINJA) $(NINJAFLAGS) \
|
||||
$(sort $(filter $(ninja-targets), $(ninja-cmd-goals))) | cat)
|
||||
+$(quiet-@)$(if $(MAKE.nq),@:, $(NINJA) -d keepdepfile \
|
||||
$(NINJAFLAGS) $(sort $(filter $(ninja-targets), $(ninja-cmd-goals))) | cat)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Force configure to re-run if the API symbols are updated
|
||||
ifeq ($(CONFIG_PLUGIN),y)
|
||||
config-host.mak: $(SRC_PATH)/plugins/qemu-plugins.symbols
|
||||
|
||||
.PHONY: plugins
|
||||
plugins:
|
||||
$(call quiet-command,\
|
||||
@@ -186,26 +189,30 @@ include $(SRC_PATH)/tests/Makefile.include
|
||||
|
||||
all: recurse-all
|
||||
|
||||
ROMS_RULES=$(foreach t, all clean, $(addsuffix /$(t), $(ROMS)))
|
||||
.PHONY: $(ROMS_RULES)
|
||||
$(ROMS_RULES):
|
||||
ROM_DIRS = $(addprefix pc-bios/, $(ROMS))
|
||||
ROM_DIRS_RULES=$(foreach t, all clean, $(addsuffix /$(t), $(ROM_DIRS)))
|
||||
# Only keep -O and -g cflags
|
||||
.PHONY: $(ROM_DIRS_RULES)
|
||||
$(ROM_DIRS_RULES):
|
||||
$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" TARGET_DIR="$(dir $@)" $(notdir $@),)
|
||||
|
||||
.PHONY: recurse-all recurse-clean
|
||||
recurse-all: $(addsuffix /all, $(ROMS))
|
||||
recurse-clean: $(addsuffix /clean, $(ROMS))
|
||||
recurse-all: $(addsuffix /all, $(ROM_DIRS))
|
||||
recurse-clean: $(addsuffix /clean, $(ROM_DIRS))
|
||||
|
||||
######################################################################
|
||||
|
||||
clean: recurse-clean
|
||||
-$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean || :
|
||||
-$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) clean-ctlist || :
|
||||
find . \( -name '*.so' -o -name '*.dll' -o \
|
||||
-name '*.[oda]' -o -name '*.gcno' \) -type f \
|
||||
# avoid old build problems by removing potentially incorrect old files
|
||||
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
|
||||
find . \( -name '*.so' -o -name '*.dll' -o -name '*.[oda]' \) -type f \
|
||||
! -path ./roms/edk2/ArmPkg/Library/GccLto/liblto-aarch64.a \
|
||||
! -path ./roms/edk2/ArmPkg/Library/GccLto/liblto-arm.a \
|
||||
-exec rm {} +
|
||||
rm -f TAGS cscope.* *~ */*~
|
||||
rm -f TAGS cscope.* *.pod *~ */*~
|
||||
rm -f fsdev/*.pod scsi/*.pod
|
||||
|
||||
VERSION = $(shell cat $(SRC_PATH)/VERSION)
|
||||
|
||||
@@ -216,10 +223,10 @@ qemu-%.tar.bz2:
|
||||
|
||||
distclean: clean
|
||||
-$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || :
|
||||
rm -f config-host.mak qemu-bundle
|
||||
rm -f config-host.mak config-host.h* config-poison.h
|
||||
rm -f tests/tcg/config-*.mak
|
||||
rm -f config.status
|
||||
rm -f roms/seabios/config.mak
|
||||
rm -f config-all-disas.mak config.status
|
||||
rm -f roms/seabios/config.mak roms/vgabios/config.mak
|
||||
rm -f qemu-plugins-ld.symbols qemu-plugins-ld64.symbols
|
||||
rm -f *-config-target.h *-config-devices.mak *-config-devices.h
|
||||
rm -rf meson-private meson-logs meson-info compile_commands.json
|
||||
@@ -280,7 +287,6 @@ cscope:
|
||||
# Needed by "meson install"
|
||||
export DESTDIR
|
||||
|
||||
include $(SRC_PATH)/tests/lcitool/Makefile.include
|
||||
include $(SRC_PATH)/tests/docker/Makefile.include
|
||||
include $(SRC_PATH)/tests/vm/Makefile.include
|
||||
|
||||
@@ -310,7 +316,6 @@ endif
|
||||
@echo 'Test targets:'
|
||||
$(call print-help,check,Run all tests (check-help for details))
|
||||
$(call print-help,bench,Run all benchmarks)
|
||||
$(call print-help,lcitool-help,Help about targets for managing build environment manifests)
|
||||
$(call print-help,docker-help,Help about targets running tests inside containers)
|
||||
$(call print-help,vm-help,Help about targets running tests inside VM)
|
||||
@echo ''
|
||||
|
||||
@@ -39,7 +39,7 @@ Documentation can be found hosted online at
|
||||
current development version that is available at
|
||||
`<https://www.qemu.org/docs/master/>`_ is generated from the ``docs/``
|
||||
folder in the source tree, and is built by `Sphinx
|
||||
<https://www.sphinx-doc.org/en/master/>`_.
|
||||
<https://www.sphinx-doc.org/en/master/>_`.
|
||||
|
||||
|
||||
Building
|
||||
@@ -78,7 +78,7 @@ format-patch' and/or 'git send-email' to format & send the mail to the
|
||||
qemu-devel@nongnu.org mailing list. All patches submitted must contain
|
||||
a 'Signed-off-by' line from the author. Patches should follow the
|
||||
guidelines set out in the `style section
|
||||
<https://www.qemu.org/docs/master/devel/style.html>`_ of
|
||||
<https://www.qemu.org/docs/master/devel/style.html>` of
|
||||
the Developers Guide.
|
||||
|
||||
Additional information on submitting patches can be found online via
|
||||
|
||||
@@ -49,14 +49,6 @@ AccelClass *accel_find(const char *opt_name)
|
||||
return ac;
|
||||
}
|
||||
|
||||
/* Return the name of the current accelerator */
|
||||
const char *current_accel_name(void)
|
||||
{
|
||||
AccelClass *ac = ACCEL_GET_CLASS(current_accel());
|
||||
|
||||
return ac->name;
|
||||
}
|
||||
|
||||
static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque)
|
||||
{
|
||||
CPUClass *cc = CPU_CLASS(klass);
|
||||
|
||||
@@ -66,7 +66,6 @@ void accel_init_ops_interfaces(AccelClass *ac)
|
||||
{
|
||||
const char *ac_name;
|
||||
char *ops_name;
|
||||
ObjectClass *oc;
|
||||
AccelOpsClass *ops;
|
||||
|
||||
ac_name = object_class_get_name(OBJECT_CLASS(ac));
|
||||
@@ -74,13 +73,8 @@ void accel_init_ops_interfaces(AccelClass *ac)
|
||||
|
||||
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);
|
||||
if (!oc) {
|
||||
error_report("fatal: could not load module for type '%s'", ops_name);
|
||||
exit(1);
|
||||
}
|
||||
g_free(ops_name);
|
||||
ops = ACCEL_OPS_CLASS(oc);
|
||||
|
||||
/*
|
||||
* all accelerators need to define ops, providing at least a mandatory
|
||||
* non-NULL create_vcpu_thread operation.
|
||||
|
||||
@@ -120,12 +120,12 @@ static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
|
||||
{
|
||||
hvf_slot *mem;
|
||||
MemoryRegion *area = section->mr;
|
||||
bool writable = !area->readonly && !area->rom_device;
|
||||
bool writeable = !area->readonly && !area->rom_device;
|
||||
hv_memory_flags_t flags;
|
||||
uint64_t page_size = qemu_real_host_page_size();
|
||||
uint64_t page_size = qemu_real_host_page_size;
|
||||
|
||||
if (!memory_region_is_ram(area)) {
|
||||
if (writable) {
|
||||
if (writeable) {
|
||||
return;
|
||||
} else if (!memory_region_is_romd(area)) {
|
||||
/*
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "sysemu/hvf.h"
|
||||
#include "sysemu/hvf_int.h"
|
||||
|
||||
@@ -74,23 +74,11 @@ static void kvm_start_vcpu_thread(CPUState *cpu)
|
||||
cpu, QEMU_THREAD_JOINABLE);
|
||||
}
|
||||
|
||||
static bool kvm_vcpu_thread_is_idle(CPUState *cpu)
|
||||
{
|
||||
return !kvm_halt_in_kernel();
|
||||
}
|
||||
|
||||
static bool kvm_cpus_are_resettable(void)
|
||||
{
|
||||
return !kvm_enabled() || kvm_cpu_check_are_resettable();
|
||||
}
|
||||
|
||||
static void kvm_accel_ops_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
|
||||
|
||||
ops->create_vcpu_thread = kvm_start_vcpu_thread;
|
||||
ops->cpu_thread_is_idle = kvm_vcpu_thread_is_idle;
|
||||
ops->cpus_are_resettable = kvm_cpus_are_resettable;
|
||||
ops->synchronize_post_reset = kvm_cpu_synchronize_post_reset;
|
||||
ops->synchronize_post_init = kvm_cpu_synchronize_post_init;
|
||||
ops->synchronize_state = kvm_cpu_synchronize_state;
|
||||
|
||||
@@ -45,10 +45,8 @@
|
||||
#include "qemu/guest-random.h"
|
||||
#include "sysemu/hw_accel.h"
|
||||
#include "kvm-cpus.h"
|
||||
#include "sysemu/dirtylimit.h"
|
||||
|
||||
#include "hw/boards.h"
|
||||
#include "monitor/stats.h"
|
||||
|
||||
/* This check must be after config-host.h is included */
|
||||
#ifdef CONFIG_EVENTFD
|
||||
@@ -61,11 +59,7 @@
|
||||
#ifdef PAGE_SIZE
|
||||
#undef PAGE_SIZE
|
||||
#endif
|
||||
#define PAGE_SIZE qemu_real_host_page_size()
|
||||
|
||||
#ifndef KVM_GUESTDBG_BLOCKIRQ
|
||||
#define KVM_GUESTDBG_BLOCKIRQ 0
|
||||
#endif
|
||||
#define PAGE_SIZE qemu_real_host_page_size
|
||||
|
||||
//#define DEBUG_KVM
|
||||
|
||||
@@ -174,8 +168,6 @@ bool kvm_vm_attributes_allowed;
|
||||
bool kvm_direct_msi_allowed;
|
||||
bool kvm_ioeventfd_any_length_allowed;
|
||||
bool kvm_msi_use_devid;
|
||||
bool kvm_has_guest_debug;
|
||||
int kvm_sstep_flags;
|
||||
static bool kvm_immediate_exit;
|
||||
static hwaddr kvm_max_slot_size = ~0;
|
||||
|
||||
@@ -326,14 +318,14 @@ static hwaddr kvm_align_section(MemoryRegionSection *section,
|
||||
with sub-page size and unaligned start address. Pad the start
|
||||
address to next and truncate size to previous page boundary. */
|
||||
aligned = ROUND_UP(section->offset_within_address_space,
|
||||
qemu_real_host_page_size());
|
||||
qemu_real_host_page_size);
|
||||
delta = aligned - section->offset_within_address_space;
|
||||
*start = aligned;
|
||||
if (delta > size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (size - delta) & qemu_real_host_page_mask();
|
||||
return (size - delta) & qemu_real_host_page_mask;
|
||||
}
|
||||
|
||||
int kvm_physical_memory_addr_from_host(KVMState *s, void *ram,
|
||||
@@ -478,7 +470,6 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
|
||||
cpu->kvm_state = s;
|
||||
cpu->vcpu_dirty = true;
|
||||
cpu->dirty_pages = 0;
|
||||
cpu->throttle_us_per_full = 0;
|
||||
|
||||
mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
|
||||
if (mmap_size < 0) {
|
||||
@@ -629,7 +620,7 @@ static void kvm_log_stop(MemoryListener *listener,
|
||||
static void kvm_slot_sync_dirty_pages(KVMSlot *slot)
|
||||
{
|
||||
ram_addr_t start = slot->ram_start_offset;
|
||||
ram_addr_t pages = slot->memory_size / qemu_real_host_page_size();
|
||||
ram_addr_t pages = slot->memory_size / qemu_real_host_page_size;
|
||||
|
||||
cpu_physical_memory_set_dirty_lebitmap(slot->dirty_bmap, start, pages);
|
||||
}
|
||||
@@ -665,7 +656,7 @@ static void kvm_slot_init_dirty_bitmap(KVMSlot *mem)
|
||||
* And mem->memory_size is aligned to it (otherwise this mem can't
|
||||
* be registered to KVM).
|
||||
*/
|
||||
hwaddr bitmap_size = ALIGN(mem->memory_size / qemu_real_host_page_size(),
|
||||
hwaddr bitmap_size = ALIGN(mem->memory_size / qemu_real_host_page_size,
|
||||
/*HOST_LONG_BITS*/ 64) / 8;
|
||||
mem->dirty_bmap = g_malloc0(bitmap_size);
|
||||
mem->dirty_bmap_size = bitmap_size;
|
||||
@@ -710,7 +701,7 @@ static void kvm_dirty_ring_mark_page(KVMState *s, uint32_t as_id,
|
||||
mem = &kml->slots[slot_id];
|
||||
|
||||
if (!mem->memory_size || offset >=
|
||||
(mem->memory_size / qemu_real_host_page_size())) {
|
||||
(mem->memory_size / qemu_real_host_page_size)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -759,20 +750,17 @@ static uint32_t kvm_dirty_ring_reap_one(KVMState *s, CPUState *cpu)
|
||||
}
|
||||
|
||||
/* Must be with slots_lock held */
|
||||
static uint64_t kvm_dirty_ring_reap_locked(KVMState *s, CPUState* cpu)
|
||||
static uint64_t kvm_dirty_ring_reap_locked(KVMState *s)
|
||||
{
|
||||
int ret;
|
||||
CPUState *cpu;
|
||||
uint64_t total = 0;
|
||||
int64_t stamp;
|
||||
|
||||
stamp = get_clock();
|
||||
|
||||
if (cpu) {
|
||||
total = kvm_dirty_ring_reap_one(s, cpu);
|
||||
} else {
|
||||
CPU_FOREACH(cpu) {
|
||||
total += kvm_dirty_ring_reap_one(s, cpu);
|
||||
}
|
||||
CPU_FOREACH(cpu) {
|
||||
total += kvm_dirty_ring_reap_one(s, cpu);
|
||||
}
|
||||
|
||||
if (total) {
|
||||
@@ -793,7 +781,7 @@ static uint64_t kvm_dirty_ring_reap_locked(KVMState *s, CPUState* cpu)
|
||||
* Currently for simplicity, we must hold BQL before calling this. We can
|
||||
* consider to drop the BQL if we're clear with all the race conditions.
|
||||
*/
|
||||
static uint64_t kvm_dirty_ring_reap(KVMState *s, CPUState *cpu)
|
||||
static uint64_t kvm_dirty_ring_reap(KVMState *s)
|
||||
{
|
||||
uint64_t total;
|
||||
|
||||
@@ -813,7 +801,7 @@ static uint64_t kvm_dirty_ring_reap(KVMState *s, CPUState *cpu)
|
||||
* reset below.
|
||||
*/
|
||||
kvm_slots_lock();
|
||||
total = kvm_dirty_ring_reap_locked(s, cpu);
|
||||
total = kvm_dirty_ring_reap_locked(s);
|
||||
kvm_slots_unlock();
|
||||
|
||||
return total;
|
||||
@@ -860,7 +848,7 @@ static void kvm_dirty_ring_flush(void)
|
||||
* vcpus out in a synchronous way.
|
||||
*/
|
||||
kvm_cpu_synchronize_kick_all();
|
||||
kvm_dirty_ring_reap(kvm_state, NULL);
|
||||
kvm_dirty_ring_reap(kvm_state);
|
||||
trace_kvm_dirty_ring_flush(1);
|
||||
}
|
||||
|
||||
@@ -901,7 +889,7 @@ static void kvm_physical_sync_dirty_bitmap(KVMMemoryListener *kml,
|
||||
|
||||
/* Alignment requirement for KVM_CLEAR_DIRTY_LOG - 64 pages */
|
||||
#define KVM_CLEAR_LOG_SHIFT 6
|
||||
#define KVM_CLEAR_LOG_ALIGN (qemu_real_host_page_size() << KVM_CLEAR_LOG_SHIFT)
|
||||
#define KVM_CLEAR_LOG_ALIGN (qemu_real_host_page_size << KVM_CLEAR_LOG_SHIFT)
|
||||
#define KVM_CLEAR_LOG_MASK (-KVM_CLEAR_LOG_ALIGN)
|
||||
|
||||
static int kvm_log_clear_one_slot(KVMSlot *mem, int as_id, uint64_t start,
|
||||
@@ -910,7 +898,7 @@ static int kvm_log_clear_one_slot(KVMSlot *mem, int as_id, uint64_t start,
|
||||
KVMState *s = kvm_state;
|
||||
uint64_t end, bmap_start, start_delta, bmap_npages;
|
||||
struct kvm_clear_dirty_log d;
|
||||
unsigned long *bmap_clear = NULL, psize = qemu_real_host_page_size();
|
||||
unsigned long *bmap_clear = NULL, psize = qemu_real_host_page_size;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -1208,8 +1196,8 @@ void kvm_hwpoison_page_add(ram_addr_t ram_addr)
|
||||
|
||||
static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size)
|
||||
{
|
||||
#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
|
||||
/* The kernel expects ioeventfd values in HOST_BIG_ENDIAN
|
||||
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
|
||||
/* The kernel expects ioeventfd values in HOST_WORDS_BIGENDIAN
|
||||
* endianness, but the memory core hands them in target endianness.
|
||||
* For example, PPC is always treated as big-endian even if running
|
||||
* on KVM and on PPC64LE. Correct here.
|
||||
@@ -1341,7 +1329,7 @@ kvm_check_extension_list(KVMState *s, const KVMCapabilityInfo *list)
|
||||
void kvm_set_max_memslot_size(hwaddr max_slot_size)
|
||||
{
|
||||
g_assert(
|
||||
ROUND_UP(max_slot_size, qemu_real_host_page_size()) == max_slot_size
|
||||
ROUND_UP(max_slot_size, qemu_real_host_page_size) == max_slot_size
|
||||
);
|
||||
kvm_max_slot_size = max_slot_size;
|
||||
}
|
||||
@@ -1352,13 +1340,13 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
||||
KVMSlot *mem;
|
||||
int err;
|
||||
MemoryRegion *mr = section->mr;
|
||||
bool writable = !mr->readonly && !mr->rom_device;
|
||||
bool writeable = !mr->readonly && !mr->rom_device;
|
||||
hwaddr start_addr, size, slot_size, mr_offset;
|
||||
ram_addr_t ram_start_offset;
|
||||
void *ram;
|
||||
|
||||
if (!memory_region_is_ram(mr)) {
|
||||
if (writable || !kvm_readonly_mem_allowed) {
|
||||
if (writeable || !kvm_readonly_mem_allowed) {
|
||||
return;
|
||||
} else if (!mr->romd_mode) {
|
||||
/* If the memory device is not in romd_mode, then we actually want
|
||||
@@ -1404,7 +1392,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
|
||||
* Not easy. Let's cross the fingers until it's fixed.
|
||||
*/
|
||||
if (kvm_state->kvm_dirty_ring_size) {
|
||||
kvm_dirty_ring_reap_locked(kvm_state, NULL);
|
||||
kvm_dirty_ring_reap_locked(kvm_state);
|
||||
} else {
|
||||
kvm_slot_get_dirty_log(kvm_state, mem);
|
||||
}
|
||||
@@ -1472,16 +1460,11 @@ static void *kvm_dirty_ring_reaper_thread(void *data)
|
||||
*/
|
||||
sleep(1);
|
||||
|
||||
/* keep sleeping so that dirtylimit not be interfered by reaper */
|
||||
if (dirtylimit_in_service()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
trace_kvm_dirty_ring_reaper("wakeup");
|
||||
r->reaper_state = KVM_DIRTY_RING_REAPER_REAPING;
|
||||
|
||||
qemu_mutex_lock_iothread();
|
||||
kvm_dirty_ring_reap(s, NULL);
|
||||
kvm_dirty_ring_reap(s);
|
||||
qemu_mutex_unlock_iothread();
|
||||
|
||||
r->reaper_iteration++;
|
||||
@@ -1657,7 +1640,7 @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
|
||||
{
|
||||
int i;
|
||||
|
||||
kml->slots = g_new0(KVMSlot, s->nr_slots);
|
||||
kml->slots = g_malloc0(s->nr_slots * sizeof(KVMSlot));
|
||||
kml->as_id = as_id;
|
||||
|
||||
for (i = 0; i < s->nr_slots; i++) {
|
||||
@@ -1952,7 +1935,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
|
||||
return virq;
|
||||
}
|
||||
|
||||
route = g_new0(KVMMSIRoute, 1);
|
||||
route = g_malloc0(sizeof(KVMMSIRoute));
|
||||
route->kroute.gsi = virq;
|
||||
route->kroute.type = KVM_IRQ_ROUTING_MSI;
|
||||
route->kroute.flags = 0;
|
||||
@@ -1972,11 +1955,10 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
|
||||
return kvm_set_irq(s, route->kroute.gsi, 1);
|
||||
}
|
||||
|
||||
int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev)
|
||||
int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
|
||||
{
|
||||
struct kvm_irq_routing_entry kroute = {};
|
||||
int virq;
|
||||
KVMState *s = c->s;
|
||||
MSIMessage msg = {0, 0};
|
||||
|
||||
if (pci_available && dev) {
|
||||
@@ -2016,7 +1998,7 @@ int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev)
|
||||
|
||||
kvm_add_routing_entry(s, &kroute);
|
||||
kvm_arch_add_msi_route_post(&kroute, vector, dev);
|
||||
c->changes++;
|
||||
kvm_irqchip_commit_routes(s);
|
||||
|
||||
return virq;
|
||||
}
|
||||
@@ -2174,7 +2156,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
|
||||
abort();
|
||||
}
|
||||
|
||||
int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev)
|
||||
int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -2265,7 +2247,7 @@ static void kvm_irqchip_create(KVMState *s)
|
||||
ret = kvm_arch_irqchip_create(s);
|
||||
if (ret == 0) {
|
||||
if (s->kernel_irqchip_split == ON_OFF_AUTO_ON) {
|
||||
error_report("Split IRQ chip mode not supported.");
|
||||
perror("Split IRQ chip mode not supported.");
|
||||
exit(1);
|
||||
} else {
|
||||
ret = kvm_vm_ioctl(s, KVM_CREATE_IRQCHIP);
|
||||
@@ -2321,15 +2303,6 @@ bool kvm_dirty_ring_enabled(void)
|
||||
return kvm_state->kvm_dirty_ring_size ? true : false;
|
||||
}
|
||||
|
||||
static void query_stats_cb(StatsResultList **result, StatsTarget target,
|
||||
strList *names, strList *targets, Error **errp);
|
||||
static void query_stats_schemas_cb(StatsSchemaList **result, Error **errp);
|
||||
|
||||
uint32_t kvm_dirty_ring_size(void)
|
||||
{
|
||||
return kvm_state->kvm_dirty_ring_size;
|
||||
}
|
||||
|
||||
static int kvm_init(MachineState *ms)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
@@ -2361,7 +2334,7 @@ static int kvm_init(MachineState *ms)
|
||||
* 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());
|
||||
assert(TARGET_PAGE_SIZE <= qemu_real_host_page_size);
|
||||
|
||||
s->sigmask_len = 8;
|
||||
|
||||
@@ -2591,25 +2564,6 @@ static int kvm_init(MachineState *ms)
|
||||
kvm_ioeventfd_any_length_allowed =
|
||||
(kvm_check_extension(s, KVM_CAP_IOEVENTFD_ANY_LENGTH) > 0);
|
||||
|
||||
#ifdef KVM_CAP_SET_GUEST_DEBUG
|
||||
kvm_has_guest_debug =
|
||||
(kvm_check_extension(s, KVM_CAP_SET_GUEST_DEBUG) > 0);
|
||||
#endif
|
||||
|
||||
kvm_sstep_flags = 0;
|
||||
if (kvm_has_guest_debug) {
|
||||
kvm_sstep_flags = SSTEP_ENABLE;
|
||||
|
||||
#if defined KVM_CAP_SET_GUEST_DEBUG2
|
||||
int guest_debug_flags =
|
||||
kvm_check_extension(s, KVM_CAP_SET_GUEST_DEBUG2);
|
||||
|
||||
if (guest_debug_flags & KVM_GUESTDBG_BLOCKIRQ) {
|
||||
kvm_sstep_flags |= SSTEP_NOIRQ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
kvm_state = s;
|
||||
|
||||
ret = kvm_arch_init(ms, s);
|
||||
@@ -2658,11 +2612,6 @@ static int kvm_init(MachineState *ms)
|
||||
}
|
||||
}
|
||||
|
||||
if (kvm_check_extension(kvm_state, KVM_CAP_BINARY_STATS_FD)) {
|
||||
add_stats_callbacks(STATS_PROVIDER_KVM, query_stats_cb,
|
||||
query_stats_schemas_cb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
@@ -2982,19 +2931,8 @@ int kvm_cpu_exec(CPUState *cpu)
|
||||
*/
|
||||
trace_kvm_dirty_ring_full(cpu->cpu_index);
|
||||
qemu_mutex_lock_iothread();
|
||||
/*
|
||||
* We throttle vCPU by making it sleep once it exit from kernel
|
||||
* due to dirty ring full. In the dirtylimit scenario, reaping
|
||||
* all vCPUs after a single vCPU dirty ring get full result in
|
||||
* the miss of sleep, so just reap the ring-fulled vCPU.
|
||||
*/
|
||||
if (dirtylimit_in_service()) {
|
||||
kvm_dirty_ring_reap(kvm_state, cpu);
|
||||
} else {
|
||||
kvm_dirty_ring_reap(kvm_state, NULL);
|
||||
}
|
||||
kvm_dirty_ring_reap(kvm_state);
|
||||
qemu_mutex_unlock_iothread();
|
||||
dirtylimit_vcpu_execute(cpu);
|
||||
ret = 0;
|
||||
break;
|
||||
case KVM_EXIT_SYSTEM_EVENT:
|
||||
@@ -3255,10 +3193,6 @@ int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap)
|
||||
|
||||
if (cpu->singlestep_enabled) {
|
||||
data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
|
||||
|
||||
if (cpu->singlestep_enabled & SSTEP_NOIRQ) {
|
||||
data.dbg.control |= KVM_GUESTDBG_BLOCKIRQ;
|
||||
}
|
||||
}
|
||||
kvm_arch_update_guest_debug(cpu, &data.dbg);
|
||||
|
||||
@@ -3280,7 +3214,7 @@ int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bp = g_new(struct kvm_sw_breakpoint, 1);
|
||||
bp = g_malloc(sizeof(struct kvm_sw_breakpoint));
|
||||
bp->pc = addr;
|
||||
bp->use_count = 1;
|
||||
err = kvm_arch_insert_sw_breakpoint(cpu, bp);
|
||||
@@ -3733,407 +3667,3 @@ static void kvm_type_init(void)
|
||||
}
|
||||
|
||||
type_init(kvm_type_init);
|
||||
|
||||
typedef struct StatsArgs {
|
||||
union StatsResultsType {
|
||||
StatsResultList **stats;
|
||||
StatsSchemaList **schema;
|
||||
} result;
|
||||
strList *names;
|
||||
Error **errp;
|
||||
} StatsArgs;
|
||||
|
||||
static StatsList *add_kvmstat_entry(struct kvm_stats_desc *pdesc,
|
||||
uint64_t *stats_data,
|
||||
StatsList *stats_list,
|
||||
Error **errp)
|
||||
{
|
||||
|
||||
Stats *stats;
|
||||
uint64List *val_list = NULL;
|
||||
|
||||
/* Only add stats that we understand. */
|
||||
switch (pdesc->flags & KVM_STATS_TYPE_MASK) {
|
||||
case KVM_STATS_TYPE_CUMULATIVE:
|
||||
case KVM_STATS_TYPE_INSTANT:
|
||||
case KVM_STATS_TYPE_PEAK:
|
||||
case KVM_STATS_TYPE_LINEAR_HIST:
|
||||
case KVM_STATS_TYPE_LOG_HIST:
|
||||
break;
|
||||
default:
|
||||
return stats_list;
|
||||
}
|
||||
|
||||
switch (pdesc->flags & KVM_STATS_UNIT_MASK) {
|
||||
case KVM_STATS_UNIT_NONE:
|
||||
case KVM_STATS_UNIT_BYTES:
|
||||
case KVM_STATS_UNIT_CYCLES:
|
||||
case KVM_STATS_UNIT_SECONDS:
|
||||
case KVM_STATS_UNIT_BOOLEAN:
|
||||
break;
|
||||
default:
|
||||
return stats_list;
|
||||
}
|
||||
|
||||
switch (pdesc->flags & KVM_STATS_BASE_MASK) {
|
||||
case KVM_STATS_BASE_POW10:
|
||||
case KVM_STATS_BASE_POW2:
|
||||
break;
|
||||
default:
|
||||
return stats_list;
|
||||
}
|
||||
|
||||
/* Alloc and populate data list */
|
||||
stats = g_new0(Stats, 1);
|
||||
stats->name = g_strdup(pdesc->name);
|
||||
stats->value = g_new0(StatsValue, 1);;
|
||||
|
||||
if ((pdesc->flags & KVM_STATS_UNIT_MASK) == KVM_STATS_UNIT_BOOLEAN) {
|
||||
stats->value->u.boolean = *stats_data;
|
||||
stats->value->type = QTYPE_QBOOL;
|
||||
} else if (pdesc->size == 1) {
|
||||
stats->value->u.scalar = *stats_data;
|
||||
stats->value->type = QTYPE_QNUM;
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < pdesc->size; i++) {
|
||||
QAPI_LIST_PREPEND(val_list, stats_data[i]);
|
||||
}
|
||||
stats->value->u.list = val_list;
|
||||
stats->value->type = QTYPE_QLIST;
|
||||
}
|
||||
|
||||
QAPI_LIST_PREPEND(stats_list, stats);
|
||||
return stats_list;
|
||||
}
|
||||
|
||||
static StatsSchemaValueList *add_kvmschema_entry(struct kvm_stats_desc *pdesc,
|
||||
StatsSchemaValueList *list,
|
||||
Error **errp)
|
||||
{
|
||||
StatsSchemaValueList *schema_entry = g_new0(StatsSchemaValueList, 1);
|
||||
schema_entry->value = g_new0(StatsSchemaValue, 1);
|
||||
|
||||
switch (pdesc->flags & KVM_STATS_TYPE_MASK) {
|
||||
case KVM_STATS_TYPE_CUMULATIVE:
|
||||
schema_entry->value->type = STATS_TYPE_CUMULATIVE;
|
||||
break;
|
||||
case KVM_STATS_TYPE_INSTANT:
|
||||
schema_entry->value->type = STATS_TYPE_INSTANT;
|
||||
break;
|
||||
case KVM_STATS_TYPE_PEAK:
|
||||
schema_entry->value->type = STATS_TYPE_PEAK;
|
||||
break;
|
||||
case KVM_STATS_TYPE_LINEAR_HIST:
|
||||
schema_entry->value->type = STATS_TYPE_LINEAR_HISTOGRAM;
|
||||
schema_entry->value->bucket_size = pdesc->bucket_size;
|
||||
schema_entry->value->has_bucket_size = true;
|
||||
break;
|
||||
case KVM_STATS_TYPE_LOG_HIST:
|
||||
schema_entry->value->type = STATS_TYPE_LOG2_HISTOGRAM;
|
||||
break;
|
||||
default:
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (pdesc->flags & KVM_STATS_UNIT_MASK) {
|
||||
case KVM_STATS_UNIT_NONE:
|
||||
break;
|
||||
case KVM_STATS_UNIT_BOOLEAN:
|
||||
schema_entry->value->has_unit = true;
|
||||
schema_entry->value->unit = STATS_UNIT_BOOLEAN;
|
||||
break;
|
||||
case KVM_STATS_UNIT_BYTES:
|
||||
schema_entry->value->has_unit = true;
|
||||
schema_entry->value->unit = STATS_UNIT_BYTES;
|
||||
break;
|
||||
case KVM_STATS_UNIT_CYCLES:
|
||||
schema_entry->value->has_unit = true;
|
||||
schema_entry->value->unit = STATS_UNIT_CYCLES;
|
||||
break;
|
||||
case KVM_STATS_UNIT_SECONDS:
|
||||
schema_entry->value->has_unit = true;
|
||||
schema_entry->value->unit = STATS_UNIT_SECONDS;
|
||||
break;
|
||||
default:
|
||||
goto exit;
|
||||
}
|
||||
|
||||
schema_entry->value->exponent = pdesc->exponent;
|
||||
if (pdesc->exponent) {
|
||||
switch (pdesc->flags & KVM_STATS_BASE_MASK) {
|
||||
case KVM_STATS_BASE_POW10:
|
||||
schema_entry->value->has_base = true;
|
||||
schema_entry->value->base = 10;
|
||||
break;
|
||||
case KVM_STATS_BASE_POW2:
|
||||
schema_entry->value->has_base = true;
|
||||
schema_entry->value->base = 2;
|
||||
break;
|
||||
default:
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
schema_entry->value->name = g_strdup(pdesc->name);
|
||||
schema_entry->next = list;
|
||||
return schema_entry;
|
||||
exit:
|
||||
g_free(schema_entry->value);
|
||||
g_free(schema_entry);
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Cached stats descriptors */
|
||||
typedef struct StatsDescriptors {
|
||||
const char *ident; /* cache key, currently the StatsTarget */
|
||||
struct kvm_stats_desc *kvm_stats_desc;
|
||||
struct kvm_stats_header *kvm_stats_header;
|
||||
QTAILQ_ENTRY(StatsDescriptors) next;
|
||||
} StatsDescriptors;
|
||||
|
||||
static QTAILQ_HEAD(, StatsDescriptors) stats_descriptors =
|
||||
QTAILQ_HEAD_INITIALIZER(stats_descriptors);
|
||||
|
||||
/*
|
||||
* Return the descriptors for 'target', that either have already been read
|
||||
* or are retrieved from 'stats_fd'.
|
||||
*/
|
||||
static StatsDescriptors *find_stats_descriptors(StatsTarget target, int stats_fd,
|
||||
Error **errp)
|
||||
{
|
||||
StatsDescriptors *descriptors;
|
||||
const char *ident;
|
||||
struct kvm_stats_desc *kvm_stats_desc;
|
||||
struct kvm_stats_header *kvm_stats_header;
|
||||
size_t size_desc;
|
||||
ssize_t ret;
|
||||
|
||||
ident = StatsTarget_str(target);
|
||||
QTAILQ_FOREACH(descriptors, &stats_descriptors, next) {
|
||||
if (g_str_equal(descriptors->ident, ident)) {
|
||||
return descriptors;
|
||||
}
|
||||
}
|
||||
|
||||
descriptors = g_new0(StatsDescriptors, 1);
|
||||
|
||||
/* Read stats header */
|
||||
kvm_stats_header = g_malloc(sizeof(*kvm_stats_header));
|
||||
ret = read(stats_fd, kvm_stats_header, sizeof(*kvm_stats_header));
|
||||
if (ret != sizeof(*kvm_stats_header)) {
|
||||
error_setg(errp, "KVM stats: failed to read stats header: "
|
||||
"expected %zu actual %zu",
|
||||
sizeof(*kvm_stats_header), ret);
|
||||
g_free(descriptors);
|
||||
return NULL;
|
||||
}
|
||||
size_desc = sizeof(*kvm_stats_desc) + kvm_stats_header->name_size;
|
||||
|
||||
/* Read stats descriptors */
|
||||
kvm_stats_desc = g_malloc0_n(kvm_stats_header->num_desc, size_desc);
|
||||
ret = pread(stats_fd, kvm_stats_desc,
|
||||
size_desc * kvm_stats_header->num_desc,
|
||||
kvm_stats_header->desc_offset);
|
||||
|
||||
if (ret != size_desc * kvm_stats_header->num_desc) {
|
||||
error_setg(errp, "KVM stats: failed to read stats descriptors: "
|
||||
"expected %zu actual %zu",
|
||||
size_desc * kvm_stats_header->num_desc, ret);
|
||||
g_free(descriptors);
|
||||
g_free(kvm_stats_desc);
|
||||
return NULL;
|
||||
}
|
||||
descriptors->kvm_stats_header = kvm_stats_header;
|
||||
descriptors->kvm_stats_desc = kvm_stats_desc;
|
||||
descriptors->ident = ident;
|
||||
QTAILQ_INSERT_TAIL(&stats_descriptors, descriptors, next);
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
static void query_stats(StatsResultList **result, StatsTarget target,
|
||||
strList *names, int stats_fd, Error **errp)
|
||||
{
|
||||
struct kvm_stats_desc *kvm_stats_desc;
|
||||
struct kvm_stats_header *kvm_stats_header;
|
||||
StatsDescriptors *descriptors;
|
||||
g_autofree uint64_t *stats_data = NULL;
|
||||
struct kvm_stats_desc *pdesc;
|
||||
StatsList *stats_list = NULL;
|
||||
size_t size_desc, size_data = 0;
|
||||
ssize_t ret;
|
||||
int i;
|
||||
|
||||
descriptors = find_stats_descriptors(target, stats_fd, errp);
|
||||
if (!descriptors) {
|
||||
return;
|
||||
}
|
||||
|
||||
kvm_stats_header = descriptors->kvm_stats_header;
|
||||
kvm_stats_desc = descriptors->kvm_stats_desc;
|
||||
size_desc = sizeof(*kvm_stats_desc) + kvm_stats_header->name_size;
|
||||
|
||||
/* Tally the total data size; read schema data */
|
||||
for (i = 0; i < kvm_stats_header->num_desc; ++i) {
|
||||
pdesc = (void *)kvm_stats_desc + i * size_desc;
|
||||
size_data += pdesc->size * sizeof(*stats_data);
|
||||
}
|
||||
|
||||
stats_data = g_malloc0(size_data);
|
||||
ret = pread(stats_fd, stats_data, size_data, kvm_stats_header->data_offset);
|
||||
|
||||
if (ret != size_data) {
|
||||
error_setg(errp, "KVM stats: failed to read data: "
|
||||
"expected %zu actual %zu", size_data, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < kvm_stats_header->num_desc; ++i) {
|
||||
uint64_t *stats;
|
||||
pdesc = (void *)kvm_stats_desc + i * size_desc;
|
||||
|
||||
/* Add entry to the list */
|
||||
stats = (void *)stats_data + pdesc->offset;
|
||||
if (!apply_str_list_filter(pdesc->name, names)) {
|
||||
continue;
|
||||
}
|
||||
stats_list = add_kvmstat_entry(pdesc, stats, stats_list, errp);
|
||||
}
|
||||
|
||||
if (!stats_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (target) {
|
||||
case STATS_TARGET_VM:
|
||||
add_stats_entry(result, STATS_PROVIDER_KVM, NULL, stats_list);
|
||||
break;
|
||||
case STATS_TARGET_VCPU:
|
||||
add_stats_entry(result, STATS_PROVIDER_KVM,
|
||||
current_cpu->parent_obj.canonical_path,
|
||||
stats_list);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static void query_stats_schema(StatsSchemaList **result, StatsTarget target,
|
||||
int stats_fd, Error **errp)
|
||||
{
|
||||
struct kvm_stats_desc *kvm_stats_desc;
|
||||
struct kvm_stats_header *kvm_stats_header;
|
||||
StatsDescriptors *descriptors;
|
||||
struct kvm_stats_desc *pdesc;
|
||||
StatsSchemaValueList *stats_list = NULL;
|
||||
size_t size_desc;
|
||||
int i;
|
||||
|
||||
descriptors = find_stats_descriptors(target, stats_fd, errp);
|
||||
if (!descriptors) {
|
||||
return;
|
||||
}
|
||||
|
||||
kvm_stats_header = descriptors->kvm_stats_header;
|
||||
kvm_stats_desc = descriptors->kvm_stats_desc;
|
||||
size_desc = sizeof(*kvm_stats_desc) + kvm_stats_header->name_size;
|
||||
|
||||
/* Tally the total data size; read schema data */
|
||||
for (i = 0; i < kvm_stats_header->num_desc; ++i) {
|
||||
pdesc = (void *)kvm_stats_desc + i * size_desc;
|
||||
stats_list = add_kvmschema_entry(pdesc, stats_list, errp);
|
||||
}
|
||||
|
||||
add_stats_schema(result, STATS_PROVIDER_KVM, target, stats_list);
|
||||
}
|
||||
|
||||
static void query_stats_vcpu(CPUState *cpu, run_on_cpu_data data)
|
||||
{
|
||||
StatsArgs *kvm_stats_args = (StatsArgs *) data.host_ptr;
|
||||
int stats_fd = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (stats_fd == -1) {
|
||||
error_setg_errno(&local_err, errno, "KVM stats: ioctl failed");
|
||||
error_propagate(kvm_stats_args->errp, local_err);
|
||||
return;
|
||||
}
|
||||
query_stats(kvm_stats_args->result.stats, STATS_TARGET_VCPU,
|
||||
kvm_stats_args->names, stats_fd, kvm_stats_args->errp);
|
||||
close(stats_fd);
|
||||
}
|
||||
|
||||
static void query_stats_schema_vcpu(CPUState *cpu, run_on_cpu_data data)
|
||||
{
|
||||
StatsArgs *kvm_stats_args = (StatsArgs *) data.host_ptr;
|
||||
int stats_fd = kvm_vcpu_ioctl(cpu, KVM_GET_STATS_FD, NULL);
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (stats_fd == -1) {
|
||||
error_setg_errno(&local_err, errno, "KVM stats: ioctl failed");
|
||||
error_propagate(kvm_stats_args->errp, local_err);
|
||||
return;
|
||||
}
|
||||
query_stats_schema(kvm_stats_args->result.schema, STATS_TARGET_VCPU, stats_fd,
|
||||
kvm_stats_args->errp);
|
||||
close(stats_fd);
|
||||
}
|
||||
|
||||
static void query_stats_cb(StatsResultList **result, StatsTarget target,
|
||||
strList *names, strList *targets, Error **errp)
|
||||
{
|
||||
KVMState *s = kvm_state;
|
||||
CPUState *cpu;
|
||||
int stats_fd;
|
||||
|
||||
switch (target) {
|
||||
case STATS_TARGET_VM:
|
||||
{
|
||||
stats_fd = kvm_vm_ioctl(s, KVM_GET_STATS_FD, NULL);
|
||||
if (stats_fd == -1) {
|
||||
error_setg_errno(errp, errno, "KVM stats: ioctl failed");
|
||||
return;
|
||||
}
|
||||
query_stats(result, target, names, stats_fd, errp);
|
||||
close(stats_fd);
|
||||
break;
|
||||
}
|
||||
case STATS_TARGET_VCPU:
|
||||
{
|
||||
StatsArgs stats_args;
|
||||
stats_args.result.stats = result;
|
||||
stats_args.names = names;
|
||||
stats_args.errp = errp;
|
||||
CPU_FOREACH(cpu) {
|
||||
if (!apply_str_list_filter(cpu->parent_obj.canonical_path, targets)) {
|
||||
continue;
|
||||
}
|
||||
run_on_cpu(cpu, query_stats_vcpu, RUN_ON_CPU_HOST_PTR(&stats_args));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void query_stats_schemas_cb(StatsSchemaList **result, Error **errp)
|
||||
{
|
||||
StatsArgs stats_args;
|
||||
KVMState *s = kvm_state;
|
||||
int stats_fd;
|
||||
|
||||
stats_fd = kvm_vm_ioctl(s, KVM_GET_STATS_FD, NULL);
|
||||
if (stats_fd == -1) {
|
||||
error_setg_errno(errp, errno, "KVM stats: ioctl failed");
|
||||
return;
|
||||
}
|
||||
query_stats_schema(result, STATS_TARGET_VM, stats_fd, errp);
|
||||
close(stats_fd);
|
||||
|
||||
if (first_cpu) {
|
||||
stats_args.result.schema = result;
|
||||
stats_args.errp = errp;
|
||||
run_on_cpu(first_cpu, query_stats_schema_vcpu, RUN_ON_CPU_HOST_PTR(&stats_args));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,12 @@ specific_ss.add(files('accel-common.c'))
|
||||
softmmu_ss.add(files('accel-softmmu.c'))
|
||||
user_ss.add(files('accel-user.c'))
|
||||
|
||||
subdir('hvf')
|
||||
subdir('qtest')
|
||||
subdir('kvm')
|
||||
subdir('tcg')
|
||||
if have_system
|
||||
subdir('hvf')
|
||||
subdir('qtest')
|
||||
subdir('kvm')
|
||||
subdir('xen')
|
||||
subdir('stubs')
|
||||
endif
|
||||
subdir('xen')
|
||||
subdir('stubs')
|
||||
|
||||
dummy_ss = ss.source_set()
|
||||
dummy_ss.add(files(
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "qemu/accel.h"
|
||||
#include "sysemu/qtest.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "sysemu/cpu-timers.h"
|
||||
#include "qemu/guest-random.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "hw/core/cpu.h"
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "sysemu/hax.h"
|
||||
|
||||
bool hax_allowed;
|
||||
|
||||
int hax_sync_vcpus(void)
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -12,7 +12,10 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "sysemu/kvm.h"
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
#include "hw/pci/msi.h"
|
||||
#endif
|
||||
|
||||
KVMState *kvm_state;
|
||||
bool kvm_kernel_irqchip;
|
||||
@@ -77,7 +80,8 @@ int kvm_on_sigbus(int code, void *addr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev)
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -148,8 +152,4 @@ bool kvm_dirty_ring_enabled(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t kvm_dirty_ring_size(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
sysemu_stubs_ss = ss.source_set()
|
||||
sysemu_stubs_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c'))
|
||||
sysemu_stubs_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c'))
|
||||
sysemu_stubs_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c'))
|
||||
sysemu_stubs_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c'))
|
||||
|
||||
specific_ss.add_all(when: ['CONFIG_SOFTMMU'], if_true: sysemu_stubs_ss)
|
||||
specific_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c'))
|
||||
specific_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c'))
|
||||
specific_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c'))
|
||||
specific_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c'))
|
||||
|
||||
@@ -21,13 +21,6 @@ void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
|
||||
{
|
||||
}
|
||||
|
||||
int probe_access_flags(CPUArchState *env, target_ulong addr,
|
||||
MMUAccessType access_type, int mmu_idx,
|
||||
bool nonfault, void **phost, uintptr_t retaddr)
|
||||
{
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
void *probe_access(CPUArchState *env, target_ulong addr, int size,
|
||||
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
|
||||
{
|
||||
@@ -35,12 +28,12 @@ void *probe_access(CPUArchState *env, target_ulong addr, int size,
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
G_NORETURN void cpu_loop_exit(CPUState *cpu)
|
||||
void QEMU_NORETURN cpu_loop_exit(CPUState *cpu)
|
||||
{
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
G_NORETURN void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc)
|
||||
void QEMU_NORETURN cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc)
|
||||
{
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
static void atomic_trace_rmw_pre(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi)
|
||||
{
|
||||
CPUState *cpu = env_cpu(env);
|
||||
|
||||
trace_guest_rmw_before_exec(cpu, addr, oi);
|
||||
}
|
||||
|
||||
static void atomic_trace_rmw_post(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi)
|
||||
{
|
||||
@@ -20,12 +28,24 @@ static void atomic_trace_rmw_post(CPUArchState *env, target_ulong addr,
|
||||
}
|
||||
|
||||
#if HAVE_ATOMIC128
|
||||
static void atomic_trace_ld_pre(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi)
|
||||
{
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
}
|
||||
|
||||
static void atomic_trace_ld_post(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi)
|
||||
{
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
|
||||
}
|
||||
|
||||
static void atomic_trace_st_pre(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi)
|
||||
{
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
}
|
||||
|
||||
static void atomic_trace_st_post(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
the ATOMIC_NAME macro, and redefined below. */
|
||||
#if DATA_SIZE == 1
|
||||
# define END
|
||||
#elif HOST_BIG_ENDIAN
|
||||
#elif defined(HOST_WORDS_BIGENDIAN)
|
||||
# define END _be
|
||||
#else
|
||||
# define END _le
|
||||
@@ -77,6 +77,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
||||
PAGE_READ | PAGE_WRITE, retaddr);
|
||||
DATA_TYPE ret;
|
||||
|
||||
atomic_trace_rmw_pre(env, addr, oi);
|
||||
#if DATA_SIZE == 16
|
||||
ret = atomic16_cmpxchg(haddr, cmpv, newv);
|
||||
#else
|
||||
@@ -96,6 +97,7 @@ ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr,
|
||||
PAGE_READ, retaddr);
|
||||
DATA_TYPE val;
|
||||
|
||||
atomic_trace_ld_pre(env, addr, oi);
|
||||
val = atomic16_read(haddr);
|
||||
ATOMIC_MMU_CLEANUP;
|
||||
atomic_trace_ld_post(env, addr, oi);
|
||||
@@ -108,6 +110,7 @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
|
||||
PAGE_WRITE, retaddr);
|
||||
|
||||
atomic_trace_st_pre(env, addr, oi);
|
||||
atomic16_set(haddr, val);
|
||||
ATOMIC_MMU_CLEANUP;
|
||||
atomic_trace_st_post(env, addr, oi);
|
||||
@@ -121,6 +124,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
||||
PAGE_READ | PAGE_WRITE, retaddr);
|
||||
DATA_TYPE ret;
|
||||
|
||||
atomic_trace_rmw_pre(env, addr, oi);
|
||||
ret = qatomic_xchg__nocheck(haddr, val);
|
||||
ATOMIC_MMU_CLEANUP;
|
||||
atomic_trace_rmw_post(env, addr, oi);
|
||||
@@ -134,6 +138,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
|
||||
PAGE_READ | PAGE_WRITE, retaddr); \
|
||||
DATA_TYPE ret; \
|
||||
atomic_trace_rmw_pre(env, addr, oi); \
|
||||
ret = qatomic_##X(haddr, val); \
|
||||
ATOMIC_MMU_CLEANUP; \
|
||||
atomic_trace_rmw_post(env, addr, oi); \
|
||||
@@ -166,6 +171,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||
XDATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
|
||||
PAGE_READ | PAGE_WRITE, retaddr); \
|
||||
XDATA_TYPE cmp, old, new, val = xval; \
|
||||
atomic_trace_rmw_pre(env, addr, oi); \
|
||||
smp_mb(); \
|
||||
cmp = qatomic_read__nocheck(haddr); \
|
||||
do { \
|
||||
@@ -196,7 +202,7 @@ GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
|
||||
|
||||
/* Define reverse-host-endian atomic operations. Note that END is used
|
||||
within the ATOMIC_NAME macro. */
|
||||
#if HOST_BIG_ENDIAN
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
# define END _le
|
||||
#else
|
||||
# define END _be
|
||||
@@ -210,6 +216,7 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
|
||||
PAGE_READ | PAGE_WRITE, retaddr);
|
||||
DATA_TYPE ret;
|
||||
|
||||
atomic_trace_rmw_pre(env, addr, oi);
|
||||
#if DATA_SIZE == 16
|
||||
ret = atomic16_cmpxchg(haddr, BSWAP(cmpv), BSWAP(newv));
|
||||
#else
|
||||
@@ -229,6 +236,7 @@ ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr,
|
||||
PAGE_READ, retaddr);
|
||||
DATA_TYPE val;
|
||||
|
||||
atomic_trace_ld_pre(env, addr, oi);
|
||||
val = atomic16_read(haddr);
|
||||
ATOMIC_MMU_CLEANUP;
|
||||
atomic_trace_ld_post(env, addr, oi);
|
||||
@@ -241,6 +249,7 @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE,
|
||||
PAGE_WRITE, retaddr);
|
||||
|
||||
atomic_trace_st_pre(env, addr, oi);
|
||||
val = BSWAP(val);
|
||||
atomic16_set(haddr, val);
|
||||
ATOMIC_MMU_CLEANUP;
|
||||
@@ -255,6 +264,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val,
|
||||
PAGE_READ | PAGE_WRITE, retaddr);
|
||||
ABI_TYPE ret;
|
||||
|
||||
atomic_trace_rmw_pre(env, addr, oi);
|
||||
ret = qatomic_xchg__nocheck(haddr, BSWAP(val));
|
||||
ATOMIC_MMU_CLEANUP;
|
||||
atomic_trace_rmw_post(env, addr, oi);
|
||||
@@ -268,6 +278,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||
DATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
|
||||
PAGE_READ | PAGE_WRITE, retaddr); \
|
||||
DATA_TYPE ret; \
|
||||
atomic_trace_rmw_pre(env, addr, oi); \
|
||||
ret = qatomic_##X(haddr, BSWAP(val)); \
|
||||
ATOMIC_MMU_CLEANUP; \
|
||||
atomic_trace_rmw_post(env, addr, oi); \
|
||||
@@ -297,6 +308,7 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
|
||||
XDATA_TYPE *haddr = atomic_mmu_lookup(env, addr, oi, DATA_SIZE, \
|
||||
PAGE_READ | PAGE_WRITE, retaddr); \
|
||||
XDATA_TYPE ldo, ldn, old, new, val = xval; \
|
||||
atomic_trace_rmw_pre(env, addr, oi); \
|
||||
smp_mb(); \
|
||||
ldn = qatomic_read__nocheck(haddr); \
|
||||
do { \
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-commands-machine.h"
|
||||
@@ -214,19 +215,17 @@ static inline void log_cpu_exec(target_ulong pc, CPUState *cpu,
|
||||
|
||||
#if defined(DEBUG_DISAS)
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
|
||||
FILE *logfile = qemu_log_trylock();
|
||||
if (logfile) {
|
||||
int flags = 0;
|
||||
FILE *logfile = qemu_log_lock();
|
||||
int flags = 0;
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) {
|
||||
flags |= CPU_DUMP_FPU;
|
||||
}
|
||||
#if defined(TARGET_I386)
|
||||
flags |= CPU_DUMP_CCOP;
|
||||
#endif
|
||||
cpu_dump_state(cpu, logfile, flags);
|
||||
qemu_log_unlock(logfile);
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) {
|
||||
flags |= CPU_DUMP_FPU;
|
||||
}
|
||||
#if defined(TARGET_I386)
|
||||
flags |= CPU_DUMP_CCOP;
|
||||
#endif
|
||||
log_cpu_state(cpu, flags);
|
||||
qemu_log_unlock(logfile);
|
||||
}
|
||||
#endif /* DEBUG_DISAS */
|
||||
}
|
||||
@@ -423,7 +422,7 @@ static void cpu_exec_exit(CPUState *cpu)
|
||||
|
||||
void cpu_exec_step_atomic(CPUState *cpu)
|
||||
{
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
CPUArchState *env = (CPUArchState *)cpu->env_ptr;
|
||||
TranslationBlock *tb;
|
||||
target_ulong cs_base, pc;
|
||||
uint32_t flags, cflags;
|
||||
@@ -533,7 +532,7 @@ TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
|
||||
struct tb_desc desc;
|
||||
uint32_t h;
|
||||
|
||||
desc.env = cpu->env_ptr;
|
||||
desc.env = (CPUArchState *)cpu->env_ptr;
|
||||
desc.cs_base = cs_base;
|
||||
desc.flags = flags;
|
||||
desc.cflags = cflags;
|
||||
@@ -649,8 +648,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
|
||||
if (replay_has_exception()
|
||||
&& cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra == 0) {
|
||||
/* Execute just one insn to trigger exception pending in the log */
|
||||
cpu->cflags_next_tb = (curr_cflags(cpu) & ~CF_USE_ICOUNT)
|
||||
| CF_NOIRQ | 1;
|
||||
cpu->cflags_next_tb = (curr_cflags(cpu) & ~CF_USE_ICOUNT) | 1;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
@@ -800,12 +798,8 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
|
||||
* raised when single-stepping so that GDB doesn't miss the
|
||||
* next instruction.
|
||||
*/
|
||||
if (unlikely(cpu->singlestep_enabled)) {
|
||||
cpu->exception_index = EXCP_DEBUG;
|
||||
qemu_mutex_unlock_iothread();
|
||||
return true;
|
||||
}
|
||||
cpu->exception_index = -1;
|
||||
cpu->exception_index =
|
||||
(cpu->singlestep_enabled ? EXCP_DEBUG : -1);
|
||||
*last_tb = NULL;
|
||||
}
|
||||
/* The target hook may have updated the 'cpu->interrupt_request';
|
||||
@@ -1048,7 +1042,7 @@ void tcg_exec_unrealizefn(CPUState *cpu)
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
static void dump_drift_info(GString *buf)
|
||||
void dump_drift_info(GString *buf)
|
||||
{
|
||||
if (!icount_enabled()) {
|
||||
return;
|
||||
@@ -1091,40 +1085,9 @@ HumanReadableText *qmp_x_query_opcount(Error **errp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tcg_dump_op_count(buf);
|
||||
dump_opcount_info(buf);
|
||||
|
||||
return human_readable_text_from_str(buf);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROFILER
|
||||
|
||||
int64_t dev_time;
|
||||
|
||||
HumanReadableText *qmp_x_query_profile(Error **errp)
|
||||
{
|
||||
g_autoptr(GString) buf = g_string_new("");
|
||||
static int64_t last_cpu_exec_time;
|
||||
int64_t cpu_exec_time;
|
||||
int64_t delta;
|
||||
|
||||
cpu_exec_time = tcg_cpu_exec_time();
|
||||
delta = cpu_exec_time - last_cpu_exec_time;
|
||||
|
||||
g_string_append_printf(buf, "async time %" PRId64 " (%0.3f)\n",
|
||||
dev_time, dev_time / (double)NANOSECONDS_PER_SECOND);
|
||||
g_string_append_printf(buf, "qemu time %" PRId64 " (%0.3f)\n",
|
||||
delta, delta / (double)NANOSECONDS_PER_SECOND);
|
||||
last_cpu_exec_time = cpu_exec_time;
|
||||
dev_time = 0;
|
||||
|
||||
return human_readable_text_from_str(buf);
|
||||
}
|
||||
#else
|
||||
HumanReadableText *qmp_x_query_profile(Error **errp)
|
||||
{
|
||||
error_setg(errp, "Internal profiler not compiled");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
|
||||
@@ -783,15 +783,6 @@ static void tlb_flush_range_by_mmuidx_async_0(CPUState *cpu,
|
||||
}
|
||||
qemu_spin_unlock(&env_tlb(env)->c.lock);
|
||||
|
||||
/*
|
||||
* If the length is larger than the jump cache size, then it will take
|
||||
* longer to clear each entry individually than it will to clear it all.
|
||||
*/
|
||||
if (d.len >= (TARGET_PAGE_SIZE * TB_JMP_CACHE_SIZE)) {
|
||||
cpu_tb_jmp_cache_clear(cpu);
|
||||
return;
|
||||
}
|
||||
|
||||
for (target_ulong i = 0; i < d.len; i += TARGET_PAGE_SIZE) {
|
||||
tb_flush_jmp_cache(cpu, d.addr + i);
|
||||
}
|
||||
@@ -1761,7 +1752,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi, int size, int prot,
|
||||
uintptr_t retaddr)
|
||||
{
|
||||
uintptr_t mmu_idx = get_mmuidx(oi);
|
||||
size_t mmu_idx = get_mmuidx(oi);
|
||||
MemOp mop = get_memop(oi);
|
||||
int a_bits = get_alignment_bits(mop);
|
||||
uintptr_t index;
|
||||
@@ -1769,8 +1760,6 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
||||
target_ulong tlb_addr;
|
||||
void *hostaddr;
|
||||
|
||||
tcg_debug_assert(mmu_idx < NB_MMU_MODES);
|
||||
|
||||
/* Adjust the given return address. */
|
||||
retaddr -= GETPC_ADJ;
|
||||
|
||||
@@ -1896,9 +1885,9 @@ load_memop(const void *haddr, MemOp op)
|
||||
return (uint32_t)ldl_be_p(haddr);
|
||||
case MO_LEUL:
|
||||
return (uint32_t)ldl_le_p(haddr);
|
||||
case MO_BEUQ:
|
||||
case MO_BEQ:
|
||||
return ldq_be_p(haddr);
|
||||
case MO_LEUQ:
|
||||
case MO_LEQ:
|
||||
return ldq_le_p(haddr);
|
||||
default:
|
||||
qemu_build_not_reached();
|
||||
@@ -1910,20 +1899,18 @@ load_helper(CPUArchState *env, target_ulong addr, MemOpIdx oi,
|
||||
uintptr_t retaddr, MemOp op, bool code_read,
|
||||
FullLoadHelper *full_load)
|
||||
{
|
||||
uintptr_t mmu_idx = get_mmuidx(oi);
|
||||
uintptr_t index = tlb_index(env, mmu_idx, addr);
|
||||
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
|
||||
target_ulong tlb_addr = code_read ? entry->addr_code : entry->addr_read;
|
||||
const size_t tlb_off = code_read ?
|
||||
offsetof(CPUTLBEntry, addr_code) : offsetof(CPUTLBEntry, addr_read);
|
||||
const MMUAccessType access_type =
|
||||
code_read ? MMU_INST_FETCH : MMU_DATA_LOAD;
|
||||
const unsigned a_bits = get_alignment_bits(get_memop(oi));
|
||||
const size_t size = memop_size(op);
|
||||
uintptr_t mmu_idx = get_mmuidx(oi);
|
||||
uintptr_t index;
|
||||
CPUTLBEntry *entry;
|
||||
target_ulong tlb_addr;
|
||||
unsigned a_bits = get_alignment_bits(get_memop(oi));
|
||||
void *haddr;
|
||||
uint64_t res;
|
||||
|
||||
tcg_debug_assert(mmu_idx < NB_MMU_MODES);
|
||||
size_t size = memop_size(op);
|
||||
|
||||
/* Handle CPU specific unaligned behaviour */
|
||||
if (addr & ((1 << a_bits) - 1)) {
|
||||
@@ -1931,10 +1918,6 @@ load_helper(CPUArchState *env, target_ulong addr, MemOpIdx oi,
|
||||
mmu_idx, retaddr);
|
||||
}
|
||||
|
||||
index = tlb_index(env, mmu_idx, addr);
|
||||
entry = tlb_entry(env, mmu_idx, addr);
|
||||
tlb_addr = code_read ? entry->addr_code : entry->addr_read;
|
||||
|
||||
/* If the TLB entry is for a different page, reload and try again. */
|
||||
if (!tlb_hit(tlb_addr, addr)) {
|
||||
if (!victim_tlb_hit(env, mmu_idx, index, tlb_off,
|
||||
@@ -2098,16 +2081,16 @@ tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
|
||||
uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
validate_memop(oi, MO_LEUQ);
|
||||
return load_helper(env, addr, oi, retaddr, MO_LEUQ, false,
|
||||
validate_memop(oi, MO_LEQ);
|
||||
return load_helper(env, addr, oi, retaddr, MO_LEQ, false,
|
||||
helper_le_ldq_mmu);
|
||||
}
|
||||
|
||||
uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
validate_memop(oi, MO_BEUQ);
|
||||
return load_helper(env, addr, oi, retaddr, MO_BEUQ, false,
|
||||
validate_memop(oi, MO_BEQ);
|
||||
return load_helper(env, addr, oi, retaddr, MO_BEQ, false,
|
||||
helper_be_ldq_mmu);
|
||||
}
|
||||
|
||||
@@ -2157,6 +2140,7 @@ static inline uint64_t cpu_load_helper(CPUArchState *env, abi_ptr addr,
|
||||
{
|
||||
uint64_t ret;
|
||||
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
ret = full_load(env, addr, oi, retaddr);
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
|
||||
return ret;
|
||||
@@ -2182,7 +2166,7 @@ uint32_t cpu_ldl_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
uint64_t cpu_ldq_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
MemOpIdx oi, uintptr_t ra)
|
||||
{
|
||||
return cpu_load_helper(env, addr, oi, ra, helper_be_ldq_mmu);
|
||||
return cpu_load_helper(env, addr, oi, MO_BEQ, helper_be_ldq_mmu);
|
||||
}
|
||||
|
||||
uint16_t cpu_ldw_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
@@ -2226,10 +2210,10 @@ store_memop(void *haddr, uint64_t val, MemOp op)
|
||||
case MO_LEUL:
|
||||
stl_le_p(haddr, val);
|
||||
break;
|
||||
case MO_BEUQ:
|
||||
case MO_BEQ:
|
||||
stq_be_p(haddr, val);
|
||||
break;
|
||||
case MO_LEUQ:
|
||||
case MO_LEQ:
|
||||
stq_le_p(haddr, val);
|
||||
break;
|
||||
default:
|
||||
@@ -2248,7 +2232,7 @@ store_helper_unaligned(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
const size_t tlb_off = offsetof(CPUTLBEntry, addr_write);
|
||||
uintptr_t index, index2;
|
||||
CPUTLBEntry *entry, *entry2;
|
||||
target_ulong page1, page2, tlb_addr, tlb_addr2;
|
||||
target_ulong page2, tlb_addr, tlb_addr2;
|
||||
MemOpIdx oi;
|
||||
size_t size2;
|
||||
int i;
|
||||
@@ -2256,17 +2240,15 @@ store_helper_unaligned(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
/*
|
||||
* Ensure the second page is in the TLB. Note that the first page
|
||||
* is already guaranteed to be filled, and that the second page
|
||||
* cannot evict the first. An exception to this rule is PAGE_WRITE_INV
|
||||
* handling: the first page could have evicted itself.
|
||||
* cannot evict the first.
|
||||
*/
|
||||
page1 = addr & TARGET_PAGE_MASK;
|
||||
page2 = (addr + size) & TARGET_PAGE_MASK;
|
||||
size2 = (addr + size) & ~TARGET_PAGE_MASK;
|
||||
index2 = tlb_index(env, mmu_idx, page2);
|
||||
entry2 = tlb_entry(env, mmu_idx, page2);
|
||||
|
||||
tlb_addr2 = tlb_addr_write(entry2);
|
||||
if (page1 != page2 && !tlb_hit_page(tlb_addr2, page2)) {
|
||||
if (!tlb_hit_page(tlb_addr2, page2)) {
|
||||
if (!victim_tlb_hit(env, mmu_idx, index2, tlb_off, page2)) {
|
||||
tlb_fill(env_cpu(env), page2, size2, MMU_DATA_STORE,
|
||||
mmu_idx, retaddr);
|
||||
@@ -2320,16 +2302,14 @@ static inline void QEMU_ALWAYS_INLINE
|
||||
store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
MemOpIdx oi, uintptr_t retaddr, MemOp op)
|
||||
{
|
||||
const size_t tlb_off = offsetof(CPUTLBEntry, addr_write);
|
||||
const unsigned a_bits = get_alignment_bits(get_memop(oi));
|
||||
const size_t size = memop_size(op);
|
||||
uintptr_t mmu_idx = get_mmuidx(oi);
|
||||
uintptr_t index;
|
||||
CPUTLBEntry *entry;
|
||||
target_ulong tlb_addr;
|
||||
uintptr_t index = tlb_index(env, mmu_idx, addr);
|
||||
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
|
||||
target_ulong tlb_addr = tlb_addr_write(entry);
|
||||
const size_t tlb_off = offsetof(CPUTLBEntry, addr_write);
|
||||
unsigned a_bits = get_alignment_bits(get_memop(oi));
|
||||
void *haddr;
|
||||
|
||||
tcg_debug_assert(mmu_idx < NB_MMU_MODES);
|
||||
size_t size = memop_size(op);
|
||||
|
||||
/* Handle CPU specific unaligned behaviour */
|
||||
if (addr & ((1 << a_bits) - 1)) {
|
||||
@@ -2337,10 +2317,6 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
mmu_idx, retaddr);
|
||||
}
|
||||
|
||||
index = tlb_index(env, mmu_idx, addr);
|
||||
entry = tlb_entry(env, mmu_idx, addr);
|
||||
tlb_addr = tlb_addr_write(entry);
|
||||
|
||||
/* If the TLB entry is for a different page, reload and try again. */
|
||||
if (!tlb_hit(tlb_addr, addr)) {
|
||||
if (!victim_tlb_hit(env, mmu_idx, index, tlb_off,
|
||||
@@ -2489,15 +2465,15 @@ void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
|
||||
void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
validate_memop(oi, MO_LEUQ);
|
||||
store_helper(env, addr, val, oi, retaddr, MO_LEUQ);
|
||||
validate_memop(oi, MO_LEQ);
|
||||
store_helper(env, addr, val, oi, retaddr, MO_LEQ);
|
||||
}
|
||||
|
||||
void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
validate_memop(oi, MO_BEUQ);
|
||||
store_helper(env, addr, val, oi, retaddr, MO_BEUQ);
|
||||
validate_memop(oi, MO_BEQ);
|
||||
store_helper(env, addr, val, oi, retaddr, MO_BEQ);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2511,6 +2487,7 @@ static inline void cpu_store_helper(CPUArchState *env, target_ulong addr,
|
||||
uint64_t val, MemOpIdx oi, uintptr_t ra,
|
||||
FullStoreHelper *full_store)
|
||||
{
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
full_store(env, addr, val, oi, ra);
|
||||
qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
|
||||
}
|
||||
@@ -2568,6 +2545,7 @@ void cpu_stq_le_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
||||
glue(glue(glue(cpu_atomic_ ## X, SUFFIX), END), _mmu)
|
||||
|
||||
#define ATOMIC_MMU_CLEANUP
|
||||
#define ATOMIC_MMU_IDX get_mmuidx(oi)
|
||||
|
||||
#include "atomic_common.c.inc"
|
||||
|
||||
@@ -2631,11 +2609,11 @@ uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr)
|
||||
static uint64_t full_ldq_code(CPUArchState *env, target_ulong addr,
|
||||
MemOpIdx oi, uintptr_t retaddr)
|
||||
{
|
||||
return load_helper(env, addr, oi, retaddr, MO_TEUQ, true, full_ldq_code);
|
||||
return load_helper(env, addr, oi, retaddr, MO_TEQ, true, full_ldq_code);
|
||||
}
|
||||
|
||||
uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(env, true));
|
||||
MemOpIdx oi = make_memop_idx(MO_TEQ, cpu_mmu_index(env, true));
|
||||
return full_ldq_code(env, addr, oi, 0);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "qapi/qapi-commands-machine.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "sysemu/tcg.h"
|
||||
|
||||
static void hmp_tcg_register(void)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc,
|
||||
target_ulong cs_base, uint32_t flags,
|
||||
int cflags);
|
||||
G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
|
||||
|
||||
void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
|
||||
void page_init(void);
|
||||
void tb_htable_init(void);
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
||||
int mmu_idx, uintptr_t ra)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
|
||||
MemOpIdx oi = make_memop_idx(MO_BEQ | MO_UNALN, mmu_idx);
|
||||
return cpu_ldq_be_mmu(env, addr, oi, ra);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
||||
uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
||||
int mmu_idx, uintptr_t ra)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
|
||||
MemOpIdx oi = make_memop_idx(MO_LEQ | MO_UNALN, mmu_idx);
|
||||
return cpu_ldq_le_mmu(env, addr, oi, ra);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
|
||||
void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
int mmu_idx, uintptr_t ra)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
|
||||
MemOpIdx oi = make_memop_idx(MO_BEQ | MO_UNALN, mmu_idx);
|
||||
cpu_stq_be_mmu(env, addr, val, oi, ra);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
|
||||
void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
int mmu_idx, uintptr_t ra)
|
||||
{
|
||||
MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
|
||||
MemOpIdx oi = make_memop_idx(MO_LEQ | MO_UNALN, mmu_idx);
|
||||
cpu_stq_le_mmu(env, addr, val, oi, ra);
|
||||
}
|
||||
|
||||
|
||||
@@ -854,20 +854,10 @@ static void plugin_gen_inject(const struct qemu_plugin_tb *plugin_tb)
|
||||
|
||||
bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool mem_only)
|
||||
{
|
||||
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
|
||||
bool ret = false;
|
||||
|
||||
if (test_bit(QEMU_PLUGIN_EV_VCPU_TB_TRANS, cpu->plugin_mask)) {
|
||||
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
|
||||
int i;
|
||||
|
||||
/* reset callbacks */
|
||||
for (i = 0; i < PLUGIN_N_CB_SUBTYPES; i++) {
|
||||
if (ptb->cbs[i]) {
|
||||
g_array_set_size(ptb->cbs[i], 0);
|
||||
}
|
||||
}
|
||||
ptb->n = 0;
|
||||
|
||||
ret = true;
|
||||
|
||||
ptb->vaddr = tb->pc;
|
||||
@@ -878,9 +868,6 @@ bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool mem_onl
|
||||
|
||||
plugin_gen_empty_callback(PLUGIN_GEN_FROM_TB);
|
||||
}
|
||||
|
||||
tcg_ctx->plugin_insn = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -917,19 +904,23 @@ void plugin_gen_insn_end(void)
|
||||
plugin_gen_empty_callback(PLUGIN_GEN_AFTER_INSN);
|
||||
}
|
||||
|
||||
/*
|
||||
* There are cases where we never get to finalise a translation - for
|
||||
* example a page fault during translation. As a result we shouldn't
|
||||
* do any clean-up here and make sure things are reset in
|
||||
* plugin_gen_tb_start.
|
||||
*/
|
||||
void plugin_gen_tb_end(CPUState *cpu)
|
||||
{
|
||||
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
|
||||
int i;
|
||||
|
||||
/* collect instrumentation requests */
|
||||
qemu_plugin_tb_trans_cb(cpu, ptb);
|
||||
|
||||
/* inject the instrumentation at the appropriate places */
|
||||
plugin_gen_inject(ptb);
|
||||
|
||||
/* clean up */
|
||||
for (i = 0; i < PLUGIN_N_CB_SUBTYPES; i++) {
|
||||
if (ptb->cbs[i]) {
|
||||
g_array_set_size(ptb->cbs[i], 0);
|
||||
}
|
||||
}
|
||||
ptb->n = 0;
|
||||
tcg_ctx->plugin_insn = NULL;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu/tcg.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "sysemu/cpu-timers.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/guest-random.h"
|
||||
#include "exec/exec-all.h"
|
||||
@@ -84,7 +85,8 @@ void icount_handle_deadline(void)
|
||||
* Don't interrupt cpu thread, when these events are waiting
|
||||
* (i.e., there is no checkpoint)
|
||||
*/
|
||||
if (deadline == 0) {
|
||||
if (deadline == 0
|
||||
&& (replay_mode != REPLAY_MODE_PLAY || replay_has_checkpoint())) {
|
||||
icount_notify_aio_contexts();
|
||||
}
|
||||
}
|
||||
@@ -108,14 +110,8 @@ void icount_prepare_for_run(CPUState *cpu)
|
||||
|
||||
replay_mutex_lock();
|
||||
|
||||
if (cpu->icount_budget == 0) {
|
||||
/*
|
||||
* We're called without the iothread lock, so must take it while
|
||||
* we're calling timer handlers.
|
||||
*/
|
||||
qemu_mutex_lock_iothread();
|
||||
if (cpu->icount_budget == 0 && replay_has_checkpoint()) {
|
||||
icount_notify_aio_contexts();
|
||||
qemu_mutex_unlock_iothread();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef TCG_ACCEL_OPS_ICOUNT_H
|
||||
#define TCG_ACCEL_OPS_ICOUNT_H
|
||||
#ifndef TCG_CPUS_ICOUNT_H
|
||||
#define TCG_CPUS_ICOUNT_H
|
||||
|
||||
void icount_handle_deadline(void);
|
||||
void icount_prepare_for_run(CPUState *cpu);
|
||||
@@ -16,4 +16,4 @@ void icount_process_data(CPUState *cpu);
|
||||
|
||||
void icount_handle_interrupt(CPUState *cpu, int mask);
|
||||
|
||||
#endif /* TCG_ACCEL_OPS_ICOUNT_H */
|
||||
#endif /* TCG_CPUS_ICOUNT_H */
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu/tcg.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "sysemu/cpu-timers.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/notify.h"
|
||||
#include "qemu/guest-random.h"
|
||||
@@ -70,8 +70,6 @@ static void *mttcg_cpu_thread_fn(void *arg)
|
||||
assert(tcg_enabled());
|
||||
g_assert(!icount_enabled());
|
||||
|
||||
tcg_cpu_init_cflags(cpu, current_machine->smp.max_cpus > 1);
|
||||
|
||||
rcu_register_thread();
|
||||
force_rcu.notifier.notify = mttcg_force_rcu;
|
||||
force_rcu.cpu = cpu;
|
||||
@@ -141,7 +139,10 @@ void mttcg_start_vcpu_thread(CPUState *cpu)
|
||||
{
|
||||
char thread_name[VCPU_THREAD_NAME_SIZE];
|
||||
|
||||
cpu->thread = g_new0(QemuThread, 1);
|
||||
g_assert(tcg_enabled());
|
||||
tcg_cpu_init_cflags(cpu, current_machine->smp.max_cpus > 1);
|
||||
|
||||
cpu->thread = g_malloc0(sizeof(QemuThread));
|
||||
cpu->halt_cond = g_malloc0(sizeof(QemuCond));
|
||||
qemu_cond_init(cpu->halt_cond);
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef TCG_ACCEL_OPS_MTTCG_H
|
||||
#define TCG_ACCEL_OPS_MTTCG_H
|
||||
#ifndef TCG_CPUS_MTTCG_H
|
||||
#define TCG_CPUS_MTTCG_H
|
||||
|
||||
/* kick MTTCG vCPU thread */
|
||||
void mttcg_kick_vcpu_thread(CPUState *cpu);
|
||||
@@ -16,4 +16,4 @@ void mttcg_kick_vcpu_thread(CPUState *cpu);
|
||||
/* start an mttcg vCPU thread */
|
||||
void mttcg_start_vcpu_thread(CPUState *cpu);
|
||||
|
||||
#endif /* TCG_ACCEL_OPS_MTTCG_H */
|
||||
#endif /* TCG_CPUS_MTTCG_H */
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu/tcg.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "sysemu/cpu-timers.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/notify.h"
|
||||
#include "qemu/guest-random.h"
|
||||
@@ -152,9 +152,7 @@ static void *rr_cpu_thread_fn(void *arg)
|
||||
Notifier force_rcu;
|
||||
CPUState *cpu = arg;
|
||||
|
||||
g_assert(tcg_enabled());
|
||||
tcg_cpu_init_cflags(cpu, false);
|
||||
|
||||
assert(tcg_enabled());
|
||||
rcu_register_thread();
|
||||
force_rcu.notify = rr_force_rcu;
|
||||
rcu_add_force_rcu_notifier(&force_rcu);
|
||||
@@ -277,9 +275,12 @@ void rr_start_vcpu_thread(CPUState *cpu)
|
||||
static QemuCond *single_tcg_halt_cond;
|
||||
static QemuThread *single_tcg_cpu_thread;
|
||||
|
||||
g_assert(tcg_enabled());
|
||||
tcg_cpu_init_cflags(cpu, false);
|
||||
|
||||
if (!single_tcg_cpu_thread) {
|
||||
cpu->thread = g_new0(QemuThread, 1);
|
||||
cpu->halt_cond = g_new0(QemuCond, 1);
|
||||
cpu->thread = g_malloc0(sizeof(QemuThread));
|
||||
cpu->halt_cond = g_malloc0(sizeof(QemuCond));
|
||||
qemu_cond_init(cpu->halt_cond);
|
||||
|
||||
/* share a single thread for all cpus with TCG */
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef TCG_ACCEL_OPS_RR_H
|
||||
#define TCG_ACCEL_OPS_RR_H
|
||||
#ifndef TCG_CPUS_RR_H
|
||||
#define TCG_CPUS_RR_H
|
||||
|
||||
#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
|
||||
|
||||
@@ -18,4 +18,4 @@ void rr_kick_vcpu_thread(CPUState *unused);
|
||||
/* start the round robin vcpu thread */
|
||||
void rr_start_vcpu_thread(CPUState *cpu);
|
||||
|
||||
#endif /* TCG_ACCEL_OPS_RR_H */
|
||||
#endif /* TCG_CPUS_RR_H */
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu/tcg.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "sysemu/cpu-timers.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/guest-random.h"
|
||||
#include "exec/exec-all.h"
|
||||
@@ -97,17 +97,16 @@ static void tcg_accel_ops_init(AccelOpsClass *ops)
|
||||
ops->create_vcpu_thread = mttcg_start_vcpu_thread;
|
||||
ops->kick_vcpu_thread = mttcg_kick_vcpu_thread;
|
||||
ops->handle_interrupt = tcg_handle_interrupt;
|
||||
} else if (icount_enabled()) {
|
||||
ops->create_vcpu_thread = rr_start_vcpu_thread;
|
||||
ops->kick_vcpu_thread = rr_kick_vcpu_thread;
|
||||
ops->handle_interrupt = icount_handle_interrupt;
|
||||
ops->get_virtual_clock = icount_get;
|
||||
ops->get_elapsed_ticks = icount_get;
|
||||
} else {
|
||||
ops->create_vcpu_thread = rr_start_vcpu_thread;
|
||||
ops->kick_vcpu_thread = rr_kick_vcpu_thread;
|
||||
|
||||
if (icount_enabled()) {
|
||||
ops->handle_interrupt = icount_handle_interrupt;
|
||||
ops->get_virtual_clock = icount_get;
|
||||
ops->get_elapsed_ticks = icount_get;
|
||||
} else {
|
||||
ops->handle_interrupt = tcg_handle_interrupt;
|
||||
}
|
||||
ops->handle_interrupt = tcg_handle_interrupt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef TCG_ACCEL_OPS_H
|
||||
#define TCG_ACCEL_OPS_H
|
||||
#ifndef TCG_CPUS_H
|
||||
#define TCG_CPUS_H
|
||||
|
||||
#include "sysemu/cpus.h"
|
||||
|
||||
@@ -19,4 +19,4 @@ int tcg_cpus_exec(CPUState *cpu);
|
||||
void tcg_handle_interrupt(CPUState *cpu, int mask);
|
||||
void tcg_cpu_init_cflags(CPUState *cpu, bool parallel);
|
||||
|
||||
#endif /* TCG_ACCEL_OPS_H */
|
||||
#endif /* TCG_CPUS_H */
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu/tcg.h"
|
||||
#include "sysemu/cpu-timers.h"
|
||||
#include "tcg/tcg.h"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
|
||||
#define NO_CPU_IO_DEFS
|
||||
#include "trace.h"
|
||||
@@ -50,7 +51,6 @@
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/cacheinfo.h"
|
||||
#include "exec/log.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "sysemu/cpu-timers.h"
|
||||
@@ -1527,75 +1527,69 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) &&
|
||||
qemu_log_in_addr_range(tb->pc)) {
|
||||
FILE *logfile = qemu_log_trylock();
|
||||
if (logfile) {
|
||||
int code_size, data_size;
|
||||
const tcg_target_ulong *rx_data_gen_ptr;
|
||||
size_t chunk_start;
|
||||
int insn = 0;
|
||||
FILE *logfile = qemu_log_lock();
|
||||
int code_size, data_size;
|
||||
const tcg_target_ulong *rx_data_gen_ptr;
|
||||
size_t chunk_start;
|
||||
int insn = 0;
|
||||
|
||||
if (tcg_ctx->data_gen_ptr) {
|
||||
rx_data_gen_ptr = tcg_splitwx_to_rx(tcg_ctx->data_gen_ptr);
|
||||
code_size = (const void *)rx_data_gen_ptr - tb->tc.ptr;
|
||||
data_size = gen_code_size - code_size;
|
||||
} else {
|
||||
rx_data_gen_ptr = 0;
|
||||
code_size = gen_code_size;
|
||||
data_size = 0;
|
||||
}
|
||||
|
||||
/* Dump header and the first instruction */
|
||||
fprintf(logfile, "OUT: [size=%d]\n", gen_code_size);
|
||||
fprintf(logfile,
|
||||
" -- guest addr 0x" TARGET_FMT_lx " + tb prologue\n",
|
||||
tcg_ctx->gen_insn_data[insn][0]);
|
||||
chunk_start = tcg_ctx->gen_insn_end_off[insn];
|
||||
disas(logfile, tb->tc.ptr, chunk_start);
|
||||
|
||||
/*
|
||||
* Dump each instruction chunk, wrapping up empty chunks into
|
||||
* the next instruction. The whole array is offset so the
|
||||
* first entry is the beginning of the 2nd instruction.
|
||||
*/
|
||||
while (insn < tb->icount) {
|
||||
size_t chunk_end = tcg_ctx->gen_insn_end_off[insn];
|
||||
if (chunk_end > chunk_start) {
|
||||
fprintf(logfile, " -- guest addr 0x" TARGET_FMT_lx "\n",
|
||||
tcg_ctx->gen_insn_data[insn][0]);
|
||||
disas(logfile, tb->tc.ptr + chunk_start,
|
||||
chunk_end - chunk_start);
|
||||
chunk_start = chunk_end;
|
||||
}
|
||||
insn++;
|
||||
}
|
||||
|
||||
if (chunk_start < code_size) {
|
||||
fprintf(logfile, " -- tb slow paths + alignment\n");
|
||||
disas(logfile, tb->tc.ptr + chunk_start,
|
||||
code_size - chunk_start);
|
||||
}
|
||||
|
||||
/* Finally dump any data we may have after the block */
|
||||
if (data_size) {
|
||||
int i;
|
||||
fprintf(logfile, " data: [size=%d]\n", data_size);
|
||||
for (i = 0; i < data_size / sizeof(tcg_target_ulong); i++) {
|
||||
if (sizeof(tcg_target_ulong) == 8) {
|
||||
fprintf(logfile,
|
||||
"0x%08" PRIxPTR ": .quad 0x%016" TCG_PRIlx "\n",
|
||||
(uintptr_t)&rx_data_gen_ptr[i], rx_data_gen_ptr[i]);
|
||||
} else if (sizeof(tcg_target_ulong) == 4) {
|
||||
fprintf(logfile,
|
||||
"0x%08" PRIxPTR ": .long 0x%08" TCG_PRIlx "\n",
|
||||
(uintptr_t)&rx_data_gen_ptr[i], rx_data_gen_ptr[i]);
|
||||
} else {
|
||||
qemu_build_not_reached();
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(logfile, "\n");
|
||||
qemu_log_unlock(logfile);
|
||||
if (tcg_ctx->data_gen_ptr) {
|
||||
rx_data_gen_ptr = tcg_splitwx_to_rx(tcg_ctx->data_gen_ptr);
|
||||
code_size = (const void *)rx_data_gen_ptr - tb->tc.ptr;
|
||||
data_size = gen_code_size - code_size;
|
||||
} else {
|
||||
rx_data_gen_ptr = 0;
|
||||
code_size = gen_code_size;
|
||||
data_size = 0;
|
||||
}
|
||||
|
||||
/* Dump header and the first instruction */
|
||||
qemu_log("OUT: [size=%d]\n", gen_code_size);
|
||||
qemu_log(" -- guest addr 0x" TARGET_FMT_lx " + tb prologue\n",
|
||||
tcg_ctx->gen_insn_data[insn][0]);
|
||||
chunk_start = tcg_ctx->gen_insn_end_off[insn];
|
||||
log_disas(tb->tc.ptr, chunk_start);
|
||||
|
||||
/*
|
||||
* Dump each instruction chunk, wrapping up empty chunks into
|
||||
* the next instruction. The whole array is offset so the
|
||||
* first entry is the beginning of the 2nd instruction.
|
||||
*/
|
||||
while (insn < tb->icount) {
|
||||
size_t chunk_end = tcg_ctx->gen_insn_end_off[insn];
|
||||
if (chunk_end > chunk_start) {
|
||||
qemu_log(" -- guest addr 0x" TARGET_FMT_lx "\n",
|
||||
tcg_ctx->gen_insn_data[insn][0]);
|
||||
log_disas(tb->tc.ptr + chunk_start, chunk_end - chunk_start);
|
||||
chunk_start = chunk_end;
|
||||
}
|
||||
insn++;
|
||||
}
|
||||
|
||||
if (chunk_start < code_size) {
|
||||
qemu_log(" -- tb slow paths + alignment\n");
|
||||
log_disas(tb->tc.ptr + chunk_start, code_size - chunk_start);
|
||||
}
|
||||
|
||||
/* Finally dump any data we may have after the block */
|
||||
if (data_size) {
|
||||
int i;
|
||||
qemu_log(" data: [size=%d]\n", data_size);
|
||||
for (i = 0; i < data_size / sizeof(tcg_target_ulong); i++) {
|
||||
if (sizeof(tcg_target_ulong) == 8) {
|
||||
qemu_log("0x%08" PRIxPTR ": .quad 0x%016" TCG_PRIlx "\n",
|
||||
(uintptr_t)&rx_data_gen_ptr[i], rx_data_gen_ptr[i]);
|
||||
} else if (sizeof(tcg_target_ulong) == 4) {
|
||||
qemu_log("0x%08" PRIxPTR ": .long 0x%08" TCG_PRIlx "\n",
|
||||
(uintptr_t)&rx_data_gen_ptr[i], rx_data_gen_ptr[i]);
|
||||
} else {
|
||||
qemu_build_not_reached();
|
||||
}
|
||||
}
|
||||
}
|
||||
qemu_log("\n");
|
||||
qemu_log_flush();
|
||||
qemu_log_unlock(logfile);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2124,6 +2118,11 @@ void dump_exec_info(GString *buf)
|
||||
tcg_dump_info(buf);
|
||||
}
|
||||
|
||||
void dump_opcount_info(GString *buf)
|
||||
{
|
||||
tcg_dump_op_count(buf);
|
||||
}
|
||||
|
||||
#else /* CONFIG_USER_ONLY */
|
||||
|
||||
void cpu_interrupt(CPUState *cpu, int mask)
|
||||
@@ -2256,15 +2255,6 @@ int page_get_flags(target_ulong address)
|
||||
return p->flags;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow the target to decide if PAGE_TARGET_[12] may be reset.
|
||||
* By default, they are not kept.
|
||||
*/
|
||||
#ifndef PAGE_TARGET_STICKY
|
||||
#define PAGE_TARGET_STICKY 0
|
||||
#endif
|
||||
#define PAGE_STICKY (PAGE_ANON | PAGE_TARGET_STICKY)
|
||||
|
||||
/* 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. */
|
||||
@@ -2308,38 +2298,12 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
|
||||
p->target_data = NULL;
|
||||
p->flags = flags;
|
||||
} else {
|
||||
/* Using mprotect on a page does not change sticky bits. */
|
||||
p->flags = (p->flags & PAGE_STICKY) | flags;
|
||||
/* Using mprotect on a page does not change MAP_ANON. */
|
||||
p->flags = (p->flags & PAGE_ANON) | flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void page_reset_target_data(target_ulong start, target_ulong end)
|
||||
{
|
||||
target_ulong addr, len;
|
||||
|
||||
/*
|
||||
* This function should never be called with addresses outside the
|
||||
* guest address space. If this assert fires, it probably indicates
|
||||
* a missing call to h2g_valid.
|
||||
*/
|
||||
assert(end - 1 <= GUEST_ADDR_MAX);
|
||||
assert(start < end);
|
||||
assert_memory_lock();
|
||||
|
||||
start = start & TARGET_PAGE_MASK;
|
||||
end = TARGET_PAGE_ALIGN(end);
|
||||
|
||||
for (addr = start, len = end - start;
|
||||
len != 0;
|
||||
len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
|
||||
PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
|
||||
|
||||
g_free(p->target_data);
|
||||
p->target_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *page_get_target_data(target_ulong address)
|
||||
{
|
||||
PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
|
||||
|
||||
@@ -139,13 +139,11 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
||||
#ifdef DEBUG_DISAS
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
|
||||
&& qemu_log_in_addr_range(db->pc_first)) {
|
||||
FILE *logfile = qemu_log_trylock();
|
||||
if (logfile) {
|
||||
fprintf(logfile, "----------------\n");
|
||||
ops->disas_log(db, cpu, logfile);
|
||||
fprintf(logfile, "\n");
|
||||
qemu_log_unlock(logfile);
|
||||
}
|
||||
FILE *logfile = qemu_log_lock();
|
||||
qemu_log("----------------\n");
|
||||
ops->disas_log(db, cpu);
|
||||
qemu_log("\n");
|
||||
qemu_log_unlock(logfile);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -101,10 +101,10 @@ MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write)
|
||||
* Return true if the write fault has been handled, and should be re-tried.
|
||||
*
|
||||
* Note that it is important that we don't call page_unprotect() unless
|
||||
* this is really a "write to nonwritable page" fault, because
|
||||
* this is really a "write to nonwriteable page" fault, because
|
||||
* page_unprotect() assumes that if it is called for an access to
|
||||
* a page that's writable this means we had two threads racing and
|
||||
* another thread got there first and already made the page writable;
|
||||
* a page that's writeable this means we had two threads racing and
|
||||
* another thread got there first and already made the page writeable;
|
||||
* so we will retry the access. If we were to call page_unprotect()
|
||||
* for some other kind of fault that should really be passed to the
|
||||
* guest, we'd end up in an infinite loop of retrying the faulting access.
|
||||
@@ -250,6 +250,7 @@ uint8_t cpu_ldb_mmu(CPUArchState *env, abi_ptr addr,
|
||||
uint8_t ret;
|
||||
|
||||
validate_memop(oi, MO_UB);
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
ret = ldub_p(haddr);
|
||||
clear_helper_retaddr();
|
||||
@@ -264,6 +265,7 @@ uint16_t cpu_ldw_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
uint16_t ret;
|
||||
|
||||
validate_memop(oi, MO_BEUW);
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
ret = lduw_be_p(haddr);
|
||||
clear_helper_retaddr();
|
||||
@@ -278,6 +280,7 @@ uint32_t cpu_ldl_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
uint32_t ret;
|
||||
|
||||
validate_memop(oi, MO_BEUL);
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
ret = ldl_be_p(haddr);
|
||||
clear_helper_retaddr();
|
||||
@@ -291,7 +294,8 @@ uint64_t cpu_ldq_be_mmu(CPUArchState *env, abi_ptr addr,
|
||||
void *haddr;
|
||||
uint64_t ret;
|
||||
|
||||
validate_memop(oi, MO_BEUQ);
|
||||
validate_memop(oi, MO_BEQ);
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
ret = ldq_be_p(haddr);
|
||||
clear_helper_retaddr();
|
||||
@@ -306,6 +310,7 @@ uint16_t cpu_ldw_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
uint16_t ret;
|
||||
|
||||
validate_memop(oi, MO_LEUW);
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
ret = lduw_le_p(haddr);
|
||||
clear_helper_retaddr();
|
||||
@@ -320,6 +325,7 @@ uint32_t cpu_ldl_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
uint32_t ret;
|
||||
|
||||
validate_memop(oi, MO_LEUL);
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
ret = ldl_le_p(haddr);
|
||||
clear_helper_retaddr();
|
||||
@@ -333,7 +339,8 @@ uint64_t cpu_ldq_le_mmu(CPUArchState *env, abi_ptr addr,
|
||||
void *haddr;
|
||||
uint64_t ret;
|
||||
|
||||
validate_memop(oi, MO_LEUQ);
|
||||
validate_memop(oi, MO_LEQ);
|
||||
trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD);
|
||||
ret = ldq_le_p(haddr);
|
||||
clear_helper_retaddr();
|
||||
@@ -347,6 +354,7 @@ void cpu_stb_mmu(CPUArchState *env, abi_ptr addr, uint8_t val,
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_UB);
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
stb_p(haddr, val);
|
||||
clear_helper_retaddr();
|
||||
@@ -359,6 +367,7 @@ void cpu_stw_be_mmu(CPUArchState *env, abi_ptr addr, uint16_t val,
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_BEUW);
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
stw_be_p(haddr, val);
|
||||
clear_helper_retaddr();
|
||||
@@ -371,6 +380,7 @@ void cpu_stl_be_mmu(CPUArchState *env, abi_ptr addr, uint32_t val,
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_BEUL);
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
stl_be_p(haddr, val);
|
||||
clear_helper_retaddr();
|
||||
@@ -382,7 +392,8 @@ void cpu_stq_be_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
{
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_BEUQ);
|
||||
validate_memop(oi, MO_BEQ);
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
stq_be_p(haddr, val);
|
||||
clear_helper_retaddr();
|
||||
@@ -395,6 +406,7 @@ void cpu_stw_le_mmu(CPUArchState *env, abi_ptr addr, uint16_t val,
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_LEUW);
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
stw_le_p(haddr, val);
|
||||
clear_helper_retaddr();
|
||||
@@ -407,6 +419,7 @@ void cpu_stl_le_mmu(CPUArchState *env, abi_ptr addr, uint32_t val,
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_LEUL);
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
stl_le_p(haddr, val);
|
||||
clear_helper_retaddr();
|
||||
@@ -418,7 +431,8 @@ void cpu_stq_le_mmu(CPUArchState *env, abi_ptr addr, uint64_t val,
|
||||
{
|
||||
void *haddr;
|
||||
|
||||
validate_memop(oi, MO_LEUQ);
|
||||
validate_memop(oi, MO_LEQ);
|
||||
trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
||||
haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_STORE);
|
||||
stq_le_p(haddr, val);
|
||||
clear_helper_retaddr();
|
||||
@@ -506,6 +520,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
||||
#define ATOMIC_NAME(X) \
|
||||
glue(glue(glue(cpu_atomic_ ## X, SUFFIX), END), _mmu)
|
||||
#define ATOMIC_MMU_CLEANUP do { clear_helper_retaddr(); } while (0)
|
||||
#define ATOMIC_MMU_IDX MMU_USER_IDX
|
||||
|
||||
#define DATA_SIZE 1
|
||||
#include "atomic_template.h"
|
||||
|
||||
@@ -72,7 +72,7 @@ struct alsa_params_obt {
|
||||
snd_pcm_uframes_t samples;
|
||||
};
|
||||
|
||||
static void G_GNUC_PRINTF (2, 3) alsa_logerr (int err, const char *fmt, ...)
|
||||
static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -83,7 +83,7 @@ static void G_GNUC_PRINTF (2, 3) alsa_logerr (int err, const char *fmt, ...)
|
||||
AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
|
||||
}
|
||||
|
||||
static void G_GNUC_PRINTF (3, 4) alsa_logerr2 (
|
||||
static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
|
||||
int err,
|
||||
const char *typ,
|
||||
const char *fmt,
|
||||
@@ -916,7 +916,6 @@ static struct audio_pcm_ops alsa_pcm_ops = {
|
||||
.init_out = alsa_init_out,
|
||||
.fini_out = alsa_fini_out,
|
||||
.write = alsa_write,
|
||||
.buffer_get_free = audio_generic_buffer_get_free,
|
||||
.run_buffer_out = audio_generic_run_buffer_out,
|
||||
.enable_out = alsa_enable_out,
|
||||
|
||||
|
||||
254
audio/audio.c
254
audio/audio.c
@@ -32,7 +32,7 @@
|
||||
#include "qapi/qapi-visit-audio.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/module.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "ui/qemu-spice.h"
|
||||
@@ -72,24 +72,20 @@ void audio_driver_register(audio_driver *drv)
|
||||
audio_driver *audio_driver_lookup(const char *name)
|
||||
{
|
||||
struct audio_driver *d;
|
||||
Error *local_err = NULL;
|
||||
int rv;
|
||||
|
||||
QLIST_FOREACH(d, &audio_drivers, next) {
|
||||
if (strcmp(name, d->name) == 0) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
rv = audio_module_load(name, &local_err);
|
||||
if (rv > 0) {
|
||||
QLIST_FOREACH(d, &audio_drivers, next) {
|
||||
if (strcmp(name, d->name) == 0) {
|
||||
return d;
|
||||
}
|
||||
|
||||
audio_module_load_one(name);
|
||||
QLIST_FOREACH(d, &audio_drivers, next) {
|
||||
if (strcmp(name, d->name) == 0) {
|
||||
return d;
|
||||
}
|
||||
} else if (rv < 0) {
|
||||
error_report_err(local_err);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -121,6 +117,7 @@ int audio_bug (const char *funcname, int cond)
|
||||
AUD_log (NULL, "I am sorry\n");
|
||||
}
|
||||
AUD_log (NULL, "Context:\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
return cond;
|
||||
@@ -141,7 +138,7 @@ static inline int audio_bits_to_index (int bits)
|
||||
default:
|
||||
audio_bug ("bits_to_index", 1);
|
||||
AUD_log (NULL, "invalid bits %d\n", bits);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +156,7 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size)
|
||||
AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
|
||||
funcname);
|
||||
AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_malloc0 (len);
|
||||
@@ -546,50 +543,70 @@ static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw)
|
||||
size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
|
||||
if (audio_bug(__func__, live > hw->conv_buf->size)) {
|
||||
dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
return live;
|
||||
}
|
||||
|
||||
static size_t audio_pcm_hw_conv_in(HWVoiceIn *hw, void *pcm_buf, size_t samples)
|
||||
static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len)
|
||||
{
|
||||
size_t conv = 0;
|
||||
STSampleBuffer *conv_buf = hw->conv_buf;
|
||||
size_t clipped = 0;
|
||||
size_t pos = hw->mix_buf->pos;
|
||||
|
||||
while (samples) {
|
||||
uint8_t *src = advance(pcm_buf, conv * hw->info.bytes_per_frame);
|
||||
size_t proc = MIN(samples, conv_buf->size - conv_buf->pos);
|
||||
while (len) {
|
||||
st_sample *src = hw->mix_buf->samples + pos;
|
||||
uint8_t *dst = advance(pcm_buf, clipped * hw->info.bytes_per_frame);
|
||||
size_t samples_till_end_of_buf = hw->mix_buf->size - pos;
|
||||
size_t samples_to_clip = MIN(len, samples_till_end_of_buf);
|
||||
|
||||
hw->conv(conv_buf->samples + conv_buf->pos, src, proc);
|
||||
conv_buf->pos = (conv_buf->pos + proc) % conv_buf->size;
|
||||
samples -= proc;
|
||||
conv += proc;
|
||||
hw->clip(dst, src, samples_to_clip);
|
||||
|
||||
pos = (pos + samples_to_clip) % hw->mix_buf->size;
|
||||
len -= samples_to_clip;
|
||||
clipped += samples_to_clip;
|
||||
}
|
||||
|
||||
return conv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Soft voice (capture)
|
||||
*/
|
||||
static size_t audio_pcm_sw_get_rpos_in(SWVoiceIn *sw)
|
||||
{
|
||||
HWVoiceIn *hw = sw->hw;
|
||||
ssize_t live = hw->total_samples_captured - sw->total_hw_samples_acquired;
|
||||
ssize_t rpos;
|
||||
|
||||
if (audio_bug(__func__, live < 0 || live > hw->conv_buf->size)) {
|
||||
dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rpos = hw->conv_buf->pos - live;
|
||||
if (rpos >= 0) {
|
||||
return rpos;
|
||||
} else {
|
||||
return hw->conv_buf->size + rpos;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
|
||||
{
|
||||
HWVoiceIn *hw = sw->hw;
|
||||
size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
|
||||
struct st_sample *src, *dst = sw->buf;
|
||||
|
||||
rpos = audio_pcm_sw_get_rpos_in(sw) % hw->conv_buf->size;
|
||||
|
||||
live = hw->total_samples_captured - sw->total_hw_samples_acquired;
|
||||
if (audio_bug(__func__, live > hw->conv_buf->size)) {
|
||||
dolog("live_in=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
samples = size / sw->info.bytes_per_frame;
|
||||
if (!live) {
|
||||
return 0;
|
||||
}
|
||||
if (audio_bug(__func__, live > hw->conv_buf->size)) {
|
||||
dolog("live_in=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
||||
abort();
|
||||
}
|
||||
|
||||
rpos = audio_ring_posb(hw->conv_buf->pos, live, hw->conv_buf->size);
|
||||
|
||||
samples = size / sw->info.bytes_per_frame;
|
||||
|
||||
swlim = (live * sw->ratio) >> 32;
|
||||
swlim = MIN (swlim, samples);
|
||||
@@ -615,7 +632,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
|
||||
total += isamp;
|
||||
}
|
||||
|
||||
if (!hw->pcm_ops->volume_in) {
|
||||
if (hw->pcm_ops && !hw->pcm_ops->volume_in) {
|
||||
mixeng_volume (sw->buf, ret, &sw->vol);
|
||||
}
|
||||
|
||||
@@ -659,45 +676,19 @@ static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
|
||||
|
||||
if (audio_bug(__func__, live > hw->mix_buf->size)) {
|
||||
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
return live;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t audio_pcm_hw_get_free(HWVoiceOut *hw)
|
||||
{
|
||||
return (hw->pcm_ops->buffer_get_free ? hw->pcm_ops->buffer_get_free(hw) :
|
||||
INT_MAX) / hw->info.bytes_per_frame;
|
||||
}
|
||||
|
||||
static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void *pcm_buf, size_t len)
|
||||
{
|
||||
size_t clipped = 0;
|
||||
size_t pos = hw->mix_buf->pos;
|
||||
|
||||
while (len) {
|
||||
st_sample *src = hw->mix_buf->samples + pos;
|
||||
uint8_t *dst = advance(pcm_buf, clipped * hw->info.bytes_per_frame);
|
||||
size_t samples_till_end_of_buf = hw->mix_buf->size - pos;
|
||||
size_t samples_to_clip = MIN(len, samples_till_end_of_buf);
|
||||
|
||||
hw->clip(dst, src, samples_to_clip);
|
||||
|
||||
pos = (pos + samples_to_clip) % hw->mix_buf->size;
|
||||
len -= samples_to_clip;
|
||||
clipped += samples_to_clip;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Soft voice (playback)
|
||||
*/
|
||||
static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
|
||||
{
|
||||
size_t hwsamples, samples, isamp, osamp, wpos, live, dead, left, blck;
|
||||
size_t hw_free;
|
||||
size_t hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
|
||||
size_t ret = 0, pos = 0, total = 0;
|
||||
|
||||
if (!sw) {
|
||||
@@ -709,7 +700,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
|
||||
live = sw->total_hw_samples_mixed;
|
||||
if (audio_bug(__func__, live > hwsamples)) {
|
||||
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hwsamples);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (live == hwsamples) {
|
||||
@@ -720,28 +711,27 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
|
||||
}
|
||||
|
||||
wpos = (sw->hw->mix_buf->pos + live) % hwsamples;
|
||||
samples = size / sw->info.bytes_per_frame;
|
||||
|
||||
dead = hwsamples - live;
|
||||
hw_free = audio_pcm_hw_get_free(sw->hw);
|
||||
hw_free = hw_free > live ? hw_free - live : 0;
|
||||
samples = ((int64_t)MIN(dead, hw_free) << 32) / sw->ratio;
|
||||
samples = MIN(samples, size / sw->info.bytes_per_frame);
|
||||
if (samples) {
|
||||
sw->conv(sw->buf, buf, samples);
|
||||
swlim = ((int64_t) dead << 32) / sw->ratio;
|
||||
swlim = MIN (swlim, samples);
|
||||
if (swlim) {
|
||||
sw->conv (sw->buf, buf, swlim);
|
||||
|
||||
if (!sw->hw->pcm_ops->volume_out) {
|
||||
mixeng_volume(sw->buf, samples, &sw->vol);
|
||||
if (sw->hw->pcm_ops && !sw->hw->pcm_ops->volume_out) {
|
||||
mixeng_volume (sw->buf, swlim, &sw->vol);
|
||||
}
|
||||
}
|
||||
|
||||
while (samples) {
|
||||
while (swlim) {
|
||||
dead = hwsamples - live;
|
||||
left = hwsamples - wpos;
|
||||
blck = MIN (dead, left);
|
||||
if (!blck) {
|
||||
break;
|
||||
}
|
||||
isamp = samples;
|
||||
isamp = swlim;
|
||||
osamp = blck;
|
||||
st_rate_flow_mix (
|
||||
sw->rate,
|
||||
@@ -751,7 +741,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
|
||||
&osamp
|
||||
);
|
||||
ret += isamp;
|
||||
samples -= isamp;
|
||||
swlim -= isamp;
|
||||
pos += isamp;
|
||||
live += osamp;
|
||||
wpos = (wpos + osamp) % hwsamples;
|
||||
@@ -1001,7 +991,7 @@ static size_t audio_get_avail (SWVoiceIn *sw)
|
||||
if (audio_bug(__func__, live > sw->hw->conv_buf->size)) {
|
||||
dolog("live=%zu sw->hw->conv_buf->size=%zu\n", live,
|
||||
sw->hw->conv_buf->size);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ldebug (
|
||||
@@ -1013,11 +1003,6 @@ static size_t audio_get_avail (SWVoiceIn *sw)
|
||||
return (((int64_t) live << 32) / sw->ratio) * sw->info.bytes_per_frame;
|
||||
}
|
||||
|
||||
static size_t audio_sw_bytes_free(SWVoiceOut *sw, size_t free)
|
||||
{
|
||||
return (((int64_t)free << 32) / sw->ratio) * sw->info.bytes_per_frame;
|
||||
}
|
||||
|
||||
static size_t audio_get_free(SWVoiceOut *sw)
|
||||
{
|
||||
size_t live, dead;
|
||||
@@ -1031,17 +1016,19 @@ static size_t audio_get_free(SWVoiceOut *sw)
|
||||
if (audio_bug(__func__, live > sw->hw->mix_buf->size)) {
|
||||
dolog("live=%zu sw->hw->mix_buf->size=%zu\n", live,
|
||||
sw->hw->mix_buf->size);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
dead = sw->hw->mix_buf->size - live;
|
||||
|
||||
#ifdef DEBUG_OUT
|
||||
dolog("%s: get_free live %zu dead %zu sw_bytes %zu\n",
|
||||
SW_NAME(sw), live, dead, audio_sw_bytes_free(sw, dead));
|
||||
dolog ("%s: get_free live %zu dead %zu ret %" PRId64 "\n",
|
||||
SW_NAME (sw),
|
||||
live, dead, (((int64_t) dead << 32) / sw->ratio) *
|
||||
sw->info.bytes_per_frame);
|
||||
#endif
|
||||
|
||||
return dead;
|
||||
return (((int64_t) dead << 32) / sw->ratio) * sw->info.bytes_per_frame;
|
||||
}
|
||||
|
||||
static void audio_capture_mix_and_clear(HWVoiceOut *hw, size_t rpos,
|
||||
@@ -1145,27 +1132,9 @@ static void audio_run_out (AudioState *s)
|
||||
}
|
||||
|
||||
while ((hw = audio_pcm_hw_find_any_enabled_out(s, hw))) {
|
||||
size_t played, live, prev_rpos;
|
||||
size_t hw_free = audio_pcm_hw_get_free(hw);
|
||||
size_t played, live, prev_rpos, free;
|
||||
int nb_live;
|
||||
|
||||
for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
|
||||
if (sw->active) {
|
||||
size_t sw_free = audio_get_free(sw);
|
||||
size_t free;
|
||||
|
||||
if (hw_free > sw->total_hw_samples_mixed) {
|
||||
free = audio_sw_bytes_free(sw,
|
||||
MIN(sw_free, hw_free - sw->total_hw_samples_mixed));
|
||||
} else {
|
||||
free = 0;
|
||||
}
|
||||
if (free > 0) {
|
||||
sw->callback.fn(sw->callback.opaque, free);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
live = audio_pcm_hw_get_live_out (hw, &nb_live);
|
||||
if (!nb_live) {
|
||||
live = 0;
|
||||
@@ -1173,7 +1142,7 @@ static void audio_run_out (AudioState *s)
|
||||
|
||||
if (audio_bug(__func__, live > hw->mix_buf->size)) {
|
||||
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
|
||||
abort();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hw->pending_disable && !nb_live) {
|
||||
@@ -1194,6 +1163,14 @@ static void audio_run_out (AudioState *s)
|
||||
}
|
||||
|
||||
if (!live) {
|
||||
for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
|
||||
if (sw->active) {
|
||||
free = audio_get_free (sw);
|
||||
if (free > 0) {
|
||||
sw->callback.fn (sw->callback.opaque, free);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hw->pcm_ops->run_buffer_out) {
|
||||
hw->pcm_ops->run_buffer_out(hw);
|
||||
}
|
||||
@@ -1206,7 +1183,7 @@ static void audio_run_out (AudioState *s)
|
||||
if (audio_bug(__func__, hw->mix_buf->pos >= hw->mix_buf->size)) {
|
||||
dolog("hw->mix_buf->pos=%zu hw->mix_buf->size=%zu played=%zu\n",
|
||||
hw->mix_buf->pos, hw->mix_buf->size, played);
|
||||
abort();
|
||||
hw->mix_buf->pos = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_OUT
|
||||
@@ -1226,7 +1203,7 @@ static void audio_run_out (AudioState *s)
|
||||
if (audio_bug(__func__, played > sw->total_hw_samples_mixed)) {
|
||||
dolog("played=%zu sw->total_hw_samples_mixed=%zu\n",
|
||||
played, sw->total_hw_samples_mixed);
|
||||
abort();
|
||||
played = sw->total_hw_samples_mixed;
|
||||
}
|
||||
|
||||
sw->total_hw_samples_mixed -= played;
|
||||
@@ -1234,6 +1211,13 @@ static void audio_run_out (AudioState *s)
|
||||
if (!sw->total_hw_samples_mixed) {
|
||||
sw->empty = 1;
|
||||
}
|
||||
|
||||
if (sw->active) {
|
||||
free = audio_get_free (sw);
|
||||
if (free > 0) {
|
||||
sw->callback.fn (sw->callback.opaque, free);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1241,6 +1225,7 @@ static void audio_run_out (AudioState *s)
|
||||
static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples)
|
||||
{
|
||||
size_t conv = 0;
|
||||
STSampleBuffer *conv_buf = hw->conv_buf;
|
||||
|
||||
if (hw->pcm_ops->run_buffer_in) {
|
||||
hw->pcm_ops->run_buffer_in(hw);
|
||||
@@ -1256,7 +1241,11 @@ static size_t audio_pcm_hw_run_in(HWVoiceIn *hw, size_t samples)
|
||||
break;
|
||||
}
|
||||
|
||||
proc = audio_pcm_hw_conv_in(hw, buf, size / hw->info.bytes_per_frame);
|
||||
proc = MIN(size / hw->info.bytes_per_frame,
|
||||
conv_buf->size - conv_buf->pos);
|
||||
|
||||
hw->conv(conv_buf->samples + conv_buf->pos, buf, proc);
|
||||
conv_buf->pos = (conv_buf->pos + proc) % conv_buf->size;
|
||||
|
||||
samples -= proc;
|
||||
conv += proc;
|
||||
@@ -1349,7 +1338,7 @@ static void audio_run_capture (AudioState *s)
|
||||
if (audio_bug(__func__, captured > sw->total_hw_samples_mixed)) {
|
||||
dolog("captured=%zu sw->total_hw_samples_mixed=%zu\n",
|
||||
captured, sw->total_hw_samples_mixed);
|
||||
abort();
|
||||
captured = sw->total_hw_samples_mixed;
|
||||
}
|
||||
|
||||
sw->total_hw_samples_mixed -= captured;
|
||||
@@ -1405,10 +1394,12 @@ void audio_generic_run_buffer_in(HWVoiceIn *hw)
|
||||
|
||||
void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size)
|
||||
{
|
||||
size_t start;
|
||||
ssize_t start = (ssize_t)hw->pos_emul - hw->pending_emul;
|
||||
|
||||
start = audio_ring_posb(hw->pos_emul, hw->pending_emul, hw->size_emul);
|
||||
assert(start < hw->size_emul);
|
||||
if (start < 0) {
|
||||
start += hw->size_emul;
|
||||
}
|
||||
assert(start >= 0 && start < hw->size_emul);
|
||||
|
||||
*size = MIN(*size, hw->pending_emul);
|
||||
*size = MIN(*size, hw->size_emul - start);
|
||||
@@ -1421,22 +1412,16 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
|
||||
hw->pending_emul -= size;
|
||||
}
|
||||
|
||||
size_t audio_generic_buffer_get_free(HWVoiceOut *hw)
|
||||
{
|
||||
if (hw->buf_emul) {
|
||||
return hw->size_emul - hw->pending_emul;
|
||||
} else {
|
||||
return hw->samples * hw->info.bytes_per_frame;
|
||||
}
|
||||
}
|
||||
|
||||
void audio_generic_run_buffer_out(HWVoiceOut *hw)
|
||||
{
|
||||
while (hw->pending_emul) {
|
||||
size_t write_len, written, start;
|
||||
size_t write_len, written;
|
||||
ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul;
|
||||
|
||||
start = audio_ring_posb(hw->pos_emul, hw->pending_emul, hw->size_emul);
|
||||
assert(start < hw->size_emul);
|
||||
if (start < 0) {
|
||||
start += hw->size_emul;
|
||||
}
|
||||
assert(start >= 0 && start < hw->size_emul);
|
||||
|
||||
write_len = MIN(hw->pending_emul, hw->size_emul - start);
|
||||
|
||||
@@ -1477,12 +1462,6 @@ size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size)
|
||||
{
|
||||
size_t total = 0;
|
||||
|
||||
if (hw->pcm_ops->buffer_get_free) {
|
||||
size_t free = hw->pcm_ops->buffer_get_free(hw);
|
||||
|
||||
size = MIN(size, free);
|
||||
}
|
||||
|
||||
while (total < size) {
|
||||
size_t dst_size = size - total;
|
||||
size_t copy_size, proc;
|
||||
@@ -1737,7 +1716,7 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
|
||||
audio_validate_opts(dev, &error_abort);
|
||||
}
|
||||
|
||||
s = g_new0(AudioState, 1);
|
||||
s = g_malloc0(sizeof(AudioState));
|
||||
s->dev = dev;
|
||||
|
||||
QLIST_INIT (&s->hw_head_out);
|
||||
@@ -1842,7 +1821,6 @@ void AUD_remove_card (QEMUSoundCard *card)
|
||||
g_free (card->name);
|
||||
}
|
||||
|
||||
static struct audio_pcm_ops capture_pcm_ops;
|
||||
|
||||
CaptureVoiceOut *AUD_add_capture(
|
||||
AudioState *s,
|
||||
@@ -1888,7 +1866,6 @@ CaptureVoiceOut *AUD_add_capture(
|
||||
|
||||
hw = &cap->hw;
|
||||
hw->s = s;
|
||||
hw->pcm_ops = &capture_pcm_ops;
|
||||
QLIST_INIT (&hw->sw_head);
|
||||
QLIST_INIT (&cap->cb_head);
|
||||
|
||||
@@ -2023,7 +2000,6 @@ void audio_create_pdos(Audiodev *dev)
|
||||
CASE(NONE, none, );
|
||||
CASE(ALSA, alsa, Alsa);
|
||||
CASE(COREAUDIO, coreaudio, Coreaudio);
|
||||
CASE(DBUS, dbus, );
|
||||
CASE(DSOUND, dsound, );
|
||||
CASE(JACK, jack, Jack);
|
||||
CASE(OSS, oss, Oss);
|
||||
@@ -2103,22 +2079,16 @@ static void audio_validate_opts(Audiodev *dev, Error **errp)
|
||||
|
||||
void audio_parse_option(const char *opt)
|
||||
{
|
||||
AudiodevListEntry *e;
|
||||
Audiodev *dev = NULL;
|
||||
|
||||
Visitor *v = qobject_input_visitor_new_str(opt, "driver", &error_fatal);
|
||||
visit_type_Audiodev(v, NULL, &dev, &error_fatal);
|
||||
visit_free(v);
|
||||
|
||||
audio_define(dev);
|
||||
}
|
||||
|
||||
void audio_define(Audiodev *dev)
|
||||
{
|
||||
AudiodevListEntry *e;
|
||||
|
||||
audio_validate_opts(dev, &error_fatal);
|
||||
|
||||
e = g_new0(AudiodevListEntry, 1);
|
||||
e = g_malloc0(sizeof(AudiodevListEntry));
|
||||
e->dev = dev;
|
||||
QSIMPLEQ_INSERT_TAIL(&audiodevs, e, next);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
typedef void (*audio_callback_fn) (void *opaque, int avail);
|
||||
|
||||
#if HOST_BIG_ENDIAN
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
#define AUDIO_HOST_ENDIANNESS 1
|
||||
#else
|
||||
#define AUDIO_HOST_ENDIANNESS 0
|
||||
@@ -91,8 +91,8 @@ typedef struct QEMUAudioTimeStamp {
|
||||
uint64_t old_ts;
|
||||
} QEMUAudioTimeStamp;
|
||||
|
||||
void AUD_vlog (const char *cap, const char *fmt, va_list ap) G_GNUC_PRINTF(2, 0);
|
||||
void AUD_log (const char *cap, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
|
||||
void AUD_vlog (const char *cap, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
|
||||
void AUD_log (const char *cap, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
|
||||
|
||||
void AUD_register_card (const char *name, QEMUSoundCard *card);
|
||||
void AUD_remove_card (QEMUSoundCard *card);
|
||||
@@ -168,7 +168,6 @@ void audio_sample_to_uint64(const void *samples, int pos,
|
||||
void audio_sample_from_uint64(void *samples, int pos,
|
||||
uint64_t left, uint64_t right);
|
||||
|
||||
void audio_define(Audiodev *audio);
|
||||
void audio_parse_option(const char *opt);
|
||||
void audio_init_audiodevs(void);
|
||||
void audio_legacy_help(void);
|
||||
|
||||
@@ -31,10 +31,6 @@
|
||||
#endif
|
||||
#include "mixeng.h"
|
||||
|
||||
#ifdef CONFIG_GIO
|
||||
#include <gio/gio.h>
|
||||
#endif
|
||||
|
||||
struct audio_pcm_ops;
|
||||
|
||||
struct audio_callback {
|
||||
@@ -144,9 +140,6 @@ struct audio_driver {
|
||||
const char *descr;
|
||||
void *(*init) (Audiodev *);
|
||||
void (*fini) (void *);
|
||||
#ifdef CONFIG_GIO
|
||||
void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *manager);
|
||||
#endif
|
||||
struct audio_pcm_ops *pcm_ops;
|
||||
int can_be_default;
|
||||
int max_voices_out;
|
||||
@@ -161,14 +154,10 @@ struct audio_pcm_ops {
|
||||
void (*fini_out)(HWVoiceOut *hw);
|
||||
size_t (*write) (HWVoiceOut *hw, void *buf, size_t size);
|
||||
void (*run_buffer_out)(HWVoiceOut *hw);
|
||||
/*
|
||||
* Get the free output buffer size. This is an upper limit. The size
|
||||
* returned by function get_buffer_out may be smaller.
|
||||
*/
|
||||
size_t (*buffer_get_free)(HWVoiceOut *hw);
|
||||
/*
|
||||
* get a buffer that after later can be passed to put_buffer_out; optional
|
||||
* returns the buffer, and writes it's size to size (in bytes)
|
||||
* this is unrelated to the above buffer_size_out function
|
||||
*/
|
||||
void *(*get_buffer_out)(HWVoiceOut *hw, size_t *size);
|
||||
/*
|
||||
@@ -194,7 +183,6 @@ void audio_generic_run_buffer_in(HWVoiceIn *hw);
|
||||
void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
|
||||
void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
|
||||
void audio_generic_run_buffer_out(HWVoiceOut *hw);
|
||||
size_t audio_generic_buffer_get_free(HWVoiceOut *hw);
|
||||
void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size);
|
||||
size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size);
|
||||
size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size);
|
||||
@@ -271,19 +259,6 @@ static inline size_t audio_ring_dist(size_t dst, size_t src, size_t len)
|
||||
return (dst >= src) ? (dst - src) : (len - src + dst);
|
||||
}
|
||||
|
||||
/**
|
||||
* audio_ring_posb() - returns new position in ringbuffer in backward
|
||||
* direction at given distance
|
||||
*
|
||||
* @pos: current position in ringbuffer
|
||||
* @dist: distance in ringbuffer to walk in reverse direction
|
||||
* @len: size of ringbuffer
|
||||
*/
|
||||
static inline size_t audio_ring_posb(size_t pos, size_t dist, size_t len)
|
||||
{
|
||||
return pos >= dist ? pos - dist : len - dist + pos;
|
||||
}
|
||||
|
||||
#define dolog(fmt, ...) AUD_log(AUDIO_CAP, fmt, ## __VA_ARGS__)
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -328,8 +328,8 @@ static void handle_per_direction(
|
||||
|
||||
static AudiodevListEntry *legacy_opt(const char *drvname)
|
||||
{
|
||||
AudiodevListEntry *e = g_new0(AudiodevListEntry, 1);
|
||||
e->dev = g_new0(Audiodev, 1);
|
||||
AudiodevListEntry *e = g_malloc0(sizeof(AudiodevListEntry));
|
||||
e->dev = g_malloc0(sizeof(Audiodev));
|
||||
e->dev->id = g_strdup(drvname);
|
||||
e->dev->driver = qapi_enum_parse(
|
||||
&AudiodevDriver_lookup, drvname, -1, &error_abort);
|
||||
@@ -508,7 +508,7 @@ static void lv_free(Visitor *v)
|
||||
|
||||
static Visitor *legacy_visitor_new(void)
|
||||
{
|
||||
LegacyPrintVisitor *lv = g_new0(LegacyPrintVisitor, 1);
|
||||
LegacyPrintVisitor *lv = g_malloc0(sizeof(LegacyPrintVisitor));
|
||||
|
||||
lv->visitor.start_struct = lv_start_struct;
|
||||
lv->visitor.end_struct = lv_end_struct;
|
||||
|
||||
@@ -59,13 +59,12 @@ static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
|
||||
if (audio_bug(__func__, !voice_size && max_voices)) {
|
||||
dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
|
||||
drv->name, max_voices);
|
||||
abort();
|
||||
glue (s->nb_hw_voices_, TYPE) = 0;
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, voice_size && !max_voices)) {
|
||||
dolog ("drv=`%s' voice_size=%d max_voices=0\n",
|
||||
drv->name, voice_size);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +81,6 @@ static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw)
|
||||
size_t samples = hw->samples;
|
||||
if (audio_bug(__func__, samples == 0)) {
|
||||
dolog("Attempted to allocate empty buffer\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples);
|
||||
@@ -254,12 +252,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
|
||||
|
||||
if (audio_bug(__func__, !drv)) {
|
||||
dolog ("No host audio driver\n");
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, !drv->pcm_ops)) {
|
||||
dolog ("Host audio driver without pcm_ops\n");
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hw = audio_calloc(__func__, 1, glue(drv->voice_size_, TYPE));
|
||||
@@ -277,13 +275,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
|
||||
QLIST_INIT (&hw->cap_head);
|
||||
#endif
|
||||
if (glue (hw->pcm_ops->init_, TYPE) (hw, as, s->drv_opaque)) {
|
||||
g_free(hw);
|
||||
return NULL;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, hw->samples <= 0)) {
|
||||
dolog("hw->samples=%zd\n", hw->samples);
|
||||
abort();
|
||||
goto err1;
|
||||
}
|
||||
|
||||
if (hw->info.is_float) {
|
||||
@@ -312,6 +309,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
|
||||
audio_attach_capture (hw);
|
||||
#endif
|
||||
return hw;
|
||||
|
||||
err1:
|
||||
glue (hw->pcm_ops->fini_, TYPE) (hw);
|
||||
err0:
|
||||
g_free (hw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
|
||||
@@ -324,8 +327,6 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
|
||||
case AUDIODEV_DRIVER_COREAUDIO:
|
||||
return qapi_AudiodevCoreaudioPerDirectionOptions_base(
|
||||
dev->u.coreaudio.TYPE);
|
||||
case AUDIODEV_DRIVER_DBUS:
|
||||
return dev->u.dbus.TYPE;
|
||||
case AUDIODEV_DRIVER_DSOUND:
|
||||
return dev->u.dsound.TYPE;
|
||||
case AUDIODEV_DRIVER_JACK:
|
||||
@@ -432,7 +433,7 @@ void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
|
||||
if (sw) {
|
||||
if (audio_bug(__func__, !card)) {
|
||||
dolog ("card=%p\n", card);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
glue (audio_close_, TYPE) (sw);
|
||||
@@ -454,7 +455,7 @@ SW *glue (AUD_open_, TYPE) (
|
||||
if (audio_bug(__func__, !card || !name || !callback_fn || !as)) {
|
||||
dolog ("card=%p name=%p callback_fn=%p as=%p\n",
|
||||
card, name, callback_fn, as);
|
||||
abort();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
s = card->state;
|
||||
@@ -465,12 +466,12 @@ SW *glue (AUD_open_, TYPE) (
|
||||
|
||||
if (audio_bug(__func__, audio_validate_settings(as))) {
|
||||
audio_print_settings (as);
|
||||
abort();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, !s->drv)) {
|
||||
dolog ("Can not open `%s' (no host audio driver)\n", name);
|
||||
abort();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (sw && audio_pcm_info_eq (&sw->info, as)) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* public domain */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
|
||||
#define AUDIO_CAP "win-int"
|
||||
#include <windows.h>
|
||||
|
||||
@@ -44,15 +44,10 @@ typedef struct coreaudioVoiceOut {
|
||||
bool enabled;
|
||||
} coreaudioVoiceOut;
|
||||
|
||||
#if !defined(MAC_OS_VERSION_12_0) \
|
||||
|| (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_12_0)
|
||||
#define kAudioObjectPropertyElementMain kAudioObjectPropertyElementMaster
|
||||
#endif
|
||||
|
||||
static const AudioObjectPropertyAddress voice_addr = {
|
||||
kAudioHardwarePropertyDefaultOutputDevice,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMain
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
static OSStatus coreaudio_get_voice(AudioDeviceID *id)
|
||||
@@ -74,7 +69,7 @@ static OSStatus coreaudio_get_framesizerange(AudioDeviceID id,
|
||||
AudioObjectPropertyAddress addr = {
|
||||
kAudioDevicePropertyBufferFrameSizeRange,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMain
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
return AudioObjectGetPropertyData(id,
|
||||
@@ -91,7 +86,7 @@ static OSStatus coreaudio_get_framesize(AudioDeviceID id, UInt32 *framesize)
|
||||
AudioObjectPropertyAddress addr = {
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMain
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
return AudioObjectGetPropertyData(id,
|
||||
@@ -108,7 +103,7 @@ static OSStatus coreaudio_set_framesize(AudioDeviceID id, UInt32 *framesize)
|
||||
AudioObjectPropertyAddress addr = {
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMain
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
return AudioObjectSetPropertyData(id,
|
||||
@@ -126,7 +121,7 @@ static OSStatus coreaudio_set_streamformat(AudioDeviceID id,
|
||||
AudioObjectPropertyAddress addr = {
|
||||
kAudioDevicePropertyStreamFormat,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMain
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
return AudioObjectSetPropertyData(id,
|
||||
@@ -143,7 +138,7 @@ static OSStatus coreaudio_get_isrunning(AudioDeviceID id, UInt32 *result)
|
||||
AudioObjectPropertyAddress addr = {
|
||||
kAudioDevicePropertyDeviceIsRunning,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMain
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
return AudioObjectGetPropertyData(id,
|
||||
@@ -211,7 +206,7 @@ static void coreaudio_logstatus (OSStatus status)
|
||||
AUD_log (AUDIO_CAP, "Reason: %s\n", str);
|
||||
}
|
||||
|
||||
static void G_GNUC_PRINTF (2, 3) coreaudio_logerr (
|
||||
static void GCC_FMT_ATTR (2, 3) coreaudio_logerr (
|
||||
OSStatus status,
|
||||
const char *fmt,
|
||||
...
|
||||
@@ -226,7 +221,7 @@ static void G_GNUC_PRINTF (2, 3) coreaudio_logerr (
|
||||
coreaudio_logstatus (status);
|
||||
}
|
||||
|
||||
static void G_GNUC_PRINTF (3, 4) coreaudio_logerr2 (
|
||||
static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
|
||||
OSStatus status,
|
||||
const char *typ,
|
||||
const char *fmt,
|
||||
@@ -288,7 +283,6 @@ static int coreaudio_buf_unlock (coreaudioVoiceOut *core, const char *fn_name)
|
||||
coreaudio_buf_unlock(core, "coreaudio_" #name); \
|
||||
return ret; \
|
||||
}
|
||||
COREAUDIO_WRAPPER_FUNC(buffer_get_free, size_t, (HWVoiceOut *hw), (hw))
|
||||
COREAUDIO_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size),
|
||||
(hw, size))
|
||||
COREAUDIO_WRAPPER_FUNC(put_buffer_out, size_t,
|
||||
@@ -339,10 +333,12 @@ static OSStatus audioDeviceIOProc(
|
||||
|
||||
len = frameCount * hw->info.bytes_per_frame;
|
||||
while (len) {
|
||||
size_t write_len, start;
|
||||
|
||||
start = audio_ring_posb(hw->pos_emul, hw->pending_emul, hw->size_emul);
|
||||
assert(start < hw->size_emul);
|
||||
size_t write_len;
|
||||
ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul;
|
||||
if (start < 0) {
|
||||
start += hw->size_emul;
|
||||
}
|
||||
assert(start >= 0 && start < hw->size_emul);
|
||||
|
||||
write_len = MIN(MIN(hw->pending_emul, len),
|
||||
hw->size_emul - start);
|
||||
@@ -545,6 +541,7 @@ static OSStatus handle_voice_change(
|
||||
const AudioObjectPropertyAddress *in_addresses,
|
||||
void *in_client_data)
|
||||
{
|
||||
OSStatus status;
|
||||
coreaudioVoiceOut *core = in_client_data;
|
||||
|
||||
qemu_mutex_lock_iothread();
|
||||
@@ -553,12 +550,13 @@ static OSStatus handle_voice_change(
|
||||
fini_out_device(core);
|
||||
}
|
||||
|
||||
if (!init_out_device(core)) {
|
||||
status = init_out_device(core);
|
||||
if (!status) {
|
||||
update_device_playback_state(core);
|
||||
}
|
||||
|
||||
qemu_mutex_unlock_iothread();
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
@@ -606,8 +604,6 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
coreaudio_playback_logerr(status,
|
||||
"Could not remove voice property change listener\n");
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -658,8 +654,6 @@ static struct audio_pcm_ops coreaudio_pcm_ops = {
|
||||
.fini_out = coreaudio_fini_out,
|
||||
/* wrapper for audio_generic_write */
|
||||
.write = coreaudio_write,
|
||||
/* wrapper for audio_generic_buffer_get_free */
|
||||
.buffer_get_free = coreaudio_buffer_get_free,
|
||||
/* wrapper for audio_generic_get_buffer_out */
|
||||
.get_buffer_out = coreaudio_get_buffer_out,
|
||||
/* wrapper for audio_generic_put_buffer_out */
|
||||
@@ -1,654 +0,0 @@
|
||||
/*
|
||||
* QEMU DBus audio
|
||||
*
|
||||
* Copyright (c) 2021 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/dbus.h"
|
||||
|
||||
#include <gio/gunixfdlist.h>
|
||||
#include "ui/dbus-display1.h"
|
||||
|
||||
#define AUDIO_CAP "dbus"
|
||||
#include "audio.h"
|
||||
#include "audio_int.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define DBUS_DISPLAY1_AUDIO_PATH DBUS_DISPLAY1_ROOT "/Audio"
|
||||
|
||||
#define DBUS_AUDIO_NSAMPLES 1024 /* could be configured? */
|
||||
|
||||
typedef struct DBusAudio {
|
||||
GDBusObjectManagerServer *server;
|
||||
GDBusObjectSkeleton *audio;
|
||||
QemuDBusDisplay1Audio *iface;
|
||||
GHashTable *out_listeners;
|
||||
GHashTable *in_listeners;
|
||||
} DBusAudio;
|
||||
|
||||
typedef struct DBusVoiceOut {
|
||||
HWVoiceOut hw;
|
||||
bool enabled;
|
||||
RateCtl rate;
|
||||
|
||||
void *buf;
|
||||
size_t buf_pos;
|
||||
size_t buf_size;
|
||||
|
||||
bool has_volume;
|
||||
Volume volume;
|
||||
} DBusVoiceOut;
|
||||
|
||||
typedef struct DBusVoiceIn {
|
||||
HWVoiceIn hw;
|
||||
bool enabled;
|
||||
RateCtl rate;
|
||||
|
||||
bool has_volume;
|
||||
Volume volume;
|
||||
} DBusVoiceIn;
|
||||
|
||||
static void *dbus_get_buffer_out(HWVoiceOut *hw, size_t *size)
|
||||
{
|
||||
DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
|
||||
|
||||
if (!vo->buf) {
|
||||
vo->buf_size = hw->samples * hw->info.bytes_per_frame;
|
||||
vo->buf = g_malloc(vo->buf_size);
|
||||
vo->buf_pos = 0;
|
||||
}
|
||||
|
||||
*size = MIN(vo->buf_size - vo->buf_pos, *size);
|
||||
*size = audio_rate_get_bytes(&hw->info, &vo->rate, *size);
|
||||
|
||||
return vo->buf + vo->buf_pos;
|
||||
|
||||
}
|
||||
|
||||
static size_t dbus_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioOutListener *listener = NULL;
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
g_autoptr(GVariant) v_data = NULL;
|
||||
|
||||
assert(buf == vo->buf + vo->buf_pos && vo->buf_pos + size <= vo->buf_size);
|
||||
vo->buf_pos += size;
|
||||
|
||||
trace_dbus_audio_put_buffer_out(size);
|
||||
|
||||
if (vo->buf_pos < vo->buf_size) {
|
||||
return size;
|
||||
}
|
||||
|
||||
bytes = g_bytes_new_take(g_steal_pointer(&vo->buf), vo->buf_size);
|
||||
v_data = g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE);
|
||||
g_variant_ref_sink(v_data);
|
||||
|
||||
g_hash_table_iter_init(&iter, da->out_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
qemu_dbus_display1_audio_out_listener_call_write(
|
||||
listener,
|
||||
(uintptr_t)hw,
|
||||
v_data,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
#if HOST_BIG_ENDIAN
|
||||
#define AUDIO_HOST_BE TRUE
|
||||
#else
|
||||
#define AUDIO_HOST_BE FALSE
|
||||
#endif
|
||||
|
||||
static void
|
||||
dbus_init_out_listener(QemuDBusDisplay1AudioOutListener *listener,
|
||||
HWVoiceOut *hw)
|
||||
{
|
||||
qemu_dbus_display1_audio_out_listener_call_init(
|
||||
listener,
|
||||
(uintptr_t)hw,
|
||||
hw->info.bits,
|
||||
hw->info.is_signed,
|
||||
hw->info.is_float,
|
||||
hw->info.freq,
|
||||
hw->info.nchannels,
|
||||
hw->info.bytes_per_frame,
|
||||
hw->info.bytes_per_second,
|
||||
hw->info.swap_endianness ? !AUDIO_HOST_BE : AUDIO_HOST_BE,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
dbus_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioOutListener *listener = NULL;
|
||||
|
||||
audio_pcm_init_info(&hw->info, as);
|
||||
hw->samples = DBUS_AUDIO_NSAMPLES;
|
||||
audio_rate_start(&vo->rate);
|
||||
|
||||
g_hash_table_iter_init(&iter, da->out_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
dbus_init_out_listener(listener, hw);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_fini_out(HWVoiceOut *hw)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioOutListener *listener = NULL;
|
||||
|
||||
g_hash_table_iter_init(&iter, da->out_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
qemu_dbus_display1_audio_out_listener_call_fini(
|
||||
listener,
|
||||
(uintptr_t)hw,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
g_clear_pointer(&vo->buf, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_enable_out(HWVoiceOut *hw, bool enable)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioOutListener *listener = NULL;
|
||||
|
||||
vo->enabled = enable;
|
||||
if (enable) {
|
||||
audio_rate_start(&vo->rate);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init(&iter, da->out_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
qemu_dbus_display1_audio_out_listener_call_set_enabled(
|
||||
listener, (uintptr_t)hw, enable,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_volume_out_listener(HWVoiceOut *hw,
|
||||
QemuDBusDisplay1AudioOutListener *listener)
|
||||
{
|
||||
DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
|
||||
Volume *vol = &vo->volume;
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
GVariant *v_vol = NULL;
|
||||
|
||||
if (!vo->has_volume) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(vol->channels < sizeof(vol->vol));
|
||||
bytes = g_bytes_new(vol->vol, vol->channels);
|
||||
v_vol = g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE);
|
||||
qemu_dbus_display1_audio_out_listener_call_set_volume(
|
||||
listener, (uintptr_t)hw, vol->mute, v_vol,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_volume_out(HWVoiceOut *hw, Volume *vol)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioOutListener *listener = NULL;
|
||||
|
||||
vo->has_volume = true;
|
||||
vo->volume = *vol;
|
||||
|
||||
g_hash_table_iter_init(&iter, da->out_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
dbus_volume_out_listener(hw, listener);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_init_in_listener(QemuDBusDisplay1AudioInListener *listener, HWVoiceIn *hw)
|
||||
{
|
||||
qemu_dbus_display1_audio_in_listener_call_init(
|
||||
listener,
|
||||
(uintptr_t)hw,
|
||||
hw->info.bits,
|
||||
hw->info.is_signed,
|
||||
hw->info.is_float,
|
||||
hw->info.freq,
|
||||
hw->info.nchannels,
|
||||
hw->info.bytes_per_frame,
|
||||
hw->info.bytes_per_second,
|
||||
hw->info.swap_endianness ? !AUDIO_HOST_BE : AUDIO_HOST_BE,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
dbus_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioInListener *listener = NULL;
|
||||
|
||||
audio_pcm_init_info(&hw->info, as);
|
||||
hw->samples = DBUS_AUDIO_NSAMPLES;
|
||||
audio_rate_start(&vo->rate);
|
||||
|
||||
g_hash_table_iter_init(&iter, da->in_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
dbus_init_in_listener(listener, hw);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_fini_in(HWVoiceIn *hw)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioInListener *listener = NULL;
|
||||
|
||||
g_hash_table_iter_init(&iter, da->in_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
qemu_dbus_display1_audio_in_listener_call_fini(
|
||||
listener,
|
||||
(uintptr_t)hw,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_volume_in_listener(HWVoiceIn *hw,
|
||||
QemuDBusDisplay1AudioInListener *listener)
|
||||
{
|
||||
DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
|
||||
Volume *vol = &vo->volume;
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
GVariant *v_vol = NULL;
|
||||
|
||||
if (!vo->has_volume) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(vol->channels < sizeof(vol->vol));
|
||||
bytes = g_bytes_new(vol->vol, vol->channels);
|
||||
v_vol = g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE);
|
||||
qemu_dbus_display1_audio_in_listener_call_set_volume(
|
||||
listener, (uintptr_t)hw, vol->mute, v_vol,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_volume_in(HWVoiceIn *hw, Volume *vol)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioInListener *listener = NULL;
|
||||
|
||||
vo->has_volume = true;
|
||||
vo->volume = *vol;
|
||||
|
||||
g_hash_table_iter_init(&iter, da->in_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
dbus_volume_in_listener(hw, listener);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
dbus_read(HWVoiceIn *hw, void *buf, size_t size)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
/* DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw); */
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioInListener *listener = NULL;
|
||||
|
||||
trace_dbus_audio_read(size);
|
||||
|
||||
/* size = audio_rate_get_bytes(&hw->info, &vo->rate, size); */
|
||||
|
||||
g_hash_table_iter_init(&iter, da->in_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
g_autoptr(GVariant) v_data = NULL;
|
||||
const char *data;
|
||||
gsize n = 0;
|
||||
|
||||
if (qemu_dbus_display1_audio_in_listener_call_read_sync(
|
||||
listener,
|
||||
(uintptr_t)hw,
|
||||
size,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1,
|
||||
&v_data, NULL, NULL)) {
|
||||
data = g_variant_get_fixed_array(v_data, &n, 1);
|
||||
g_warn_if_fail(n <= size);
|
||||
size = MIN(n, size);
|
||||
memcpy(buf, data, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_enable_in(HWVoiceIn *hw, bool enable)
|
||||
{
|
||||
DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
|
||||
DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
|
||||
GHashTableIter iter;
|
||||
QemuDBusDisplay1AudioInListener *listener = NULL;
|
||||
|
||||
vo->enabled = enable;
|
||||
if (enable) {
|
||||
audio_rate_start(&vo->rate);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init(&iter, da->in_listeners);
|
||||
while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
|
||||
qemu_dbus_display1_audio_in_listener_call_set_enabled(
|
||||
listener, (uintptr_t)hw, enable,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
dbus_audio_init(Audiodev *dev)
|
||||
{
|
||||
DBusAudio *da = g_new0(DBusAudio, 1);
|
||||
|
||||
da->out_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
g_free, g_object_unref);
|
||||
da->in_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
g_free, g_object_unref);
|
||||
return da;
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_audio_fini(void *opaque)
|
||||
{
|
||||
DBusAudio *da = opaque;
|
||||
|
||||
if (da->server) {
|
||||
g_dbus_object_manager_server_unexport(da->server,
|
||||
DBUS_DISPLAY1_AUDIO_PATH);
|
||||
}
|
||||
g_clear_object(&da->audio);
|
||||
g_clear_object(&da->iface);
|
||||
g_clear_pointer(&da->in_listeners, g_hash_table_unref);
|
||||
g_clear_pointer(&da->out_listeners, g_hash_table_unref);
|
||||
g_clear_object(&da->server);
|
||||
g_free(da);
|
||||
}
|
||||
|
||||
static void
|
||||
listener_out_vanished_cb(GDBusConnection *connection,
|
||||
gboolean remote_peer_vanished,
|
||||
GError *error,
|
||||
DBusAudio *da)
|
||||
{
|
||||
char *name = g_object_get_data(G_OBJECT(connection), "name");
|
||||
|
||||
g_hash_table_remove(da->out_listeners, name);
|
||||
}
|
||||
|
||||
static void
|
||||
listener_in_vanished_cb(GDBusConnection *connection,
|
||||
gboolean remote_peer_vanished,
|
||||
GError *error,
|
||||
DBusAudio *da)
|
||||
{
|
||||
char *name = g_object_get_data(G_OBJECT(connection), "name");
|
||||
|
||||
g_hash_table_remove(da->in_listeners, name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_audio_register_listener(AudioState *s,
|
||||
GDBusMethodInvocation *invocation,
|
||||
GUnixFDList *fd_list,
|
||||
GVariant *arg_listener,
|
||||
bool out)
|
||||
{
|
||||
DBusAudio *da = s->drv_opaque;
|
||||
const char *sender = g_dbus_method_invocation_get_sender(invocation);
|
||||
g_autoptr(GDBusConnection) listener_conn = NULL;
|
||||
g_autoptr(GError) err = NULL;
|
||||
g_autoptr(GSocket) socket = NULL;
|
||||
g_autoptr(GSocketConnection) socket_conn = NULL;
|
||||
g_autofree char *guid = g_dbus_generate_guid();
|
||||
GHashTable *listeners = out ? da->out_listeners : da->in_listeners;
|
||||
GObject *listener;
|
||||
int fd;
|
||||
|
||||
trace_dbus_audio_register(sender, out ? "out" : "in");
|
||||
|
||||
if (g_hash_table_contains(listeners, sender)) {
|
||||
g_dbus_method_invocation_return_error(invocation,
|
||||
DBUS_DISPLAY_ERROR,
|
||||
DBUS_DISPLAY_ERROR_INVALID,
|
||||
"`%s` is already registered!",
|
||||
sender);
|
||||
return DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
fd = g_unix_fd_list_get(fd_list, g_variant_get_handle(arg_listener), &err);
|
||||
if (err) {
|
||||
g_dbus_method_invocation_return_error(invocation,
|
||||
DBUS_DISPLAY_ERROR,
|
||||
DBUS_DISPLAY_ERROR_FAILED,
|
||||
"Couldn't get peer fd: %s",
|
||||
err->message);
|
||||
return DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
socket = g_socket_new_from_fd(fd, &err);
|
||||
if (err) {
|
||||
g_dbus_method_invocation_return_error(invocation,
|
||||
DBUS_DISPLAY_ERROR,
|
||||
DBUS_DISPLAY_ERROR_FAILED,
|
||||
"Couldn't make a socket: %s",
|
||||
err->message);
|
||||
return DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
socket_conn = g_socket_connection_factory_create_connection(socket);
|
||||
if (out) {
|
||||
qemu_dbus_display1_audio_complete_register_out_listener(
|
||||
da->iface, invocation, NULL);
|
||||
} else {
|
||||
qemu_dbus_display1_audio_complete_register_in_listener(
|
||||
da->iface, invocation, NULL);
|
||||
}
|
||||
|
||||
listener_conn =
|
||||
g_dbus_connection_new_sync(
|
||||
G_IO_STREAM(socket_conn),
|
||||
guid,
|
||||
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER,
|
||||
NULL, NULL, &err);
|
||||
if (err) {
|
||||
error_report("Failed to setup peer connection: %s", err->message);
|
||||
return DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
listener = out ?
|
||||
G_OBJECT(qemu_dbus_display1_audio_out_listener_proxy_new_sync(
|
||||
listener_conn,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
NULL,
|
||||
"/org/qemu/Display1/AudioOutListener",
|
||||
NULL,
|
||||
&err)) :
|
||||
G_OBJECT(qemu_dbus_display1_audio_in_listener_proxy_new_sync(
|
||||
listener_conn,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
NULL,
|
||||
"/org/qemu/Display1/AudioInListener",
|
||||
NULL,
|
||||
&err));
|
||||
if (!listener) {
|
||||
error_report("Failed to setup proxy: %s", err->message);
|
||||
return DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
if (out) {
|
||||
HWVoiceOut *hw;
|
||||
|
||||
QLIST_FOREACH(hw, &s->hw_head_out, entries) {
|
||||
DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
|
||||
QemuDBusDisplay1AudioOutListener *l =
|
||||
QEMU_DBUS_DISPLAY1_AUDIO_OUT_LISTENER(listener);
|
||||
|
||||
dbus_init_out_listener(l, hw);
|
||||
qemu_dbus_display1_audio_out_listener_call_set_enabled(
|
||||
l, (uintptr_t)hw, vo->enabled,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
HWVoiceIn *hw;
|
||||
|
||||
QLIST_FOREACH(hw, &s->hw_head_in, entries) {
|
||||
DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
|
||||
QemuDBusDisplay1AudioInListener *l =
|
||||
QEMU_DBUS_DISPLAY1_AUDIO_IN_LISTENER(listener);
|
||||
|
||||
dbus_init_in_listener(
|
||||
QEMU_DBUS_DISPLAY1_AUDIO_IN_LISTENER(listener), hw);
|
||||
qemu_dbus_display1_audio_in_listener_call_set_enabled(
|
||||
l, (uintptr_t)hw, vo->enabled,
|
||||
G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_set_data_full(G_OBJECT(listener_conn), "name",
|
||||
g_strdup(sender), g_free);
|
||||
g_hash_table_insert(listeners, g_strdup(sender), listener);
|
||||
g_object_connect(listener_conn,
|
||||
"signal::closed",
|
||||
out ? listener_out_vanished_cb : listener_in_vanished_cb,
|
||||
da,
|
||||
NULL);
|
||||
|
||||
return DBUS_METHOD_INVOCATION_HANDLED;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_audio_register_out_listener(AudioState *s,
|
||||
GDBusMethodInvocation *invocation,
|
||||
GUnixFDList *fd_list,
|
||||
GVariant *arg_listener)
|
||||
{
|
||||
return dbus_audio_register_listener(s, invocation,
|
||||
fd_list, arg_listener, true);
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dbus_audio_register_in_listener(AudioState *s,
|
||||
GDBusMethodInvocation *invocation,
|
||||
GUnixFDList *fd_list,
|
||||
GVariant *arg_listener)
|
||||
{
|
||||
return dbus_audio_register_listener(s, invocation,
|
||||
fd_list, arg_listener, false);
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server)
|
||||
{
|
||||
DBusAudio *da = s->drv_opaque;
|
||||
|
||||
g_assert(da);
|
||||
g_assert(!da->server);
|
||||
|
||||
da->server = g_object_ref(server);
|
||||
|
||||
da->audio = g_dbus_object_skeleton_new(DBUS_DISPLAY1_AUDIO_PATH);
|
||||
da->iface = qemu_dbus_display1_audio_skeleton_new();
|
||||
g_object_connect(da->iface,
|
||||
"swapped-signal::handle-register-in-listener",
|
||||
dbus_audio_register_in_listener, s,
|
||||
"swapped-signal::handle-register-out-listener",
|
||||
dbus_audio_register_out_listener, s,
|
||||
NULL);
|
||||
|
||||
g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(da->audio),
|
||||
G_DBUS_INTERFACE_SKELETON(da->iface));
|
||||
g_dbus_object_manager_server_export(da->server, da->audio);
|
||||
}
|
||||
|
||||
static struct audio_pcm_ops dbus_pcm_ops = {
|
||||
.init_out = dbus_init_out,
|
||||
.fini_out = dbus_fini_out,
|
||||
.write = audio_generic_write,
|
||||
.get_buffer_out = dbus_get_buffer_out,
|
||||
.put_buffer_out = dbus_put_buffer_out,
|
||||
.enable_out = dbus_enable_out,
|
||||
.volume_out = dbus_volume_out,
|
||||
|
||||
.init_in = dbus_init_in,
|
||||
.fini_in = dbus_fini_in,
|
||||
.read = dbus_read,
|
||||
.run_buffer_in = audio_generic_run_buffer_in,
|
||||
.enable_in = dbus_enable_in,
|
||||
.volume_in = dbus_volume_in,
|
||||
};
|
||||
|
||||
static struct audio_driver dbus_audio_driver = {
|
||||
.name = "dbus",
|
||||
.descr = "Timer based audio exposed with DBus interface",
|
||||
.init = dbus_audio_init,
|
||||
.fini = dbus_audio_fini,
|
||||
.set_dbus_server = dbus_audio_set_server,
|
||||
.pcm_ops = &dbus_pcm_ops,
|
||||
.can_be_default = 1,
|
||||
.max_voices_out = INT_MAX,
|
||||
.max_voices_in = INT_MAX,
|
||||
.voice_size_out = sizeof(DBusVoiceOut),
|
||||
.voice_size_in = sizeof(DBusVoiceIn)
|
||||
};
|
||||
|
||||
static void register_audio_dbus(void)
|
||||
{
|
||||
audio_driver_register(&dbus_audio_driver);
|
||||
}
|
||||
type_init(register_audio_dbus);
|
||||
|
||||
module_dep("ui-dbus")
|
||||
@@ -222,7 +222,7 @@ static void dsound_log_hresult (HRESULT hr)
|
||||
AUD_log (AUDIO_CAP, "Reason: %s\n", str);
|
||||
}
|
||||
|
||||
static void G_GNUC_PRINTF (2, 3) dsound_logerr (
|
||||
static void GCC_FMT_ATTR (2, 3) dsound_logerr (
|
||||
HRESULT hr,
|
||||
const char *fmt,
|
||||
...
|
||||
@@ -237,7 +237,7 @@ static void G_GNUC_PRINTF (2, 3) dsound_logerr (
|
||||
dsound_log_hresult (hr);
|
||||
}
|
||||
|
||||
static void G_GNUC_PRINTF (3, 4) dsound_logerr2 (
|
||||
static void GCC_FMT_ATTR (3, 4) dsound_logerr2 (
|
||||
HRESULT hr,
|
||||
const char *typ,
|
||||
const char *fmt,
|
||||
@@ -427,18 +427,22 @@ static void dsound_enable_out(HWVoiceOut *hw, bool enable)
|
||||
}
|
||||
}
|
||||
|
||||
static size_t dsound_buffer_get_free(HWVoiceOut *hw)
|
||||
static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t *size)
|
||||
{
|
||||
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
|
||||
LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
|
||||
HRESULT hr;
|
||||
DWORD ppos, wpos;
|
||||
DWORD ppos, wpos, act_size;
|
||||
size_t req_size;
|
||||
int err;
|
||||
void *ret;
|
||||
|
||||
hr = IDirectSoundBuffer_GetCurrentPosition(
|
||||
dsb, &ppos, ds->first_time ? &wpos : NULL);
|
||||
if (FAILED(hr)) {
|
||||
dsound_logerr(hr, "Could not get playback buffer position\n");
|
||||
return 0;
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ds->first_time) {
|
||||
@@ -446,20 +450,13 @@ static size_t dsound_buffer_get_free(HWVoiceOut *hw)
|
||||
ds->first_time = false;
|
||||
}
|
||||
|
||||
return audio_ring_dist(ppos, hw->pos_emul, hw->size_emul);
|
||||
}
|
||||
req_size = audio_ring_dist(ppos, hw->pos_emul, hw->size_emul);
|
||||
req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
|
||||
|
||||
static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t *size)
|
||||
{
|
||||
DSoundVoiceOut *ds = (DSoundVoiceOut *)hw;
|
||||
LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
|
||||
DWORD act_size;
|
||||
size_t req_size;
|
||||
int err;
|
||||
void *ret;
|
||||
|
||||
req_size = MIN(*size, hw->size_emul - hw->pos_emul);
|
||||
assert(req_size > 0);
|
||||
if (req_size == 0) {
|
||||
*size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
|
||||
&act_size, NULL, false, ds->s);
|
||||
@@ -539,12 +536,13 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size)
|
||||
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
|
||||
LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
|
||||
HRESULT hr;
|
||||
DWORD rpos, act_size;
|
||||
DWORD cpos, rpos, act_size;
|
||||
size_t req_size;
|
||||
int err;
|
||||
void *ret;
|
||||
|
||||
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, NULL, &rpos);
|
||||
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(
|
||||
dscb, &cpos, ds->first_time ? &rpos : NULL);
|
||||
if (FAILED(hr)) {
|
||||
dsound_logerr(hr, "Could not get capture buffer position\n");
|
||||
*size = 0;
|
||||
@@ -556,7 +554,7 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size)
|
||||
ds->first_time = false;
|
||||
}
|
||||
|
||||
req_size = audio_ring_dist(rpos, hw->pos_emul, hw->size_emul);
|
||||
req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul);
|
||||
req_size = MIN(*size, MIN(req_size, hw->size_emul - hw->pos_emul));
|
||||
|
||||
if (req_size == 0) {
|
||||
@@ -623,7 +621,7 @@ static void *dsound_audio_init(Audiodev *dev)
|
||||
{
|
||||
int err;
|
||||
HRESULT hr;
|
||||
dsound *s = g_new0(dsound, 1);
|
||||
dsound *s = g_malloc0(sizeof(dsound));
|
||||
AudiodevDsoundOptions *dso;
|
||||
|
||||
assert(dev->driver == AUDIODEV_DRIVER_DSOUND);
|
||||
@@ -702,7 +700,6 @@ static struct audio_pcm_ops dsound_pcm_ops = {
|
||||
.init_out = dsound_init_out,
|
||||
.fini_out = dsound_fini_out,
|
||||
.write = audio_generic_write,
|
||||
.buffer_get_free = dsound_buffer_get_free,
|
||||
.get_buffer_out = dsound_get_buffer_out,
|
||||
.put_buffer_out = dsound_put_buffer_out,
|
||||
.enable_out = dsound_enable_out,
|
||||
|
||||
@@ -97,9 +97,9 @@ static void qjack_buffer_create(QJackBuffer *buffer, int channels, int frames)
|
||||
buffer->used = 0;
|
||||
buffer->rptr = 0;
|
||||
buffer->wptr = 0;
|
||||
buffer->data = g_new(float *, channels);
|
||||
buffer->data = g_malloc(channels * sizeof(float *));
|
||||
for (int i = 0; i < channels; ++i) {
|
||||
buffer->data[i] = g_new(float, frames);
|
||||
buffer->data[i] = g_malloc(frames * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,7 +453,7 @@ static int qjack_client_init(QJackClient *c)
|
||||
jack_on_shutdown(c->client, qjack_shutdown, c);
|
||||
|
||||
/* allocate and register the ports */
|
||||
c->port = g_new(jack_port_t *, c->nchannels);
|
||||
c->port = g_malloc(sizeof(jack_port_t *) * c->nchannels);
|
||||
for (int i = 0; i < c->nchannels; ++i) {
|
||||
|
||||
char port_name[16];
|
||||
@@ -483,8 +483,8 @@ static int qjack_client_init(QJackClient *c)
|
||||
c->buffersize = 512;
|
||||
}
|
||||
|
||||
/* create a 3 period buffer */
|
||||
qjack_buffer_create(&c->fifo, c->nchannels, c->buffersize * 3);
|
||||
/* create a 2 period buffer */
|
||||
qjack_buffer_create(&c->fifo, c->nchannels, c->buffersize * 2);
|
||||
|
||||
qjack_client_connect_ports(c);
|
||||
c->state = QJACK_STATE_RUNNING;
|
||||
@@ -622,7 +622,6 @@ static void qjack_enable_in(HWVoiceIn *hw, bool enable)
|
||||
ji->c.enabled = enable;
|
||||
}
|
||||
|
||||
#if !defined(WIN32) && defined(CONFIG_PTHREAD_SETNAME_NP_W_TID)
|
||||
static int qjack_thread_creator(jack_native_thread_t *thread,
|
||||
const pthread_attr_t *attr, void *(*function)(void *), void *arg)
|
||||
{
|
||||
@@ -636,7 +635,6 @@ static int qjack_thread_creator(jack_native_thread_t *thread,
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *qjack_init(Audiodev *dev)
|
||||
{
|
||||
@@ -652,7 +650,6 @@ static struct audio_pcm_ops jack_pcm_ops = {
|
||||
.init_out = qjack_init_out,
|
||||
.fini_out = qjack_fini_out,
|
||||
.write = qjack_write,
|
||||
.buffer_get_free = audio_generic_buffer_get_free,
|
||||
.run_buffer_out = audio_generic_run_buffer_out,
|
||||
.enable_out = qjack_enable_out,
|
||||
|
||||
@@ -690,9 +687,7 @@ static void register_audio_jack(void)
|
||||
{
|
||||
qemu_mutex_init(&qjack_shutdown_lock);
|
||||
audio_driver_register(&jack_driver);
|
||||
#if !defined(WIN32) && defined(CONFIG_PTHREAD_SETNAME_NP_W_TID)
|
||||
jack_set_thread_creator(qjack_thread_creator);
|
||||
#endif
|
||||
jack_set_error_function(qjack_error);
|
||||
jack_set_info_function(qjack_info);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ softmmu_ss.add(files(
|
||||
'wavcapture.c',
|
||||
))
|
||||
|
||||
softmmu_ss.add(when: coreaudio, if_true: files('coreaudio.m'))
|
||||
softmmu_ss.add(when: coreaudio, if_true: files('coreaudio.c'))
|
||||
softmmu_ss.add(when: dsound, if_true: files('dsoundaudio.c', 'audio_win_int.c'))
|
||||
|
||||
audio_modules = {}
|
||||
@@ -26,10 +26,4 @@ foreach m : [
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if dbus_display
|
||||
module_ss = ss.source_set()
|
||||
module_ss.add(when: gio, if_true: files('dbusaudio.c'))
|
||||
audio_modules += {'dbus': module_ss}
|
||||
endif
|
||||
|
||||
modules += {'audio': audio_modules}
|
||||
|
||||
@@ -342,13 +342,13 @@ f_sample *mixeng_clip_float[2] = {
|
||||
void audio_sample_to_uint64(const void *samples, int pos,
|
||||
uint64_t *left, uint64_t *right)
|
||||
{
|
||||
const struct st_sample *sample = samples;
|
||||
sample += pos;
|
||||
#ifdef FLOAT_MIXENG
|
||||
error_report(
|
||||
"Coreaudio and floating point samples are not supported by replay yet");
|
||||
abort();
|
||||
#else
|
||||
const struct st_sample *sample = samples;
|
||||
sample += pos;
|
||||
*left = sample->l;
|
||||
*right = sample->r;
|
||||
#endif
|
||||
@@ -357,13 +357,13 @@ void audio_sample_to_uint64(const void *samples, int pos,
|
||||
void audio_sample_from_uint64(void *samples, int pos,
|
||||
uint64_t left, uint64_t right)
|
||||
{
|
||||
struct st_sample *sample = samples;
|
||||
sample += pos;
|
||||
#ifdef FLOAT_MIXENG
|
||||
error_report(
|
||||
"Coreaudio and floating point samples are not supported by replay yet");
|
||||
abort();
|
||||
#else
|
||||
struct st_sample *sample = samples;
|
||||
sample += pos;
|
||||
sample->l = left;
|
||||
sample->r = right;
|
||||
#endif
|
||||
|
||||
@@ -118,7 +118,6 @@ static struct audio_pcm_ops no_pcm_ops = {
|
||||
.init_out = no_init_out,
|
||||
.fini_out = no_fini_out,
|
||||
.write = no_write,
|
||||
.buffer_get_free = audio_generic_buffer_get_free,
|
||||
.run_buffer_out = audio_generic_run_buffer_out,
|
||||
.enable_out = no_enable_out,
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ struct oss_params {
|
||||
int fragsize;
|
||||
};
|
||||
|
||||
static void G_GNUC_PRINTF (2, 3) oss_logerr (int err, const char *fmt, ...)
|
||||
static void GCC_FMT_ATTR (2, 3) oss_logerr (int err, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -74,7 +74,7 @@ static void G_GNUC_PRINTF (2, 3) oss_logerr (int err, const char *fmt, ...)
|
||||
AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err));
|
||||
}
|
||||
|
||||
static void G_GNUC_PRINTF (3, 4) oss_logerr2 (
|
||||
static void GCC_FMT_ATTR (3, 4) oss_logerr2 (
|
||||
int err,
|
||||
const char *typ,
|
||||
const char *fmt,
|
||||
@@ -389,23 +389,11 @@ static void oss_run_buffer_out(HWVoiceOut *hw)
|
||||
}
|
||||
}
|
||||
|
||||
static size_t oss_buffer_get_free(HWVoiceOut *hw)
|
||||
{
|
||||
OSSVoiceOut *oss = (OSSVoiceOut *)hw;
|
||||
|
||||
if (oss->mmapped) {
|
||||
return oss_get_available_bytes(oss);
|
||||
} else {
|
||||
return audio_generic_buffer_get_free(hw);
|
||||
}
|
||||
}
|
||||
|
||||
static void *oss_get_buffer_out(HWVoiceOut *hw, size_t *size)
|
||||
{
|
||||
OSSVoiceOut *oss = (OSSVoiceOut *)hw;
|
||||
|
||||
OSSVoiceOut *oss = (OSSVoiceOut *) hw;
|
||||
if (oss->mmapped) {
|
||||
*size = hw->size_emul - hw->pos_emul;
|
||||
*size = MIN(oss_get_available_bytes(oss), hw->size_emul - hw->pos_emul);
|
||||
return hw->buf_emul + hw->pos_emul;
|
||||
} else {
|
||||
return audio_generic_get_buffer_out(hw, size);
|
||||
@@ -762,7 +750,6 @@ static struct audio_pcm_ops oss_pcm_ops = {
|
||||
.init_out = oss_init_out,
|
||||
.fini_out = oss_fini_out,
|
||||
.write = oss_write,
|
||||
.buffer_get_free = oss_buffer_get_free,
|
||||
.run_buffer_out = oss_run_buffer_out,
|
||||
.get_buffer_out = oss_get_buffer_out,
|
||||
.put_buffer_out = oss_put_buffer_out,
|
||||
|
||||
@@ -43,7 +43,7 @@ typedef struct {
|
||||
|
||||
static void qpa_conn_fini(PAConnection *c);
|
||||
|
||||
static void G_GNUC_PRINTF (2, 3) qpa_logerr (int err, const char *fmt, ...)
|
||||
static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -201,11 +201,13 @@ unlock_and_fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t qpa_buffer_get_free(HWVoiceOut *hw)
|
||||
static void *qpa_get_buffer_out(HWVoiceOut *hw, size_t *size)
|
||||
{
|
||||
PAVoiceOut *p = (PAVoiceOut *)hw;
|
||||
PAVoiceOut *p = (PAVoiceOut *) hw;
|
||||
PAConnection *c = p->g->conn;
|
||||
void *ret;
|
||||
size_t l;
|
||||
int r;
|
||||
|
||||
pa_threaded_mainloop_lock(c->mainloop);
|
||||
|
||||
@@ -214,6 +216,7 @@ static size_t qpa_buffer_get_free(HWVoiceOut *hw)
|
||||
if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
|
||||
/* wait for stream to become ready */
|
||||
l = 0;
|
||||
ret = NULL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
@@ -221,33 +224,16 @@ static size_t qpa_buffer_get_free(HWVoiceOut *hw)
|
||||
CHECK_SUCCESS_GOTO(c, l != (size_t) -1, unlock_and_fail,
|
||||
"pa_stream_writable_size failed\n");
|
||||
|
||||
unlock:
|
||||
pa_threaded_mainloop_unlock(c->mainloop);
|
||||
return l;
|
||||
|
||||
unlock_and_fail:
|
||||
pa_threaded_mainloop_unlock(c->mainloop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *qpa_get_buffer_out(HWVoiceOut *hw, size_t *size)
|
||||
{
|
||||
PAVoiceOut *p = (PAVoiceOut *)hw;
|
||||
PAConnection *c = p->g->conn;
|
||||
void *ret;
|
||||
int r;
|
||||
|
||||
pa_threaded_mainloop_lock(c->mainloop);
|
||||
|
||||
CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
|
||||
"pa_threaded_mainloop_lock failed\n");
|
||||
|
||||
*size = -1;
|
||||
r = pa_stream_begin_write(p->stream, &ret, size);
|
||||
CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail,
|
||||
"pa_stream_begin_write failed\n");
|
||||
|
||||
unlock:
|
||||
pa_threaded_mainloop_unlock(c->mainloop);
|
||||
if (*size > l) {
|
||||
*size = l;
|
||||
}
|
||||
return ret;
|
||||
|
||||
unlock_and_fail:
|
||||
@@ -549,8 +535,11 @@ static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
}
|
||||
|
||||
audio_pcm_init_info (&hw->info, &obt_as);
|
||||
/* hw->samples counts in frames */
|
||||
hw->samples = audio_buffer_frames(
|
||||
/*
|
||||
* This is wrong. hw->samples counts in frames. hw->samples will be
|
||||
* number of channels times larger than expected.
|
||||
*/
|
||||
hw->samples = audio_buffer_samples(
|
||||
qapi_AudiodevPaPerDirectionOptions_base(ppdo), &obt_as, 46440);
|
||||
|
||||
return 0;
|
||||
@@ -598,8 +587,11 @@ static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
|
||||
}
|
||||
|
||||
audio_pcm_init_info (&hw->info, &obt_as);
|
||||
/* hw->samples counts in frames */
|
||||
hw->samples = audio_buffer_frames(
|
||||
/*
|
||||
* This is wrong. hw->samples counts in frames. hw->samples will be
|
||||
* number of channels times larger than expected.
|
||||
*/
|
||||
hw->samples = audio_buffer_samples(
|
||||
qapi_AudiodevPaPerDirectionOptions_base(ppdo), &obt_as, 46440);
|
||||
|
||||
return 0;
|
||||
@@ -752,7 +744,7 @@ static int qpa_validate_per_direction_opts(Audiodev *dev,
|
||||
{
|
||||
if (!pdo->has_latency) {
|
||||
pdo->has_latency = true;
|
||||
pdo->latency = 46440;
|
||||
pdo->latency = 15000;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -760,7 +752,7 @@ static int qpa_validate_per_direction_opts(Audiodev *dev,
|
||||
/* common */
|
||||
static void *qpa_conn_init(const char *server)
|
||||
{
|
||||
PAConnection *c = g_new0(PAConnection, 1);
|
||||
PAConnection *c = g_malloc0(sizeof(PAConnection));
|
||||
QTAILQ_INSERT_TAIL(&pa_conns, c, list);
|
||||
|
||||
c->mainloop = pa_threaded_mainloop_new();
|
||||
@@ -849,7 +841,7 @@ static void *qpa_audio_init(Audiodev *dev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g = g_new0(paaudio, 1);
|
||||
g = g_malloc0(sizeof(paaudio));
|
||||
server = popts->has_server ? popts->server : NULL;
|
||||
|
||||
g->dev = dev;
|
||||
@@ -909,7 +901,6 @@ static struct audio_pcm_ops qpa_pcm_ops = {
|
||||
.init_out = qpa_init_out,
|
||||
.fini_out = qpa_fini_out,
|
||||
.write = qpa_write,
|
||||
.buffer_get_free = qpa_buffer_get_free,
|
||||
.get_buffer_out = qpa_get_buffer_out,
|
||||
.put_buffer_out = qpa_put_buffer_out,
|
||||
.volume_out = qpa_volume_out,
|
||||
|
||||
@@ -55,7 +55,7 @@ typedef struct SDLVoiceIn {
|
||||
SDL_AudioDeviceID devid;
|
||||
} SDLVoiceIn;
|
||||
|
||||
static void G_GNUC_PRINTF (1, 2) sdl_logerr (const char *fmt, ...)
|
||||
static void GCC_FMT_ATTR (1, 2) sdl_logerr (const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -224,11 +224,12 @@ static void sdl_callback_out(void *opaque, Uint8 *buf, int len)
|
||||
/* dolog("callback_out: len=%d avail=%zu\n", len, hw->pending_emul); */
|
||||
|
||||
while (hw->pending_emul && len) {
|
||||
size_t write_len, start;
|
||||
|
||||
start = audio_ring_posb(hw->pos_emul, hw->pending_emul,
|
||||
hw->size_emul);
|
||||
assert(start < hw->size_emul);
|
||||
size_t write_len;
|
||||
ssize_t start = (ssize_t)hw->pos_emul - hw->pending_emul;
|
||||
if (start < 0) {
|
||||
start += hw->size_emul;
|
||||
}
|
||||
assert(start >= 0 && start < hw->size_emul);
|
||||
|
||||
write_len = MIN(MIN(hw->pending_emul, len),
|
||||
hw->size_emul - start);
|
||||
@@ -309,7 +310,6 @@ static void sdl_callback_in(void *opaque, Uint8 *buf, int len)
|
||||
SDL_UnlockAudioDevice(sdl->devid); \
|
||||
}
|
||||
|
||||
SDL_WRAPPER_FUNC(buffer_get_free, size_t, (HWVoiceOut *hw), (hw), Out)
|
||||
SDL_WRAPPER_FUNC(get_buffer_out, void *, (HWVoiceOut *hw, size_t *size),
|
||||
(hw, size), Out)
|
||||
SDL_WRAPPER_FUNC(put_buffer_out, size_t,
|
||||
@@ -347,8 +347,11 @@ static int sdl_init_out(HWVoiceOut *hw, struct audsettings *as,
|
||||
req.freq = as->freq;
|
||||
req.format = aud_to_sdlfmt (as->fmt);
|
||||
req.channels = as->nchannels;
|
||||
/* SDL samples are QEMU frames */
|
||||
req.samples = audio_buffer_frames(
|
||||
/*
|
||||
* This is wrong. SDL samples are QEMU frames. The buffer size will be
|
||||
* the requested buffer size multiplied by the number of channels.
|
||||
*/
|
||||
req.samples = audio_buffer_samples(
|
||||
qapi_AudiodevSdlPerDirectionOptions_base(spdo), as, 11610);
|
||||
req.callback = sdl_callback_out;
|
||||
req.userdata = sdl;
|
||||
@@ -469,8 +472,6 @@ static struct audio_pcm_ops sdl_pcm_ops = {
|
||||
.fini_out = sdl_fini_out,
|
||||
/* wrapper for audio_generic_write */
|
||||
.write = sdl_write,
|
||||
/* wrapper for audio_generic_buffer_get_free */
|
||||
.buffer_get_free = sdl_buffer_get_free,
|
||||
/* wrapper for audio_generic_get_buffer_out */
|
||||
.get_buffer_out = sdl_get_buffer_out,
|
||||
/* wrapper for audio_generic_put_buffer_out */
|
||||
|
||||
@@ -13,11 +13,6 @@ alsa_resume_out(void) "Resuming suspended output stream"
|
||||
# ossaudio.c
|
||||
oss_version(int version) "OSS version = 0x%x"
|
||||
|
||||
# dbusaudio.c
|
||||
dbus_audio_register(const char *s, const char *dir) "sender = %s, dir = %s"
|
||||
dbus_audio_put_buffer_out(size_t len) "len = %zu"
|
||||
dbus_audio_read(size_t len) "len = %zu"
|
||||
|
||||
# audio.c
|
||||
audio_timer_start(int interval) "interval %d ms"
|
||||
audio_timer_stop(void) ""
|
||||
|
||||
@@ -197,7 +197,6 @@ static struct audio_pcm_ops wav_pcm_ops = {
|
||||
.init_out = wav_init_out,
|
||||
.fini_out = wav_fini_out,
|
||||
.write = wav_write_out,
|
||||
.buffer_get_free = audio_generic_buffer_get_free,
|
||||
.run_buffer_out = audio_generic_run_buffer_out,
|
||||
.enable_out = wav_enable_out,
|
||||
};
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "qapi/error.h"
|
||||
#include "standard-headers/linux/virtio_crypto.h"
|
||||
#include "crypto/cipher.h"
|
||||
#include "crypto/akcipher.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
|
||||
@@ -43,11 +42,10 @@ typedef struct CryptoDevBackendBuiltinSession {
|
||||
QCryptoCipher *cipher;
|
||||
uint8_t direction; /* encryption or decryption */
|
||||
uint8_t type; /* cipher? hash? aead? */
|
||||
QCryptoAkCipher *akcipher;
|
||||
QTAILQ_ENTRY(CryptoDevBackendBuiltinSession) next;
|
||||
} CryptoDevBackendBuiltinSession;
|
||||
|
||||
/* Max number of symmetric/asymmetric sessions */
|
||||
/* Max number of symmetric sessions */
|
||||
#define MAX_NUM_SESSIONS 256
|
||||
|
||||
#define CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN 512
|
||||
@@ -82,17 +80,15 @@ static void cryptodev_builtin_init(
|
||||
backend->conf.crypto_services =
|
||||
1u << VIRTIO_CRYPTO_SERVICE_CIPHER |
|
||||
1u << VIRTIO_CRYPTO_SERVICE_HASH |
|
||||
1u << VIRTIO_CRYPTO_SERVICE_MAC |
|
||||
1u << VIRTIO_CRYPTO_SERVICE_AKCIPHER;
|
||||
1u << VIRTIO_CRYPTO_SERVICE_MAC;
|
||||
backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
|
||||
backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
|
||||
backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA;
|
||||
/*
|
||||
* Set the Maximum length of crypto request.
|
||||
* Why this value? Just avoid to overflow when
|
||||
* memory allocation for each crypto request.
|
||||
*/
|
||||
backend->conf.max_size = LONG_MAX - sizeof(CryptoDevBackendOpInfo);
|
||||
backend->conf.max_size = LONG_MAX - sizeof(CryptoDevBackendSymOpInfo);
|
||||
backend->conf.max_cipher_key_len = CRYPTODEV_BUITLIN_MAX_CIPHER_KEY_LEN;
|
||||
backend->conf.max_auth_key_len = CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN;
|
||||
|
||||
@@ -152,55 +148,6 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cryptodev_builtin_get_rsa_hash_algo(
|
||||
int virtio_rsa_hash, Error **errp)
|
||||
{
|
||||
switch (virtio_rsa_hash) {
|
||||
case VIRTIO_CRYPTO_RSA_MD5:
|
||||
return QCRYPTO_HASH_ALG_MD5;
|
||||
|
||||
case VIRTIO_CRYPTO_RSA_SHA1:
|
||||
return QCRYPTO_HASH_ALG_SHA1;
|
||||
|
||||
case VIRTIO_CRYPTO_RSA_SHA256:
|
||||
return QCRYPTO_HASH_ALG_SHA256;
|
||||
|
||||
case VIRTIO_CRYPTO_RSA_SHA512:
|
||||
return QCRYPTO_HASH_ALG_SHA512;
|
||||
|
||||
default:
|
||||
error_setg(errp, "Unsupported rsa hash algo: %d", virtio_rsa_hash);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int cryptodev_builtin_set_rsa_options(
|
||||
int virtio_padding_algo,
|
||||
int virtio_hash_algo,
|
||||
QCryptoAkCipherOptionsRSA *opt,
|
||||
Error **errp)
|
||||
{
|
||||
if (virtio_padding_algo == VIRTIO_CRYPTO_RSA_PKCS1_PADDING) {
|
||||
int hash_alg;
|
||||
|
||||
hash_alg = cryptodev_builtin_get_rsa_hash_algo(virtio_hash_algo, errp);
|
||||
if (hash_alg < 0) {
|
||||
return -1;
|
||||
}
|
||||
opt->hash_alg = hash_alg;
|
||||
opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_PKCS1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (virtio_padding_algo == VIRTIO_CRYPTO_RSA_RAW_PADDING) {
|
||||
opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_RAW;
|
||||
return 0;
|
||||
}
|
||||
|
||||
error_setg(errp, "Unsupported rsa padding algo: %d", virtio_padding_algo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cryptodev_builtin_create_cipher_session(
|
||||
CryptoDevBackendBuiltin *builtin,
|
||||
CryptoDevBackendSymSessionInfo *sess_info,
|
||||
@@ -293,89 +240,26 @@ static int cryptodev_builtin_create_cipher_session(
|
||||
return index;
|
||||
}
|
||||
|
||||
static int cryptodev_builtin_create_akcipher_session(
|
||||
CryptoDevBackendBuiltin *builtin,
|
||||
CryptoDevBackendAsymSessionInfo *sess_info,
|
||||
Error **errp)
|
||||
{
|
||||
CryptoDevBackendBuiltinSession *sess;
|
||||
QCryptoAkCipher *akcipher;
|
||||
int index;
|
||||
QCryptoAkCipherKeyType type;
|
||||
QCryptoAkCipherOptions opts;
|
||||
|
||||
switch (sess_info->algo) {
|
||||
case VIRTIO_CRYPTO_AKCIPHER_RSA:
|
||||
opts.alg = QCRYPTO_AKCIPHER_ALG_RSA;
|
||||
if (cryptodev_builtin_set_rsa_options(sess_info->u.rsa.padding_algo,
|
||||
sess_info->u.rsa.hash_algo, &opts.u.rsa, errp) != 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
/* TODO support DSA&ECDSA until qemu crypto framework support these */
|
||||
|
||||
default:
|
||||
error_setg(errp, "Unsupported akcipher alg %u", sess_info->algo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (sess_info->keytype) {
|
||||
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
|
||||
type = QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC;
|
||||
break;
|
||||
|
||||
case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
|
||||
type = QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE;
|
||||
break;
|
||||
|
||||
default:
|
||||
error_setg(errp, "Unsupported akcipher keytype %u", sess_info->keytype);
|
||||
return -1;
|
||||
}
|
||||
|
||||
index = cryptodev_builtin_get_unused_session_index(builtin);
|
||||
if (index < 0) {
|
||||
error_setg(errp, "Total number of sessions created exceeds %u",
|
||||
MAX_NUM_SESSIONS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
akcipher = qcrypto_akcipher_new(&opts, type, sess_info->key,
|
||||
sess_info->keylen, errp);
|
||||
if (!akcipher) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sess = g_new0(CryptoDevBackendBuiltinSession, 1);
|
||||
sess->akcipher = akcipher;
|
||||
|
||||
builtin->sessions[index] = sess;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static int64_t cryptodev_builtin_create_session(
|
||||
static int64_t cryptodev_builtin_sym_create_session(
|
||||
CryptoDevBackend *backend,
|
||||
CryptoDevBackendSessionInfo *sess_info,
|
||||
CryptoDevBackendSymSessionInfo *sess_info,
|
||||
uint32_t queue_index, Error **errp)
|
||||
{
|
||||
CryptoDevBackendBuiltin *builtin =
|
||||
CRYPTODEV_BACKEND_BUILTIN(backend);
|
||||
CryptoDevBackendSymSessionInfo *sym_sess_info;
|
||||
CryptoDevBackendAsymSessionInfo *asym_sess_info;
|
||||
int64_t session_id = -1;
|
||||
int ret;
|
||||
|
||||
switch (sess_info->op_code) {
|
||||
case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
|
||||
sym_sess_info = &sess_info->u.sym_sess_info;
|
||||
return cryptodev_builtin_create_cipher_session(
|
||||
builtin, sym_sess_info, errp);
|
||||
|
||||
case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
|
||||
asym_sess_info = &sess_info->u.asym_sess_info;
|
||||
return cryptodev_builtin_create_akcipher_session(
|
||||
builtin, asym_sess_info, errp);
|
||||
|
||||
ret = cryptodev_builtin_create_cipher_session(
|
||||
builtin, sess_info, errp);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
} else {
|
||||
session_id = ret;
|
||||
}
|
||||
break;
|
||||
case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
|
||||
case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
|
||||
default:
|
||||
@@ -384,44 +268,50 @@ static int64_t cryptodev_builtin_create_session(
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return session_id;
|
||||
}
|
||||
|
||||
static int cryptodev_builtin_close_session(
|
||||
static int cryptodev_builtin_sym_close_session(
|
||||
CryptoDevBackend *backend,
|
||||
uint64_t session_id,
|
||||
uint32_t queue_index, Error **errp)
|
||||
{
|
||||
CryptoDevBackendBuiltin *builtin =
|
||||
CRYPTODEV_BACKEND_BUILTIN(backend);
|
||||
CryptoDevBackendBuiltinSession *session;
|
||||
|
||||
assert(session_id < MAX_NUM_SESSIONS && builtin->sessions[session_id]);
|
||||
|
||||
session = builtin->sessions[session_id];
|
||||
if (session->cipher) {
|
||||
qcrypto_cipher_free(session->cipher);
|
||||
} else if (session->akcipher) {
|
||||
qcrypto_akcipher_free(session->akcipher);
|
||||
}
|
||||
|
||||
g_free(session);
|
||||
qcrypto_cipher_free(builtin->sessions[session_id]->cipher);
|
||||
g_free(builtin->sessions[session_id]);
|
||||
builtin->sessions[session_id] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cryptodev_builtin_sym_operation(
|
||||
CryptoDevBackendBuiltinSession *sess,
|
||||
CryptoDevBackendSymOpInfo *op_info, Error **errp)
|
||||
CryptoDevBackend *backend,
|
||||
CryptoDevBackendSymOpInfo *op_info,
|
||||
uint32_t queue_index, Error **errp)
|
||||
{
|
||||
CryptoDevBackendBuiltin *builtin =
|
||||
CRYPTODEV_BACKEND_BUILTIN(backend);
|
||||
CryptoDevBackendBuiltinSession *sess;
|
||||
int ret;
|
||||
|
||||
if (op_info->session_id >= MAX_NUM_SESSIONS ||
|
||||
builtin->sessions[op_info->session_id] == NULL) {
|
||||
error_setg(errp, "Cannot find a valid session id: %" PRIu64 "",
|
||||
op_info->session_id);
|
||||
return -VIRTIO_CRYPTO_INVSESS;
|
||||
}
|
||||
|
||||
if (op_info->op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
|
||||
error_setg(errp,
|
||||
"Algorithm chain is unsupported for cryptdoev-builtin");
|
||||
return -VIRTIO_CRYPTO_NOTSUPP;
|
||||
}
|
||||
|
||||
sess = builtin->sessions[op_info->session_id];
|
||||
|
||||
if (op_info->iv_len > 0) {
|
||||
ret = qcrypto_cipher_setiv(sess->cipher, op_info->iv,
|
||||
op_info->iv_len, errp);
|
||||
@@ -443,99 +333,9 @@ static int cryptodev_builtin_sym_operation(
|
||||
return -VIRTIO_CRYPTO_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return VIRTIO_CRYPTO_OK;
|
||||
}
|
||||
|
||||
static int cryptodev_builtin_asym_operation(
|
||||
CryptoDevBackendBuiltinSession *sess, uint32_t op_code,
|
||||
CryptoDevBackendAsymOpInfo *op_info, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (op_code) {
|
||||
case VIRTIO_CRYPTO_AKCIPHER_ENCRYPT:
|
||||
ret = qcrypto_akcipher_encrypt(sess->akcipher,
|
||||
op_info->src, op_info->src_len,
|
||||
op_info->dst, op_info->dst_len, errp);
|
||||
break;
|
||||
|
||||
case VIRTIO_CRYPTO_AKCIPHER_DECRYPT:
|
||||
ret = qcrypto_akcipher_decrypt(sess->akcipher,
|
||||
op_info->src, op_info->src_len,
|
||||
op_info->dst, op_info->dst_len, errp);
|
||||
break;
|
||||
|
||||
case VIRTIO_CRYPTO_AKCIPHER_SIGN:
|
||||
ret = qcrypto_akcipher_sign(sess->akcipher,
|
||||
op_info->src, op_info->src_len,
|
||||
op_info->dst, op_info->dst_len, errp);
|
||||
break;
|
||||
|
||||
case VIRTIO_CRYPTO_AKCIPHER_VERIFY:
|
||||
ret = qcrypto_akcipher_verify(sess->akcipher,
|
||||
op_info->src, op_info->src_len,
|
||||
op_info->dst, op_info->dst_len, errp);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -VIRTIO_CRYPTO_ERR;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (op_code == VIRTIO_CRYPTO_AKCIPHER_VERIFY) {
|
||||
return -VIRTIO_CRYPTO_KEY_REJECTED;
|
||||
}
|
||||
return -VIRTIO_CRYPTO_ERR;
|
||||
}
|
||||
|
||||
/* Buffer is too short, typically the driver should handle this case */
|
||||
if (unlikely(ret > op_info->dst_len)) {
|
||||
if (errp && !*errp) {
|
||||
error_setg(errp, "dst buffer too short");
|
||||
}
|
||||
|
||||
return -VIRTIO_CRYPTO_ERR;
|
||||
}
|
||||
|
||||
op_info->dst_len = ret;
|
||||
|
||||
return VIRTIO_CRYPTO_OK;
|
||||
}
|
||||
|
||||
static int cryptodev_builtin_operation(
|
||||
CryptoDevBackend *backend,
|
||||
CryptoDevBackendOpInfo *op_info,
|
||||
uint32_t queue_index, Error **errp)
|
||||
{
|
||||
CryptoDevBackendBuiltin *builtin =
|
||||
CRYPTODEV_BACKEND_BUILTIN(backend);
|
||||
CryptoDevBackendBuiltinSession *sess;
|
||||
CryptoDevBackendSymOpInfo *sym_op_info;
|
||||
CryptoDevBackendAsymOpInfo *asym_op_info;
|
||||
enum CryptoDevBackendAlgType algtype = op_info->algtype;
|
||||
int ret = -VIRTIO_CRYPTO_ERR;
|
||||
|
||||
if (op_info->session_id >= MAX_NUM_SESSIONS ||
|
||||
builtin->sessions[op_info->session_id] == NULL) {
|
||||
error_setg(errp, "Cannot find a valid session id: %" PRIu64 "",
|
||||
op_info->session_id);
|
||||
return -VIRTIO_CRYPTO_INVSESS;
|
||||
}
|
||||
|
||||
sess = builtin->sessions[op_info->session_id];
|
||||
if (algtype == CRYPTODEV_BACKEND_ALG_SYM) {
|
||||
sym_op_info = op_info->u.sym_op_info;
|
||||
ret = cryptodev_builtin_sym_operation(sess, sym_op_info, errp);
|
||||
} else if (algtype == CRYPTODEV_BACKEND_ALG_ASYM) {
|
||||
asym_op_info = op_info->u.asym_op_info;
|
||||
ret = cryptodev_builtin_asym_operation(sess, op_info->op_code,
|
||||
asym_op_info, errp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cryptodev_builtin_cleanup(
|
||||
CryptoDevBackend *backend,
|
||||
Error **errp)
|
||||
@@ -548,7 +348,7 @@ static void cryptodev_builtin_cleanup(
|
||||
|
||||
for (i = 0; i < MAX_NUM_SESSIONS; i++) {
|
||||
if (builtin->sessions[i] != NULL) {
|
||||
cryptodev_builtin_close_session(backend, i, 0, &error_abort);
|
||||
cryptodev_builtin_sym_close_session(backend, i, 0, &error_abort);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,9 +370,9 @@ cryptodev_builtin_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
bc->init = cryptodev_builtin_init;
|
||||
bc->cleanup = cryptodev_builtin_cleanup;
|
||||
bc->create_session = cryptodev_builtin_create_session;
|
||||
bc->close_session = cryptodev_builtin_close_session;
|
||||
bc->do_op = cryptodev_builtin_operation;
|
||||
bc->create_session = cryptodev_builtin_sym_create_session;
|
||||
bc->close_session = cryptodev_builtin_sym_close_session;
|
||||
bc->do_sym_op = cryptodev_builtin_sym_operation;
|
||||
}
|
||||
|
||||
static const TypeInfo cryptodev_builtin_info = {
|
||||
|
||||
@@ -259,33 +259,7 @@ static int64_t cryptodev_vhost_user_sym_create_session(
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int64_t cryptodev_vhost_user_create_session(
|
||||
CryptoDevBackend *backend,
|
||||
CryptoDevBackendSessionInfo *sess_info,
|
||||
uint32_t queue_index, Error **errp)
|
||||
{
|
||||
uint32_t op_code = sess_info->op_code;
|
||||
CryptoDevBackendSymSessionInfo *sym_sess_info;
|
||||
|
||||
switch (op_code) {
|
||||
case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
|
||||
case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
|
||||
case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
|
||||
case VIRTIO_CRYPTO_AEAD_CREATE_SESSION:
|
||||
sym_sess_info = &sess_info->u.sym_sess_info;
|
||||
return cryptodev_vhost_user_sym_create_session(backend, sym_sess_info,
|
||||
queue_index, errp);
|
||||
default:
|
||||
error_setg(errp, "Unsupported opcode :%" PRIu32 "",
|
||||
sess_info->op_code);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cryptodev_vhost_user_close_session(
|
||||
static int cryptodev_vhost_user_sym_close_session(
|
||||
CryptoDevBackend *backend,
|
||||
uint64_t session_id,
|
||||
uint32_t queue_index, Error **errp)
|
||||
@@ -377,9 +351,9 @@ cryptodev_vhost_user_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
bc->init = cryptodev_vhost_user_init;
|
||||
bc->cleanup = cryptodev_vhost_user_cleanup;
|
||||
bc->create_session = cryptodev_vhost_user_create_session;
|
||||
bc->close_session = cryptodev_vhost_user_close_session;
|
||||
bc->do_op = NULL;
|
||||
bc->create_session = cryptodev_vhost_user_sym_create_session;
|
||||
bc->close_session = cryptodev_vhost_user_sym_close_session;
|
||||
bc->do_sym_op = NULL;
|
||||
|
||||
object_class_property_add_str(oc, "chardev",
|
||||
cryptodev_vhost_user_get_chardev,
|
||||
|
||||
@@ -39,7 +39,7 @@ cryptodev_backend_new_client(const char *model,
|
||||
{
|
||||
CryptoDevBackendClient *cc;
|
||||
|
||||
cc = g_new0(CryptoDevBackendClient, 1);
|
||||
cc = g_malloc0(sizeof(CryptoDevBackendClient));
|
||||
cc->model = g_strdup(model);
|
||||
if (name) {
|
||||
cc->name = g_strdup(name);
|
||||
@@ -72,9 +72,9 @@ void cryptodev_backend_cleanup(
|
||||
}
|
||||
}
|
||||
|
||||
int64_t cryptodev_backend_create_session(
|
||||
int64_t cryptodev_backend_sym_create_session(
|
||||
CryptoDevBackend *backend,
|
||||
CryptoDevBackendSessionInfo *sess_info,
|
||||
CryptoDevBackendSymSessionInfo *sess_info,
|
||||
uint32_t queue_index, Error **errp)
|
||||
{
|
||||
CryptoDevBackendClass *bc =
|
||||
@@ -87,7 +87,7 @@ int64_t cryptodev_backend_create_session(
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cryptodev_backend_close_session(
|
||||
int cryptodev_backend_sym_close_session(
|
||||
CryptoDevBackend *backend,
|
||||
uint64_t session_id,
|
||||
uint32_t queue_index, Error **errp)
|
||||
@@ -102,16 +102,16 @@ int cryptodev_backend_close_session(
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cryptodev_backend_operation(
|
||||
static int cryptodev_backend_sym_operation(
|
||||
CryptoDevBackend *backend,
|
||||
CryptoDevBackendOpInfo *op_info,
|
||||
CryptoDevBackendSymOpInfo *op_info,
|
||||
uint32_t queue_index, Error **errp)
|
||||
{
|
||||
CryptoDevBackendClass *bc =
|
||||
CRYPTODEV_BACKEND_GET_CLASS(backend);
|
||||
|
||||
if (bc->do_op) {
|
||||
return bc->do_op(backend, op_info, queue_index, errp);
|
||||
if (bc->do_sym_op) {
|
||||
return bc->do_sym_op(backend, op_info, queue_index, errp);
|
||||
}
|
||||
|
||||
return -VIRTIO_CRYPTO_ERR;
|
||||
@@ -123,18 +123,20 @@ int cryptodev_backend_crypto_operation(
|
||||
uint32_t queue_index, Error **errp)
|
||||
{
|
||||
VirtIOCryptoReq *req = opaque;
|
||||
CryptoDevBackendOpInfo *op_info = &req->op_info;
|
||||
enum CryptoDevBackendAlgType algtype = req->flags;
|
||||
|
||||
if ((algtype != CRYPTODEV_BACKEND_ALG_SYM)
|
||||
&& (algtype != CRYPTODEV_BACKEND_ALG_ASYM)) {
|
||||
if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
|
||||
CryptoDevBackendSymOpInfo *op_info;
|
||||
op_info = req->u.sym_op_info;
|
||||
|
||||
return cryptodev_backend_sym_operation(backend,
|
||||
op_info, queue_index, errp);
|
||||
} else {
|
||||
error_setg(errp, "Unsupported cryptodev alg type: %" PRIu32 "",
|
||||
algtype);
|
||||
|
||||
return -VIRTIO_CRYPTO_NOTSUPP;
|
||||
req->flags);
|
||||
return -VIRTIO_CRYPTO_NOTSUPP;
|
||||
}
|
||||
|
||||
return cryptodev_backend_operation(backend, op_info, queue_index, errp);
|
||||
return -VIRTIO_CRYPTO_ERR;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -114,19 +114,14 @@ dbus_get_proxies(DBusVMState *self, GError **err)
|
||||
"org.qemu.VMState1",
|
||||
NULL, err);
|
||||
if (!proxy) {
|
||||
if (err != NULL && *err != NULL) {
|
||||
warn_report("%s: Failed to create proxy: %s",
|
||||
__func__, (*err)->message);
|
||||
g_clear_error(err);
|
||||
}
|
||||
continue;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = g_dbus_proxy_get_cached_property(proxy, "Id");
|
||||
if (!result) {
|
||||
warn_report("%s: VMState Id property is missing.", __func__);
|
||||
g_clear_object(&proxy);
|
||||
continue;
|
||||
g_set_error_literal(err, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"VMState Id property is missing.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
id = g_variant_dup_string(result, &size);
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
|
||||
<!--
|
||||
org.qemu.VMState1:
|
||||
|
||||
This interface must be implemented at the object path
|
||||
``/org/qemu/VMState1`` to support helper migration.
|
||||
-->
|
||||
<interface name="org.qemu.VMState1">
|
||||
|
||||
<!--
|
||||
Id:
|
||||
|
||||
A string that identifies the helper uniquely. (maximum 256 bytes
|
||||
including terminating NUL byte)
|
||||
|
||||
.. note::
|
||||
|
||||
The VMState helper ID namespace is its own namespace. In particular,
|
||||
it is not related to QEMU "id" used in -object/-device objects.
|
||||
-->
|
||||
<property name="Id" type="s" access="read"/>
|
||||
|
||||
<!--
|
||||
Load:
|
||||
@data: data to restore the state.
|
||||
|
||||
The method called on destination with the state to restore.
|
||||
|
||||
The helper may be initially started in a waiting state (with an
|
||||
``-incoming`` argument for example), and it may resume on success.
|
||||
|
||||
An error may be returned to the caller.
|
||||
-->
|
||||
<method name="Load">
|
||||
<arg type="ay" name="data" direction="in"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
Save:
|
||||
@data: state data to save for later resume.
|
||||
|
||||
The method called on the source to get the current state to be
|
||||
migrated. The helper should continue to run normally.
|
||||
|
||||
An error may be returned to the caller.
|
||||
-->
|
||||
<method name="Save">
|
||||
<arg type="ay" name="data" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "qapi/error.h"
|
||||
#include "sysemu/hostmem.h"
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/madvise.h"
|
||||
#include "sysemu/hostmem.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "qemu/config-file.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "qemu/mmap-alloc.h"
|
||||
#include "qemu/madvise.h"
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
#include <numaif.h>
|
||||
@@ -274,7 +273,7 @@ static void host_memory_backend_init(Object *obj)
|
||||
backend->merge = machine_mem_merge(machine);
|
||||
backend->dump = machine_dump_guest_core(machine);
|
||||
backend->reserve = true;
|
||||
backend->prealloc_threads = machine->smp.cpus;
|
||||
backend->prealloc_threads = 1;
|
||||
}
|
||||
|
||||
static void host_memory_backend_post_init(Object *obj)
|
||||
@@ -319,7 +318,7 @@ size_t host_memory_backend_pagesize(HostMemoryBackend *memdev)
|
||||
#else
|
||||
size_t host_memory_backend_pagesize(HostMemoryBackend *memdev)
|
||||
{
|
||||
return qemu_real_host_page_size();
|
||||
return qemu_real_host_page_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,14 +12,10 @@ softmmu_ss.add([files(
|
||||
softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files('rng-random.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_POSIX', if_true: files('hostmem-file.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_LINUX', if_true: files('hostmem-memfd.c'))
|
||||
if have_vhost_user
|
||||
softmmu_ss.add(when: 'CONFIG_VIRTIO', if_true: files('vhost-user.c'))
|
||||
endif
|
||||
softmmu_ss.add(when: ['CONFIG_VHOST_USER', 'CONFIG_VIRTIO'], if_true: files('vhost-user.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: files('cryptodev-vhost.c'))
|
||||
if have_vhost_user_crypto
|
||||
softmmu_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: files('cryptodev-vhost-user.c'))
|
||||
endif
|
||||
softmmu_ss.add(when: gio, if_true: files('dbus-vmstate.c'))
|
||||
softmmu_ss.add(when: ['CONFIG_VIRTIO_CRYPTO', 'CONFIG_VHOST_CRYPTO'], if_true: files('cryptodev-vhost-user.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_GIO', if_true: [files('dbus-vmstate.c'), gio])
|
||||
softmmu_ss.add(when: 'CONFIG_SGX', if_true: files('hostmem-epc.c'))
|
||||
|
||||
subdir('tpm')
|
||||
|
||||
@@ -48,10 +48,24 @@ static bool rng_backend_prop_get_opened(Object *obj, Error **errp)
|
||||
|
||||
static void rng_backend_complete(UserCreatable *uc, Error **errp)
|
||||
{
|
||||
RngBackend *s = RNG_BACKEND(uc);
|
||||
object_property_set_bool(OBJECT(uc), "opened", true, errp);
|
||||
}
|
||||
|
||||
static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
|
||||
{
|
||||
RngBackend *s = RNG_BACKEND(obj);
|
||||
RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (value == s->opened) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!value && s->opened) {
|
||||
error_setg(errp, QERR_PERMISSION_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (k->opened) {
|
||||
k->opened(s, &local_err);
|
||||
if (local_err) {
|
||||
@@ -108,7 +122,7 @@ static void rng_backend_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
object_class_property_add_bool(oc, "opened",
|
||||
rng_backend_prop_get_opened,
|
||||
NULL);
|
||||
rng_backend_prop_set_opened);
|
||||
}
|
||||
|
||||
static const TypeInfo rng_backend_info = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user