Merge branch 'master' of github.com:AFLplusplus/qemu-libafl-bridge
This commit is contained in:
commit
fa2b9c4a25
@ -100,6 +100,17 @@ 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
|
||||
- scripts/device-crash-test -q ./qemu-system-i386
|
||||
|
||||
build-system-fedora:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
@ -134,6 +145,18 @@ 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
|
||||
- scripts/device-crash-test -q ./qemu-system-ppc
|
||||
- scripts/device-crash-test -q ./qemu-system-riscv32
|
||||
|
||||
build-system-centos:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
|
@ -89,3 +89,38 @@ 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:
|
||||
stage: build
|
||||
image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:master
|
||||
needs: []
|
||||
timeout: 80m
|
||||
allow_failure: true
|
||||
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
|
||||
rules:
|
||||
- when: manual
|
||||
|
||||
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
|
||||
|
31
.gitlab-ci.d/cirrus/kvm-build.yml
Normal file
31
.gitlab-ci.d/cirrus/kvm-build.yml
Normal file
@ -0,0 +1,31 @@
|
||||
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
|
@ -11,3 +11,4 @@ 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'
|
||||
|
98
.gitlab-ci.d/windows.yml
Normal file
98
.gitlab-ci.d/windows.yml
Normal file
@ -0,0 +1,98 @@
|
||||
.shared_msys2_builder:
|
||||
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/2021-07-25/msys2-base-x86_64-20210725.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-libxml2
|
||||
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
|
||||
- .\msys64\usr\bin\bash -lc './configure --target-list=x86_64-softmmu
|
||||
--enable-capstone=system --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-libxml2
|
||||
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
|
||||
- mkdir output
|
||||
- cd output
|
||||
- ..\msys64\usr\bin\bash -lc "../configure --target-list=ppc64-softmmu
|
||||
--enable-capstone=system"
|
||||
- ..\msys64\usr\bin\bash -lc 'make -j2'
|
||||
- ..\msys64\usr\bin\bash -lc 'make check'
|
1
.mailmap
1
.mailmap
@ -50,6 +50,7 @@ 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@adacore.com> <fred.konrad@greensocs.com>
|
||||
Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
|
||||
|
32
MAINTAINERS
32
MAINTAINERS
@ -324,7 +324,7 @@ F: disas/sparc.c
|
||||
X86 TCG CPUs
|
||||
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
M: Richard Henderson <richard.henderson@linaro.org>
|
||||
M: Eduardo Habkost <ehabkost@redhat.com>
|
||||
M: Eduardo Habkost <eduardo@habkost.net>
|
||||
S: Maintained
|
||||
F: target/i386/tcg/
|
||||
F: tests/tcg/i386/
|
||||
@ -393,7 +393,7 @@ F: target/ppc/kvm.c
|
||||
|
||||
S390 KVM CPUs
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
S: Supported
|
||||
F: target/s390x/kvm/
|
||||
F: target/s390x/ioinst.[ch]
|
||||
@ -1527,7 +1527,7 @@ S390 Machines
|
||||
-------------
|
||||
S390 Virtio-ccw
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
S: Supported
|
||||
F: hw/char/sclp*.[hc]
|
||||
F: hw/char/terminal3270.c
|
||||
@ -1541,7 +1541,7 @@ T: git https://github.com/borntraeger/qemu.git s390-next
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
S390-ccw boot
|
||||
M: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
M: Thomas Huth <thuth@redhat.com>
|
||||
S: Supported
|
||||
F: hw/s390x/ipl.*
|
||||
@ -1628,7 +1628,7 @@ F: include/hw/i386/microvm.h
|
||||
F: pc-bios/bios-microvm.bin
|
||||
|
||||
Machine core
|
||||
M: Eduardo Habkost <ehabkost@redhat.com>
|
||||
M: Eduardo Habkost <eduardo@habkost.net>
|
||||
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
|
||||
R: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
S: Supported
|
||||
@ -1825,6 +1825,7 @@ 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
|
||||
@ -2648,13 +2649,13 @@ F: backends/cryptodev*.c
|
||||
Python library
|
||||
M: John Snow <jsnow@redhat.com>
|
||||
M: Cleber Rosa <crosa@redhat.com>
|
||||
R: Eduardo Habkost <ehabkost@redhat.com>
|
||||
R: Eduardo Habkost <eduardo@habkost.net>
|
||||
S: Maintained
|
||||
F: python/
|
||||
T: git https://gitlab.com/jsnow/qemu.git python
|
||||
|
||||
Python scripts
|
||||
M: Eduardo Habkost <ehabkost@redhat.com>
|
||||
M: Eduardo Habkost <eduardo@habkost.net>
|
||||
M: Cleber Rosa <crosa@redhat.com>
|
||||
S: Odd Fixes
|
||||
F: scripts/*.py
|
||||
@ -2730,7 +2731,7 @@ T: git https://github.com/mdroth/qemu.git qga
|
||||
QOM
|
||||
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
R: Daniel P. Berrange <berrange@redhat.com>
|
||||
R: Eduardo Habkost <ehabkost@redhat.com>
|
||||
R: Eduardo Habkost <eduardo@habkost.net>
|
||||
S: Supported
|
||||
F: docs/qdev-device-use.txt
|
||||
F: hw/core/qdev*
|
||||
@ -2750,7 +2751,7 @@ F: tests/unit/check-qom-proplist.c
|
||||
F: tests/unit/test-qdev-global-props.c
|
||||
|
||||
QOM boilerplate conversion script
|
||||
M: Eduardo Habkost <ehabkost@redhat.com>
|
||||
M: Eduardo Habkost <eduardo@habkost.net>
|
||||
S: Maintained
|
||||
F: scripts/codeconverter/
|
||||
|
||||
@ -3076,8 +3077,9 @@ 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>
|
||||
@ -3469,7 +3471,7 @@ M: Alex Bennée <alex.bennee@linaro.org>
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
M: Thomas Huth <thuth@redhat.com>
|
||||
R: Wainer dos Santos Moschetta <wainersm@redhat.com>
|
||||
R: Willian Rampazzo <willianr@redhat.com>
|
||||
R: Beraldo Leal <bleal@redhat.com>
|
||||
S: Maintained
|
||||
F: .github/lockdown.yml
|
||||
F: .gitlab-ci.yml
|
||||
@ -3507,10 +3509,16 @@ W: https://trello.com/b/6Qi1pxVn/avocado-qemu
|
||||
R: Cleber Rosa <crosa@redhat.com>
|
||||
R: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
R: Wainer dos Santos Moschetta <wainersm@redhat.com>
|
||||
R: Willian Rampazzo <willianr@redhat.com>
|
||||
R: Beraldo Leal <bleal@redhat.com>
|
||||
S: Odd Fixes
|
||||
F: tests/avocado/
|
||||
|
||||
GitLab custom runner (Works On Arm Sponsored)
|
||||
M: Alex Bennée <alex.bennee@linaro.org>
|
||||
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
S: Maintained
|
||||
F: .gitlab-ci.d/custom-runners/ubuntu-20.04-aarch64.yml
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
Build system architecture
|
||||
|
@ -61,6 +61,10 @@
|
||||
#endif
|
||||
#define PAGE_SIZE qemu_real_host_page_size
|
||||
|
||||
#ifndef KVM_GUESTDBG_BLOCKIRQ
|
||||
#define KVM_GUESTDBG_BLOCKIRQ 0
|
||||
#endif
|
||||
|
||||
//#define DEBUG_KVM
|
||||
|
||||
#ifdef DEBUG_KVM
|
||||
@ -168,6 +172,8 @@ 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;
|
||||
|
||||
@ -2564,6 +2570,25 @@ 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);
|
||||
@ -3193,6 +3218,10 @@ 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);
|
||||
|
||||
|
@ -733,6 +733,15 @@ static inline bool need_replay_interrupt(int interrupt_request)
|
||||
static inline bool cpu_handle_interrupt(CPUState *cpu,
|
||||
TranslationBlock **last_tb)
|
||||
{
|
||||
/*
|
||||
* If we have requested custom cflags with CF_NOIRQ we should
|
||||
* skip checking here. Any pending interrupts will get picked up
|
||||
* by the next TB we execute under normal cflags.
|
||||
*/
|
||||
if (cpu->cflags_next_tb != -1 && cpu->cflags_next_tb & CF_NOIRQ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Clear the interrupt flag now since we're processing
|
||||
* cpu->interrupt_request and cpu->exit_request.
|
||||
* Ensure zeroing happens before reading cpu->exit_request or
|
||||
|
@ -2243,7 +2243,7 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
|
||||
if (current_tb_modified) {
|
||||
page_collection_unlock(pages);
|
||||
/* Force execution of one insn next time. */
|
||||
cpu->cflags_next_tb = 1 | curr_cflags(cpu);
|
||||
cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu);
|
||||
mmap_unlock();
|
||||
cpu_loop_exit_noexc(cpu);
|
||||
}
|
||||
@ -2411,7 +2411,7 @@ static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc)
|
||||
#ifdef TARGET_HAS_PRECISE_SMC
|
||||
if (current_tb_modified) {
|
||||
/* Force execution of one insn next time. */
|
||||
cpu->cflags_next_tb = 1 | curr_cflags(cpu);
|
||||
cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -206,8 +206,9 @@ static void nvme_free_req_queue_cb(void *opaque)
|
||||
NVMeQueuePair *q = opaque;
|
||||
|
||||
qemu_mutex_lock(&q->lock);
|
||||
while (qemu_co_enter_next(&q->free_req_queue, &q->lock)) {
|
||||
/* Retry all pending requests */
|
||||
while (q->free_req_head != -1 &&
|
||||
qemu_co_enter_next(&q->free_req_queue, &q->lock)) {
|
||||
/* Retry waiting requests */
|
||||
}
|
||||
qemu_mutex_unlock(&q->lock);
|
||||
}
|
||||
|
@ -1279,8 +1279,18 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
|
||||
qemu_co_mutex_init(&s->lock);
|
||||
|
||||
ret = 0;
|
||||
qemu_opts_del(opts);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
g_free(s->qcow_filename);
|
||||
s->qcow_filename = NULL;
|
||||
g_free(s->cluster_buffer);
|
||||
s->cluster_buffer = NULL;
|
||||
g_free(s->used_clusters);
|
||||
s->used_clusters = NULL;
|
||||
|
||||
qemu_opts_del(opts);
|
||||
return ret;
|
||||
}
|
||||
@ -3118,7 +3128,7 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
|
||||
int size = sector2cluster(s, s->sector_count);
|
||||
QDict *options;
|
||||
|
||||
s->used_clusters = calloc(size, 1);
|
||||
s->used_clusters = g_malloc0(size);
|
||||
|
||||
array_init(&(s->commits), sizeof(commit_t));
|
||||
|
||||
@ -3166,8 +3176,6 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
g_free(s->qcow_filename);
|
||||
s->qcow_filename = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
10
blockdev.c
10
blockdev.c
@ -303,16 +303,6 @@ int drive_get_max_bus(BlockInterfaceType type)
|
||||
return max_bus;
|
||||
}
|
||||
|
||||
/* Get a block device. This should only be used for single-drive devices
|
||||
(e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
|
||||
appropriate bus. */
|
||||
DriveInfo *drive_get_next(BlockInterfaceType type)
|
||||
{
|
||||
static int next_block_unit[IF_COUNT];
|
||||
|
||||
return drive_get(type, 0, next_block_unit[type]++);
|
||||
}
|
||||
|
||||
static void bdrv_format_print(void *opaque, const char *name)
|
||||
{
|
||||
qemu_printf(" %s", name);
|
||||
|
@ -151,6 +151,10 @@
|
||||
/* Internal errors: */
|
||||
#define TARGET_EJUSTRETURN 254 /* Just return without modifing regs */
|
||||
#define TARGET_ERESTART 255 /* Restart syscall */
|
||||
#define TARGET_ERESTARTSYS TARGET_ERESTART /* Linux compat */
|
||||
|
||||
#include "special-errno.h"
|
||||
|
||||
_Static_assert(TARGET_ERESTART == QEMU_ERESTARTSYS,
|
||||
"TARGET_ERESTART and QEMU_ERESTARTSYS expected to match");
|
||||
|
||||
#endif /* ! _ERRNO_DEFS_H_ */
|
||||
|
@ -2,6 +2,10 @@ if not have_bsd_user
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
bsd_user_ss = ss.source_set()
|
||||
|
||||
common_user_inc += include_directories('.')
|
||||
|
||||
bsd_user_ss.add(files(
|
||||
'bsdload.c',
|
||||
'elfload.c',
|
||||
@ -15,3 +19,5 @@ bsd_user_ss.add(files(
|
||||
|
||||
# Pull in the OS-specific build glue, if any
|
||||
subdir(targetos)
|
||||
|
||||
specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
|
||||
|
24
bsd-user/special-errno.h
Normal file
24
bsd-user/special-errno.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* QEMU internal errno values for implementing user-only POSIX.
|
||||
*
|
||||
* Copyright (c) 2021 Linaro, Ltd.
|
||||
*/
|
||||
|
||||
#ifndef SPECIAL_ERRNO_H
|
||||
#define SPECIAL_ERRNO_H
|
||||
|
||||
/*
|
||||
* All of these are QEMU internal, not visible to the guest.
|
||||
* They should be chosen so as to not overlap with any host
|
||||
* or guest errno.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is returned when a system call should be restarted, to tell the
|
||||
* main loop that it should wind the guest PC backwards so it will
|
||||
* re-execute the syscall after handling any pending signals.
|
||||
*/
|
||||
#define QEMU_ERESTARTSYS 255
|
||||
|
||||
#endif /* SPECIAL_ERRNO_H */
|
@ -320,7 +320,6 @@ static void wctablet_chr_finalize(Object *obj)
|
||||
TabletChardev *tablet = WCTABLET_CHARDEV(obj);
|
||||
|
||||
qemu_input_handler_unregister(tablet->hs);
|
||||
g_free(tablet);
|
||||
}
|
||||
|
||||
static void wctablet_chr_open(Chardev *chr,
|
||||
|
88
common-user/host/aarch64/safe-syscall.inc.S
Normal file
88
common-user/host/aarch64/safe-syscall.inc.S
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* safe-syscall.inc.S : host-specific assembly fragment
|
||||
* to handle signals occurring at the same time as system calls.
|
||||
* This is intended to be included by common-user/safe-syscall.S
|
||||
*
|
||||
* Written by Richard Henderson <rth@twiddle.net>
|
||||
* Copyright (C) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
.global safe_syscall_base
|
||||
.global safe_syscall_start
|
||||
.global safe_syscall_end
|
||||
.type safe_syscall_base, #function
|
||||
.type safe_syscall_start, #function
|
||||
.type safe_syscall_end, #function
|
||||
|
||||
/* This is the entry point for making a system call. The calling
|
||||
* convention here is that of a C varargs function with the
|
||||
* first argument an 'int *' to the signal_pending flag, the
|
||||
* second one the system call number (as a 'long'), and all further
|
||||
* arguments being syscall arguments (also 'long').
|
||||
*/
|
||||
safe_syscall_base:
|
||||
.cfi_startproc
|
||||
/* The syscall calling convention isn't the same as the
|
||||
* C one:
|
||||
* we enter with x0 == &signal_pending
|
||||
* x1 == syscall number
|
||||
* x2 ... x7, (stack) == syscall arguments
|
||||
* and return the result in x0
|
||||
* and the syscall instruction needs
|
||||
* x8 == syscall number
|
||||
* x0 ... x6 == syscall arguments
|
||||
* and returns the result in x0
|
||||
* Shuffle everything around appropriately.
|
||||
*/
|
||||
mov x9, x0 /* signal_pending pointer */
|
||||
mov x8, x1 /* syscall number */
|
||||
mov x0, x2 /* syscall arguments */
|
||||
mov x1, x3
|
||||
mov x2, x4
|
||||
mov x3, x5
|
||||
mov x4, x6
|
||||
mov x5, x7
|
||||
ldr x6, [sp]
|
||||
|
||||
/* This next sequence of code works in conjunction with the
|
||||
* rewind_if_safe_syscall_function(). If a signal is taken
|
||||
* and the interrupted PC is anywhere between 'safe_syscall_start'
|
||||
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
|
||||
* The code sequence must therefore be able to cope with this, and
|
||||
* the syscall instruction must be the final one in the sequence.
|
||||
*/
|
||||
safe_syscall_start:
|
||||
/* if signal_pending is non-zero, don't do the call */
|
||||
ldr w10, [x9]
|
||||
cbnz w10, 2f
|
||||
svc 0x0
|
||||
safe_syscall_end:
|
||||
|
||||
/* code path for having successfully executed the syscall */
|
||||
#if defined(__linux__)
|
||||
/* Linux kernel returns (small) negative errno. */
|
||||
cmp x0, #-4096
|
||||
b.hi 0f
|
||||
#elif defined(__FreeBSD__)
|
||||
/* FreeBSD kernel returns positive errno and C bit set. */
|
||||
b.cs 1f
|
||||
#else
|
||||
#error "unsupported os"
|
||||
#endif
|
||||
ret
|
||||
|
||||
#if defined(__linux__)
|
||||
/* code path setting errno */
|
||||
0: neg w0, w0
|
||||
b safe_syscall_set_errno_tail
|
||||
#endif
|
||||
|
||||
/* code path when we didn't execute the syscall */
|
||||
2: mov w0, #QEMU_ERESTARTSYS
|
||||
1: b safe_syscall_set_errno_tail
|
||||
|
||||
.cfi_endproc
|
||||
.size safe_syscall_base, .-safe_syscall_base
|
108
common-user/host/arm/safe-syscall.inc.S
Normal file
108
common-user/host/arm/safe-syscall.inc.S
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* safe-syscall.inc.S : host-specific assembly fragment
|
||||
* to handle signals occurring at the same time as system calls.
|
||||
* This is intended to be included by common-user/safe-syscall.S
|
||||
*
|
||||
* Written by Richard Henderson <rth@twiddle.net>
|
||||
* Copyright (C) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
.global safe_syscall_base
|
||||
.global safe_syscall_start
|
||||
.global safe_syscall_end
|
||||
.type safe_syscall_base, %function
|
||||
|
||||
.cfi_sections .debug_frame
|
||||
|
||||
.text
|
||||
.syntax unified
|
||||
.arm
|
||||
.align 2
|
||||
|
||||
/* This is the entry point for making a system call. The calling
|
||||
* convention here is that of a C varargs function with the
|
||||
* first argument an 'int *' to the signal_pending flag, the
|
||||
* second one the system call number (as a 'long'), and all further
|
||||
* arguments being syscall arguments (also 'long').
|
||||
*/
|
||||
safe_syscall_base:
|
||||
.fnstart
|
||||
.cfi_startproc
|
||||
mov r12, sp /* save entry stack */
|
||||
push { r4, r5, r6, r7, r8, lr }
|
||||
.save { r4, r5, r6, r7, r8, lr }
|
||||
.cfi_adjust_cfa_offset 24
|
||||
.cfi_rel_offset r4, 0
|
||||
.cfi_rel_offset r5, 4
|
||||
.cfi_rel_offset r6, 8
|
||||
.cfi_rel_offset r7, 12
|
||||
.cfi_rel_offset r8, 16
|
||||
.cfi_rel_offset lr, 20
|
||||
|
||||
/* The syscall calling convention isn't the same as the C one:
|
||||
* we enter with r0 == &signal_pending
|
||||
* r1 == syscall number
|
||||
* r2, r3, [sp+0] ... [sp+12] == syscall arguments
|
||||
* and return the result in r0
|
||||
* and the syscall instruction needs
|
||||
* r7 == syscall number
|
||||
* r0 ... r6 == syscall arguments
|
||||
* and returns the result in r0
|
||||
* Shuffle everything around appropriately.
|
||||
* Note the 16 bytes that we pushed to save registers.
|
||||
*/
|
||||
mov r8, r0 /* copy signal_pending */
|
||||
mov r7, r1 /* syscall number */
|
||||
mov r0, r2 /* syscall args */
|
||||
mov r1, r3
|
||||
ldm r12, { r2, r3, r4, r5, r6 }
|
||||
|
||||
/* This next sequence of code works in conjunction with the
|
||||
* rewind_if_safe_syscall_function(). If a signal is taken
|
||||
* and the interrupted PC is anywhere between 'safe_syscall_start'
|
||||
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
|
||||
* The code sequence must therefore be able to cope with this, and
|
||||
* the syscall instruction must be the final one in the sequence.
|
||||
*/
|
||||
safe_syscall_start:
|
||||
/* if signal_pending is non-zero, don't do the call */
|
||||
ldr r12, [r8] /* signal_pending */
|
||||
tst r12, r12
|
||||
bne 2f
|
||||
swi 0
|
||||
safe_syscall_end:
|
||||
|
||||
/* code path for having successfully executed the syscall */
|
||||
#if defined(__linux__)
|
||||
/* Linux kernel returns (small) negative errno. */
|
||||
cmp r0, #-4096
|
||||
neghi r0, r0
|
||||
bhi 1f
|
||||
#elif defined(__FreeBSD__)
|
||||
/* FreeBSD kernel returns positive errno and C bit set. */
|
||||
bcs 1f
|
||||
#else
|
||||
#error "unsupported os"
|
||||
#endif
|
||||
pop { r4, r5, r6, r7, r8, pc }
|
||||
|
||||
/* code path when we didn't execute the syscall */
|
||||
2: mov r0, #QEMU_ERESTARTSYS
|
||||
|
||||
/* code path setting errno */
|
||||
1: pop { r4, r5, r6, r7, r8, lr }
|
||||
.cfi_adjust_cfa_offset -24
|
||||
.cfi_restore r4
|
||||
.cfi_restore r5
|
||||
.cfi_restore r6
|
||||
.cfi_restore r7
|
||||
.cfi_restore r8
|
||||
.cfi_restore lr
|
||||
b safe_syscall_set_errno_tail
|
||||
|
||||
.fnend
|
||||
.cfi_endproc
|
||||
.size safe_syscall_base, .-safe_syscall_base
|
126
common-user/host/i386/safe-syscall.inc.S
Normal file
126
common-user/host/i386/safe-syscall.inc.S
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* safe-syscall.inc.S : host-specific assembly fragment
|
||||
* to handle signals occurring at the same time as system calls.
|
||||
* This is intended to be included by common-user/safe-syscall.S
|
||||
*
|
||||
* Written by Richard Henderson <rth@twiddle.net>
|
||||
* Copyright (C) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
.global safe_syscall_base
|
||||
.global safe_syscall_start
|
||||
.global safe_syscall_end
|
||||
.type safe_syscall_base, @function
|
||||
|
||||
/* This is the entry point for making a system call. The calling
|
||||
* convention here is that of a C varargs function with the
|
||||
* first argument an 'int *' to the signal_pending flag, the
|
||||
* second one the system call number (as a 'long'), and all further
|
||||
* arguments being syscall arguments (also 'long').
|
||||
*/
|
||||
safe_syscall_base:
|
||||
.cfi_startproc
|
||||
push %ebp
|
||||
.cfi_adjust_cfa_offset 4
|
||||
.cfi_rel_offset ebp, 0
|
||||
push %esi
|
||||
.cfi_adjust_cfa_offset 4
|
||||
.cfi_rel_offset esi, 0
|
||||
push %edi
|
||||
.cfi_adjust_cfa_offset 4
|
||||
.cfi_rel_offset edi, 0
|
||||
push %ebx
|
||||
.cfi_adjust_cfa_offset 4
|
||||
.cfi_rel_offset ebx, 0
|
||||
|
||||
/* The syscall calling convention isn't the same as the C one:
|
||||
* we enter with 0(%esp) == return address
|
||||
* 4(%esp) == &signal_pending
|
||||
* 8(%esp) == syscall number
|
||||
* 12(%esp) ... 32(%esp) == syscall arguments
|
||||
* and return the result in eax
|
||||
* and the syscall instruction needs
|
||||
* eax == syscall number
|
||||
* ebx, ecx, edx, esi, edi, ebp == syscall arguments
|
||||
* and returns the result in eax
|
||||
* Shuffle everything around appropriately.
|
||||
* Note the 16 bytes that we pushed to save registers.
|
||||
*/
|
||||
mov 12+16(%esp), %ebx /* the syscall arguments */
|
||||
mov 16+16(%esp), %ecx
|
||||
mov 20+16(%esp), %edx
|
||||
mov 24+16(%esp), %esi
|
||||
mov 28+16(%esp), %edi
|
||||
mov 32+16(%esp), %ebp
|
||||
|
||||
/* This next sequence of code works in conjunction with the
|
||||
* rewind_if_safe_syscall_function(). If a signal is taken
|
||||
* and the interrupted PC is anywhere between 'safe_syscall_start'
|
||||
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
|
||||
* The code sequence must therefore be able to cope with this, and
|
||||
* the syscall instruction must be the final one in the sequence.
|
||||
*/
|
||||
safe_syscall_start:
|
||||
/* if signal_pending is non-zero, don't do the call */
|
||||
mov 4+16(%esp), %eax /* signal_pending */
|
||||
cmpl $0, (%eax)
|
||||
jnz 2f
|
||||
mov 8+16(%esp), %eax /* syscall number */
|
||||
int $0x80
|
||||
safe_syscall_end:
|
||||
|
||||
/* code path for having successfully executed the syscall */
|
||||
#if defined(__linux__)
|
||||
/* Linux kernel returns (small) negative errno. */
|
||||
cmp $-4095, %eax
|
||||
jae 0f
|
||||
#elif defined(__FreeBSD__)
|
||||
/* FreeBSD kernel returns positive errno and C bit set. */
|
||||
jc 1f
|
||||
#else
|
||||
#error "unsupported os"
|
||||
#endif
|
||||
pop %ebx
|
||||
.cfi_remember_state
|
||||
.cfi_adjust_cfa_offset -4
|
||||
.cfi_restore ebx
|
||||
pop %edi
|
||||
.cfi_adjust_cfa_offset -4
|
||||
.cfi_restore edi
|
||||
pop %esi
|
||||
.cfi_adjust_cfa_offset -4
|
||||
.cfi_restore esi
|
||||
pop %ebp
|
||||
.cfi_adjust_cfa_offset -4
|
||||
.cfi_restore ebp
|
||||
ret
|
||||
.cfi_restore_state
|
||||
|
||||
#if defined(__linux__)
|
||||
0: neg %eax
|
||||
jmp 1f
|
||||
#endif
|
||||
|
||||
/* code path when we didn't execute the syscall */
|
||||
2: mov $QEMU_ERESTARTSYS, %eax
|
||||
|
||||
/* code path setting errno */
|
||||
1: pop %ebx
|
||||
.cfi_adjust_cfa_offset -4
|
||||
.cfi_restore ebx
|
||||
pop %edi
|
||||
.cfi_adjust_cfa_offset -4
|
||||
.cfi_restore edi
|
||||
pop %esi
|
||||
.cfi_adjust_cfa_offset -4
|
||||
.cfi_restore esi
|
||||
pop %ebp
|
||||
.cfi_adjust_cfa_offset -4
|
||||
.cfi_restore ebp
|
||||
jmp safe_syscall_set_errno_tail
|
||||
|
||||
.cfi_endproc
|
||||
.size safe_syscall_base, .-safe_syscall_base
|
148
common-user/host/mips/safe-syscall.inc.S
Normal file
148
common-user/host/mips/safe-syscall.inc.S
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* safe-syscall.inc.S : host-specific assembly fragment
|
||||
* to handle signals occurring at the same time as system calls.
|
||||
* This is intended to be included by common-user/safe-syscall.S
|
||||
*
|
||||
* Written by Richard Henderson <richard.henderson@linaro.org>
|
||||
* Copyright (C) 2021 Linaro, Inc.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "sys/regdef.h"
|
||||
#include "sys/asm.h"
|
||||
|
||||
.text
|
||||
.set nomips16
|
||||
.set reorder
|
||||
|
||||
.global safe_syscall_start
|
||||
.global safe_syscall_end
|
||||
.type safe_syscall_start, @function
|
||||
.type safe_syscall_end, @function
|
||||
|
||||
/*
|
||||
* This is the entry point for making a system call. The calling
|
||||
* convention here is that of a C varargs function with the
|
||||
* first argument an 'int *' to the signal_pending flag, the
|
||||
* second one the system call number (as a 'long'), and all further
|
||||
* arguments being syscall arguments (also 'long').
|
||||
*/
|
||||
|
||||
#if _MIPS_SIM == _ABIO32
|
||||
/* 8 * 4 = 32 for outgoing parameters; 1 * 4 for s0 save; 1 * 4 for align. */
|
||||
#define FRAME 40
|
||||
#define OFS_S0 32
|
||||
#else
|
||||
/* 1 * 8 for s0 save; 1 * 8 for align. */
|
||||
#define FRAME 16
|
||||
#define OFS_S0 0
|
||||
#endif
|
||||
|
||||
|
||||
NESTED(safe_syscall_base, FRAME, ra)
|
||||
.cfi_startproc
|
||||
PTR_ADDIU sp, sp, -FRAME
|
||||
.cfi_adjust_cfa_offset FRAME
|
||||
REG_S s0, OFS_S0(sp)
|
||||
.cfi_rel_offset s0, OFS_S0
|
||||
#if _MIPS_SIM == _ABIO32
|
||||
/*
|
||||
* The syscall calling convention is nearly the same as C:
|
||||
* we enter with a0 == &signal_pending
|
||||
* a1 == syscall number
|
||||
* a2, a3, stack == syscall arguments
|
||||
* and return the result in a0
|
||||
* and the syscall instruction needs
|
||||
* v0 == syscall number
|
||||
* a0 ... a3, stack == syscall arguments
|
||||
* and returns the result in v0
|
||||
* Shuffle everything around appropriately.
|
||||
*/
|
||||
move s0, a0 /* signal_pending pointer */
|
||||
move v0, a1 /* syscall number */
|
||||
move a0, a2 /* syscall arguments */
|
||||
move a1, a3
|
||||
lw a2, FRAME+16(sp)
|
||||
lw a3, FRAME+20(sp)
|
||||
lw t4, FRAME+24(sp)
|
||||
lw t5, FRAME+28(sp)
|
||||
lw t6, FRAME+32(sp)
|
||||
lw t7, FRAME+40(sp)
|
||||
sw t4, 16(sp)
|
||||
sw t5, 20(sp)
|
||||
sw t6, 24(sp)
|
||||
sw t7, 28(sp)
|
||||
#else
|
||||
/*
|
||||
* The syscall calling convention is nearly the same as C:
|
||||
* we enter with a0 == &signal_pending
|
||||
* a1 == syscall number
|
||||
* a2 ... a7 == syscall arguments
|
||||
* and return the result in a0
|
||||
* and the syscall instruction needs
|
||||
* v0 == syscall number
|
||||
* a0 ... a5 == syscall arguments
|
||||
* and returns the result in v0
|
||||
* Shuffle everything around appropriately.
|
||||
*/
|
||||
move s0, a0 /* signal_pending pointer */
|
||||
move v0, a1 /* syscall number */
|
||||
move a0, a2 /* syscall arguments */
|
||||
move a1, a3
|
||||
move a2, a4
|
||||
move a3, a5
|
||||
move a4, a6
|
||||
move a5, a7
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This next sequence of code works in conjunction with the
|
||||
* rewind_if_safe_syscall_function(). If a signal is taken
|
||||
* and the interrupted PC is anywhere between 'safe_syscall_start'
|
||||
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
|
||||
* The code sequence must therefore be able to cope with this, and
|
||||
* the syscall instruction must be the final one in the sequence.
|
||||
*/
|
||||
safe_syscall_start:
|
||||
/* If signal_pending is non-zero, don't do the call */
|
||||
lw t1, 0(s0)
|
||||
bnez t1, 2f
|
||||
syscall
|
||||
safe_syscall_end:
|
||||
|
||||
/* code path for having successfully executed the syscall */
|
||||
REG_L s0, OFS_S0(sp)
|
||||
PTR_ADDIU sp, sp, FRAME
|
||||
.cfi_remember_state
|
||||
.cfi_adjust_cfa_offset -FRAME
|
||||
.cfi_restore s0
|
||||
bnez a3, 1f
|
||||
jr ra
|
||||
.cfi_restore_state
|
||||
|
||||
/* code path when we didn't execute the syscall */
|
||||
2: REG_L s0, OFS_S0(sp)
|
||||
PTR_ADDIU sp, sp, FRAME
|
||||
.cfi_adjust_cfa_offset -FRAME
|
||||
.cfi_restore s0
|
||||
li v0, QEMU_ERESTARTSYS
|
||||
|
||||
/* code path setting errno */
|
||||
/*
|
||||
* We didn't setup GP on entry, optimistic of the syscall success.
|
||||
* We must do so now to load the address of the helper, as required
|
||||
* by the ABI, into t9.
|
||||
*
|
||||
* Note that SETUP_GPX and SETUP_GPX64 are themselves conditional,
|
||||
* so we can simply let the one that's not empty succeed.
|
||||
*/
|
||||
1: USE_ALT_CP(t0)
|
||||
SETUP_GPX(t1)
|
||||
SETUP_GPX64(t0, t1)
|
||||
PTR_LA t9, safe_syscall_set_errno_tail
|
||||
jr t9
|
||||
|
||||
.cfi_endproc
|
||||
END(safe_syscall_base)
|
94
common-user/host/ppc64/safe-syscall.inc.S
Normal file
94
common-user/host/ppc64/safe-syscall.inc.S
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* safe-syscall.inc.S : host-specific assembly fragment
|
||||
* to handle signals occurring at the same time as system calls.
|
||||
* This is intended to be included by common-user/safe-syscall.S
|
||||
*
|
||||
* Written by Richard Henderson <rth@twiddle.net>
|
||||
* Copyright (C) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
.global safe_syscall_base
|
||||
.global safe_syscall_start
|
||||
.global safe_syscall_end
|
||||
.type safe_syscall_base, @function
|
||||
|
||||
.text
|
||||
|
||||
/* This is the entry point for making a system call. The calling
|
||||
* convention here is that of a C varargs function with the
|
||||
* first argument an 'int *' to the signal_pending flag, the
|
||||
* second one the system call number (as a 'long'), and all further
|
||||
* arguments being syscall arguments (also 'long').
|
||||
*/
|
||||
#if _CALL_ELF == 2
|
||||
safe_syscall_base:
|
||||
.cfi_startproc
|
||||
.localentry safe_syscall_base,0
|
||||
#else
|
||||
.section ".opd","aw"
|
||||
.align 3
|
||||
safe_syscall_base:
|
||||
.quad .L.safe_syscall_base,.TOC.@tocbase,0
|
||||
.previous
|
||||
.L.safe_syscall_base:
|
||||
.cfi_startproc
|
||||
#endif
|
||||
/* We enter with r3 == &signal_pending
|
||||
* r4 == syscall number
|
||||
* r5 ... r10 == syscall arguments
|
||||
* and return the result in r3
|
||||
* and the syscall instruction needs
|
||||
* r0 == syscall number
|
||||
* r3 ... r8 == syscall arguments
|
||||
* and returns the result in r3
|
||||
* Shuffle everything around appropriately.
|
||||
*/
|
||||
std 14, 16(1) /* Preserve r14 in SP+16 */
|
||||
.cfi_offset 14, 16
|
||||
mr 14, 3 /* signal_pending */
|
||||
mr 0, 4 /* syscall number */
|
||||
mr 3, 5 /* syscall arguments */
|
||||
mr 4, 6
|
||||
mr 5, 7
|
||||
mr 6, 8
|
||||
mr 7, 9
|
||||
mr 8, 10
|
||||
|
||||
/* This next sequence of code works in conjunction with the
|
||||
* rewind_if_safe_syscall_function(). If a signal is taken
|
||||
* and the interrupted PC is anywhere between 'safe_syscall_start'
|
||||
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
|
||||
* The code sequence must therefore be able to cope with this, and
|
||||
* the syscall instruction must be the final one in the sequence.
|
||||
*/
|
||||
safe_syscall_start:
|
||||
/* if signal_pending is non-zero, don't do the call */
|
||||
lwz 12, 0(14)
|
||||
cmpwi 0, 12, 0
|
||||
bne- 2f
|
||||
sc
|
||||
safe_syscall_end:
|
||||
/* code path when we did execute the syscall */
|
||||
ld 14, 16(1) /* restore r14 */
|
||||
bso- 1f
|
||||
blr
|
||||
|
||||
/* code path when we didn't execute the syscall */
|
||||
2: ld 14, 16(1) /* restore r14 */
|
||||
addi 3, 0, QEMU_ERESTARTSYS
|
||||
|
||||
/* code path setting errno */
|
||||
1: b safe_syscall_set_errno_tail
|
||||
nop /* per abi, for the linker to modify */
|
||||
|
||||
.cfi_endproc
|
||||
|
||||
#if _CALL_ELF == 2
|
||||
.size safe_syscall_base, .-safe_syscall_base
|
||||
#else
|
||||
.size safe_syscall_base, .-.L.safe_syscall_base
|
||||
.size .L.safe_syscall_base, .-.L.safe_syscall_base
|
||||
#endif
|
79
common-user/host/riscv/safe-syscall.inc.S
Normal file
79
common-user/host/riscv/safe-syscall.inc.S
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* safe-syscall.inc.S : host-specific assembly fragment
|
||||
* to handle signals occurring at the same time as system calls.
|
||||
* This is intended to be included by common-user/safe-syscall.S
|
||||
*
|
||||
* Written by Richard Henderson <rth@twiddle.net>
|
||||
* Copyright (C) 2018 Linaro, Inc.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
.global safe_syscall_base
|
||||
.global safe_syscall_start
|
||||
.global safe_syscall_end
|
||||
.type safe_syscall_base, @function
|
||||
.type safe_syscall_start, @function
|
||||
.type safe_syscall_end, @function
|
||||
|
||||
/*
|
||||
* This is the entry point for making a system call. The calling
|
||||
* convention here is that of a C varargs function with the
|
||||
* first argument an 'int *' to the signal_pending flag, the
|
||||
* second one the system call number (as a 'long'), and all further
|
||||
* arguments being syscall arguments (also 'long').
|
||||
*/
|
||||
safe_syscall_base:
|
||||
.cfi_startproc
|
||||
/*
|
||||
* The syscall calling convention is nearly the same as C:
|
||||
* we enter with a0 == &signal_pending
|
||||
* a1 == syscall number
|
||||
* a2 ... a7 == syscall arguments
|
||||
* and return the result in a0
|
||||
* and the syscall instruction needs
|
||||
* a7 == syscall number
|
||||
* a0 ... a5 == syscall arguments
|
||||
* and returns the result in a0
|
||||
* Shuffle everything around appropriately.
|
||||
*/
|
||||
mv t0, a0 /* signal_pending pointer */
|
||||
mv t1, a1 /* syscall number */
|
||||
mv a0, a2 /* syscall arguments */
|
||||
mv a1, a3
|
||||
mv a2, a4
|
||||
mv a3, a5
|
||||
mv a4, a6
|
||||
mv a5, a7
|
||||
mv a7, t1
|
||||
|
||||
/*
|
||||
* This next sequence of code works in conjunction with the
|
||||
* rewind_if_safe_syscall_function(). If a signal is taken
|
||||
* and the interrupted PC is anywhere between 'safe_syscall_start'
|
||||
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
|
||||
* The code sequence must therefore be able to cope with this, and
|
||||
* the syscall instruction must be the final one in the sequence.
|
||||
*/
|
||||
safe_syscall_start:
|
||||
/* If signal_pending is non-zero, don't do the call */
|
||||
lw t1, 0(t0)
|
||||
bnez t1, 2f
|
||||
scall
|
||||
safe_syscall_end:
|
||||
/* code path for having successfully executed the syscall */
|
||||
li t2, -4096
|
||||
bgtu a0, t2, 0f
|
||||
ret
|
||||
|
||||
/* code path setting errno */
|
||||
0: neg a0, a0
|
||||
j safe_syscall_set_errno_tail
|
||||
|
||||
/* code path when we didn't execute the syscall */
|
||||
2: li a0, QEMU_ERESTARTSYS
|
||||
j safe_syscall_set_errno_tail
|
||||
|
||||
.cfi_endproc
|
||||
.size safe_syscall_base, .-safe_syscall_base
|
98
common-user/host/s390x/safe-syscall.inc.S
Normal file
98
common-user/host/s390x/safe-syscall.inc.S
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* safe-syscall.inc.S : host-specific assembly fragment
|
||||
* to handle signals occurring at the same time as system calls.
|
||||
* This is intended to be included by common-user/safe-syscall.S
|
||||
*
|
||||
* Written by Richard Henderson <rth@twiddle.net>
|
||||
* Copyright (C) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
.global safe_syscall_base
|
||||
.global safe_syscall_start
|
||||
.global safe_syscall_end
|
||||
.type safe_syscall_base, @function
|
||||
|
||||
/* This is the entry point for making a system call. The calling
|
||||
* convention here is that of a C varargs function with the
|
||||
* first argument an 'int *' to the signal_pending flag, the
|
||||
* second one the system call number (as a 'long'), and all further
|
||||
* arguments being syscall arguments (also 'long').
|
||||
*/
|
||||
safe_syscall_base:
|
||||
.cfi_startproc
|
||||
stmg %r6,%r15,48(%r15) /* save all call-saved registers */
|
||||
.cfi_offset %r15,-40
|
||||
.cfi_offset %r14,-48
|
||||
.cfi_offset %r13,-56
|
||||
.cfi_offset %r12,-64
|
||||
.cfi_offset %r11,-72
|
||||
.cfi_offset %r10,-80
|
||||
.cfi_offset %r9,-88
|
||||
.cfi_offset %r8,-96
|
||||
.cfi_offset %r7,-104
|
||||
.cfi_offset %r6,-112
|
||||
lgr %r1,%r15
|
||||
lg %r0,8(%r15) /* load eos */
|
||||
aghi %r15,-160
|
||||
.cfi_adjust_cfa_offset 160
|
||||
stg %r1,0(%r15) /* store back chain */
|
||||
stg %r0,8(%r15) /* store eos */
|
||||
|
||||
/*
|
||||
* The syscall calling convention isn't the same as the C one:
|
||||
* we enter with r2 == &signal_pending
|
||||
* r3 == syscall number
|
||||
* r4, r5, r6, (stack) == syscall arguments
|
||||
* and return the result in r2
|
||||
* and the syscall instruction needs
|
||||
* r1 == syscall number
|
||||
* r2 ... r7 == syscall arguments
|
||||
* and returns the result in r2
|
||||
* Shuffle everything around appropriately.
|
||||
*/
|
||||
lgr %r8,%r2 /* signal_pending pointer */
|
||||
lgr %r1,%r3 /* syscall number */
|
||||
lgr %r2,%r4 /* syscall args */
|
||||
lgr %r3,%r5
|
||||
lgr %r4,%r6
|
||||
lmg %r5,%r7,320(%r15)
|
||||
|
||||
/* This next sequence of code works in conjunction with the
|
||||
* rewind_if_safe_syscall_function(). If a signal is taken
|
||||
* and the interrupted PC is anywhere between 'safe_syscall_start'
|
||||
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
|
||||
* The code sequence must therefore be able to cope with this, and
|
||||
* the syscall instruction must be the final one in the sequence.
|
||||
*/
|
||||
safe_syscall_start:
|
||||
/* if signal_pending is non-zero, don't do the call */
|
||||
icm %r0,15,0(%r8)
|
||||
jne 2f
|
||||
svc 0
|
||||
safe_syscall_end:
|
||||
|
||||
/* code path for having successfully executed the syscall */
|
||||
lg %r15,0(%r15) /* load back chain */
|
||||
.cfi_remember_state
|
||||
.cfi_adjust_cfa_offset -160
|
||||
lmg %r6,%r15,48(%r15) /* load saved registers */
|
||||
|
||||
lghi %r0, -4095 /* check for syscall error */
|
||||
clgr %r2, %r0
|
||||
blr %r14 /* return on success */
|
||||
lcr %r2, %r2 /* create positive errno */
|
||||
jg safe_syscall_set_errno_tail
|
||||
.cfi_restore_state
|
||||
|
||||
/* code path when we didn't execute the syscall */
|
||||
2: lg %r15,0(%r15) /* load back chain */
|
||||
.cfi_adjust_cfa_offset -160
|
||||
lmg %r6,%r15,48(%r15) /* load saved registers */
|
||||
lghi %r2, QEMU_ERESTARTSYS
|
||||
jg safe_syscall_set_errno_tail
|
||||
|
||||
.cfi_endproc
|
||||
.size safe_syscall_base, .-safe_syscall_base
|
89
common-user/host/sparc64/safe-syscall.inc.S
Normal file
89
common-user/host/sparc64/safe-syscall.inc.S
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* safe-syscall.inc.S : host-specific assembly fragment
|
||||
* to handle signals occurring at the same time as system calls.
|
||||
* This is intended to be included by common-user/safe-syscall.S
|
||||
*
|
||||
* Written by Richard Henderson <richard.henderson@linaro.org>
|
||||
* Copyright (C) 2021 Linaro, Inc.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
.text
|
||||
.balign 4
|
||||
|
||||
.register %g2, #scratch
|
||||
.register %g3, #scratch
|
||||
|
||||
.global safe_syscall_base
|
||||
.global safe_syscall_start
|
||||
.global safe_syscall_end
|
||||
.type safe_syscall_base, @function
|
||||
.type safe_syscall_start, @function
|
||||
.type safe_syscall_end, @function
|
||||
|
||||
#define STACK_BIAS 2047
|
||||
#define PARAM(N) STACK_BIAS + N*8
|
||||
|
||||
/*
|
||||
* This is the entry point for making a system call. The calling
|
||||
* convention here is that of a C varargs function with the
|
||||
* first argument an 'int *' to the signal_pending flag, the
|
||||
* second one the system call number (as a 'long'), and all further
|
||||
* arguments being syscall arguments (also 'long').
|
||||
*/
|
||||
safe_syscall_base:
|
||||
.cfi_startproc
|
||||
/*
|
||||
* The syscall calling convention isn't the same as the C one:
|
||||
* we enter with o0 == &signal_pending
|
||||
* o1 == syscall number
|
||||
* o2 ... o5, (stack) == syscall arguments
|
||||
* and return the result in x0
|
||||
* and the syscall instruction needs
|
||||
* g1 == syscall number
|
||||
* o0 ... o5 == syscall arguments
|
||||
* and returns the result in o0
|
||||
* Shuffle everything around appropriately.
|
||||
*/
|
||||
mov %o0, %g2 /* signal_pending pointer */
|
||||
mov %o1, %g1 /* syscall number */
|
||||
mov %o2, %o0 /* syscall arguments */
|
||||
mov %o3, %o1
|
||||
mov %o4, %o2
|
||||
mov %o5, %o3
|
||||
ldx [%sp + PARAM(6)], %o4
|
||||
ldx [%sp + PARAM(7)], %o5
|
||||
|
||||
/*
|
||||
* This next sequence of code works in conjunction with the
|
||||
* rewind_if_safe_syscall_function(). If a signal is taken
|
||||
* and the interrupted PC is anywhere between 'safe_syscall_start'
|
||||
* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
|
||||
* The code sequence must therefore be able to cope with this, and
|
||||
* the syscall instruction must be the final one in the sequence.
|
||||
*/
|
||||
safe_syscall_start:
|
||||
/* if signal_pending is non-zero, don't do the call */
|
||||
lduw [%g2], %g3
|
||||
brnz,pn %g3, 2f
|
||||
nop
|
||||
ta 0x6d
|
||||
safe_syscall_end:
|
||||
/* code path for having successfully executed the syscall */
|
||||
bcs,pn %xcc, 1f
|
||||
nop
|
||||
ret
|
||||
nop
|
||||
|
||||
/* code path when we didn't execute the syscall */
|
||||
2: set QEMU_ERESTARTSYS, %o0
|
||||
|
||||
/* code path setting errno */
|
||||
1: mov %o7, %g1
|
||||
call safe_syscall_set_errno_tail
|
||||
mov %g1, %o7
|
||||
|
||||
.cfi_endproc
|
||||
.size safe_syscall_base, .-safe_syscall_base
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* safe-syscall.inc.S : host-specific assembly fragment
|
||||
* to handle signals occurring at the same time as system calls.
|
||||
* This is intended to be included by linux-user/safe-syscall.S
|
||||
* This is intended to be included by common-user/safe-syscall.S
|
||||
*
|
||||
* Copyright (C) 2015 Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
|
||||
*
|
||||
@ -19,9 +19,6 @@
|
||||
* first argument an 'int *' to the signal_pending flag, the
|
||||
* second one the system call number (as a 'long'), and all further
|
||||
* arguments being syscall arguments (also 'long').
|
||||
* We return a long which is the syscall's return value, which
|
||||
* may be negative-errno on failure. Conversion to the
|
||||
* -1-and-errno-set convention is done by the calling wrapper.
|
||||
*/
|
||||
safe_syscall_base:
|
||||
.cfi_startproc
|
||||
@ -35,9 +32,9 @@ safe_syscall_base:
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.cfi_rel_offset rbp, 0
|
||||
|
||||
/* The syscall calling convention isn't the same as the
|
||||
* C one:
|
||||
* we enter with rdi == *signal_pending
|
||||
/*
|
||||
* The syscall calling convention isn't the same as the C one:
|
||||
* we enter with rdi == &signal_pending
|
||||
* rsi == syscall number
|
||||
* rdx, rcx, r8, r9, (stack), (stack) == syscall arguments
|
||||
* and return the result in rax
|
||||
@ -67,25 +64,42 @@ safe_syscall_base:
|
||||
*/
|
||||
safe_syscall_start:
|
||||
/* if signal_pending is non-zero, don't do the call */
|
||||
cmpl $0, (%rbp)
|
||||
jnz 1f
|
||||
cmpl $0, (%rbp)
|
||||
jnz 2f
|
||||
syscall
|
||||
safe_syscall_end:
|
||||
|
||||
/* code path for having successfully executed the syscall */
|
||||
#if defined(__linux__)
|
||||
/* Linux kernel returns (small) negative errno. */
|
||||
cmp $-4095, %rax
|
||||
jae 0f
|
||||
#elif defined(__FreeBSD__)
|
||||
/* FreeBSD kernel returns positive errno and C bit set. */
|
||||
jc 1f
|
||||
#else
|
||||
#error "unsupported os"
|
||||
#endif
|
||||
pop %rbp
|
||||
.cfi_remember_state
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_restore rbp
|
||||
ret
|
||||
|
||||
1:
|
||||
/* code path when we didn't execute the syscall */
|
||||
.cfi_restore_state
|
||||
mov $-TARGET_ERESTARTSYS, %rax
|
||||
pop %rbp
|
||||
|
||||
#if defined(__linux__)
|
||||
0: neg %eax
|
||||
jmp 1f
|
||||
#endif
|
||||
|
||||
/* code path when we didn't execute the syscall */
|
||||
2: mov $QEMU_ERESTARTSYS, %eax
|
||||
|
||||
/* code path setting errno */
|
||||
1: pop %rbp
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_restore rbp
|
||||
ret
|
||||
jmp safe_syscall_set_errno_tail
|
||||
.cfi_endproc
|
||||
|
||||
.size safe_syscall_base, .-safe_syscall_base
|
6
common-user/meson.build
Normal file
6
common-user/meson.build
Normal file
@ -0,0 +1,6 @@
|
||||
common_user_inc += include_directories('host/' / host_arch)
|
||||
|
||||
common_user_ss.add(files(
|
||||
'safe-syscall.S',
|
||||
'safe-syscall-error.c',
|
||||
))
|
25
common-user/safe-syscall-error.c
Normal file
25
common-user/safe-syscall-error.c
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* safe-syscall-error.c: errno setting fragment
|
||||
* This is intended to be invoked by safe-syscall.S
|
||||
*
|
||||
* Written by Richard Henderson <rth@twiddle.net>
|
||||
* Copyright (C) 2021 Red Hat, Inc.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "user/safe-syscall.h"
|
||||
|
||||
/*
|
||||
* This is intended to be invoked via tail-call on the error path
|
||||
* from the assembly in host/arch/safe-syscall.inc.S. This takes
|
||||
* care of the host specific addressing of errno.
|
||||
* Return -1 to finalize the return value for safe_syscall_base.
|
||||
*/
|
||||
long safe_syscall_set_errno_tail(int value)
|
||||
{
|
||||
errno = value;
|
||||
return -1;
|
||||
}
|
@ -10,15 +10,12 @@
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "hostdep.h"
|
||||
#include "target_errno_defs.h"
|
||||
#include "special-errno.h"
|
||||
|
||||
/* We have the correct host directory on our include path
|
||||
* so that this will pull in the right fragment for the architecture.
|
||||
*/
|
||||
#ifdef HAVE_SAFE_SYSCALL
|
||||
#include "safe-syscall.inc.S"
|
||||
#endif
|
||||
|
||||
/* We must specifically say that we're happy for the stack to not be
|
||||
* executable, otherwise the toolchain will default to assuming our
|
287
configure
vendored
287
configure
vendored
@ -344,7 +344,6 @@ debug_stack_usage="no"
|
||||
crypto_afalg="no"
|
||||
tls_priority="NORMAL"
|
||||
tpm="$default_feature"
|
||||
libssh="$default_feature"
|
||||
live_block_migration=${default_feature:-yes}
|
||||
numa="$default_feature"
|
||||
replication=${default_feature:-yes}
|
||||
@ -502,42 +501,93 @@ EOF
|
||||
}
|
||||
|
||||
if check_define __linux__ ; then
|
||||
targetos="Linux"
|
||||
targetos=linux
|
||||
elif check_define _WIN32 ; then
|
||||
targetos='MINGW32'
|
||||
targetos=windows
|
||||
elif check_define __OpenBSD__ ; then
|
||||
targetos='OpenBSD'
|
||||
targetos=openbsd
|
||||
elif check_define __sun__ ; then
|
||||
targetos='SunOS'
|
||||
targetos=sunos
|
||||
elif check_define __HAIKU__ ; then
|
||||
targetos='Haiku'
|
||||
targetos=haiku
|
||||
elif check_define __FreeBSD__ ; then
|
||||
targetos='FreeBSD'
|
||||
targetos=freebsd
|
||||
elif check_define __FreeBSD_kernel__ && check_define __GLIBC__; then
|
||||
targetos='GNU/kFreeBSD'
|
||||
targetos=gnu/kfreebsd
|
||||
elif check_define __DragonFly__ ; then
|
||||
targetos='DragonFly'
|
||||
targetos=dragonfly
|
||||
elif check_define __NetBSD__; then
|
||||
targetos='NetBSD'
|
||||
targetos=netbsd
|
||||
elif check_define __APPLE__; then
|
||||
targetos='Darwin'
|
||||
targetos=darwin
|
||||
else
|
||||
# This is a fatal error, but don't report it yet, because we
|
||||
# might be going to just print the --help text, or it might
|
||||
# be the result of a missing compiler.
|
||||
targetos='bogus'
|
||||
targetos=bogus
|
||||
fi
|
||||
|
||||
# Some host OSes need non-standard checks for which CPU to use.
|
||||
# Note that these checks are broken for cross-compilation: if you're
|
||||
# cross-compiling to one of these OSes then you'll need to specify
|
||||
# the correct CPU with the --cpu option.
|
||||
# OS specific
|
||||
|
||||
case $targetos in
|
||||
SunOS)
|
||||
windows)
|
||||
mingw32="yes"
|
||||
plugins="no"
|
||||
pie="no"
|
||||
;;
|
||||
gnu/kfreebsd)
|
||||
bsd="yes"
|
||||
;;
|
||||
freebsd)
|
||||
bsd="yes"
|
||||
bsd_user="yes"
|
||||
make="${MAKE-gmake}"
|
||||
# needed for kinfo_getvmmap(3) in libutil.h
|
||||
;;
|
||||
dragonfly)
|
||||
bsd="yes"
|
||||
make="${MAKE-gmake}"
|
||||
;;
|
||||
netbsd)
|
||||
bsd="yes"
|
||||
make="${MAKE-gmake}"
|
||||
;;
|
||||
openbsd)
|
||||
bsd="yes"
|
||||
make="${MAKE-gmake}"
|
||||
;;
|
||||
darwin)
|
||||
bsd="yes"
|
||||
darwin="yes"
|
||||
# Disable attempts to use ObjectiveC features in os/object.h since they
|
||||
# won't work when we're compiling with gcc as a C compiler.
|
||||
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
|
||||
;;
|
||||
sunos)
|
||||
solaris="yes"
|
||||
make="${MAKE-gmake}"
|
||||
smbd="${SMBD-/usr/sfw/sbin/smbd}"
|
||||
# needed for CMSG_ macros in sys/socket.h
|
||||
QEMU_CFLAGS="-D_XOPEN_SOURCE=600 $QEMU_CFLAGS"
|
||||
# needed for TIOCWIN* defines in termios.h
|
||||
QEMU_CFLAGS="-D__EXTENSIONS__ $QEMU_CFLAGS"
|
||||
# $(uname -m) returns i86pc even on an x86_64 box, so default based on isainfo
|
||||
# Note that this check is broken for cross-compilation: if you're
|
||||
# cross-compiling to one of these OSes then you'll need to specify
|
||||
# the correct CPU with the --cpu option.
|
||||
if test -z "$cpu" && test "$(isainfo -k)" = "amd64"; then
|
||||
cpu="x86_64"
|
||||
fi
|
||||
;;
|
||||
haiku)
|
||||
pie="no"
|
||||
QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -D_BSD_SOURCE -fPIC $QEMU_CFLAGS"
|
||||
;;
|
||||
linux)
|
||||
linux="yes"
|
||||
linux_user="yes"
|
||||
vhost_user=${default_feature:-yes}
|
||||
;;
|
||||
esac
|
||||
|
||||
if test ! -z "$cpu" ; then
|
||||
@ -585,98 +635,46 @@ else
|
||||
cpu=$(uname -m)
|
||||
fi
|
||||
|
||||
ARCH=
|
||||
# Normalise host CPU name and set ARCH.
|
||||
# Normalise host CPU name, set multilib cflags
|
||||
# Note that this case should only have supported host CPUs, not guests.
|
||||
case "$cpu" in
|
||||
ppc|ppc64|s390x|sparc64|x32|riscv)
|
||||
;;
|
||||
ppc64le)
|
||||
ARCH="ppc64"
|
||||
;;
|
||||
armv*b|armv*l|arm)
|
||||
cpu="arm" ;;
|
||||
|
||||
i386|i486|i586|i686|i86pc|BePC)
|
||||
cpu="i386"
|
||||
;;
|
||||
CPU_CFLAGS="-m32" ;;
|
||||
x32)
|
||||
cpu="x86_64"
|
||||
CPU_CFLAGS="-mx32" ;;
|
||||
x86_64|amd64)
|
||||
cpu="x86_64"
|
||||
;;
|
||||
armv*b|armv*l|arm)
|
||||
cpu="arm"
|
||||
;;
|
||||
aarch64)
|
||||
cpu="aarch64"
|
||||
;;
|
||||
# ??? Only extremely old AMD cpus do not have cmpxchg16b.
|
||||
# If we truly care, we should simply detect this case at
|
||||
# runtime and generate the fallback to serial emulation.
|
||||
CPU_CFLAGS="-m64 -mcx16" ;;
|
||||
|
||||
mips*)
|
||||
cpu="mips"
|
||||
;;
|
||||
cpu="mips" ;;
|
||||
|
||||
ppc)
|
||||
CPU_CFLAGS="-m32" ;;
|
||||
ppc64)
|
||||
CPU_CFLAGS="-m64 -mbig" ;;
|
||||
ppc64le)
|
||||
cpu="ppc64"
|
||||
CPU_CFLAGS="-m64 -mlittle" ;;
|
||||
|
||||
s390)
|
||||
CPU_CFLAGS="-m31" ;;
|
||||
s390x)
|
||||
CPU_CFLAGS="-m64" ;;
|
||||
|
||||
sparc|sun4[cdmuv])
|
||||
cpu="sparc"
|
||||
;;
|
||||
*)
|
||||
# This will result in either an error or falling back to TCI later
|
||||
ARCH=unknown
|
||||
;;
|
||||
esac
|
||||
if test -z "$ARCH"; then
|
||||
ARCH="$cpu"
|
||||
fi
|
||||
|
||||
# OS specific
|
||||
|
||||
case $targetos in
|
||||
MINGW32*)
|
||||
mingw32="yes"
|
||||
supported_os="yes"
|
||||
plugins="no"
|
||||
pie="no"
|
||||
;;
|
||||
GNU/kFreeBSD)
|
||||
bsd="yes"
|
||||
;;
|
||||
FreeBSD)
|
||||
bsd="yes"
|
||||
bsd_user="yes"
|
||||
make="${MAKE-gmake}"
|
||||
# needed for kinfo_getvmmap(3) in libutil.h
|
||||
;;
|
||||
DragonFly)
|
||||
bsd="yes"
|
||||
make="${MAKE-gmake}"
|
||||
;;
|
||||
NetBSD)
|
||||
bsd="yes"
|
||||
make="${MAKE-gmake}"
|
||||
;;
|
||||
OpenBSD)
|
||||
bsd="yes"
|
||||
make="${MAKE-gmake}"
|
||||
;;
|
||||
Darwin)
|
||||
bsd="yes"
|
||||
darwin="yes"
|
||||
# Disable attempts to use ObjectiveC features in os/object.h since they
|
||||
# won't work when we're compiling with gcc as a C compiler.
|
||||
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
|
||||
;;
|
||||
SunOS)
|
||||
solaris="yes"
|
||||
make="${MAKE-gmake}"
|
||||
smbd="${SMBD-/usr/sfw/sbin/smbd}"
|
||||
# needed for CMSG_ macros in sys/socket.h
|
||||
QEMU_CFLAGS="-D_XOPEN_SOURCE=600 $QEMU_CFLAGS"
|
||||
# needed for TIOCWIN* defines in termios.h
|
||||
QEMU_CFLAGS="-D__EXTENSIONS__ $QEMU_CFLAGS"
|
||||
;;
|
||||
Haiku)
|
||||
haiku="yes"
|
||||
pie="no"
|
||||
QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -D_BSD_SOURCE -fPIC $QEMU_CFLAGS"
|
||||
;;
|
||||
Linux)
|
||||
linux="yes"
|
||||
linux_user="yes"
|
||||
vhost_user=${default_feature:-yes}
|
||||
;;
|
||||
CPU_CFLAGS="-m32 -mv8plus -mcpu=ultrasparc" ;;
|
||||
sparc64)
|
||||
CPU_CFLAGS="-m64 -mcpu=ultrasparc" ;;
|
||||
esac
|
||||
|
||||
: ${make=${MAKE-make}}
|
||||
@ -1080,10 +1078,6 @@ for opt do
|
||||
;;
|
||||
--enable-tpm) tpm="yes"
|
||||
;;
|
||||
--disable-libssh) libssh="no"
|
||||
;;
|
||||
--enable-libssh) libssh="yes"
|
||||
;;
|
||||
--disable-live-block-migration) live_block_migration="no"
|
||||
;;
|
||||
--enable-live-block-migration) live_block_migration="yes"
|
||||
@ -1276,24 +1270,6 @@ local_statedir="${local_statedir:-$prefix/var}"
|
||||
firmwarepath="${firmwarepath:-$datadir/qemu-firmware}"
|
||||
localedir="${localedir:-$datadir/locale}"
|
||||
|
||||
case "$cpu" in
|
||||
ppc) CPU_CFLAGS="-m32" ;;
|
||||
ppc64) CPU_CFLAGS="-m64" ;;
|
||||
sparc) CPU_CFLAGS="-m32 -mv8plus -mcpu=ultrasparc" ;;
|
||||
sparc64) CPU_CFLAGS="-m64 -mcpu=ultrasparc" ;;
|
||||
s390) CPU_CFLAGS="-m31" ;;
|
||||
s390x) CPU_CFLAGS="-m64" ;;
|
||||
i386) CPU_CFLAGS="-m32" ;;
|
||||
x32) CPU_CFLAGS="-mx32" ;;
|
||||
|
||||
# ??? Only extremely old AMD cpus do not have cmpxchg16b.
|
||||
# If we truly care, we should simply detect this case at
|
||||
# runtime and generate the fallback to serial emulation.
|
||||
x86_64) CPU_CFLAGS="-m64 -mcx16" ;;
|
||||
|
||||
# No special flags required for other host CPUs
|
||||
esac
|
||||
|
||||
if eval test -z "\${cross_cc_$cpu}"; then
|
||||
eval "cross_cc_${cpu}=\$cc"
|
||||
cross_cc_vars="$cross_cc_vars cross_cc_${cpu}"
|
||||
@ -1460,7 +1436,6 @@ cat << EOF
|
||||
live-block-migration Block migration in the main migration stream
|
||||
coroutine-pool coroutine freelist (better performance)
|
||||
tpm TPM support
|
||||
libssh ssh block device support
|
||||
numa libnuma support
|
||||
avx2 AVX2 optimization support
|
||||
avx512f AVX512F optimization support
|
||||
@ -2573,21 +2548,6 @@ if test "$modules" = yes; then
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# libssh probe
|
||||
if test "$libssh" != "no" ; then
|
||||
if $pkg_config --exists "libssh >= 0.8.7"; then
|
||||
libssh_cflags=$($pkg_config libssh --cflags)
|
||||
libssh_libs=$($pkg_config libssh --libs)
|
||||
libssh=yes
|
||||
else
|
||||
if test "$libssh" = "yes" ; then
|
||||
error_exit "libssh required for --enable-libssh"
|
||||
fi
|
||||
libssh=no
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# TPM emulation is only on POSIX
|
||||
|
||||
@ -3369,8 +3329,8 @@ QEMU_GA_MSI_MINGW_DLL_PATH="$($pkg_config --variable=prefix glib-2.0)/bin"
|
||||
# Mac OS X ships with a broken assembler
|
||||
roms=
|
||||
if { test "$cpu" = "i386" || test "$cpu" = "x86_64"; } && \
|
||||
test "$targetos" != "Darwin" && test "$targetos" != "SunOS" && \
|
||||
test "$targetos" != "Haiku" && test "$softmmu" = yes ; then
|
||||
test "$targetos" != "darwin" && test "$targetos" != "sunos" && \
|
||||
test "$targetos" != "haiku" && test "$softmmu" = yes ; then
|
||||
# Different host OS linkers have different ideas about the name of the ELF
|
||||
# emulation. Linux and OpenBSD/amd64 use 'elf_i386'; FreeBSD uses the _fbsd
|
||||
# variant; OpenBSD/i386 uses the _obsd variant; and Windows uses i386pe.
|
||||
@ -3447,8 +3407,6 @@ echo "GIT=$git" >> $config_host_mak
|
||||
echo "GIT_SUBMODULES=$git_submodules" >> $config_host_mak
|
||||
echo "GIT_SUBMODULES_ACTION=$git_submodules_action" >> $config_host_mak
|
||||
|
||||
echo "ARCH=$ARCH" >> $config_host_mak
|
||||
|
||||
if test "$debug_tcg" = "yes" ; then
|
||||
echo "CONFIG_DEBUG_TCG=y" >> $config_host_mak
|
||||
fi
|
||||
@ -3484,9 +3442,6 @@ fi
|
||||
if test "$solaris" = "yes" ; then
|
||||
echo "CONFIG_SOLARIS=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$haiku" = "yes" ; then
|
||||
echo "CONFIG_HAIKU=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$static" = "yes" ; then
|
||||
echo "CONFIG_STATIC=y" >> $config_host_mak
|
||||
fi
|
||||
@ -3648,12 +3603,6 @@ if test "$cmpxchg128" = "yes" ; then
|
||||
echo "CONFIG_CMPXCHG128=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$libssh" = "yes" ; then
|
||||
echo "CONFIG_LIBSSH=y" >> $config_host_mak
|
||||
echo "LIBSSH_CFLAGS=$libssh_cflags" >> $config_host_mak
|
||||
echo "LIBSSH_LIBS=$libssh_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$live_block_migration" = "yes" ; then
|
||||
echo "CONFIG_LIVE_BLOCK_MIGRATION=y" >> $config_host_mak
|
||||
fi
|
||||
@ -3777,10 +3726,10 @@ fi
|
||||
if test "$linux" = "yes" ; then
|
||||
mkdir -p linux-headers
|
||||
case "$cpu" in
|
||||
i386|x86_64|x32)
|
||||
i386|x86_64)
|
||||
linux_arch=x86
|
||||
;;
|
||||
ppc|ppc64|ppc64le)
|
||||
ppc|ppc64)
|
||||
linux_arch=powerpc
|
||||
;;
|
||||
s390x)
|
||||
@ -3805,7 +3754,7 @@ fi
|
||||
|
||||
for target in $target_list; do
|
||||
target_dir="$target"
|
||||
target_name=$(echo $target | cut -d '-' -f 1)
|
||||
target_name=$(echo $target | cut -d '-' -f 1)$EXESUF
|
||||
mkdir -p $target_dir
|
||||
case $target in
|
||||
*-user) symlink "../qemu-$target_name" "$target_dir/qemu-$target_name" ;;
|
||||
@ -3832,7 +3781,6 @@ if test "$safe_stack" = "yes"; then
|
||||
fi
|
||||
|
||||
# If we're using a separate build tree, set it up now.
|
||||
# DIRS are directories which we simply mkdir in the build tree;
|
||||
# LINKS are things to symlink back into the source tree
|
||||
# (these can be both files and directories).
|
||||
# Caution: do not add files or directories here using wildcards. This
|
||||
@ -3844,12 +3792,6 @@ fi
|
||||
# UNLINK is used to remove symlinks from older development versions
|
||||
# that might get into the way when doing "git update" without doing
|
||||
# a "make distclean" in between.
|
||||
DIRS="tests tests/tcg tests/qapi-schema tests/qtest/libqos"
|
||||
DIRS="$DIRS tests/qtest tests/qemu-iotests tests/vm tests/fp tests/qgraph"
|
||||
DIRS="$DIRS docs docs/interop fsdev scsi"
|
||||
DIRS="$DIRS pc-bios/optionrom pc-bios/s390-ccw"
|
||||
DIRS="$DIRS roms/seabios"
|
||||
DIRS="$DIRS contrib/plugins/"
|
||||
LINKS="Makefile"
|
||||
LINKS="$LINKS tests/tcg/Makefile.target"
|
||||
LINKS="$LINKS pc-bios/optionrom/Makefile"
|
||||
@ -3871,16 +3813,15 @@ for bios_file in \
|
||||
$source_path/pc-bios/*.img \
|
||||
$source_path/pc-bios/openbios-* \
|
||||
$source_path/pc-bios/u-boot.* \
|
||||
$source_path/pc-bios/edk2-*.fd.bz2 \
|
||||
$source_path/pc-bios/palcode-* \
|
||||
$source_path/pc-bios/qemu_vga.ndrv
|
||||
|
||||
do
|
||||
LINKS="$LINKS pc-bios/$(basename $bios_file)"
|
||||
done
|
||||
mkdir -p $DIRS
|
||||
for f in $LINKS ; do
|
||||
if [ -e "$source_path/$f" ]; then
|
||||
mkdir -p `dirname ./$f`
|
||||
symlink "$source_path/$f" "$f"
|
||||
fi
|
||||
done
|
||||
@ -3954,27 +3895,13 @@ if test "$skip_meson" = no; then
|
||||
if test "$cross_compile" = "yes"; then
|
||||
cross_arg="--cross-file config-meson.cross"
|
||||
echo "[host_machine]" >> $cross
|
||||
if test "$mingw32" = "yes" ; then
|
||||
echo "system = 'windows'" >> $cross
|
||||
fi
|
||||
if test "$linux" = "yes" ; then
|
||||
echo "system = 'linux'" >> $cross
|
||||
fi
|
||||
if test "$darwin" = "yes" ; then
|
||||
echo "system = 'darwin'" >> $cross
|
||||
fi
|
||||
case "$ARCH" in
|
||||
echo "system = '$targetos'" >> $cross
|
||||
case "$cpu" in
|
||||
i386)
|
||||
echo "cpu_family = 'x86'" >> $cross
|
||||
;;
|
||||
x86_64|x32)
|
||||
echo "cpu_family = 'x86_64'" >> $cross
|
||||
;;
|
||||
ppc64le)
|
||||
echo "cpu_family = 'ppc64'" >> $cross
|
||||
;;
|
||||
*)
|
||||
echo "cpu_family = '$ARCH'" >> $cross
|
||||
echo "cpu_family = '$cpu'" >> $cross
|
||||
;;
|
||||
esac
|
||||
echo "cpu = '$cpu'" >> $cross
|
||||
|
5
cpu.c
5
cpu.c
@ -318,12 +318,10 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
|
||||
if (!accel_cpu_realizefn(cpu, errp)) {
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_TCG
|
||||
/* NB: errp parameter is unused currently */
|
||||
if (tcg_enabled()) {
|
||||
tcg_exec_realizefn(cpu, errp);
|
||||
}
|
||||
#endif /* CONFIG_TCG */
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
|
||||
@ -350,12 +348,9 @@ void cpu_exec_unrealizefn(CPUState *cpu)
|
||||
vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_TCG
|
||||
/* NB: errp parameter is unused currently */
|
||||
if (tcg_enabled()) {
|
||||
tcg_exec_unrealizefn(cpu);
|
||||
}
|
||||
#endif /* CONFIG_TCG */
|
||||
|
||||
cpu_list_remove(cpu);
|
||||
}
|
||||
|
106
docs/COLO-FT.txt
106
docs/COLO-FT.txt
@ -209,9 +209,9 @@ children.0=childs0 \
|
||||
|
||||
|
||||
3. On Secondary VM's QEMU monitor, issue command
|
||||
{'execute':'qmp_capabilities'}
|
||||
{'execute': 'nbd-server-start', 'arguments': {'addr': {'type': 'inet', 'data': {'host': '0.0.0.0', 'port': '9999'} } } }
|
||||
{'execute': 'nbd-server-add', 'arguments': {'device': 'parent0', 'writable': true } }
|
||||
{"execute":"qmp_capabilities"}
|
||||
{"execute": "nbd-server-start", "arguments": {"addr": {"type": "inet", "data": {"host": "0.0.0.0", "port": "9999"} } } }
|
||||
{"execute": "nbd-server-add", "arguments": {"device": "parent0", "writable": true } }
|
||||
|
||||
Note:
|
||||
a. The qmp command nbd-server-start and nbd-server-add must be run
|
||||
@ -222,11 +222,11 @@ Note:
|
||||
will be merged into the parent disk on failover.
|
||||
|
||||
4. On Primary VM's QEMU monitor, issue command:
|
||||
{'execute':'qmp_capabilities'}
|
||||
{'execute': 'human-monitor-command', 'arguments': {'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0'}}
|
||||
{'execute': 'x-blockdev-change', 'arguments':{'parent': 'colo-disk0', 'node': 'replication0' } }
|
||||
{'execute': 'migrate-set-capabilities', 'arguments': {'capabilities': [ {'capability': 'x-colo', 'state': true } ] } }
|
||||
{'execute': 'migrate', 'arguments': {'uri': 'tcp:127.0.0.2:9998' } }
|
||||
{"execute":"qmp_capabilities"}
|
||||
{"execute": "human-monitor-command", "arguments": {"command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0"}}
|
||||
{"execute": "x-blockdev-change", "arguments":{"parent": "colo-disk0", "node": "replication0" } }
|
||||
{"execute": "migrate-set-capabilities", "arguments": {"capabilities": [ {"capability": "x-colo", "state": true } ] } }
|
||||
{"execute": "migrate", "arguments": {"uri": "tcp:127.0.0.2:9998" } }
|
||||
|
||||
Note:
|
||||
a. There should be only one NBD Client for each primary disk.
|
||||
@ -249,59 +249,59 @@ if you want to resume the replication, follow "Secondary resume replication"
|
||||
== Primary Failover ==
|
||||
The Secondary died, resume on the Primary
|
||||
|
||||
{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'child': 'children.1'} }
|
||||
{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_del replication0' } }
|
||||
{'execute': 'object-del', 'arguments':{ 'id': 'comp0' } }
|
||||
{'execute': 'object-del', 'arguments':{ 'id': 'iothread1' } }
|
||||
{'execute': 'object-del', 'arguments':{ 'id': 'm0' } }
|
||||
{'execute': 'object-del', 'arguments':{ 'id': 'redire0' } }
|
||||
{'execute': 'object-del', 'arguments':{ 'id': 'redire1' } }
|
||||
{'execute': 'x-colo-lost-heartbeat' }
|
||||
{"execute": "x-blockdev-change", "arguments":{ "parent": "colo-disk0", "child": "children.1"} }
|
||||
{"execute": "human-monitor-command", "arguments":{ "command-line": "drive_del replication0" } }
|
||||
{"execute": "object-del", "arguments":{ "id": "comp0" } }
|
||||
{"execute": "object-del", "arguments":{ "id": "iothread1" } }
|
||||
{"execute": "object-del", "arguments":{ "id": "m0" } }
|
||||
{"execute": "object-del", "arguments":{ "id": "redire0" } }
|
||||
{"execute": "object-del", "arguments":{ "id": "redire1" } }
|
||||
{"execute": "x-colo-lost-heartbeat" }
|
||||
|
||||
== Secondary Failover ==
|
||||
The Primary died, resume on the Secondary and prepare to become the new Primary
|
||||
|
||||
{'execute': 'nbd-server-stop'}
|
||||
{'execute': 'x-colo-lost-heartbeat'}
|
||||
{"execute": "nbd-server-stop"}
|
||||
{"execute": "x-colo-lost-heartbeat"}
|
||||
|
||||
{'execute': 'object-del', 'arguments':{ 'id': 'f2' } }
|
||||
{'execute': 'object-del', 'arguments':{ 'id': 'f1' } }
|
||||
{'execute': 'chardev-remove', 'arguments':{ 'id': 'red1' } }
|
||||
{'execute': 'chardev-remove', 'arguments':{ 'id': 'red0' } }
|
||||
{"execute": "object-del", "arguments":{ "id": "f2" } }
|
||||
{"execute": "object-del", "arguments":{ "id": "f1" } }
|
||||
{"execute": "chardev-remove", "arguments":{ "id": "red1" } }
|
||||
{"execute": "chardev-remove", "arguments":{ "id": "red0" } }
|
||||
|
||||
{'execute': 'chardev-add', 'arguments':{ 'id': 'mirror0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '0.0.0.0', 'port': '9003' } }, 'server': true } } } }
|
||||
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare1', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '0.0.0.0', 'port': '9004' } }, 'server': true } } } }
|
||||
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9001' } }, 'server': true } } } }
|
||||
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare0-0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9001' } }, 'server': false } } } }
|
||||
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': true } } } }
|
||||
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': false } } } }
|
||||
{"execute": "chardev-add", "arguments":{ "id": "mirror0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "0.0.0.0", "port": "9003" } }, "server": true } } } }
|
||||
{"execute": "chardev-add", "arguments":{ "id": "compare1", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "0.0.0.0", "port": "9004" } }, "server": true } } } }
|
||||
{"execute": "chardev-add", "arguments":{ "id": "compare0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9001" } }, "server": true } } } }
|
||||
{"execute": "chardev-add", "arguments":{ "id": "compare0-0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9001" } }, "server": false } } } }
|
||||
{"execute": "chardev-add", "arguments":{ "id": "compare_out", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9005" } }, "server": true } } } }
|
||||
{"execute": "chardev-add", "arguments":{ "id": "compare_out0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9005" } }, "server": false } } } }
|
||||
|
||||
== Primary resume replication ==
|
||||
Resume replication after new Secondary is up.
|
||||
|
||||
Start the new Secondary (Steps 2 and 3 above), then on the Primary:
|
||||
{'execute': 'drive-mirror', 'arguments':{ 'device': 'colo-disk0', 'job-id': 'resync', 'target': 'nbd://127.0.0.2:9999/parent0', 'mode': 'existing', 'format': 'raw', 'sync': 'full'} }
|
||||
{"execute": "drive-mirror", "arguments":{ "device": "colo-disk0", "job-id": "resync", "target": "nbd://127.0.0.2:9999/parent0", "mode": "existing", "format": "raw", "sync": "full"} }
|
||||
|
||||
Wait until disk is synced, then:
|
||||
{'execute': 'stop'}
|
||||
{'execute': 'block-job-cancel', 'arguments':{ 'device': 'resync'} }
|
||||
{"execute": "stop"}
|
||||
{"execute": "block-job-cancel", "arguments":{ "device": "resync"} }
|
||||
|
||||
{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0'}}
|
||||
{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } }
|
||||
{"execute": "human-monitor-command", "arguments":{ "command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0"}}
|
||||
{"execute": "x-blockdev-change", "arguments":{ "parent": "colo-disk0", "node": "replication0" } }
|
||||
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'props': { 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } }
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'props': { 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } }
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'props': { 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } }
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } }
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'props': { 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "filter-mirror", "id": "m0", "netdev": "hn0", "queue": "tx", "outdev": "mirror0" } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire0", "netdev": "hn0", "queue": "rx", "indev": "compare_out" } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire1", "netdev": "hn0", "queue": "rx", "outdev": "compare0" } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "iothread", "id": "iothread1" } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "colo-compare", "id": "comp0", "primary_in": "compare0-0", "secondary_in": "compare1", "outdev": "compare_out0", "iothread": "iothread1" } }
|
||||
|
||||
{'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } }
|
||||
{'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.2:9998' } }
|
||||
{"execute": "migrate-set-capabilities", "arguments":{ "capabilities": [ {"capability": "x-colo", "state": true } ] } }
|
||||
{"execute": "migrate", "arguments":{ "uri": "tcp:127.0.0.2:9998" } }
|
||||
|
||||
Note:
|
||||
If this Primary previously was a Secondary, then we need to insert the
|
||||
filters before the filter-rewriter by using the
|
||||
"'insert': 'before', 'position': 'id=rew0'" Options. See below.
|
||||
""insert": "before", "position": "id=rew0"" Options. See below.
|
||||
|
||||
== Secondary resume replication ==
|
||||
Become Primary and resume replication after new Secondary is up. Note
|
||||
@ -309,23 +309,23 @@ that now 127.0.0.1 is the Secondary and 127.0.0.2 is the Primary.
|
||||
|
||||
Start the new Secondary (Steps 2 and 3 above, but with primary_ip=127.0.0.2),
|
||||
then on the old Secondary:
|
||||
{'execute': 'drive-mirror', 'arguments':{ 'device': 'colo-disk0', 'job-id': 'resync', 'target': 'nbd://127.0.0.1:9999/parent0', 'mode': 'existing', 'format': 'raw', 'sync': 'full'} }
|
||||
{"execute": "drive-mirror", "arguments":{ "device": "colo-disk0", "job-id": "resync", "target": "nbd://127.0.0.1:9999/parent0", "mode": "existing", "format": "raw", "sync": "full"} }
|
||||
|
||||
Wait until disk is synced, then:
|
||||
{'execute': 'stop'}
|
||||
{'execute': 'block-job-cancel', 'arguments':{ 'device': 'resync' } }
|
||||
{"execute": "stop"}
|
||||
{"execute": "block-job-cancel", "arguments":{ "device": "resync" } }
|
||||
|
||||
{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.1,file.port=9999,file.export=parent0,node-name=replication0'}}
|
||||
{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } }
|
||||
{"execute": "human-monitor-command", "arguments":{ "command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.1,file.port=9999,file.export=parent0,node-name=replication0"}}
|
||||
{"execute": "x-blockdev-change", "arguments":{ "parent": "colo-disk0", "node": "replication0" } }
|
||||
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } }
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } }
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } }
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } }
|
||||
{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'props': { 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "filter-mirror", "id": "m0", "insert": "before", "position": "id=rew0", "netdev": "hn0", "queue": "tx", "outdev": "mirror0" } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire0", "insert": "before", "position": "id=rew0", "netdev": "hn0", "queue": "rx", "indev": "compare_out" } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire1", "insert": "before", "position": "id=rew0", "netdev": "hn0", "queue": "rx", "outdev": "compare0" } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "iothread", "id": "iothread1" } }
|
||||
{"execute": "object-add", "arguments":{ "qom-type": "colo-compare", "id": "comp0", "primary_in": "compare0-0", "secondary_in": "compare1", "outdev": "compare_out0", "iothread": "iothread1" } }
|
||||
|
||||
{'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } }
|
||||
{'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.1:9998' } }
|
||||
{"execute": "migrate-set-capabilities", "arguments":{ "capabilities": [ {"capability": "x-colo", "state": true } ] } }
|
||||
{"execute": "migrate", "arguments":{ "uri": "tcp:127.0.0.1:9998" } }
|
||||
|
||||
== TODO ==
|
||||
1. Support shared storage.
|
||||
|
@ -192,6 +192,12 @@ as short-form boolean values, and passed to plugins as ``arg_name=on``.
|
||||
However, short-form booleans are deprecated and full explicit ``arg_name=on``
|
||||
form is preferred.
|
||||
|
||||
``-drive if=none`` for the sifive_u OTP device (since 6.2)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
Using ``-drive if=none`` to configure the OTP device of the sifive_u
|
||||
RISC-V machine is deprecated. Use ``-drive if=pflash`` instead.
|
||||
|
||||
|
||||
QEMU Machine Protocol (QMP) commands
|
||||
------------------------------------
|
||||
@ -309,6 +315,15 @@ This machine is deprecated because we have enough AST2500 based OpenPOWER
|
||||
machines. It can be easily replaced by the ``witherspoon-bmc`` or the
|
||||
``romulus-bmc`` machines.
|
||||
|
||||
PPC 405 ``taihu`` machine (since 7.0)
|
||||
'''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The PPC 405 CPU is a system-on-a-chip, so all 405 machines are very similar,
|
||||
except for some external periphery. However, the periphery of the ``taihu``
|
||||
machine is hardly emulated at all (e.g. neither the LCD nor the USB part had
|
||||
been implemented), so there is not much value added by this board. Use the
|
||||
``ref405ep`` machine instead.
|
||||
|
||||
Backend options
|
||||
---------------
|
||||
|
||||
|
@ -658,8 +658,8 @@ enforce that any failure to open the backing image (including if the
|
||||
backing file is missing or an incorrect format was specified) is an
|
||||
error when ``-u`` is not used.
|
||||
|
||||
qemu-img amend to adjust backing file (removed in 6.1)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
``qemu-img amend`` to adjust backing file (removed in 6.1)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The use of ``qemu-img amend`` to modify the name or format of a qcow2
|
||||
backing image was never fully documented or tested, and interferes
|
||||
@ -670,8 +670,8 @@ backing chain should be performed with ``qemu-img rebase -u`` either
|
||||
before or after the remaining changes being performed by amend, as
|
||||
appropriate.
|
||||
|
||||
qemu-img backing file without format (removed in 6.1)
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
``qemu-img`` backing file without format (removed in 6.1)
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The use of ``qemu-img create``, ``qemu-img rebase``, or ``qemu-img
|
||||
convert`` to create or modify an image that depends on a backing file
|
||||
|
@ -156,15 +156,15 @@ Primary:
|
||||
children.0.driver=raw
|
||||
|
||||
Run qmp command in primary qemu:
|
||||
{ 'execute': 'human-monitor-command',
|
||||
'arguments': {
|
||||
'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=xxxx,file.port=xxxx,file.export=colo1,node-name=nbd_client1'
|
||||
{ "execute": "human-monitor-command",
|
||||
"arguments": {
|
||||
"command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=xxxx,file.port=xxxx,file.export=colo1,node-name=nbd_client1"
|
||||
}
|
||||
}
|
||||
{ 'execute': 'x-blockdev-change',
|
||||
'arguments': {
|
||||
'parent': 'colo1',
|
||||
'node': 'nbd_client1'
|
||||
{ "execute": "x-blockdev-change",
|
||||
"arguments": {
|
||||
"parent": "colo1",
|
||||
"node": "nbd_client1"
|
||||
}
|
||||
}
|
||||
Note:
|
||||
@ -179,7 +179,7 @@ Primary:
|
||||
|
||||
Secondary:
|
||||
-drive if=none,driver=raw,file.filename=1.raw,id=colo1 \
|
||||
-drive if=none,id=childs1,driver=replication,mode=secondary,top-id=childs1
|
||||
-drive if=none,id=childs1,driver=replication,mode=secondary,top-id=top-disk1
|
||||
file.file.filename=active_disk.qcow2,\
|
||||
file.driver=qcow2,\
|
||||
file.backing.file.filename=hidden_disk.qcow2,\
|
||||
@ -189,21 +189,21 @@ Secondary:
|
||||
vote-threshold=1,children.0=childs1
|
||||
|
||||
Then run qmp command in secondary qemu:
|
||||
{ 'execute': 'nbd-server-start',
|
||||
'arguments': {
|
||||
'addr': {
|
||||
'type': 'inet',
|
||||
'data': {
|
||||
'host': 'xxx',
|
||||
'port': 'xxx'
|
||||
{ "execute": "nbd-server-start",
|
||||
"arguments": {
|
||||
"addr": {
|
||||
"type": "inet",
|
||||
"data": {
|
||||
"host": "xxx",
|
||||
"port": "xxx"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{ 'execute': 'nbd-server-add',
|
||||
'arguments': {
|
||||
'device': 'colo1',
|
||||
'writable': true
|
||||
{ "execute": "nbd-server-add",
|
||||
"arguments": {
|
||||
"device": "colo1",
|
||||
"writable": true
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,22 +223,22 @@ After Failover:
|
||||
Primary:
|
||||
The secondary host is down, so we should run the following qmp command
|
||||
to remove the nbd child from the quorum:
|
||||
{ 'execute': 'x-blockdev-change',
|
||||
'arguments': {
|
||||
'parent': 'colo1',
|
||||
'child': 'children.1'
|
||||
{ "execute": "x-blockdev-change",
|
||||
"arguments": {
|
||||
"parent": "colo1",
|
||||
"child": "children.1"
|
||||
}
|
||||
}
|
||||
{ 'execute': 'human-monitor-command',
|
||||
'arguments': {
|
||||
'command-line': 'drive_del xxxx'
|
||||
{ "execute": "human-monitor-command",
|
||||
"arguments": {
|
||||
"command-line": "drive_del xxxx"
|
||||
}
|
||||
}
|
||||
Note: there is no qmp command to remove the blockdev now
|
||||
|
||||
Secondary:
|
||||
The primary host is down, so we should do the following thing:
|
||||
{ 'execute': 'nbd-server-stop' }
|
||||
{ "execute": "nbd-server-stop" }
|
||||
|
||||
Promote Secondary to Primary:
|
||||
see COLO-FT.txt
|
||||
|
@ -121,11 +121,11 @@ process for:
|
||||
|
||||
1) executables, which include:
|
||||
|
||||
- Tools - qemu-img, qemu-nbd, qga (guest agent), etc
|
||||
- Tools - ``qemu-img``, ``qemu-nbd``, ``qga`` (guest agent), etc
|
||||
|
||||
- System emulators - qemu-system-$ARCH
|
||||
- System emulators - ``qemu-system-$ARCH``
|
||||
|
||||
- Userspace emulators - qemu-$ARCH
|
||||
- Userspace emulators - ``qemu-$ARCH``
|
||||
|
||||
- Unit tests
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
============
|
||||
Qemu modules
|
||||
QEMU modules
|
||||
============
|
||||
|
||||
.. kernel-doc:: include/qemu/module.h
|
||||
|
@ -187,9 +187,9 @@ desired, in which the emulation application should only be allowed to
|
||||
access the files or devices the VM it's running on behalf of can access.
|
||||
#### qemu-io model
|
||||
|
||||
Qemu-io is a test harness used to test changes to the QEMU block backend
|
||||
object code. (e.g., the code that implements disk images for disk driver
|
||||
emulation) Qemu-io is not a device emulation application per se, but it
|
||||
``qemu-io`` is a test harness used to test changes to the QEMU block backend
|
||||
object code (e.g., the code that implements disk images for disk driver
|
||||
emulation). ``qemu-io`` is not a device emulation application per se, but it
|
||||
does compile the QEMU block objects into a separate binary from the main
|
||||
QEMU one. This could be useful for disk device emulation, since its
|
||||
emulation applications will need to include the QEMU block objects.
|
||||
@ -641,7 +641,7 @@ the CPU that issued the MMIO.
|
||||
+==========+========================+
|
||||
| rid | range MMIO is within |
|
||||
+----------+------------------------+
|
||||
| offset | offset withing *rid* |
|
||||
| offset | offset within *rid* |
|
||||
+----------+------------------------+
|
||||
| type | e.g., load or store |
|
||||
+----------+------------------------+
|
||||
|
@ -228,7 +228,7 @@ Emulated hardware state
|
||||
|
||||
Currently thanks to KVM work any access to IO memory is automatically
|
||||
protected by the global iothread mutex, also known as the BQL (Big
|
||||
Qemu Lock). Any IO region that doesn't use global mutex is expected to
|
||||
QEMU Lock). Any IO region that doesn't use global mutex is expected to
|
||||
do its own locking.
|
||||
|
||||
However IO memory isn't the only way emulated hardware state can be
|
||||
|
@ -14,7 +14,7 @@ support that device.
|
||||
Using only libqos APIs, the test has to manually take care of
|
||||
covering all the setups, and build the correct command line.
|
||||
|
||||
This also introduces backward compability issues: if a device/driver command
|
||||
This also introduces backward compatibility issues: if a device/driver command
|
||||
line name is changed, all tests that use that will not work
|
||||
properly anymore and need to be adjusted.
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _stable-process:
|
||||
|
||||
QEMU and the stable process
|
||||
===========================
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _coding-style:
|
||||
|
||||
=================
|
||||
QEMU Coding Style
|
||||
=================
|
||||
@ -686,7 +688,7 @@ Rationale: hex numbers are hard to read in logs when there is no 0x prefix,
|
||||
especially when (occasionally) the representation doesn't contain any letters
|
||||
and especially in one line with other decimal numbers. Number groups are allowed
|
||||
to not use '0x' because for some things notations like %x.%x.%x are used not
|
||||
only in Qemu. Also dumping raw data bytes with '0x' is less readable.
|
||||
only in QEMU. Also dumping raw data bytes with '0x' is less readable.
|
||||
|
||||
'#' printf flag
|
||||
---------------
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _submitting-a-patch:
|
||||
|
||||
Submitting a Patch
|
||||
==================
|
||||
|
||||
@ -20,11 +22,11 @@ one-shot fix, the bare minimum we ask is that:
|
||||
should not be posted on the bug tracker, posted on forums, or
|
||||
externally hosted and linked to. (We have other mailing lists too,
|
||||
but all patches must go to qemu-devel, possibly with a Cc: to another
|
||||
list.) ``git send-email`` works best for delivering the patch without
|
||||
mangling it (`hints for setting it
|
||||
up <http://lxr.free-electrons.com/source/Documentation/process/email-clients.rst>`__),
|
||||
but attachments can be used as a last resort on a first-time
|
||||
submission.
|
||||
list.) ``git send-email`` (`step-by-step setup
|
||||
guide <https://git-send-email.io/>`__ and `hints and
|
||||
tips <https://elixir.bootlin.com/linux/latest/source/Documentation/process/email-clients.rst>`__)
|
||||
works best for delivering the patch without mangling it, but
|
||||
attachments can be used as a last resort on a first-time submission.
|
||||
- You must read replies to your message, and be willing to act on them.
|
||||
Note, however, that maintainers are often willing to manually fix up
|
||||
first-time contributions, since there is a learning curve involved in
|
||||
@ -45,6 +47,8 @@ Reading the table of contents below should already give you an idea of
|
||||
the basic requirements. Use the table of contents as a reference, and
|
||||
read the parts that you have doubts about.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
.. _writing_your_patches:
|
||||
|
||||
Writing your Patches
|
||||
@ -60,11 +64,9 @@ check that you are in compliance with our coding standards. Be aware
|
||||
that ``checkpatch.pl`` is not infallible, though, especially where C
|
||||
preprocessor macros are involved; use some common sense too. See also:
|
||||
|
||||
- `QEMU Coding Style
|
||||
<https://qemu-project.gitlab.io/qemu/devel/style.html>`__
|
||||
|
||||
- :ref:`coding-style`
|
||||
- `Automate a checkpatch run on
|
||||
commit <http://blog.vmsplice.net/2011/03/how-to-automatically-run-checkpatchpl.html>`__
|
||||
commit <https://blog.vmsplice.net/2011/03/how-to-automatically-run-checkpatchpl.html>`__
|
||||
|
||||
.. _base_patches_against_current_git_master:
|
||||
|
||||
@ -76,6 +78,13 @@ of QEMU because development will have moved on from then and it probably
|
||||
won't even apply to master. We only apply selected bugfixes to release
|
||||
branches and then only as backports once the code has gone into master.
|
||||
|
||||
It is also okay to base patches on top of other on-going work that is
|
||||
not yet part of the git master branch. To aid continuous integration
|
||||
tools, such as `patchew <http://patchew.org/QEMU/>`__, you should `add a
|
||||
tag <https://lists.gnu.org/archive/html/qemu-devel/2017-08/msg01288.html>`__
|
||||
line ``Based-on: $MESSAGE_ID`` to your cover letter to make the series
|
||||
dependency obvious.
|
||||
|
||||
.. _split_up_long_patches:
|
||||
|
||||
Split up long patches
|
||||
@ -104,18 +113,17 @@ Make code motion patches easy to review
|
||||
If a series requires large blocks of code motion, there are tricks for
|
||||
making the refactoring easier to review. Split up the series so that
|
||||
semantic changes (or even function renames) are done in a separate patch
|
||||
from the raw code motion. Use a one-time setup of
|
||||
``git config diff.renames true; git config diff.algorithm patience``
|
||||
(Refer to `git-config <http://git-scm.com/docs/git-config>`__.) The
|
||||
``diff.renames`` property ensures file rename patches will be given in a
|
||||
more compact representation that focuses only on the differences across
|
||||
the file rename, instead of showing the entire old file as a deletion
|
||||
and the new file as an insertion. Meanwhile, the 'diff.algorithm'
|
||||
property ensures that extracting a non-contiguous subset of one file
|
||||
into a new file, but where all extracted parts occur in the same order
|
||||
both before and after the patch, will reduce churn in trying to treat
|
||||
unrelated ``}`` lines in the original file as separating hunks of
|
||||
changes.
|
||||
from the raw code motion. Use a one-time setup of ``git config
|
||||
diff.renames true;`` ``git config diff.algorithm patience`` (refer to
|
||||
`git-config <http://git-scm.com/docs/git-config>`__). The 'diff.renames'
|
||||
property ensures file rename patches will be given in a more compact
|
||||
representation that focuses only on the differences across the file
|
||||
rename, instead of showing the entire old file as a deletion and the new
|
||||
file as an insertion. Meanwhile, the 'diff.algorithm' property ensures
|
||||
that extracting a non-contiguous subset of one file into a new file, but
|
||||
where all extracted parts occur in the same order both before and after
|
||||
the patch, will reduce churn in trying to treat unrelated ``}`` lines in
|
||||
the original file as separating hunks of changes.
|
||||
|
||||
Ideally, a code motion patch can be reviewed by doing::
|
||||
|
||||
@ -138,8 +146,7 @@ as a separate patch which makes no semantic changes; don't put it in the
|
||||
same patch as your bug fix.
|
||||
|
||||
For smaller patches in less frequently changed areas of QEMU, consider
|
||||
using the `trivial patches process
|
||||
<https://qemu-project.gitlab.io/qemu/devel/style.html>`__.
|
||||
using the :ref:`trivial-patches` process.
|
||||
|
||||
.. _write_a_meaningful_commit_message:
|
||||
|
||||
@ -154,7 +161,7 @@ QEMU follows the usual standard for git commit messages: the first line
|
||||
(which becomes the email subject line) is "subsystem: single line
|
||||
summary of change". Whether the "single line summary of change" starts
|
||||
with a capital is a matter of taste, but we prefer that the summary does
|
||||
not end in ".". Look at ``git shortlog -30`` for an idea of sample
|
||||
not end in a dot. Look at ``git shortlog -30`` for an idea of sample
|
||||
subject lines. Then there is a blank line and a more detailed
|
||||
description of the patch, another blank and your Signed-off-by: line.
|
||||
Please do not use lines that are longer than 76 characters in your
|
||||
@ -170,11 +177,79 @@ displays the subject line some distance apart (that is, a body that
|
||||
starts with "... so that" as a continuation of the subject line is
|
||||
harder to follow).
|
||||
|
||||
If your patch fixes a commit that is already in the repository, please
|
||||
add an additional line with "Fixes: <at-least-12-digits-of-SHA-commit-id>
|
||||
("Fixed commit subject")" below the patch description / before your
|
||||
"Signed-off-by:" line in the commit message.
|
||||
|
||||
If your patch fixes a bug in the gitlab bug tracker, please add a line
|
||||
with "Resolves: <URL-of-the-bug>" to the commit message, too. Gitlab can
|
||||
close bugs automatically once commits with the "Resolved:" keyword get
|
||||
merged into the master branch of the project. And if your patch addresses
|
||||
a bug in another public bug tracker, you can also use a line with
|
||||
"Buglink: <URL-of-the-bug>" for reference here, too.
|
||||
|
||||
Example::
|
||||
|
||||
Fixes: 14055ce53c2d ("s390x/tcg: avoid overflows in time2tod/tod2time")
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/42
|
||||
Buglink: https://bugs.launchpad.net/qemu/+bug/1804323``
|
||||
|
||||
Some other tags that are used in commit messages include "Message-Id:"
|
||||
"Tested-by:", "Acked-by:", "Reported-by:", "Suggested-by:". See ``git
|
||||
log`` for these keywords for example usage.
|
||||
|
||||
.. _test_your_patches:
|
||||
|
||||
Test your patches
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Although QEMU has `continuous integration
|
||||
services <Testing#Continuous_Integration>`__ that attempt to test
|
||||
patches submitted to the list, it still saves everyone time if you have
|
||||
already tested that your patch compiles and works. Because QEMU is such
|
||||
a large project, it's okay to use configure arguments to limit what is
|
||||
built for faster turnaround during your development time; but it is
|
||||
still wise to also check that your patches work with a full build before
|
||||
submitting a series, especially if your changes might have an unintended
|
||||
effect on other areas of the code you don't normally experiment with.
|
||||
See `Testing <Testing>`__ for more details on what tests are available.
|
||||
Also, it is a wise idea to include a testsuite addition as part of your
|
||||
patches - either to ensure that future changes won't regress your new
|
||||
feature, or to add a test which exposes the bug that the rest of your
|
||||
series fixes. Keeping separate commits for the test and the fix allows
|
||||
reviewers to rebase the test to occur first to prove it catches the
|
||||
problem, then again to place it last in the series so that bisection
|
||||
doesn't land on a known-broken state.
|
||||
|
||||
.. _submitting_your_patches:
|
||||
|
||||
Submitting your Patches
|
||||
-----------------------
|
||||
|
||||
.. _if_you_cannot_send_patch_emails:
|
||||
|
||||
If you cannot send patch emails
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In rare cases it may not be possible to send properly formatted patch
|
||||
emails. You can use `sourcehut <https://sourcehut.org/>`__ to send your
|
||||
patches to the QEMU mailing list by following these steps:
|
||||
|
||||
#. Register or sign in to your account
|
||||
#. Add your SSH public key in `meta \|
|
||||
keys <https://meta.sr.ht/keys>`__.
|
||||
#. Publish your git branch using **git push git@git.sr.ht:~USERNAME/qemu
|
||||
HEAD**
|
||||
#. Send your patches to the QEMU mailing list using the web-based
|
||||
``git-send-email`` UI at https://git.sr.ht/~USERNAME/qemu/send-email
|
||||
|
||||
`This video
|
||||
<https://spacepub.space/videos/watch/ad258d23-0ac6-488c-83fc-2bacf578de3a>`__
|
||||
shows the web-based ``git-send-email`` workflow. Documentation is
|
||||
available `here
|
||||
<https://man.sr.ht/git.sr.ht/#sending-patches-upstream>`__.
|
||||
|
||||
.. _cc_the_relevant_maintainer:
|
||||
|
||||
CC the relevant maintainer
|
||||
@ -219,17 +294,26 @@ such as 'git-email' on Fedora-based systems.) Patch series need a cover
|
||||
letter, with shallow threading (all patches in the series are
|
||||
in-reply-to the cover letter, but not to each other); single unrelated
|
||||
patches do not need a cover letter (but if you do send a cover letter,
|
||||
use --numbered so the cover and the patch have distinct subject lines).
|
||||
use ``--numbered`` so the cover and the patch have distinct subject lines).
|
||||
Patches are easier to find if they start a new top-level thread, rather
|
||||
than being buried in-reply-to another existing thread.
|
||||
|
||||
.. _avoid_posting_large_binary_blob:
|
||||
|
||||
Avoid posting large binary blob
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you added binaries to the repository, consider producing the patch
|
||||
emails using ``git format-patch --no-binary`` and include a link to a
|
||||
git repository to fetch the original commit.
|
||||
|
||||
.. _patch_emails_must_include_a_signed_off_by_line:
|
||||
|
||||
Patch emails must include a ``Signed-off-by:`` line
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For more information see `1.12) Sign your work
|
||||
<http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/SubmittingPatches?id=f6f94e2ab1b33f0082ac22d71f66385a60d8157f#n296>`__.
|
||||
For more information see `SubmittingPatches 1.12
|
||||
<http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/SubmittingPatches?id=f6f94e2ab1b33f0082ac22d71f66385a60d8157f#n297>`__.
|
||||
This is vital or we will not be able to apply your patch! Please use
|
||||
your real name to sign a patch (not an alias or acronym).
|
||||
|
||||
@ -246,8 +330,13 @@ that author's Signed-off-by: line is mandatory, with the same spelling.
|
||||
Include a meaningful cover letter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This usually applies only to a series that includes multiple patches;
|
||||
the cover letter explains the overall goal of such a series.
|
||||
This is a requirement for any series with multiple patches (as it aids
|
||||
continuous integration), but optional for an isolated patch. The cover
|
||||
letter explains the overall goal of such a series, and also provides a
|
||||
convenient 0/N email for others to reply to the series as a whole. A
|
||||
one-time setup of ``git config format.coverletter auto`` (refer to
|
||||
`git-config <http://git-scm.com/docs/git-config>`__) will generate the
|
||||
cover letter as needed.
|
||||
|
||||
When reviewers don't know your goal at the start of their review, they
|
||||
may object to early changes that don't make sense until the end of the
|
||||
@ -288,6 +377,18 @@ it's best to:
|
||||
of the patchset you're looking for review on, and why reviewers
|
||||
should care
|
||||
|
||||
.. _consider_whether_your_patch_is_applicable_for_stable:
|
||||
|
||||
Consider whether your patch is applicable for stable
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If your patch fixes a severe issue or a regression, it may be applicable
|
||||
for stable. In that case, consider adding ``Cc: qemu-stable@nongnu.org``
|
||||
to your patch to notify the stable maintainers.
|
||||
|
||||
For more details on how QEMU's stable process works, refer to the
|
||||
:ref:`stable-process` page.
|
||||
|
||||
.. _participating_in_code_review:
|
||||
|
||||
Participating in Code Review
|
||||
@ -367,19 +468,19 @@ Include version history in patchset revisions
|
||||
|
||||
For later versions of patches, include a summary of changes from
|
||||
previous versions, but not in the commit message itself. In an email
|
||||
formatted as a git patch, the commit message is the part above the "---"
|
||||
formatted as a git patch, the commit message is the part above the ``---``
|
||||
line, and this will go into the git changelog when the patch is
|
||||
committed. This part should be a self-contained description of what this
|
||||
version of the patch does, written to make sense to anybody who comes
|
||||
back to look at this commit in git in six months' time. The part below
|
||||
the "---" line and above the patch proper (git format-patch puts the
|
||||
the ``---`` line and above the patch proper (git format-patch puts the
|
||||
diffstat here) is a good place to put remarks for people reading the
|
||||
patch email, and this is where the "changes since previous version"
|
||||
summary belongs. The
|
||||
`git-publish <https://github.com/stefanha/git-publish>`__ script can
|
||||
help with tracking a good summary across versions. Also, the
|
||||
`git-backport-diff <https://github.com/codyprime/git-scripts>`__ script
|
||||
can help focus reviewers on what changed between revisions.
|
||||
summary belongs. The `git-publish
|
||||
<https://github.com/stefanha/git-publish>`__ script can help with
|
||||
tracking a good summary across versions. Also, the `git-backport-diff
|
||||
<https://github.com/codyprime/git-scripts>`__ script can help focus
|
||||
reviewers on what changed between revisions.
|
||||
|
||||
.. _tips_and_tricks:
|
||||
|
||||
@ -411,27 +512,32 @@ If your patch seems to have been ignored
|
||||
If your patchset has received no replies you should "ping" it after a
|
||||
week or two, by sending an email as a reply-to-all to the patch mail,
|
||||
including the word "ping" and ideally also a link to the page for the
|
||||
patch on
|
||||
`patchwork <http://patchwork.ozlabs.org/project/qemu-devel/list/>`__ or
|
||||
GMANE. It's worth double-checking for reasons why your patch might have
|
||||
been ignored (forgot to CC the maintainer? annoyed people by failing to
|
||||
respond to review comments on an earlier version?), but often for
|
||||
less-maintained areas of QEMU patches do just slip through the cracks.
|
||||
If your ping is also ignored, ping again after another week or so. As
|
||||
the submitter, you are the person with the most motivation to get your
|
||||
patch applied, so you have to be persistent.
|
||||
patch on `patchew <https://patchew.org/QEMU/>`__ or
|
||||
`lore.kernel.org <https://lore.kernel.org/qemu-devel/>`__. It's worth
|
||||
double-checking for reasons why your patch might have been ignored
|
||||
(forgot to CC the maintainer? annoyed people by failing to respond to
|
||||
review comments on an earlier version?), but often for less-maintained
|
||||
areas of QEMU patches do just slip through the cracks. If your ping is
|
||||
also ignored, ping again after another week or so. As the submitter, you
|
||||
are the person with the most motivation to get your patch applied, so
|
||||
you have to be persistent.
|
||||
|
||||
.. _is_my_patch_in:
|
||||
|
||||
Is my patch in?
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
QEMU has some Continuous Integration machines that try to catch patch
|
||||
submission problems as soon as possible. `patchew
|
||||
<http://patchew.org/QEMU/>`__ includes a web interface for tracking the
|
||||
status of various threads that have been posted to the list, and may
|
||||
send you an automated mail if it detected a problem with your patch.
|
||||
|
||||
Once your patch has had enough review on list, the maintainer for that
|
||||
area of code will send notification to the list that they are including
|
||||
your patch in a particular staging branch. Periodically, the maintainer
|
||||
then sends a `pull request
|
||||
<https://qemu-project.gitlab.io/qemu/devel/submitting-a-pull-request.html>`__
|
||||
for aggregating topic branches into mainline qemu. Generally, you do not
|
||||
then takes care of :ref:`submitting-a-pull-request`
|
||||
for aggregating topic branches into mainline QEMU. Generally, you do not
|
||||
need to send a pull request unless you have contributed enough patches
|
||||
to become a maintainer over a particular section of code. Maintainers
|
||||
may further modify your commit, by resolving simple merge conflicts or
|
||||
|
@ -1,10 +1,11 @@
|
||||
Submit a Pull Request
|
||||
=====================
|
||||
.. _submitting-a-pull-request:
|
||||
|
||||
Submitting a Pull Request
|
||||
=========================
|
||||
|
||||
QEMU welcomes contributions of code, but we generally expect these to be
|
||||
sent as simple patch emails to the mailing list (see our page on
|
||||
`submitting a patch
|
||||
<https://qemu-project.gitlab.io/qemu/devel/submitting-a-patch.html>`__
|
||||
:ref:`submitting-a-patch`
|
||||
for more details). Generally only existing submaintainers of a tree
|
||||
will need to submit pull requests, although occasionally for a large
|
||||
patch series we might ask a submitter to send a pull request. This page
|
||||
|
@ -564,11 +564,11 @@ exploiting a QEMU security bug to compromise the host.
|
||||
QEMU binaries
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
By default, qemu-system-x86_64 is searched in $PATH to run the guest. If there
|
||||
isn't one, or if it is older than 2.10, the test won't work. In this case,
|
||||
By default, ``qemu-system-x86_64`` is searched in $PATH to run the guest. If
|
||||
there isn't one, or if it is older than 2.10, the test won't work. In this case,
|
||||
provide the QEMU binary in env var: ``QEMU=/path/to/qemu-2.10+``.
|
||||
|
||||
Likewise the path to qemu-img can be set in QEMU_IMG environment variable.
|
||||
Likewise the path to ``qemu-img`` can be set in QEMU_IMG environment variable.
|
||||
|
||||
Make jobs
|
||||
~~~~~~~~~
|
||||
@ -650,7 +650,7 @@ supported. To start the fuzzer, run
|
||||
|
||||
tests/image-fuzzer/runner.py -c '[["qemu-img", "info", "$test_img"]]' /tmp/test qcow2
|
||||
|
||||
Alternatively, some command different from "qemu-img info" can be tested, by
|
||||
Alternatively, some command different from ``qemu-img info`` can be tested, by
|
||||
changing the ``-c`` option.
|
||||
|
||||
Integration tests using the Avocado Framework
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _trivial-patches:
|
||||
|
||||
Trivial Patches
|
||||
===============
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
=================
|
||||
Qemu UI subsystem
|
||||
QEMU UI subsystem
|
||||
=================
|
||||
|
||||
Qemu Clipboard
|
||||
QEMU Clipboard
|
||||
--------------
|
||||
|
||||
.. kernel-doc:: include/ui/clipboard.h
|
||||
|
@ -677,7 +677,7 @@ return a single text string::
|
||||
|
||||
The ``HumanReadableText`` struct is intended to be used for all
|
||||
commands, under the ``x-`` name prefix that are returning unstructured
|
||||
text targetted at humans. It should never be used for commands outside
|
||||
text targeted at humans. It should never be used for commands outside
|
||||
the ``x-`` name prefix, as those should be using structured QAPI types.
|
||||
|
||||
Implementing the QMP command
|
||||
|
@ -195,7 +195,7 @@ The enlightenment allows to use Hyper-V SynIC with hardware APICv/AVIC enabled.
|
||||
Normally, Hyper-V SynIC disables these hardware feature and suggests the guest
|
||||
to use paravirtualized AutoEOI feature.
|
||||
Note: enabling this feature on old hardware (without APICv/AVIC support) may
|
||||
have negative effect on guest's performace.
|
||||
have negative effect on guest's performance.
|
||||
|
||||
3.19. hv-no-nonarch-coresharing=on/off/auto
|
||||
===========================================
|
||||
|
@ -51,10 +51,10 @@ assumes that core dumps will be generated in the current working directory.
|
||||
For comprehensive test results, please, set up your test environment
|
||||
properly.
|
||||
|
||||
Paths to binaries under test (SUTs) qemu-img and qemu-io are retrieved from
|
||||
environment variables. If the environment check fails the runner will
|
||||
Paths to binaries under test (SUTs) ``qemu-img`` and ``qemu-io`` are retrieved
|
||||
from environment variables. If the environment check fails the runner will
|
||||
use SUTs installed in system paths.
|
||||
qemu-img is required for creation of backing files, so it's mandatory to set
|
||||
``qemu-img`` is required for creation of backing files, so it's mandatory to set
|
||||
the related environment variable if it's not installed in the system path.
|
||||
For details about environment variables see qemu-iotests/check.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
Qemu supports the NBD protocol, and has an internal NBD client (see
|
||||
QEMU supports the NBD protocol, and has an internal NBD client (see
|
||||
block/nbd.c), an internal NBD server (see blockdev-nbd.c), and an
|
||||
external NBD server tool (see qemu-nbd.c). The common code is placed
|
||||
in nbd/*.
|
||||
@ -7,11 +7,11 @@ The NBD protocol is specified here:
|
||||
https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md
|
||||
|
||||
The following paragraphs describe some specific properties of NBD
|
||||
protocol realization in Qemu.
|
||||
protocol realization in QEMU.
|
||||
|
||||
= Metadata namespaces =
|
||||
|
||||
Qemu supports the "base:allocation" metadata context as defined in the
|
||||
QEMU supports the "base:allocation" metadata context as defined in the
|
||||
NBD protocol specification, and also defines an additional metadata
|
||||
namespace "qemu".
|
||||
|
||||
|
@ -313,7 +313,7 @@ The fields of the bitmaps extension are:
|
||||
The number of bitmaps contained in the image. Must be
|
||||
greater than or equal to 1.
|
||||
|
||||
Note: Qemu currently only supports up to 65535 bitmaps per
|
||||
Note: QEMU currently only supports up to 65535 bitmaps per
|
||||
image.
|
||||
|
||||
4 - 7: Reserved, must be zero.
|
||||
@ -775,7 +775,7 @@ Structure of a bitmap directory entry:
|
||||
2: extra_data_compatible
|
||||
This flags is meaningful when the extra data is
|
||||
unknown to the software (currently any extra data is
|
||||
unknown to Qemu).
|
||||
unknown to QEMU).
|
||||
If it is set, the bitmap may be used as expected, extra
|
||||
data must be left as is.
|
||||
If it is not set, the bitmap must not be used, but
|
||||
@ -793,7 +793,7 @@ Structure of a bitmap directory entry:
|
||||
17: granularity_bits
|
||||
Granularity bits. Valid values: 0 - 63.
|
||||
|
||||
Note: Qemu currently supports only values 9 - 31.
|
||||
Note: QEMU currently supports only values 9 - 31.
|
||||
|
||||
Granularity is calculated as
|
||||
granularity = 1 << granularity_bits
|
||||
@ -804,7 +804,7 @@ Structure of a bitmap directory entry:
|
||||
18 - 19: name_size
|
||||
Size of the bitmap name. Must be non-zero.
|
||||
|
||||
Note: Qemu currently doesn't support values greater than
|
||||
Note: QEMU currently doesn't support values greater than
|
||||
1023.
|
||||
|
||||
20 - 23: extra_data_size
|
||||
|
@ -18,12 +18,12 @@ if sphinx_build.found()
|
||||
# This is a bit awkward but works: create a trivial document and
|
||||
# try to run it with our configuration file (which enforces a
|
||||
# version requirement). This will fail if sphinx-build is too old.
|
||||
run_command('mkdir', ['-p', tmpdir / 'sphinx'])
|
||||
run_command('touch', [tmpdir / 'sphinx/index.rst'])
|
||||
run_command('mkdir', ['-p', tmpdir / 'sphinx'], check: true)
|
||||
run_command('touch', [tmpdir / 'sphinx/index.rst'], check: true)
|
||||
sphinx_build_test_out = run_command(SPHINX_ARGS + [
|
||||
'-c', meson.current_source_dir(),
|
||||
'-b', 'html', tmpdir / 'sphinx',
|
||||
tmpdir / 'sphinx/out'])
|
||||
tmpdir / 'sphinx/out'], check: false)
|
||||
build_docs = (sphinx_build_test_out.returncode() == 0)
|
||||
|
||||
if not build_docs
|
||||
|
@ -123,7 +123,7 @@ Background info is here:
|
||||
guest side with pci-bridge-seat
|
||||
-------------------------------
|
||||
|
||||
Qemu version 2.4 and newer has a new pci-bridge-seat device which
|
||||
QEMU version 2.4 and newer has a new pci-bridge-seat device which
|
||||
can be used instead of pci-bridge. Just swap the device name in the
|
||||
qemu command line above. The only difference between the two devices
|
||||
is the pci id. We can match the pci id instead of the device path
|
||||
|
100
docs/specs/ppc-spapr-hcalls.rst
Normal file
100
docs/specs/ppc-spapr-hcalls.rst
Normal file
@ -0,0 +1,100 @@
|
||||
sPAPR hypervisor calls
|
||||
----------------------
|
||||
|
||||
When used with the ``pseries`` machine type, ``qemu-system-ppc64`` implements
|
||||
a set of hypervisor calls (a.k.a. hcalls) defined in the `Linux on Power
|
||||
Architecture Reference document (LoPAR)
|
||||
<https://cdn.openpowerfoundation.org/wp-content/uploads/2020/07/LoPAR-20200812.pdf>`_.
|
||||
This document is a subset of the Power Architecture Platform Reference (PAPR+)
|
||||
specification (IBM internal only), which is what PowerVM, the IBM proprietary
|
||||
hypervisor, adheres to.
|
||||
|
||||
The subset in LoPAR is selected based on the requirements of Linux as a guest.
|
||||
|
||||
In addition to those calls, we have added our own private hypervisor
|
||||
calls which are mostly used as a private interface between the firmware
|
||||
running in the guest and QEMU.
|
||||
|
||||
All those hypercalls start at hcall number 0xf000 which correspond
|
||||
to an implementation specific range in PAPR.
|
||||
|
||||
H_RTAS (0xf000)
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
RTAS stands for Run-Time Abstraction Sercies and is a set of runtime services
|
||||
generally provided by the firmware inside the guest to the operating system. It
|
||||
predates the existence of hypervisors (it was originally an extension to Open
|
||||
Firmware) and is still used by PAPR and LoPAR to provide various services that
|
||||
are not performance sensitive.
|
||||
|
||||
We currently implement the RTAS services in QEMU itself. The actual RTAS
|
||||
"firmware" blob in the guest is a small stub of a few instructions which
|
||||
calls our private H_RTAS hypervisor call to pass the RTAS calls to QEMU.
|
||||
|
||||
Arguments:
|
||||
|
||||
``r3``: ``H_RTAS (0xf000)``
|
||||
|
||||
``r4``: Guest physical address of RTAS parameter block.
|
||||
|
||||
Returns:
|
||||
|
||||
``H_SUCCESS``: Successfully called the RTAS function (RTAS result will have
|
||||
been stored in the parameter block).
|
||||
|
||||
``H_PARAMETER``: Unknown token.
|
||||
|
||||
H_LOGICAL_MEMOP (0xf001)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When the guest runs in "real mode" (in powerpc terminology this means with MMU
|
||||
disabled, i.e. guest effective address equals to guest physical address), it
|
||||
only has access to a subset of memory and no I/Os.
|
||||
|
||||
PAPR and LoPAR provides a set of hypervisor calls to perform cacheable or
|
||||
non-cacheable accesses to any guest physical addresses that the
|
||||
guest can use in order to access IO devices while in real mode.
|
||||
|
||||
This is typically used by the firmware running in the guest.
|
||||
|
||||
However, doing a hypercall for each access is extremely inefficient
|
||||
(even more so when running KVM) when accessing the frame buffer. In
|
||||
that case, things like scrolling become unusably slow.
|
||||
|
||||
This hypercall allows the guest to request a "memory op" to be applied
|
||||
to memory. The supported memory ops at this point are to copy a range
|
||||
of memory (supports overlap of source and destination) and XOR which
|
||||
is used by our SLOF firmware to invert the screen.
|
||||
|
||||
Arguments:
|
||||
|
||||
``r3 ``: ``H_LOGICAL_MEMOP (0xf001)``
|
||||
|
||||
``r4``: Guest physical address of destination.
|
||||
|
||||
``r5``: Guest physical address of source.
|
||||
|
||||
``r6``: Individual element size, defined by the binary logarithm of the
|
||||
desired size. Supported values are:
|
||||
|
||||
``0`` = 1 byte
|
||||
|
||||
``1`` = 2 bytes
|
||||
|
||||
``2`` = 4 bytes
|
||||
|
||||
``3`` = 8 bytes
|
||||
|
||||
``r7``: Number of elements.
|
||||
|
||||
``r8``: Operation. Supported values are:
|
||||
|
||||
``0``: copy
|
||||
|
||||
``1``: xor
|
||||
|
||||
Returns:
|
||||
|
||||
``H_SUCCESS``: Success.
|
||||
|
||||
``H_PARAMETER``: Invalid argument.
|
@ -1,78 +0,0 @@
|
||||
When used with the "pseries" machine type, QEMU-system-ppc64 implements
|
||||
a set of hypervisor calls using a subset of the server "PAPR" specification
|
||||
(IBM internal at this point), which is also what IBM's proprietary hypervisor
|
||||
adheres too.
|
||||
|
||||
The subset is selected based on the requirements of Linux as a guest.
|
||||
|
||||
In addition to those calls, we have added our own private hypervisor
|
||||
calls which are mostly used as a private interface between the firmware
|
||||
running in the guest and QEMU.
|
||||
|
||||
All those hypercalls start at hcall number 0xf000 which correspond
|
||||
to an implementation specific range in PAPR.
|
||||
|
||||
- H_RTAS (0xf000)
|
||||
|
||||
RTAS is a set of runtime services generally provided by the firmware
|
||||
inside the guest to the operating system. It predates the existence
|
||||
of hypervisors (it was originally an extension to Open Firmware) and
|
||||
is still used by PAPR to provide various services that aren't performance
|
||||
sensitive.
|
||||
|
||||
We currently implement the RTAS services in QEMU itself. The actual RTAS
|
||||
"firmware" blob in the guest is a small stub of a few instructions which
|
||||
calls our private H_RTAS hypervisor call to pass the RTAS calls to QEMU.
|
||||
|
||||
Arguments:
|
||||
|
||||
r3 : H_RTAS (0xf000)
|
||||
r4 : Guest physical address of RTAS parameter block
|
||||
|
||||
Returns:
|
||||
|
||||
H_SUCCESS : Successfully called the RTAS function (RTAS result
|
||||
will have been stored in the parameter block)
|
||||
H_PARAMETER : Unknown token
|
||||
|
||||
- H_LOGICAL_MEMOP (0xf001)
|
||||
|
||||
When the guest runs in "real mode" (in powerpc lingua this means
|
||||
with MMU disabled, ie guest effective == guest physical), it only
|
||||
has access to a subset of memory and no IOs.
|
||||
|
||||
PAPR provides a set of hypervisor calls to perform cacheable or
|
||||
non-cacheable accesses to any guest physical addresses that the
|
||||
guest can use in order to access IO devices while in real mode.
|
||||
|
||||
This is typically used by the firmware running in the guest.
|
||||
|
||||
However, doing a hypercall for each access is extremely inefficient
|
||||
(even more so when running KVM) when accessing the frame buffer. In
|
||||
that case, things like scrolling become unusably slow.
|
||||
|
||||
This hypercall allows the guest to request a "memory op" to be applied
|
||||
to memory. The supported memory ops at this point are to copy a range
|
||||
of memory (supports overlap of source and destination) and XOR which
|
||||
is used by our SLOF firmware to invert the screen.
|
||||
|
||||
Arguments:
|
||||
|
||||
r3: H_LOGICAL_MEMOP (0xf001)
|
||||
r4: Guest physical address of destination
|
||||
r5: Guest physical address of source
|
||||
r6: Individual element size
|
||||
0 = 1 byte
|
||||
1 = 2 bytes
|
||||
2 = 4 bytes
|
||||
3 = 8 bytes
|
||||
r7: Number of elements
|
||||
r8: Operation
|
||||
0 = copy
|
||||
1 = xor
|
||||
|
||||
Returns:
|
||||
|
||||
H_SUCCESS : Success
|
||||
H_PARAMETER : Invalid argument
|
||||
|
@ -14,6 +14,7 @@ AST2400 SoC based machines :
|
||||
|
||||
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
|
||||
- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
|
||||
- ``supermicrox11-bmc`` Supermicro X11 BMC
|
||||
|
||||
AST2500 SoC based machines :
|
||||
|
||||
@ -21,12 +22,16 @@ AST2500 SoC based machines :
|
||||
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
|
||||
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
|
||||
- ``sonorapass-bmc`` OCP SonoraPass BMC
|
||||
- ``swift-bmc`` OpenPOWER Swift BMC POWER9
|
||||
- ``swift-bmc`` OpenPOWER Swift BMC POWER9 (to be removed in v7.0)
|
||||
- ``fp5280g2-bmc`` Inspur FP5280G2 BMC
|
||||
- ``g220a-bmc`` Bytedance G220A BMC
|
||||
|
||||
AST2600 SoC based machines :
|
||||
|
||||
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
|
||||
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
|
||||
- ``rainier-bmc`` IBM Rainier POWER10 BMC
|
||||
- ``fuji-bmc`` Facebook Fuji BMC
|
||||
|
||||
Supported devices
|
||||
-----------------
|
||||
@ -51,13 +56,13 @@ Supported devices
|
||||
* Front LEDs (PCA9552 on I2C bus)
|
||||
* LPC Peripheral Controller (a subset of subdevices are supported)
|
||||
* Hash/Crypto Engine (HACE) - Hash support only. TODO: HMAC and RSA
|
||||
* ADC
|
||||
|
||||
|
||||
Missing devices
|
||||
---------------
|
||||
|
||||
* Coprocessor support
|
||||
* ADC (out of tree implementation)
|
||||
* PWM and Fan Controller
|
||||
* Slave GPIO Controller
|
||||
* Super I/O Controller
|
||||
@ -73,16 +78,25 @@ Missing devices
|
||||
Boot options
|
||||
------------
|
||||
|
||||
The Aspeed machines can be started using the ``-kernel`` option to
|
||||
load a Linux kernel or from a firmware. Images can be downloaded from
|
||||
the OpenBMC jenkins :
|
||||
The Aspeed machines can be started using the ``-kernel`` and ``-dtb`` options
|
||||
to load a Linux kernel or from a firmware. Images can be downloaded from the
|
||||
OpenBMC jenkins :
|
||||
|
||||
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/distro=ubuntu,label=docker-builder
|
||||
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
|
||||
|
||||
or directly from the OpenBMC GitHub release repository :
|
||||
|
||||
https://github.com/openbmc/openbmc/releases
|
||||
|
||||
To boot a kernel directly from a Linux build tree:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ qemu-system-arm -M ast2600-evb -nographic \
|
||||
-kernel arch/arm/boot/zImage \
|
||||
-dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \
|
||||
-initrd rootfs.cpio
|
||||
|
||||
The image should be attached as an MTD drive. Run :
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -128,7 +128,7 @@ Alternatively, you can also choose to build you own image with buildroot
|
||||
using the orangepi_pc_defconfig. Also see https://buildroot.org for more information.
|
||||
|
||||
When using an image as an SD card, it must be resized to a power of two. This can be
|
||||
done with the qemu-img command. It is recommended to only increase the image size
|
||||
done with the ``qemu-img`` command. It is recommended to only increase the image size
|
||||
instead of shrinking it to a power of two, to avoid loss of data. For example,
|
||||
to prepare a downloaded Armbian image, first extract it and then increase
|
||||
its size to one gigabyte as follows:
|
||||
|
@ -77,9 +77,7 @@ To create an instance of this driver via QMP:
|
||||
"arguments": {
|
||||
"qom-type": "authz-simple",
|
||||
"id": "authz0",
|
||||
"props": {
|
||||
"identity": "fred"
|
||||
}
|
||||
"identity": "fred"
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,15 +108,13 @@ To create an instance of this class via QMP:
|
||||
"arguments": {
|
||||
"qom-type": "authz-list",
|
||||
"id": "authz0",
|
||||
"props": {
|
||||
"rules": [
|
||||
{ "match": "fred", "policy": "allow", "format": "exact" },
|
||||
{ "match": "bob", "policy": "allow", "format": "exact" },
|
||||
{ "match": "danb", "policy": "deny", "format": "exact" },
|
||||
{ "match": "dan*", "policy": "allow", "format": "glob" }
|
||||
],
|
||||
"policy": "deny"
|
||||
}
|
||||
"rules": [
|
||||
{ "match": "fred", "policy": "allow", "format": "exact" },
|
||||
{ "match": "bob", "policy": "allow", "format": "exact" },
|
||||
{ "match": "danb", "policy": "deny", "format": "exact" },
|
||||
{ "match": "dan*", "policy": "allow", "format": "glob" }
|
||||
],
|
||||
"policy": "deny"
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,10 +139,8 @@ To create an instance of this class via QMP:
|
||||
"arguments": {
|
||||
"qom-type": "authz-list-file",
|
||||
"id": "authz0",
|
||||
"props": {
|
||||
"filename": "/etc/qemu/myvm-vnc.acl",
|
||||
"refresh": true
|
||||
}
|
||||
"filename": "/etc/qemu/myvm-vnc.acl",
|
||||
"refresh": true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ future OS and toolchains are likely to target newer ABIs. The
|
||||
table that follows illustrates which ABI compatibility levels
|
||||
can be satisfied by the QEMU CPU models. Note that the table only
|
||||
lists the long term stable CPU model versions (eg Haswell-v4).
|
||||
In addition to whats listed, there are also many CPU model
|
||||
In addition to what is listed, there are also many CPU model
|
||||
aliases which resolve to a different CPU model version,
|
||||
depending on the machine type is in use.
|
||||
|
||||
|
@ -15,7 +15,7 @@ These are specified using a special URL syntax.
|
||||
'iqn.2008-11.org.linux-kvm[:<name>]' but this can also be set from
|
||||
the command line or a configuration file.
|
||||
|
||||
Since version Qemu 2.4 it is possible to specify a iSCSI request
|
||||
Since version QEMU 2.4 it is possible to specify a iSCSI request
|
||||
timeout to detect stalled requests and force a reestablishment of the
|
||||
session. The timeout is specified in seconds. The default is 0 which
|
||||
means no timeout. Libiscsi 1.15.0 or greater is required for this
|
||||
|
@ -70,7 +70,7 @@ namespaces and additional features, the ``nvme-ns`` device must be used.
|
||||
|
||||
The namespaces defined by the ``nvme-ns`` device will attach to the most
|
||||
recently defined ``nvme-bus`` that is created by the ``nvme`` device. Namespace
|
||||
identifers are allocated automatically, starting from ``1``.
|
||||
identifiers are allocated automatically, starting from ``1``.
|
||||
|
||||
There are a number of parameters available:
|
||||
|
||||
|
@ -56,7 +56,7 @@ machine has more than one CPU, QEMU exposes each CPU cluster as a
|
||||
separate "inferior", where each CPU within the cluster is a separate
|
||||
"thread". Most QEMU machine types have identical CPUs, so there is a
|
||||
single cluster which has all the CPUs in it. A few machine types are
|
||||
heterogenous and have multiple clusters: for example the ``sifive_u``
|
||||
heterogeneous and have multiple clusters: for example the ``sifive_u``
|
||||
machine has a cluster with one E51 core and a second cluster with four
|
||||
U54 cores. Here the E51 is the only thread in the first inferior, and
|
||||
the U54 cores are all threads in the second inferior.
|
||||
|
@ -20,13 +20,13 @@ report the same CPUID info to guest as on host for most of SGX CPUID. With
|
||||
reporting the same CPUID guest is able to use full capacity of SGX, and KVM
|
||||
doesn't need to emulate those info.
|
||||
|
||||
The guest's EPC base and size are determined by Qemu, and KVM needs Qemu to
|
||||
The guest's EPC base and size are determined by QEMU, and KVM needs QEMU to
|
||||
notify such info to it before it can initialize SGX for guest.
|
||||
|
||||
Virtual EPC
|
||||
~~~~~~~~~~~
|
||||
|
||||
By default, Qemu does not assign EPC to a VM, i.e. fully enabling SGX in a VM
|
||||
By default, QEMU does not assign EPC to a VM, i.e. fully enabling SGX in a VM
|
||||
requires explicit allocation of EPC to the VM. Similar to other specialized
|
||||
memory types, e.g. hugetlbfs, EPC is exposed as a memory backend.
|
||||
|
||||
@ -35,12 +35,12 @@ prior to realizing the vCPUs themselves, which occurs long before generic
|
||||
devices are parsed and realized. This limitation means that EPC does not
|
||||
require -maxmem as EPC is not treated as {cold,hot}plugged memory.
|
||||
|
||||
Qemu does not artificially restrict the number of EPC sections exposed to a
|
||||
guest, e.g. Qemu will happily allow you to create 64 1M EPC sections. Be aware
|
||||
QEMU does not artificially restrict the number of EPC sections exposed to a
|
||||
guest, e.g. QEMU will happily allow you to create 64 1M EPC sections. Be aware
|
||||
that some kernels may not recognize all EPC sections, e.g. the Linux SGX driver
|
||||
is hardwired to support only 8 EPC sections.
|
||||
|
||||
The following Qemu snippet creates two EPC sections, with 64M pre-allocated
|
||||
The following QEMU snippet creates two EPC sections, with 64M pre-allocated
|
||||
to the VM and an additional 28M mapped but not allocated::
|
||||
|
||||
-object memory-backend-epc,id=mem1,size=64M,prealloc=on \
|
||||
@ -54,7 +54,7 @@ to physical EPC. Because physical EPC is protected via range registers,
|
||||
the size of the physical EPC must be a power of two (though software sees
|
||||
a subset of the full EPC, e.g. 92M or 128M) and the EPC must be naturally
|
||||
aligned. KVM SGX's virtual EPC is purely a software construct and only
|
||||
requires the size and location to be page aligned. Qemu enforces the EPC
|
||||
requires the size and location to be page aligned. QEMU enforces the EPC
|
||||
size is a multiple of 4k and will ensure the base of the EPC is 4k aligned.
|
||||
To simplify the implementation, EPC is always located above 4g in the guest
|
||||
physical address space.
|
||||
@ -62,7 +62,7 @@ physical address space.
|
||||
Migration
|
||||
~~~~~~~~~
|
||||
|
||||
Qemu/KVM doesn't prevent live migrating SGX VMs, although from hardware's
|
||||
QEMU/KVM doesn't prevent live migrating SGX VMs, although from hardware's
|
||||
perspective, SGX doesn't support live migration, since both EPC and the SGX
|
||||
key hierarchy are bound to the physical platform. However live migration
|
||||
can be supported in the sense if guest software stack can support recreating
|
||||
@ -76,7 +76,7 @@ CPUID
|
||||
~~~~~
|
||||
|
||||
Due to its myriad dependencies, SGX is currently not listed as supported
|
||||
in any of Qemu's built-in CPU configuration. To expose SGX (and SGX Launch
|
||||
in any of QEMU's built-in CPU configuration. To expose SGX (and SGX Launch
|
||||
Control) to a guest, you must either use ``-cpu host`` to pass-through the
|
||||
host CPU model, or explicitly enable SGX when using a built-in CPU model,
|
||||
e.g. via ``-cpu <model>,+sgx`` or ``-cpu <model>,+sgx,+sgxlc``.
|
||||
@ -101,7 +101,7 @@ controlled via -cpu are prefixed with "sgx", e.g.::
|
||||
sgx2
|
||||
sgxlc
|
||||
|
||||
The following Qemu snippet passes through the host CPU but restricts access to
|
||||
The following QEMU snippet passes through the host CPU but restricts access to
|
||||
the provision and EINIT token keys::
|
||||
|
||||
-cpu host,-sgx-provisionkey,-sgx-tokenkey
|
||||
@ -112,11 +112,11 @@ in hardware cannot be forced on via '-cpu'.
|
||||
Virtualize SGX Launch Control
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Qemu SGX support for Launch Control (LC) is passive, in the sense that it
|
||||
does not actively change the LC configuration. Qemu SGX provides the user
|
||||
QEMU SGX support for Launch Control (LC) is passive, in the sense that it
|
||||
does not actively change the LC configuration. QEMU SGX provides the user
|
||||
the ability to set/clear the CPUID flag (and by extension the associated
|
||||
IA32_FEATURE_CONTROL MSR bit in fw_cfg) and saves/restores the LE Hash MSRs
|
||||
when getting/putting guest state, but Qemu does not add new controls to
|
||||
when getting/putting guest state, but QEMU does not add new controls to
|
||||
directly modify the LC configuration. Similar to hardware behavior, locking
|
||||
the LC configuration to a non-Intel value is left to guest firmware. Unlike
|
||||
host bios setting for SGX launch control(LC), there is no special bios setting
|
||||
@ -126,7 +126,7 @@ creating VM with SGX.
|
||||
Feature Control
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Qemu SGX updates the ``etc/msr_feature_control`` fw_cfg entry to set the SGX
|
||||
QEMU SGX updates the ``etc/msr_feature_control`` fw_cfg entry to set the SGX
|
||||
(bit 18) and SGX LC (bit 17) flags based on their respective CPUID support,
|
||||
i.e. existing guest firmware will automatically set SGX and SGX LC accordingly,
|
||||
assuming said firmware supports fw_cfg.msr_feature_control.
|
||||
@ -141,8 +141,7 @@ To launch a SGX guest:
|
||||
|qemu_system_x86| \\
|
||||
-cpu host,+sgx-provisionkey \\
|
||||
-object memory-backend-epc,id=mem1,size=64M,prealloc=on \\
|
||||
-object memory-backend-epc,id=mem2,size=28M \\
|
||||
-M sgx-epc.0.memdev=mem1,sgx-epc.1.memdev=mem2
|
||||
-M sgx-epc.0.memdev=mem1,sgx-epc.0.node=0
|
||||
|
||||
Utilizing SGX in the guest requires a kernel/OS with SGX support.
|
||||
The support can be determined in guest by::
|
||||
@ -152,8 +151,32 @@ The support can be determined in guest by::
|
||||
and SGX epc info by::
|
||||
|
||||
$ dmesg | grep sgx
|
||||
[ 1.242142] sgx: EPC section 0x180000000-0x181bfffff
|
||||
[ 1.242319] sgx: EPC section 0x181c00000-0x1837fffff
|
||||
[ 0.182807] sgx: EPC section 0x140000000-0x143ffffff
|
||||
[ 0.183695] sgx: [Firmware Bug]: Unable to map EPC section to online node. Fallback to the NUMA node 0.
|
||||
|
||||
To launch a SGX numa guest:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
|qemu_system_x86| \\
|
||||
-cpu host,+sgx-provisionkey \\
|
||||
-object memory-backend-ram,size=2G,host-nodes=0,policy=bind,id=node0 \\
|
||||
-object memory-backend-epc,id=mem0,size=64M,prealloc=on,host-nodes=0,policy=bind \\
|
||||
-numa node,nodeid=0,cpus=0-1,memdev=node0 \\
|
||||
-object memory-backend-ram,size=2G,host-nodes=1,policy=bind,id=node1 \\
|
||||
-object memory-backend-epc,id=mem1,size=28M,prealloc=on,host-nodes=1,policy=bind \\
|
||||
-numa node,nodeid=1,cpus=2-3,memdev=node1 \\
|
||||
-M sgx-epc.0.memdev=mem0,sgx-epc.0.node=0,sgx-epc.1.memdev=mem1,sgx-epc.1.node=1
|
||||
|
||||
and SGX epc numa info by::
|
||||
|
||||
$ dmesg | grep sgx
|
||||
[ 0.369937] sgx: EPC section 0x180000000-0x183ffffff
|
||||
[ 0.370259] sgx: EPC section 0x184000000-0x185bfffff
|
||||
|
||||
$ dmesg | grep SRAT
|
||||
[ 0.009981] ACPI: SRAT: Node 0 PXM 0 [mem 0x180000000-0x183ffffff]
|
||||
[ 0.009982] ACPI: SRAT: Node 1 PXM 1 [mem 0x184000000-0x185bfffff]
|
||||
|
||||
References
|
||||
----------
|
||||
|
@ -20,7 +20,7 @@ where myimage.img is the disk image filename and mysize is its size in
|
||||
kilobytes. You can add an ``M`` suffix to give the size in megabytes and
|
||||
a ``G`` suffix for gigabytes.
|
||||
|
||||
See the qemu-img invocation documentation for more information.
|
||||
See the ``qemu-img`` invocation documentation for more information.
|
||||
|
||||
.. _disk_005fimages_005fsnapshot_005fmode:
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
PowerNV family boards (``powernv8``, ``powernv9``)
|
||||
PowerNV family boards (``powernv8``, ``powernv9``, ``powernv10``)
|
||||
==================================================================
|
||||
|
||||
PowerNV (as Non-Virtualized) is the "baremetal" platform using the
|
||||
PowerNV (as Non-Virtualized) is the "bare metal" platform using the
|
||||
OPAL firmware. It runs Linux on IBM and OpenPOWER systems and it can
|
||||
be used as an hypervisor OS, running KVM guests, or simply as a host
|
||||
OS.
|
||||
@ -16,16 +16,14 @@ Supported devices
|
||||
-----------------
|
||||
|
||||
* Multi processor support for POWER8, POWER8NVL and POWER9.
|
||||
* XSCOM, serial communication sideband bus to configure chiplets
|
||||
* Simple LPC Controller
|
||||
* Processor Service Interface (PSI) Controller
|
||||
* Interrupt Controller, XICS (POWER8) and XIVE (POWER9)
|
||||
* POWER8 PHB3 PCIe Host bridge and POWER9 PHB4 PCIe Host bridge
|
||||
* Simple OCC is an on-chip microcontroller used for power management
|
||||
tasks
|
||||
* iBT device to handle BMC communication, with the internal BMC
|
||||
simulator provided by QEMU or an external BMC such as an Aspeed
|
||||
QEMU machine.
|
||||
* XSCOM, serial communication sideband bus to configure chiplets.
|
||||
* Simple LPC Controller.
|
||||
* Processor Service Interface (PSI) Controller.
|
||||
* Interrupt Controller, XICS (POWER8) and XIVE (POWER9) and XIVE2 (Power10).
|
||||
* POWER8 PHB3 PCIe Host bridge and POWER9 PHB4 PCIe Host bridge.
|
||||
* Simple OCC is an on-chip micro-controller used for power management tasks.
|
||||
* iBT device to handle BMC communication, with the internal BMC simulator
|
||||
provided by QEMU or an external BMC such as an Aspeed QEMU machine.
|
||||
* PNOR containing the different firmware partitions.
|
||||
|
||||
Missing devices
|
||||
@ -33,31 +31,42 @@ Missing devices
|
||||
|
||||
A lot is missing, among which :
|
||||
|
||||
* POWER10 processor
|
||||
* XIVE2 (POWER10) interrupt controller
|
||||
* I2C controllers (yet to be merged)
|
||||
* NPU/NPU2/NPU3 controllers
|
||||
* EEH support for PCIe Host bridge controllers
|
||||
* NX controller
|
||||
* VAS controller
|
||||
* chipTOD (Time Of Day)
|
||||
* I2C controllers (yet to be merged).
|
||||
* NPU/NPU2/NPU3 controllers.
|
||||
* EEH support for PCIe Host bridge controllers.
|
||||
* NX controller.
|
||||
* VAS controller.
|
||||
* chipTOD (Time Of Day).
|
||||
* Self Boot Engine (SBE).
|
||||
* FSI bus
|
||||
* FSI bus.
|
||||
|
||||
Firmware
|
||||
--------
|
||||
|
||||
The OPAL firmware (OpenPower Abstraction Layer) for OpenPower systems
|
||||
includes the runtime services ``skiboot`` and the bootloader kernel and
|
||||
initramfs ``skiroot``. Source code can be found on GitHub:
|
||||
initramfs ``skiroot``. Source code can be found on the `OpenPOWER account at
|
||||
GitHub <https://github.com/open-power>`_.
|
||||
|
||||
https://github.com/open-power.
|
||||
|
||||
Prebuilt images of ``skiboot`` and ``skiroot`` are made available on the `OpenPOWER <https://github.com/open-power/op-build/releases/>`__ site.
|
||||
Prebuilt images of ``skiboot`` and ``skiroot`` are made available on the
|
||||
`OpenPOWER <https://github.com/open-power/op-build/releases/>`__ site.
|
||||
|
||||
QEMU includes a prebuilt image of ``skiboot`` which is updated when a
|
||||
more recent version is required by the models.
|
||||
|
||||
Current acceleration status
|
||||
---------------------------
|
||||
|
||||
KVM acceleration in Linux Power hosts is provided by the kvm-hv and
|
||||
kvm-pr modules. kvm-hv is adherent to PAPR and it's not compliant with
|
||||
powernv. kvm-pr in theory could be used as a valid accel option but
|
||||
this isn't supported by kvm-pr at this moment.
|
||||
|
||||
To spare users from dealing with not so informative errors when attempting
|
||||
to use accel=kvm, the powernv machine will throw an error informing that
|
||||
KVM is not supported. This can be revisited in the future if kvm-pr (or
|
||||
any other KVM alternative) is usable as KVM accel for this machine.
|
||||
|
||||
Boot options
|
||||
------------
|
||||
|
||||
@ -83,6 +92,7 @@ and a SATA disk :
|
||||
|
||||
Complex PCIe configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Six PHBs are defined per chip (POWER9) but no default PCI layout is
|
||||
provided (to be compatible with libvirt). One PCI device can be added
|
||||
on any of the available PCIe slots using command line options such as:
|
||||
@ -157,7 +167,7 @@ one on the command line :
|
||||
The files `palmetto-SDR.bin <http://www.kaod.org/qemu/powernv/palmetto-SDR.bin>`__
|
||||
and `palmetto-FRU.bin <http://www.kaod.org/qemu/powernv/palmetto-FRU.bin>`__
|
||||
define a Sensor Data Record repository and a Field Replaceable Unit
|
||||
inventory for a palmetto BMC. They can be used to extend the QEMU BMC
|
||||
inventory for a Palmetto BMC. They can be used to extend the QEMU BMC
|
||||
simulator.
|
||||
|
||||
.. code-block:: bash
|
||||
@ -189,4 +199,8 @@ CAVEATS
|
||||
-------
|
||||
|
||||
* No support for multiple HW threads (SMT=1). Same as pseries.
|
||||
* CPU can hang when doing intensive I/Os. Use ``-append powersave=off`` in that case.
|
||||
|
||||
Maintainer contact information
|
||||
------------------------------
|
||||
|
||||
Cédric Le Goater <clg@kaod.org>
|
||||
|
@ -75,7 +75,7 @@ as the BIOS. QEMU follows below truth table to select which payload to execute:
|
||||
When both -bios and -kernel are present, QEMU loads U-Boot and U-Boot in turns
|
||||
automatically loads the kernel image specified by the -kernel parameter via
|
||||
U-Boot's built-in "bootm" command, hence a legacy uImage format is required in
|
||||
such senario.
|
||||
such scenario.
|
||||
|
||||
Running Linux kernel
|
||||
--------------------
|
||||
|
@ -1,12 +1,238 @@
|
||||
pSeries family boards (``pseries``)
|
||||
===================================
|
||||
|
||||
The Power machine para-virtualized environment described by the `Linux on Power
|
||||
Architecture Reference document (LoPAR)
|
||||
<https://openpowerfoundation.org/wp-content/uploads/2020/07/LoPAR-20200812.pdf>`_
|
||||
is called pSeries. This environment is also known as sPAPR, System p guests, or
|
||||
simply Power Linux guests (although it is capable of running other operating
|
||||
systems, such as AIX).
|
||||
|
||||
Even though pSeries is designed to behave as a guest environment, it is also
|
||||
capable of acting as a hypervisor OS, providing, on that role, nested
|
||||
virtualization capabilities.
|
||||
|
||||
Supported devices
|
||||
-----------------
|
||||
|
||||
* Multi processor support for many Power processors generations: POWER7,
|
||||
POWER7+, POWER8, POWER8NVL, POWER9, and Power10. Support for POWER5+ exists,
|
||||
but its state is unknown.
|
||||
* Interrupt Controller, XICS (POWER8) and XIVE (POWER9 and Power10)
|
||||
* vPHB PCIe Host bridge.
|
||||
* vscsi and vnet devices, compatible with the same devices available on a
|
||||
PowerVM hypervisor with VIOS managing LPARs.
|
||||
* Virtio based devices.
|
||||
* PCIe device pass through.
|
||||
|
||||
Missing devices
|
||||
---------------
|
||||
|
||||
* SPICE support.
|
||||
|
||||
Firmware
|
||||
--------
|
||||
|
||||
`SLOF <https://github.com/aik/SLOF>`_ (Slimline Open Firmware) is an
|
||||
implementation of the `IEEE 1275-1994, Standard for Boot (Initialization
|
||||
Configuration) Firmware: Core Requirements and Practices
|
||||
<https://standards.ieee.org/standard/1275-1994.html>`_.
|
||||
|
||||
QEMU includes a prebuilt image of SLOF which is updated when a more recent
|
||||
version is required.
|
||||
|
||||
Build directions
|
||||
----------------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./configure --target-list=ppc64-softmmu && make
|
||||
|
||||
Running instructions
|
||||
--------------------
|
||||
|
||||
Someone can select the pSeries machine type by running QEMU with the following
|
||||
options:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
qemu-system-ppc64 -M pseries <other QEMU arguments>
|
||||
|
||||
sPAPR devices
|
||||
-------------
|
||||
|
||||
The sPAPR specification defines a set of para-virtualized devices, which are
|
||||
also supported by the pSeries machine in QEMU and can be instantiated with the
|
||||
``-device`` option:
|
||||
|
||||
* ``spapr-vlan`` : a virtual network interface.
|
||||
* ``spapr-vscsi`` : a virtual SCSI disk interface.
|
||||
* ``spapr-rng`` : a pseudo-device for passing random number generator data to the
|
||||
guest (see the `H_RANDOM hypercall feature
|
||||
<https://wiki.qemu.org/Features/HRandomHypercall>`_ for details).
|
||||
* ``spapr-vty``: a virtual teletype.
|
||||
* ``spapr-pci-host-bridge``: a PCI host bridge.
|
||||
* ``tpm-spapr``: a Trusted Platform Module (TPM).
|
||||
* ``spapr-tpm-proxy``: a TPM proxy.
|
||||
|
||||
These are compatible with the devices historically available for use when
|
||||
running the IBM PowerVM hypervisor with LPARs.
|
||||
|
||||
However, since these devices have originally been specified with another
|
||||
hypervisor and non-Linux guests in mind, you should use the virtio counterparts
|
||||
(virtio-net, virtio-blk/scsi and virtio-rng for instance) if possible instead,
|
||||
since they will most probably give you better performance with Linux guests in a
|
||||
QEMU environment.
|
||||
|
||||
The pSeries machine in QEMU is always instantiated with the following devices:
|
||||
|
||||
* A NVRAM device (``spapr-nvram``).
|
||||
* A virtual teletype (``spapr-vty``).
|
||||
* A PCI host bridge (``spapr-pci-host-bridge``).
|
||||
|
||||
Hence, it is not needed to add them manually, unless you use the ``-nodefaults``
|
||||
command line option in QEMU.
|
||||
|
||||
In the case of the default ``spapr-nvram`` device, if someone wants to make the
|
||||
contents of the NVRAM device persistent, they will need to specify a PFLASH
|
||||
device when starting QEMU, i.e. either use
|
||||
``-drive if=pflash,file=<filename>,format=raw`` to set the default PFLASH
|
||||
device, or specify one with an ID
|
||||
(``-drive if=none,file=<filename>,format=raw,id=pfid``) and pass that ID to the
|
||||
NVRAM device with ``-global spapr-nvram.drive=pfid``.
|
||||
|
||||
sPAPR specification
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The main source of documentation on the sPAPR standard is the `Linux on Power
|
||||
Architecture Reference document (LoPAR)
|
||||
<https://openpowerfoundation.org/wp-content/uploads/2020/07/LoPAR-20200812.pdf>`_.
|
||||
However, documentation specific to QEMU's implementation of the specification
|
||||
can also be found in QEMU documentation:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
../../specs/ppc-spapr-hcalls.rst
|
||||
../../specs/ppc-spapr-numa.rst
|
||||
../../specs/ppc-spapr-xive.rst
|
||||
|
||||
Other documentation available in QEMU docs directory:
|
||||
|
||||
* Hot plug (``/docs/specs/ppc-spapr-hotplug.txt``).
|
||||
* Hypervisor calls needed by the Ultravisor
|
||||
(``/docs/specs/ppc-spapr-uv-hcalls.txt``).
|
||||
|
||||
Switching between the KVM-PR and KVM-HV kernel module
|
||||
-----------------------------------------------------
|
||||
|
||||
Currently, there are two implementations of KVM on Power, ``kvm_hv.ko`` and
|
||||
``kvm_pr.ko``.
|
||||
|
||||
|
||||
If a host supports both KVM modes, and both KVM kernel modules are loaded, it is
|
||||
possible to switch between the two modes with the ``kvm-type`` parameter:
|
||||
|
||||
* Use ``qemu-system-ppc64 -M pseries,accel=kvm,kvm-type=PR`` to use the
|
||||
``kvm_pr.ko`` kernel module.
|
||||
* Use ``qemu-system-ppc64 -M pseries,accel=kvm,kvm-type=HV`` to use ``kvm_hv.ko``
|
||||
instead.
|
||||
|
||||
KVM-PR
|
||||
^^^^^^
|
||||
|
||||
KVM-PR uses the so-called **PR**\ oblem state of the PPC CPUs to run the guests,
|
||||
i.e. the virtual machine is run in user mode and all privileged instructions
|
||||
trap and have to be emulated by the host. That means you can run KVM-PR inside
|
||||
a pSeries guest (or a PowerVM LPAR for that matter), and that is where it has
|
||||
originated, as historically (prior to POWER7) it was not possible to run Linux
|
||||
on hypervisor mode on a Power processor (this function was restricted to
|
||||
PowerVM, the IBM proprietary hypervisor).
|
||||
|
||||
Because all privileged instructions are trapped, guests that use a lot of
|
||||
privileged instructions run quite slow with KVM-PR. On the other hand, because
|
||||
of that, this kernel module can run on pretty much every PPC hardware, and is
|
||||
able to emulate a lot of guests CPUs. This module can even be used to run other
|
||||
PowerPC guests like an emulated PowerMac.
|
||||
|
||||
As KVM-PR can be run inside a pSeries guest, it can also provide nested
|
||||
virtualization capabilities (i.e. running a guest from within a guest).
|
||||
|
||||
It is important to notice that, as KVM-HV provides a much better execution
|
||||
performance, maintenance work has been much more focused on it in the past
|
||||
years. Maintenance for KVM-PR has been minimal.
|
||||
|
||||
In order to run KVM-PR guests with POWER9 processors, someone will need to start
|
||||
QEMU with ``kernel_irqchip=off`` command line option.
|
||||
|
||||
KVM-HV
|
||||
^^^^^^
|
||||
|
||||
KVM-HV uses the hypervisor mode of more recent Power processors, that allow
|
||||
access to the bare metal hardware directly. Although POWER7 had this capability,
|
||||
it was only starting with POWER8 that this was officially supported by IBM.
|
||||
|
||||
Originally, KVM-HV was only available when running on a PowerNV platform (a.k.a.
|
||||
Power bare metal). Although it runs on a PowerNV platform, it can only be used
|
||||
to start pSeries guests. As the pSeries guest doesn't have access to the
|
||||
hypervisor mode of the Power CPU, it wasn't possible to run KVM-HV on a guest.
|
||||
This limitation has been lifted, and now it is possible to run KVM-HV inside
|
||||
pSeries guests as well, making nested virtualization possible with KVM-HV.
|
||||
|
||||
As KVM-HV has access to privileged instructions, guests that use a lot of these
|
||||
can run much faster than with KVM-PR. On the other hand, the guest CPU has to be
|
||||
of the same type as the host CPU this way, e.g. it is not possible to specify an
|
||||
embedded PPC CPU for the guest with KVM-HV. However, there is at least the
|
||||
possibility to run the guest in a backward-compatibility mode of the previous
|
||||
CPUs generations, e.g. you can run a POWER7 guest on a POWER8 host by using
|
||||
``-cpu POWER8,compat=power7`` as parameter to QEMU.
|
||||
|
||||
Modules support
|
||||
---------------
|
||||
|
||||
As noticed in the sections above, each module can run in a different
|
||||
environment. The following table shows with which environment each module can
|
||||
run. As long as you are in a supported environment, you can run KVM-PR or KVM-HV
|
||||
nested. Combinations not shown in the table are not available.
|
||||
|
||||
+--------------+------------+------+-------------------+----------+--------+
|
||||
| Platform | Host type | Bits | Page table format | KVM-HV | KVM-PR |
|
||||
+==============+============+======+===================+==========+========+
|
||||
| PowerNV | bare metal | 32 | hash | no | yes |
|
||||
| | | +-------------------+----------+--------+
|
||||
| | | | radix | N/A | N/A |
|
||||
| | +------+-------------------+----------+--------+
|
||||
| | | 64 | hash | yes | yes |
|
||||
| | | +-------------------+----------+--------+
|
||||
| | | | radix | yes | no |
|
||||
+--------------+------------+------+-------------------+----------+--------+
|
||||
| pSeries [1]_ | PowerNV | 32 | hash | no | yes |
|
||||
| | | +-------------------+----------+--------+
|
||||
| | | | radix | N/A | N/A |
|
||||
| | +------+-------------------+----------+--------+
|
||||
| | | 64 | hash | no | yes |
|
||||
| | | +-------------------+----------+--------+
|
||||
| | | | radix | yes [2]_ | no |
|
||||
| +------------+------+-------------------+----------+--------+
|
||||
| | PowerVM | 32 | hash | no | yes |
|
||||
| | | +-------------------+----------+--------+
|
||||
| | | | radix | N/A | N/A |
|
||||
| | +------+-------------------+----------+--------+
|
||||
| | | 64 | hash | no | yes |
|
||||
| | | +-------------------+----------+--------+
|
||||
| | | | radix [3]_ | no | yes |
|
||||
+--------------+------------+------+-------------------+----------+--------+
|
||||
|
||||
.. [1] On POWER9 DD2.1 processors, the page table format on the host and guest
|
||||
must be the same.
|
||||
|
||||
.. [2] KVM-HV cannot run nested on POWER8 machines.
|
||||
|
||||
.. [3] Introduced on Power10 machines.
|
||||
|
||||
Maintainer contact information
|
||||
------------------------------
|
||||
|
||||
Cédric Le Goater <clg@kaod.org>
|
||||
|
||||
Daniel Henrique Barboza <danielhb413@gmail.com>
|
||||
|
@ -511,13 +511,13 @@ of an inet socket:
|
||||
|
||||
|qemu_system| linux.img -hdb nbd+unix://?socket=/tmp/my_socket
|
||||
|
||||
In this case, the block device must be exported using qemu-nbd:
|
||||
In this case, the block device must be exported using ``qemu-nbd``:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
|
||||
|
||||
The use of qemu-nbd allows sharing of a disk between several guests:
|
||||
The use of ``qemu-nbd`` allows sharing of a disk between several guests:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@ -530,7 +530,7 @@ and then you can use it with two guests:
|
||||
|qemu_system| linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
|
||||
|qemu_system| linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
|
||||
|
||||
If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
|
||||
If the ``nbd-server`` uses named exports (supported since NBD 2.9.18, or with QEMU's
|
||||
own embedded NBD server), you must specify an export name in the URI:
|
||||
|
||||
.. parsed-literal::
|
||||
|
@ -45,7 +45,7 @@ Shakti SDK can be used to generate the baremetal example UART applications.
|
||||
Binary would be generated in:
|
||||
software/examples/uart_applns/loopback/output/loopback.shakti
|
||||
|
||||
You could also download the precompiled example applicatons using below
|
||||
You could also download the precompiled example applications using below
|
||||
commands.
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -311,7 +311,7 @@ containing one or more usernames and random keys::
|
||||
mkdir -m 0700 /tmp/keys
|
||||
psktool -u rich -p /tmp/keys/keys.psk
|
||||
|
||||
TLS-enabled servers such as qemu-nbd can use this directory like so::
|
||||
TLS-enabled servers such as ``qemu-nbd`` can use this directory like so::
|
||||
|
||||
qemu-nbd \
|
||||
-t -x / \
|
||||
|
@ -273,11 +273,9 @@ A group can be created using the object-add QMP function:
|
||||
"arguments": {
|
||||
"qom-type": "throttle-group",
|
||||
"id": "group0",
|
||||
"props": {
|
||||
"limits" : {
|
||||
"iops-total": 1000
|
||||
"bps-write": 2097152
|
||||
}
|
||||
"limits" : {
|
||||
"iops-total": 1000,
|
||||
"bps-write": 2097152
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,9 +127,9 @@ by the used format or see the format descriptions below for details.
|
||||
.. option:: -S SIZE
|
||||
|
||||
Indicates the consecutive number of bytes that must contain only zeros
|
||||
for qemu-img to create a sparse image during conversion. This value is rounded
|
||||
down to the nearest 512 bytes. You may use the common size suffixes like
|
||||
``k`` for kilobytes.
|
||||
for ``qemu-img`` to create a sparse image during conversion. This value is
|
||||
rounded down to the nearest 512 bytes. You may use the common size suffixes
|
||||
like ``k`` for kilobytes.
|
||||
|
||||
.. option:: -t CACHE
|
||||
|
||||
@ -431,7 +431,7 @@ Command description:
|
||||
suppressed from the destination image.
|
||||
|
||||
*SPARSE_SIZE* indicates the consecutive number of bytes (defaults to 4k)
|
||||
that must contain only zeros for qemu-img to create a sparse image during
|
||||
that must contain only zeros for ``qemu-img`` to create a sparse image during
|
||||
conversion. If *SPARSE_SIZE* is 0, the source will not be scanned for
|
||||
unallocated or zero sectors, and the destination image will always be
|
||||
fully allocated.
|
||||
@ -447,7 +447,7 @@ Command description:
|
||||
If the ``-n`` option is specified, the target volume creation will be
|
||||
skipped. This is useful for formats such as ``rbd`` if the target
|
||||
volume has already been created with site specific options that cannot
|
||||
be supplied through qemu-img.
|
||||
be supplied through ``qemu-img``.
|
||||
|
||||
Out of order writes can be enabled with ``-W`` to improve performance.
|
||||
This is only recommended for preallocated devices like host devices or other
|
||||
@ -472,7 +472,7 @@ Command description:
|
||||
If the option *BACKING_FILE* is specified, then the image will record
|
||||
only the differences from *BACKING_FILE*. No size needs to be specified in
|
||||
this case. *BACKING_FILE* will never be modified unless you use the
|
||||
``commit`` monitor command (or qemu-img commit).
|
||||
``commit`` monitor command (or ``qemu-img commit``).
|
||||
|
||||
If a relative path name is given, the backing file is looked up relative to
|
||||
the directory containing *FILENAME*.
|
||||
@ -684,7 +684,7 @@ Command description:
|
||||
|
||||
Safe mode
|
||||
This is the default mode and performs a real rebase operation. The
|
||||
new backing file may differ from the old one and qemu-img rebase
|
||||
new backing file may differ from the old one and ``qemu-img rebase``
|
||||
will take care of keeping the guest-visible content of *FILENAME*
|
||||
unchanged.
|
||||
|
||||
@ -697,7 +697,7 @@ Command description:
|
||||
exists.
|
||||
|
||||
Unsafe mode
|
||||
qemu-img uses the unsafe mode if ``-u`` is specified. In this
|
||||
``qemu-img`` uses the unsafe mode if ``-u`` is specified. In this
|
||||
mode, only the backing file name and format of *FILENAME* is changed
|
||||
without any checks on the file contents. The user must take care of
|
||||
specifying the correct new backing file, or the guest-visible
|
||||
@ -735,7 +735,7 @@ Command description:
|
||||
sizes accordingly. Failure to do so will result in data loss!
|
||||
|
||||
When shrinking images, the ``--shrink`` option must be given. This informs
|
||||
qemu-img that the user acknowledges all loss of data beyond the truncated
|
||||
``qemu-img`` that the user acknowledges all loss of data beyond the truncated
|
||||
image's end.
|
||||
|
||||
After using this command to grow a disk image, you must use file system and
|
||||
|
@ -31,14 +31,14 @@ driver options if ``--image-opts`` is specified.
|
||||
|
||||
*dev* is an NBD device.
|
||||
|
||||
.. option:: --object type,id=ID,...props...
|
||||
.. option:: --object type,id=ID,...
|
||||
|
||||
Define a new instance of the *type* object class identified by *ID*.
|
||||
See the :manpage:`qemu(1)` manual page for full details of the properties
|
||||
supported. The common object types that it makes sense to define are the
|
||||
``secret`` object, which is used to supply passwords and/or encryption
|
||||
keys, and the ``tls-creds`` object, which is used to supply TLS
|
||||
credentials for the qemu-nbd server or client.
|
||||
credentials for the ``qemu-nbd`` server or client.
|
||||
|
||||
.. option:: -p, --port=PORT
|
||||
|
||||
@ -238,7 +238,7 @@ daemon:
|
||||
Expose the guest-visible contents of a qcow2 file via a block device
|
||||
/dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for
|
||||
partitions found within), then disconnect the device when done.
|
||||
Access to bind qemu-nbd to an /dev/nbd device generally requires root
|
||||
Access to bind ``qemu-nbd`` to a /dev/nbd device generally requires root
|
||||
privileges, and may also require the execution of ``modprobe nbd``
|
||||
to enable the kernel NBD client module. *CAUTION*: Do not use
|
||||
this method to mount filesystems from an untrusted guest image - a
|
||||
|
@ -10,9 +10,10 @@ Synopsis
|
||||
Description
|
||||
-----------
|
||||
|
||||
qemu-storage-daemon provides disk image functionality from QEMU, qemu-img, and
|
||||
qemu-nbd in a long-running process controlled via QMP commands without running
|
||||
a virtual machine. It can export disk images, run block job operations, and
|
||||
``qemu-storage-daemon`` provides disk image functionality from QEMU,
|
||||
``qemu-img``, and ``qemu-nbd`` in a long-running process controlled via QMP
|
||||
commands without running a virtual machine.
|
||||
It can export disk images, run block job operations, and
|
||||
perform other disk-related operations. The daemon is controlled via a QMP
|
||||
monitor and initial configuration from the command-line.
|
||||
|
||||
|
@ -136,8 +136,8 @@ Extended attribute (xattr) mapping
|
||||
By default the name of xattr's used by the client are passed through to the server
|
||||
file system. This can be a problem where either those xattr names are used
|
||||
by something on the server (e.g. selinux client/server confusion) or if the
|
||||
virtiofsd is running in a container with restricted privileges where it cannot
|
||||
access some attributes.
|
||||
``virtiofsd`` is running in a container with restricted privileges where it
|
||||
cannot access some attributes.
|
||||
|
||||
Mapping syntax
|
||||
~~~~~~~~~~~~~~
|
||||
|
@ -21,7 +21,7 @@ The second factor is materialized by a device implementing the U2F
|
||||
protocol. In case of a USB U2F security key, it is a USB HID device
|
||||
that implements the U2F protocol.
|
||||
|
||||
In Qemu, the USB U2F key device offers a dedicated support of U2F, allowing
|
||||
In QEMU, the USB U2F key device offers a dedicated support of U2F, allowing
|
||||
guest USB FIDO/U2F security keys operating in two possible modes:
|
||||
pass-through and emulated.
|
||||
|
||||
|
10
dump/dump.c
10
dump/dump.c
@ -1293,14 +1293,6 @@ static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if the page is all 0
|
||||
*/
|
||||
static inline bool is_zero_page(const uint8_t *buf, size_t page_size)
|
||||
{
|
||||
return buffer_is_zero(buf, page_size);
|
||||
}
|
||||
|
||||
static void write_dump_pages(DumpState *s, Error **errp)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -1357,7 +1349,7 @@ static void write_dump_pages(DumpState *s, Error **errp)
|
||||
*/
|
||||
while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
|
||||
/* check zero page */
|
||||
if (is_zero_page(buf, s->dump_info.page_size)) {
|
||||
if (buffer_is_zero(buf, s->dump_info.page_size)) {
|
||||
ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
|
||||
false);
|
||||
if (ret < 0) {
|
||||
|
@ -19,7 +19,7 @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
|
||||
{
|
||||
switch (a->cls) {
|
||||
case float_class_snan:
|
||||
float_raise(float_flag_invalid, s);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
|
||||
if (s->default_nan_mode) {
|
||||
parts_default_nan(a, s);
|
||||
} else {
|
||||
@ -40,7 +40,7 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
|
||||
float_status *s)
|
||||
{
|
||||
if (is_snan(a->cls) || is_snan(b->cls)) {
|
||||
float_raise(float_flag_invalid, s);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
|
||||
}
|
||||
|
||||
if (s->default_nan_mode) {
|
||||
@ -68,7 +68,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
|
||||
int which;
|
||||
|
||||
if (unlikely(abc_mask & float_cmask_snan)) {
|
||||
float_raise(float_flag_invalid, s);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
|
||||
}
|
||||
|
||||
which = pickNaNMulAdd(a->cls, b->cls, c->cls,
|
||||
@ -354,7 +354,7 @@ static FloatPartsN *partsN(addsub)(FloatPartsN *a, FloatPartsN *b,
|
||||
return a;
|
||||
}
|
||||
/* Inf - Inf */
|
||||
float_raise(float_flag_invalid, s);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_isi, s);
|
||||
parts_default_nan(a, s);
|
||||
return a;
|
||||
}
|
||||
@ -423,7 +423,7 @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
|
||||
|
||||
/* Inf * Zero == NaN */
|
||||
if (unlikely(ab_mask == float_cmask_infzero)) {
|
||||
float_raise(float_flag_invalid, s);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
|
||||
parts_default_nan(a, s);
|
||||
return a;
|
||||
}
|
||||
@ -489,11 +489,13 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
|
||||
|
||||
if (unlikely(ab_mask != float_cmask_normal)) {
|
||||
if (unlikely(ab_mask == float_cmask_infzero)) {
|
||||
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
|
||||
goto d_nan;
|
||||
}
|
||||
|
||||
if (ab_mask & float_cmask_inf) {
|
||||
if (c->cls == float_class_inf && a->sign != c->sign) {
|
||||
float_raise(float_flag_invalid | float_flag_invalid_isi, s);
|
||||
goto d_nan;
|
||||
}
|
||||
goto return_inf;
|
||||
@ -566,7 +568,6 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
|
||||
goto finish_sign;
|
||||
|
||||
d_nan:
|
||||
float_raise(float_flag_invalid, s);
|
||||
parts_default_nan(a, s);
|
||||
return a;
|
||||
}
|
||||
@ -589,11 +590,13 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b,
|
||||
}
|
||||
|
||||
/* 0/0 or Inf/Inf => NaN */
|
||||
if (unlikely(ab_mask == float_cmask_zero) ||
|
||||
unlikely(ab_mask == float_cmask_inf)) {
|
||||
float_raise(float_flag_invalid, s);
|
||||
parts_default_nan(a, s);
|
||||
return a;
|
||||
if (unlikely(ab_mask == float_cmask_zero)) {
|
||||
float_raise(float_flag_invalid | float_flag_invalid_zdz, s);
|
||||
goto d_nan;
|
||||
}
|
||||
if (unlikely(ab_mask == float_cmask_inf)) {
|
||||
float_raise(float_flag_invalid | float_flag_invalid_idi, s);
|
||||
goto d_nan;
|
||||
}
|
||||
|
||||
/* All the NaN cases */
|
||||
@ -624,6 +627,10 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b,
|
||||
float_raise(float_flag_divbyzero, s);
|
||||
a->cls = float_class_inf;
|
||||
return a;
|
||||
|
||||
d_nan:
|
||||
parts_default_nan(a, s);
|
||||
return a;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -862,7 +869,7 @@ static void partsN(sqrt)(FloatPartsN *a, float_status *status,
|
||||
return;
|
||||
|
||||
d_nan:
|
||||
float_raise(float_flag_invalid, status);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_sqrt, status);
|
||||
parts_default_nan(a, status);
|
||||
}
|
||||
|
||||
@ -1042,13 +1049,15 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,
|
||||
|
||||
switch (p->cls) {
|
||||
case float_class_snan:
|
||||
flags |= float_flag_invalid_snan;
|
||||
/* fall through */
|
||||
case float_class_qnan:
|
||||
flags = float_flag_invalid;
|
||||
flags |= float_flag_invalid;
|
||||
r = max;
|
||||
break;
|
||||
|
||||
case float_class_inf:
|
||||
flags = float_flag_invalid;
|
||||
flags = float_flag_invalid | float_flag_invalid_cvti;
|
||||
r = p->sign ? min : max;
|
||||
break;
|
||||
|
||||
@ -1070,11 +1079,11 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,
|
||||
if (r <= -(uint64_t)min) {
|
||||
r = -r;
|
||||
} else {
|
||||
flags = float_flag_invalid;
|
||||
flags = float_flag_invalid | float_flag_invalid_cvti;
|
||||
r = min;
|
||||
}
|
||||
} else if (r > max) {
|
||||
flags = float_flag_invalid;
|
||||
flags = float_flag_invalid | float_flag_invalid_cvti;
|
||||
r = max;
|
||||
}
|
||||
break;
|
||||
@ -1107,13 +1116,15 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
|
||||
|
||||
switch (p->cls) {
|
||||
case float_class_snan:
|
||||
flags |= float_flag_invalid_snan;
|
||||
/* fall through */
|
||||
case float_class_qnan:
|
||||
flags = float_flag_invalid;
|
||||
flags |= float_flag_invalid;
|
||||
r = max;
|
||||
break;
|
||||
|
||||
case float_class_inf:
|
||||
flags = float_flag_invalid;
|
||||
flags = float_flag_invalid | float_flag_invalid_cvti;
|
||||
r = p->sign ? 0 : max;
|
||||
break;
|
||||
|
||||
@ -1131,15 +1142,15 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
|
||||
}
|
||||
|
||||
if (p->sign) {
|
||||
flags = float_flag_invalid;
|
||||
flags = float_flag_invalid | float_flag_invalid_cvti;
|
||||
r = 0;
|
||||
} else if (p->exp > DECOMPOSED_BINARY_POINT) {
|
||||
flags = float_flag_invalid;
|
||||
flags = float_flag_invalid | float_flag_invalid_cvti;
|
||||
r = max;
|
||||
} else {
|
||||
r = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
|
||||
if (r > max) {
|
||||
flags = float_flag_invalid;
|
||||
flags = float_flag_invalid | float_flag_invalid_cvti;
|
||||
r = max;
|
||||
}
|
||||
}
|
||||
@ -1334,7 +1345,9 @@ static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b,
|
||||
}
|
||||
|
||||
if (unlikely(ab_mask & float_cmask_anynan)) {
|
||||
if (!is_quiet || (ab_mask & float_cmask_snan)) {
|
||||
if (ab_mask & float_cmask_snan) {
|
||||
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
|
||||
} else if (!is_quiet) {
|
||||
float_raise(float_flag_invalid, s);
|
||||
}
|
||||
return float_relation_unordered;
|
||||
|
@ -506,7 +506,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
|
||||
* the default NaN
|
||||
*/
|
||||
if (infzero && is_qnan(c_cls)) {
|
||||
float_raise(float_flag_invalid, status);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_imz, status);
|
||||
return 3;
|
||||
}
|
||||
|
||||
@ -533,7 +533,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
|
||||
* case sets InvalidOp and returns the default NaN
|
||||
*/
|
||||
if (infzero) {
|
||||
float_raise(float_flag_invalid, status);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_imz, status);
|
||||
return 3;
|
||||
}
|
||||
/* Prefer sNaN over qNaN, in the a, b, c order. */
|
||||
@ -556,7 +556,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
|
||||
* case sets InvalidOp and returns the input value 'c'
|
||||
*/
|
||||
if (infzero) {
|
||||
float_raise(float_flag_invalid, status);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_imz, status);
|
||||
return 2;
|
||||
}
|
||||
/* Prefer sNaN over qNaN, in the c, a, b order. */
|
||||
@ -580,7 +580,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
|
||||
* a default NaN
|
||||
*/
|
||||
if (infzero) {
|
||||
float_raise(float_flag_invalid, status);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_imz, status);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -597,7 +597,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
|
||||
#elif defined(TARGET_RISCV)
|
||||
/* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
|
||||
if (infzero) {
|
||||
float_raise(float_flag_invalid, status);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_imz, status);
|
||||
}
|
||||
return 3; /* default NaN */
|
||||
#elif defined(TARGET_XTENSA)
|
||||
@ -606,7 +606,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
|
||||
* an input NaN if we have one (ie c).
|
||||
*/
|
||||
if (infzero) {
|
||||
float_raise(float_flag_invalid, status);
|
||||
float_raise(float_flag_invalid | float_flag_invalid_imz, status);
|
||||
return 2;
|
||||
}
|
||||
if (status->use_first_nan) {
|
||||
|
114
fpu/softfloat.c
114
fpu/softfloat.c
@ -1693,6 +1693,50 @@ static float64 float64_round_pack_canonical(FloatParts64 *p,
|
||||
return float64_pack_raw(p);
|
||||
}
|
||||
|
||||
static float64 float64r32_round_pack_canonical(FloatParts64 *p,
|
||||
float_status *s)
|
||||
{
|
||||
parts_uncanon(p, s, &float32_params);
|
||||
|
||||
/*
|
||||
* In parts_uncanon, we placed the fraction for float32 at the lsb.
|
||||
* We need to adjust the fraction higher so that the least N bits are
|
||||
* zero, and the fraction is adjacent to the float64 implicit bit.
|
||||
*/
|
||||
switch (p->cls) {
|
||||
case float_class_normal:
|
||||
if (unlikely(p->exp == 0)) {
|
||||
/*
|
||||
* The result is denormal for float32, but can be represented
|
||||
* in normalized form for float64. Adjust, per canonicalize.
|
||||
*/
|
||||
int shift = frac_normalize(p);
|
||||
p->exp = (float32_params.frac_shift -
|
||||
float32_params.exp_bias - shift + 1 +
|
||||
float64_params.exp_bias);
|
||||
frac_shr(p, float64_params.frac_shift);
|
||||
} else {
|
||||
frac_shl(p, float32_params.frac_shift - float64_params.frac_shift);
|
||||
p->exp += float64_params.exp_bias - float32_params.exp_bias;
|
||||
}
|
||||
break;
|
||||
case float_class_snan:
|
||||
case float_class_qnan:
|
||||
frac_shl(p, float32_params.frac_shift - float64_params.frac_shift);
|
||||
p->exp = float64_params.exp_max;
|
||||
break;
|
||||
case float_class_inf:
|
||||
p->exp = float64_params.exp_max;
|
||||
break;
|
||||
case float_class_zero:
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
return float64_pack_raw(p);
|
||||
}
|
||||
|
||||
static void float128_unpack_canonical(FloatParts128 *p, float128 f,
|
||||
float_status *s)
|
||||
{
|
||||
@ -1938,6 +1982,28 @@ float64_sub(float64 a, float64 b, float_status *s)
|
||||
return float64_addsub(a, b, s, hard_f64_sub, soft_f64_sub);
|
||||
}
|
||||
|
||||
static float64 float64r32_addsub(float64 a, float64 b, float_status *status,
|
||||
bool subtract)
|
||||
{
|
||||
FloatParts64 pa, pb, *pr;
|
||||
|
||||
float64_unpack_canonical(&pa, a, status);
|
||||
float64_unpack_canonical(&pb, b, status);
|
||||
pr = parts_addsub(&pa, &pb, status, subtract);
|
||||
|
||||
return float64r32_round_pack_canonical(pr, status);
|
||||
}
|
||||
|
||||
float64 float64r32_add(float64 a, float64 b, float_status *status)
|
||||
{
|
||||
return float64r32_addsub(a, b, status, false);
|
||||
}
|
||||
|
||||
float64 float64r32_sub(float64 a, float64 b, float_status *status)
|
||||
{
|
||||
return float64r32_addsub(a, b, status, true);
|
||||
}
|
||||
|
||||
static bfloat16 QEMU_FLATTEN
|
||||
bfloat16_addsub(bfloat16 a, bfloat16 b, float_status *status, bool subtract)
|
||||
{
|
||||
@ -2069,6 +2135,17 @@ float64_mul(float64 a, float64 b, float_status *s)
|
||||
f64_is_zon2, f64_addsubmul_post);
|
||||
}
|
||||
|
||||
float64 float64r32_mul(float64 a, float64 b, float_status *status)
|
||||
{
|
||||
FloatParts64 pa, pb, *pr;
|
||||
|
||||
float64_unpack_canonical(&pa, a, status);
|
||||
float64_unpack_canonical(&pb, b, status);
|
||||
pr = parts_mul(&pa, &pb, status);
|
||||
|
||||
return float64r32_round_pack_canonical(pr, status);
|
||||
}
|
||||
|
||||
bfloat16 QEMU_FLATTEN
|
||||
bfloat16_mul(bfloat16 a, bfloat16 b, float_status *status)
|
||||
{
|
||||
@ -2296,6 +2373,19 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
|
||||
return soft_f64_muladd(ua.s, ub.s, uc.s, flags, s);
|
||||
}
|
||||
|
||||
float64 float64r32_muladd(float64 a, float64 b, float64 c,
|
||||
int flags, float_status *status)
|
||||
{
|
||||
FloatParts64 pa, pb, pc, *pr;
|
||||
|
||||
float64_unpack_canonical(&pa, a, status);
|
||||
float64_unpack_canonical(&pb, b, status);
|
||||
float64_unpack_canonical(&pc, c, status);
|
||||
pr = parts_muladd(&pa, &pb, &pc, flags, status);
|
||||
|
||||
return float64r32_round_pack_canonical(pr, status);
|
||||
}
|
||||
|
||||
bfloat16 QEMU_FLATTEN bfloat16_muladd(bfloat16 a, bfloat16 b, bfloat16 c,
|
||||
int flags, float_status *status)
|
||||
{
|
||||
@ -2419,6 +2509,17 @@ float64_div(float64 a, float64 b, float_status *s)
|
||||
f64_div_pre, f64_div_post);
|
||||
}
|
||||
|
||||
float64 float64r32_div(float64 a, float64 b, float_status *status)
|
||||
{
|
||||
FloatParts64 pa, pb, *pr;
|
||||
|
||||
float64_unpack_canonical(&pa, a, status);
|
||||
float64_unpack_canonical(&pb, b, status);
|
||||
pr = parts_div(&pa, &pb, status);
|
||||
|
||||
return float64r32_round_pack_canonical(pr, status);
|
||||
}
|
||||
|
||||
bfloat16 QEMU_FLATTEN
|
||||
bfloat16_div(bfloat16 a, bfloat16 b, float_status *status)
|
||||
{
|
||||
@ -2543,8 +2644,10 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
|
||||
static void parts_float_to_ahp(FloatParts64 *a, float_status *s)
|
||||
{
|
||||
switch (a->cls) {
|
||||
case float_class_qnan:
|
||||
case float_class_snan:
|
||||
float_raise(float_flag_invalid_snan, s);
|
||||
/* fall through */
|
||||
case float_class_qnan:
|
||||
/*
|
||||
* There is no NaN in the destination format. Raise Invalid
|
||||
* and return a zero with the sign of the input NaN.
|
||||
@ -4283,6 +4386,15 @@ float64 QEMU_FLATTEN float64_sqrt(float64 xa, float_status *s)
|
||||
return soft_f64_sqrt(ua.s, s);
|
||||
}
|
||||
|
||||
float64 float64r32_sqrt(float64 a, float_status *status)
|
||||
{
|
||||
FloatParts64 p;
|
||||
|
||||
float64_unpack_canonical(&p, a, status);
|
||||
parts_sqrt(&p, status, &float64_params);
|
||||
return float64r32_round_pack_canonical(&p, status);
|
||||
}
|
||||
|
||||
bfloat16 QEMU_FLATTEN bfloat16_sqrt(bfloat16 a, float_status *status)
|
||||
{
|
||||
FloatParts64 p;
|
||||
|
85
gdbstub.c
85
gdbstub.c
@ -94,7 +94,7 @@ static inline int cpu_gdb_index(CPUState *cpu)
|
||||
{
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
TaskState *ts = (TaskState *) cpu->opaque;
|
||||
return ts->ts_tid;
|
||||
return ts ? ts->ts_tid : -1;
|
||||
#else
|
||||
return cpu->cpu_index + 1;
|
||||
#endif
|
||||
@ -368,27 +368,10 @@ typedef struct GDBState {
|
||||
gdb_syscall_complete_cb current_syscall_cb;
|
||||
GString *str_buf;
|
||||
GByteArray *mem_buf;
|
||||
int sstep_flags;
|
||||
int supported_sstep_flags;
|
||||
} GDBState;
|
||||
|
||||
/* By default use no IRQs and no timers while single stepping so as to
|
||||
* make single stepping like an ICE HW step.
|
||||
*/
|
||||
static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
|
||||
|
||||
/* Retrieves flags for single step mode. */
|
||||
static int get_sstep_flags(void)
|
||||
{
|
||||
/*
|
||||
* In replay mode all events written into the log should be replayed.
|
||||
* That is why NOIRQ flag is removed in this mode.
|
||||
*/
|
||||
if (replay_mode != REPLAY_MODE_NONE) {
|
||||
return SSTEP_ENABLE;
|
||||
} else {
|
||||
return sstep_flags;
|
||||
}
|
||||
}
|
||||
|
||||
static GDBState gdbserver_state;
|
||||
|
||||
static void init_gdbserver_state(void)
|
||||
@ -399,6 +382,29 @@ static void init_gdbserver_state(void)
|
||||
gdbserver_state.str_buf = g_string_new(NULL);
|
||||
gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
|
||||
gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
|
||||
|
||||
/*
|
||||
* In replay mode all events will come from the log and can't be
|
||||
* suppressed otherwise we would break determinism. However as those
|
||||
* events are tied to the number of executed instructions we won't see
|
||||
* them occurring every time we single step.
|
||||
*/
|
||||
if (replay_mode != REPLAY_MODE_NONE) {
|
||||
gdbserver_state.supported_sstep_flags = SSTEP_ENABLE;
|
||||
} else if (kvm_enabled()) {
|
||||
gdbserver_state.supported_sstep_flags = kvm_get_supported_sstep_flags();
|
||||
} else {
|
||||
gdbserver_state.supported_sstep_flags =
|
||||
SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
|
||||
}
|
||||
|
||||
/*
|
||||
* By default use no IRQs and no timers while single stepping so as to
|
||||
* make single stepping like an ICE HW step.
|
||||
*/
|
||||
gdbserver_state.sstep_flags = SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
|
||||
gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
|
||||
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
@ -505,7 +511,7 @@ static int gdb_continue_partial(char *newstates)
|
||||
CPU_FOREACH(cpu) {
|
||||
if (newstates[cpu->cpu_index] == 's') {
|
||||
trace_gdbstub_op_stepping(cpu->cpu_index);
|
||||
cpu_single_step(cpu, sstep_flags);
|
||||
cpu_single_step(cpu, gdbserver_state.sstep_flags);
|
||||
}
|
||||
}
|
||||
gdbserver_state.running_state = 1;
|
||||
@ -524,7 +530,7 @@ static int gdb_continue_partial(char *newstates)
|
||||
break; /* nothing to do here */
|
||||
case 's':
|
||||
trace_gdbstub_op_stepping(cpu->cpu_index);
|
||||
cpu_single_step(cpu, get_sstep_flags());
|
||||
cpu_single_step(cpu, gdbserver_state.sstep_flags);
|
||||
cpu_resume(cpu);
|
||||
flag = 1;
|
||||
break;
|
||||
@ -1883,7 +1889,7 @@ static void handle_step(GArray *params, void *user_ctx)
|
||||
gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
|
||||
}
|
||||
|
||||
cpu_single_step(gdbserver_state.c_cpu, get_sstep_flags());
|
||||
cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
|
||||
gdb_continue();
|
||||
}
|
||||
|
||||
@ -2017,24 +2023,44 @@ static void handle_v_commands(GArray *params, void *user_ctx)
|
||||
|
||||
static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
|
||||
{
|
||||
g_string_printf(gdbserver_state.str_buf, "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
|
||||
SSTEP_ENABLE, SSTEP_NOIRQ, SSTEP_NOTIMER);
|
||||
g_string_printf(gdbserver_state.str_buf, "ENABLE=%x", SSTEP_ENABLE);
|
||||
|
||||
if (gdbserver_state.supported_sstep_flags & SSTEP_NOIRQ) {
|
||||
g_string_append_printf(gdbserver_state.str_buf, ",NOIRQ=%x",
|
||||
SSTEP_NOIRQ);
|
||||
}
|
||||
|
||||
if (gdbserver_state.supported_sstep_flags & SSTEP_NOTIMER) {
|
||||
g_string_append_printf(gdbserver_state.str_buf, ",NOTIMER=%x",
|
||||
SSTEP_NOTIMER);
|
||||
}
|
||||
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
|
||||
{
|
||||
int new_sstep_flags;
|
||||
|
||||
if (!params->len) {
|
||||
return;
|
||||
}
|
||||
|
||||
sstep_flags = get_param(params, 0)->val_ul;
|
||||
new_sstep_flags = get_param(params, 0)->val_ul;
|
||||
|
||||
if (new_sstep_flags & ~gdbserver_state.supported_sstep_flags) {
|
||||
put_packet("E22");
|
||||
return;
|
||||
}
|
||||
|
||||
gdbserver_state.sstep_flags = new_sstep_flags;
|
||||
put_packet("OK");
|
||||
}
|
||||
|
||||
static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
|
||||
{
|
||||
g_string_printf(gdbserver_state.str_buf, "0x%x", sstep_flags);
|
||||
g_string_printf(gdbserver_state.str_buf, "0x%x",
|
||||
gdbserver_state.sstep_flags);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
@ -3497,6 +3523,11 @@ int gdbserver_start(const char *device)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (kvm_enabled() && !kvm_supports_guest_debug()) {
|
||||
error_report("gdbstub: KVM doesn't support guest debugging");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!device)
|
||||
return -1;
|
||||
if (strcmp(device, "none") != 0) {
|
||||
|
@ -222,9 +222,27 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo
|
||||
PCIDevice *dev = PCI_DEVICE(qdev);
|
||||
if (PCI_SLOT(dev->devfn) == slot) {
|
||||
if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(qdev);
|
||||
hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort);
|
||||
object_unparent(OBJECT(qdev));
|
||||
/*
|
||||
* partially_hotplugged is used by virtio-net failover:
|
||||
* failover has asked the guest OS to unplug the device
|
||||
* but we need to keep some references to the device
|
||||
* to be able to plug it back in case of failure so
|
||||
* we don't execute hotplug_handler_unplug().
|
||||
*/
|
||||
if (dev->partially_hotplugged) {
|
||||
/*
|
||||
* pending_deleted_event is set to true when
|
||||
* virtio-net failover asks to unplug the device,
|
||||
* and set to false here when the operation is done
|
||||
* This is used by the migration loop to detect the
|
||||
* end of the operation and really start the migration.
|
||||
*/
|
||||
qdev->pending_deleted_event = false;
|
||||
} else {
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(qdev);
|
||||
hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort);
|
||||
object_unparent(OBJECT(qdev));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -396,6 +414,12 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* pending_deleted_event is used by virtio-net failover to detect the
|
||||
* end of the unplug operation, the flag is set to false in
|
||||
* acpi_pcihp_eject_slot() when the operation is completed.
|
||||
*/
|
||||
pdev->qdev.pending_deleted_event = true;
|
||||
s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
|
||||
acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ config ARM_VIRT
|
||||
select DIMM
|
||||
select ACPI_HW_REDUCED
|
||||
select ACPI_APEI
|
||||
select ACPI_VIOT
|
||||
|
||||
config CHEETAH
|
||||
bool
|
||||
|
@ -284,12 +284,13 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
|
||||
}
|
||||
|
||||
static void aspeed_board_init_flashes(AspeedSMCState *s,
|
||||
const char *flashtype)
|
||||
const char *flashtype,
|
||||
int unit0)
|
||||
{
|
||||
int i ;
|
||||
|
||||
for (i = 0; i < s->num_cs; ++i) {
|
||||
DriveInfo *dinfo = drive_get_next(IF_MTD);
|
||||
DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
|
||||
qemu_irq cs_line;
|
||||
DeviceState *dev;
|
||||
|
||||
@ -382,10 +383,12 @@ static void aspeed_machine_init(MachineState *machine)
|
||||
"max_ram", max_ram_size - machine->ram_size);
|
||||
memory_region_add_subregion(&bmc->ram_container, machine->ram_size, &bmc->max_ram);
|
||||
|
||||
aspeed_board_init_flashes(&bmc->soc.fmc, bmc->fmc_model ?
|
||||
bmc->fmc_model : amc->fmc_model);
|
||||
aspeed_board_init_flashes(&bmc->soc.spi[0], bmc->spi_model ?
|
||||
bmc->spi_model : amc->spi_model);
|
||||
aspeed_board_init_flashes(&bmc->soc.fmc,
|
||||
bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
|
||||
0);
|
||||
aspeed_board_init_flashes(&bmc->soc.spi[0],
|
||||
bmc->spi_model ? bmc->spi_model : amc->spi_model,
|
||||
bmc->soc.fmc.num_cs);
|
||||
|
||||
/* Install first FMC flash content as a boot rom. */
|
||||
if (drive0) {
|
||||
@ -435,11 +438,13 @@ static void aspeed_machine_init(MachineState *machine)
|
||||
}
|
||||
|
||||
for (i = 0; i < bmc->soc.sdhci.num_slots; i++) {
|
||||
sdhci_attach_drive(&bmc->soc.sdhci.slots[i], drive_get_next(IF_SD));
|
||||
sdhci_attach_drive(&bmc->soc.sdhci.slots[i],
|
||||
drive_get(IF_SD, 0, i));
|
||||
}
|
||||
|
||||
if (bmc->soc.emmc.num_slots) {
|
||||
sdhci_attach_drive(&bmc->soc.emmc.slots[0], drive_get_next(IF_SD));
|
||||
sdhci_attach_drive(&bmc->soc.emmc.slots[0],
|
||||
drive_get(IF_SD, 0, bmc->soc.sdhci.num_slots));
|
||||
}
|
||||
|
||||
arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/datadir.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qapi/error.h"
|
||||
|
@ -81,7 +81,7 @@ static void cubieboard_init(MachineState *machine)
|
||||
}
|
||||
|
||||
/* Retrieve SD bus */
|
||||
di = drive_get_next(IF_SD);
|
||||
di = drive_get(IF_SD, 0, 0);
|
||||
blk = di ? blk_by_legacy_dinfo(di) : NULL;
|
||||
bus = qdev_get_child_bus(DEVICE(a10), "sd-bus");
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/datadir.h"
|
||||
#include "hw/boards.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/datadir.h"
|
||||
#include "qapi/error.h"
|
||||
#include "hw/sysbus.h"
|
||||
|
@ -123,7 +123,7 @@ static void imx25_pdk_init(MachineState *machine)
|
||||
DriveInfo *di;
|
||||
BlockBackend *blk;
|
||||
|
||||
di = drive_get_next(IF_SD);
|
||||
di = drive_get(IF_SD, 0, i);
|
||||
blk = di ? blk_by_legacy_dinfo(di) : NULL;
|
||||
bus = qdev_get_child_bus(DEVICE(&s->soc.esdhc[i]), "sd-bus");
|
||||
carddev = qdev_new(TYPE_SD_CARD);
|
||||
|
@ -649,7 +649,7 @@ static void integratorcp_init(MachineState *machine)
|
||||
qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_WPROT, 0));
|
||||
qdev_connect_gpio_out_named(dev, "card-inserted", 0,
|
||||
qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_CARDIN, 0));
|
||||
dinfo = drive_get_next(IF_SD);
|
||||
dinfo = drive_get(IF_SD, 0, 0);
|
||||
if (dinfo) {
|
||||
DeviceState *card;
|
||||
|
||||
|
@ -52,7 +52,7 @@ static void mcimx6ul_evk_init(MachineState *machine)
|
||||
DriveInfo *di;
|
||||
BlockBackend *blk;
|
||||
|
||||
di = drive_get_next(IF_SD);
|
||||
di = drive_get(IF_SD, 0, i);
|
||||
blk = di ? blk_by_legacy_dinfo(di) : NULL;
|
||||
bus = qdev_get_child_bus(DEVICE(&s->usdhc[i]), "sd-bus");
|
||||
carddev = qdev_new(TYPE_SD_CARD);
|
||||
|
@ -52,7 +52,7 @@ static void mcimx7d_sabre_init(MachineState *machine)
|
||||
DriveInfo *di;
|
||||
BlockBackend *blk;
|
||||
|
||||
di = drive_get_next(IF_SD);
|
||||
di = drive_get(IF_SD, 0, i);
|
||||
blk = di ? blk_by_legacy_dinfo(di) : NULL;
|
||||
bus = qdev_get_child_bus(DEVICE(&s->usdhc[i]), "sd-bus");
|
||||
carddev = qdev_new(TYPE_SD_CARD);
|
||||
|
@ -45,7 +45,7 @@ static void emcraft_sf2_s2s010_init(MachineState *machine)
|
||||
DeviceState *spi_flash;
|
||||
MSF2State *soc;
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
DriveInfo *dinfo = drive_get_next(IF_MTD);
|
||||
DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
|
||||
qemu_irq cs_line;
|
||||
BusState *spi_bus;
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "hw/qdev-core.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/datadir.h"
|
||||
#include "qemu/units.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
@ -84,9 +83,9 @@ static void npcm7xx_connect_dram(NPCM7xxState *soc, MemoryRegion *dram)
|
||||
&error_abort);
|
||||
}
|
||||
|
||||
static void sdhci_attach_drive(SDHCIState *sdhci)
|
||||
static void sdhci_attach_drive(SDHCIState *sdhci, int unit)
|
||||
{
|
||||
DriveInfo *di = drive_get_next(IF_SD);
|
||||
DriveInfo *di = drive_get(IF_SD, 0, unit);
|
||||
BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
|
||||
|
||||
BusState *bus = qdev_get_child_bus(DEVICE(sdhci), "sd-bus");
|
||||
@ -374,7 +373,7 @@ static void quanta_gbs_init(MachineState *machine)
|
||||
drive_get(IF_MTD, 0, 0));
|
||||
|
||||
quanta_gbs_i2c_init(soc);
|
||||
sdhci_attach_drive(&soc->mmc.sdhci);
|
||||
sdhci_attach_drive(&soc->mmc.sdhci, 0);
|
||||
npcm7xx_load_kernel(machine, soc);
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ static void orangepi_init(MachineState *machine)
|
||||
qdev_realize(DEVICE(h3), NULL, &error_abort);
|
||||
|
||||
/* Retrieve SD bus */
|
||||
di = drive_get_next(IF_SD);
|
||||
di = drive_get(IF_SD, 0, 0);
|
||||
blk = di ? blk_by_legacy_dinfo(di) : NULL;
|
||||
bus = qdev_get_child_bus(DEVICE(h3), "sd-bus");
|
||||
|
||||
|
@ -284,7 +284,7 @@ static void raspi_machine_init(MachineState *machine)
|
||||
qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
|
||||
|
||||
/* Create and plug in the SD cards */
|
||||
di = drive_get_next(IF_SD);
|
||||
di = drive_get(IF_SD, 0, 0);
|
||||
blk = di ? blk_by_legacy_dinfo(di) : NULL;
|
||||
bus = qdev_get_child_bus(DEVICE(&s->soc), "sd-bus");
|
||||
if (bus == NULL) {
|
||||
|
@ -237,7 +237,7 @@ static void realview_init(MachineState *machine,
|
||||
qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
|
||||
qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
|
||||
qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
|
||||
dinfo = drive_get_next(IF_SD);
|
||||
dinfo = drive_get(IF_SD, 0, 0);
|
||||
if (dinfo) {
|
||||
DeviceState *card;
|
||||
|
||||
|
@ -76,7 +76,7 @@ static void sabrelite_init(MachineState *machine)
|
||||
if (spi_bus) {
|
||||
DeviceState *flash_dev;
|
||||
qemu_irq cs_line;
|
||||
DriveInfo *dinfo = drive_get_next(IF_MTD);
|
||||
DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
|
||||
|
||||
flash_dev = qdev_new("sst25vf016b");
|
||||
if (dinfo) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user