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

This commit is contained in:
Andrea Fioraldi 2022-02-25 10:47:38 +01:00
commit 090feffaaa
260 changed files with 6046 additions and 3276 deletions

View File

@ -2189,6 +2189,7 @@ F: tests/qtest/prom-env-test.c
VM Generation ID
S: Orphan
R: Ani Sinha <ani@anisinha.ca>
F: hw/acpi/vmgenid.c
F: include/hw/acpi/vmgenid.h
F: docs/specs/vmgenid.txt
@ -2204,6 +2205,7 @@ F: hw/misc/led.c
Unimplemented device
M: Peter Maydell <peter.maydell@linaro.org>
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
R: Ani Sinha <ani@anisinha.ca>
S: Maintained
F: include/hw/misc/unimp.h
F: hw/misc/unimp.c
@ -2211,6 +2213,7 @@ F: hw/misc/unimp.c
Empty slot
M: Artyom Tarasenko <atar4qemu@gmail.com>
R: Philippe Mathieu-Daudé <f4bug@amsat.org>
R: Ani Sinha <ani@anisinha.ca>
S: Maintained
F: include/hw/misc/empty_slot.h
F: hw/misc/empty_slot.c
@ -2413,6 +2416,7 @@ F: audio/alsaaudio.c
Core Audio framework backend
M: Gerd Hoffmann <kraxel@redhat.com>
R: Christian Schoenebeck <qemu_oss@crudebyte.com>
R: Akihiko Odaki <akihiko.odaki@gmail.com>
S: Odd Fixes
F: audio/coreaudio.c
@ -2665,6 +2669,7 @@ F: util/drm.c
Cocoa graphics
M: Peter Maydell <peter.maydell@linaro.org>
R: Akihiko Odaki <akihiko.odaki@gmail.com>
S: Odd Fixes
F: ui/cocoa.m
@ -2985,10 +2990,11 @@ F: docs/sphinx/fakedbusdoc.py
F: tests/qtest/dbus*
Seccomp
M: Eduardo Otubo <otubo@redhat.com>
S: Supported
M: Daniel P. Berrange <berrange@redhat.com>
S: Odd Fixes
F: softmmu/qemu-seccomp.c
F: include/sysemu/seccomp.h
F: tests/unit/test-seccomp.c
Cryptography
M: Daniel P. Berrange <berrange@redhat.com>

View File

@ -51,6 +51,7 @@
#include "qemu/qemu-print.h"
#include "qemu/timer.h"
#include "qemu/main-loop.h"
#include "qemu/cacheinfo.h"
#include "exec/log.h"
#include "sysemu/cpus.h"
#include "sysemu/cpu-timers.h"

View File

@ -14,6 +14,7 @@
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/madvise.h"
#include "sysemu/hostmem.h"
#include "qom/object_interfaces.h"
#include "qom/object.h"

View File

@ -19,6 +19,7 @@
#include "qemu/config-file.h"
#include "qom/object_interfaces.h"
#include "qemu/mmap-alloc.h"
#include "qemu/madvise.h"
#ifdef CONFIG_NUMA
#include <numaif.h>

View File

@ -1,8 +1,6 @@
tpm_ss = ss.source_set()
tpm_ss.add(files('tpm_backend.c'))
tpm_ss.add(files('tpm_util.c'))
tpm_ss.add(when: 'CONFIG_TPM_PASSTHROUGH', if_true: files('tpm_passthrough.c'))
tpm_ss.add(when: 'CONFIG_TPM_EMULATOR', if_true: files('tpm_emulator.c'))
softmmu_ss.add_all(when: 'CONFIG_TPM', if_true: tpm_ss)
if have_tpm
softmmu_ss.add(files('tpm_backend.c'))
softmmu_ss.add(files('tpm_util.c'))
softmmu_ss.add(when: 'CONFIG_TPM_PASSTHROUGH', if_true: files('tpm_passthrough.c'))
softmmu_ss.add(when: 'CONFIG_TPM_EMULATOR', if_true: files('tpm_emulator.c'))
endif

View File

@ -45,25 +45,44 @@ block_ss.add(files(
softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
block_ss.add(when: 'CONFIG_QCOW1', if_true: files('qcow.c'))
block_ss.add(when: 'CONFIG_VDI', if_true: files('vdi.c'))
block_ss.add(when: 'CONFIG_CLOOP', if_true: files('cloop.c'))
block_ss.add(when: 'CONFIG_BOCHS', if_true: files('bochs.c'))
block_ss.add(when: 'CONFIG_VVFAT', if_true: files('vvfat.c'))
block_ss.add(when: 'CONFIG_DMG', if_true: files('dmg.c'))
block_ss.add(when: 'CONFIG_QED', if_true: files(
if get_option('qcow1').allowed()
block_ss.add(files('qcow.c'))
endif
if get_option('vdi').allowed()
block_ss.add(files('vdi.c'))
endif
if get_option('cloop').allowed()
block_ss.add(files('cloop.c'))
endif
if get_option('bochs').allowed()
block_ss.add(files('bochs.c'))
endif
if get_option('vvfat').allowed()
block_ss.add(files('vvfat.c'))
endif
if get_option('dmg').allowed()
block_ss.add(files('dmg.c'))
endif
if get_option('qed').allowed()
block_ss.add(files(
'qed-check.c',
'qed-cluster.c',
'qed-l2-cache.c',
'qed-table.c',
'qed.c',
))
block_ss.add(when: 'CONFIG_PARALLELS', if_true: files('parallels.c', 'parallels-ext.c'))
))
endif
if get_option('parallels').allowed()
block_ss.add(files('parallels.c', 'parallels-ext.c'))
endif
block_ss.add(when: 'CONFIG_WIN32', if_true: files('file-win32.c', 'win32-aio.c'))
block_ss.add(when: 'CONFIG_POSIX', if_true: [files('file-posix.c'), coref, iokit])
block_ss.add(when: libiscsi, if_true: files('iscsi-opts.c'))
block_ss.add(when: 'CONFIG_LINUX', if_true: files('nvme.c'))
block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
if not get_option('replication').disabled()
block_ss.add(files('replication.c'))
endif
block_ss.add(when: libaio, if_true: files('linux-aio.c'))
block_ss.add(when: linux_io_uring, if_true: files('io_uring.c'))
@ -89,7 +108,7 @@ foreach m : [
endforeach
# those are not exactly regular block modules, so treat them apart
if 'CONFIG_DMG' in config_host
if get_option('dmg').allowed()
foreach m : [
[liblzfse, 'dmg-lzfse', liblzfse, 'dmg-lzfse.c'],
[libbzip2, 'dmg-bz2', [glib, libbzip2], 'dmg-bz2.c']

View File

@ -386,14 +386,28 @@ static int compare_fingerprint(const unsigned char *fingerprint, size_t len,
return *host_key_check - '\0';
}
static char *format_fingerprint(const unsigned char *fingerprint, size_t len)
{
static const char *hex = "0123456789abcdef";
char *ret = g_new0(char, (len * 2) + 1);
for (size_t i = 0; i < len; i++) {
ret[i * 2] = hex[((fingerprint[i] >> 4) & 0xf)];
ret[(i * 2) + 1] = hex[(fingerprint[i] & 0xf)];
}
ret[len * 2] = '\0';
return ret;
}
static int
check_host_key_hash(BDRVSSHState *s, const char *hash,
enum ssh_publickey_hash_type type, Error **errp)
enum ssh_publickey_hash_type type, const char *typestr,
Error **errp)
{
int r;
ssh_key pubkey;
unsigned char *server_hash;
size_t server_hash_len;
const char *keytype;
r = ssh_get_server_publickey(s->session, &pubkey);
if (r != SSH_OK) {
@ -401,6 +415,8 @@ check_host_key_hash(BDRVSSHState *s, const char *hash,
return -EINVAL;
}
keytype = ssh_key_type_to_char(ssh_key_type(pubkey));
r = ssh_get_publickey_hash(pubkey, type, &server_hash, &server_hash_len);
ssh_key_free(pubkey);
if (r != 0) {
@ -410,12 +426,16 @@ check_host_key_hash(BDRVSSHState *s, const char *hash,
}
r = compare_fingerprint(server_hash, server_hash_len, hash);
ssh_clean_pubkey_hash(&server_hash);
if (r != 0) {
error_setg(errp, "remote host key does not match host_key_check '%s'",
hash);
g_autofree char *server_fp = format_fingerprint(server_hash,
server_hash_len);
error_setg(errp, "remote host %s key fingerprint '%s:%s' "
"does not match host_key_check '%s:%s'",
keytype, typestr, server_fp, typestr, hash);
ssh_clean_pubkey_hash(&server_hash);
return -EPERM;
}
ssh_clean_pubkey_hash(&server_hash);
return 0;
}
@ -436,13 +456,16 @@ static int check_host_key(BDRVSSHState *s, SshHostKeyCheck *hkc, Error **errp)
case SSH_HOST_KEY_CHECK_MODE_HASH:
if (hkc->u.hash.type == SSH_HOST_KEY_CHECK_HASH_TYPE_MD5) {
return check_host_key_hash(s, hkc->u.hash.hash,
SSH_PUBLICKEY_HASH_MD5, errp);
SSH_PUBLICKEY_HASH_MD5, "md5",
errp);
} else if (hkc->u.hash.type == SSH_HOST_KEY_CHECK_HASH_TYPE_SHA1) {
return check_host_key_hash(s, hkc->u.hash.hash,
SSH_PUBLICKEY_HASH_SHA1, errp);
SSH_PUBLICKEY_HASH_SHA1, "sha1",
errp);
} else if (hkc->u.hash.type == SSH_HOST_KEY_CHECK_HASH_TYPE_SHA256) {
return check_host_key_hash(s, hkc->u.hash.hash,
SSH_PUBLICKEY_HASH_SHA256, errp);
SSH_PUBLICKEY_HASH_SHA256, "sha256",
errp);
}
g_assert_not_reached();
break;
@ -556,6 +579,11 @@ static bool ssh_process_legacy_options(QDict *output_opts,
qdict_put_str(output_opts, "host-key-check.type", "sha1");
qdict_put_str(output_opts, "host-key-check.hash",
&host_key_check[5]);
} else if (strncmp(host_key_check, "sha256:", 7) == 0) {
qdict_put_str(output_opts, "host-key-check.mode", "hash");
qdict_put_str(output_opts, "host-key-check.type", "sha256");
qdict_put_str(output_opts, "host-key-check.hash",
&host_key_check[7]);
} else if (strcmp(host_key_check, "yes") == 0) {
qdict_put_str(output_opts, "host-key-check.mode", "known_hosts");
} else {

View File

@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu.h"
#include "signal-common.h"
#include "trace.h"

607
configure vendored
View File

@ -238,9 +238,7 @@ cross_prefix=""
audio_drv_list="default"
block_drv_rw_whitelist=""
block_drv_ro_whitelist=""
block_drv_whitelist_tools="no"
host_cc="cc"
libs_qga=""
debug_info="yes"
lto="false"
stack_protector=""
@ -290,7 +288,6 @@ EXTRA_CXXFLAGS=""
EXTRA_LDFLAGS=""
xen_ctrl_version="$default_feature"
membarrier="$default_feature"
vhost_kernel="$default_feature"
vhost_net="$default_feature"
vhost_crypto="$default_feature"
@ -301,7 +298,6 @@ vhost_user_fs="$default_feature"
vhost_vdpa="$default_feature"
rdma="$default_feature"
pvrdma="$default_feature"
gprof="no"
debug_tcg="no"
debug="no"
sanitizers="no"
@ -313,57 +309,36 @@ modules="no"
module_upgrades="no"
prefix="/usr/local"
qemu_suffix="qemu"
profiler="no"
softmmu="yes"
linux_user=""
bsd_user=""
pkgversion=""
pie=""
qom_cast_debug="yes"
trace_backends="log"
trace_file="trace"
opengl="$default_feature"
cpuid_h="no"
avx2_opt="$default_feature"
guest_agent="$default_feature"
vss_win32_sdk="$default_feature"
win_sdk="no"
want_tools="$default_feature"
coroutine=""
coroutine_pool="$default_feature"
debug_stack_usage="no"
crypto_afalg="no"
tls_priority="NORMAL"
tpm="$default_feature"
live_block_migration=${default_feature:-yes}
numa="$default_feature"
replication=${default_feature:-yes}
bochs=${default_feature:-yes}
cloop=${default_feature:-yes}
dmg=${default_feature:-yes}
qcow1=${default_feature:-yes}
vdi=${default_feature:-yes}
vvfat=${default_feature:-yes}
qed=${default_feature:-yes}
parallels=${default_feature:-yes}
debug_mutex="no"
plugins="$default_feature"
rng_none="no"
secret_keyring="$default_feature"
meson=""
meson_args=""
ninja=""
gio="$default_feature"
skip_meson=no
slirp_smbd="$default_feature"
# The following Meson options are handled manually (still they
# are included in the automatically generated help message)
# 1. Track which submodules are needed
capstone="auto"
if test "$default_feature" = no ; then
capstone="disabled"
slirp="disabled"
else
capstone="auto"
slirp="auto"
fi
fdt="auto"
slirp="auto"
# 2. Support --with/--without option
default_devices="true"
@ -441,6 +416,7 @@ objcopy="${OBJCOPY-${cross_prefix}objcopy}"
ld="${LD-${cross_prefix}ld}"
ranlib="${RANLIB-${cross_prefix}ranlib}"
nm="${NM-${cross_prefix}nm}"
smbd="$SMBD"
strip="${STRIP-${cross_prefix}strip}"
windres="${WINDRES-${cross_prefix}windres}"
pkg_config_exe="${PKG_CONFIG-${cross_prefix}pkg-config}"
@ -560,7 +536,6 @@ darwin)
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
@ -714,7 +689,6 @@ if test "$mingw32" = "yes" ; then
write_c_skeleton;
prefix="/qemu"
qemu_suffix=""
libs_qga="-lws2_32 -lwinmm -lpowrprof -lwtsapi32 -lwininet -liphlpapi -lnetapi32 $libs_qga"
fi
werror=""
@ -826,8 +800,6 @@ for opt do
;;
--without-default-features) # processed above
;;
--enable-gprof) gprof="yes"
;;
--enable-gcov) gcov="yes"
;;
--static)
@ -868,20 +840,12 @@ for opt do
# configure to be used by RPM and similar macros that set
# lots of directory switches by default.
;;
--disable-qom-cast-debug) qom_cast_debug="no"
;;
--enable-qom-cast-debug) qom_cast_debug="yes"
;;
--audio-drv-list=*) audio_drv_list="$optarg"
;;
--block-drv-rw-whitelist=*|--block-drv-whitelist=*) block_drv_rw_whitelist=$(echo "$optarg" | sed -e 's/,/ /g')
;;
--block-drv-ro-whitelist=*) block_drv_ro_whitelist=$(echo "$optarg" | sed -e 's/,/ /g')
;;
--enable-block-drv-whitelist-in-tools) block_drv_whitelist_tools="yes"
;;
--disable-block-drv-whitelist-in-tools) block_drv_whitelist_tools="no"
;;
--enable-debug-tcg) debug_tcg="yes"
;;
--disable-debug-tcg) debug_tcg="no"
@ -889,7 +853,7 @@ for opt do
--enable-debug)
# Enable debugging options that aren't excessively noisy
debug_tcg="yes"
debug_mutex="yes"
meson_option_parse --enable-debug-mutex ""
debug="yes"
fortify_source="no"
;;
@ -918,8 +882,6 @@ for opt do
;;
--enable-tcg) tcg="enabled"
;;
--enable-profiler) profiler="yes"
;;
--disable-system) softmmu="no"
;;
--enable-system) softmmu="yes"
@ -971,24 +933,10 @@ for opt do
;;
--enable-fdt=*) fdt="$optarg"
;;
--disable-membarrier) membarrier="no"
;;
--enable-membarrier) membarrier="yes"
;;
--with-pkgversion=*) pkgversion="$optarg"
;;
--with-coroutine=*) coroutine="$optarg"
;;
--disable-coroutine-pool) coroutine_pool="no"
;;
--enable-coroutine-pool) coroutine_pool="yes"
;;
--enable-debug-stack-usage) debug_stack_usage="yes"
;;
--enable-crypto-afalg) crypto_afalg="yes"
;;
--disable-crypto-afalg) crypto_afalg="no"
;;
--disable-vhost-net) vhost_net="no"
;;
--enable-vhost-net) vhost_net="yes"
@ -1015,34 +963,6 @@ for opt do
;;
--disable-zlib-test)
;;
--enable-guest-agent) guest_agent="yes"
;;
--disable-guest-agent) guest_agent="no"
;;
--with-vss-sdk) vss_win32_sdk=""
;;
--with-vss-sdk=*) vss_win32_sdk="$optarg"
;;
--without-vss-sdk) vss_win32_sdk="no"
;;
--with-win-sdk) win_sdk=""
;;
--with-win-sdk=*) win_sdk="$optarg"
;;
--without-win-sdk) win_sdk="no"
;;
--enable-tools) want_tools="yes"
;;
--disable-tools) want_tools="no"
;;
--disable-avx2) avx2_opt="no"
;;
--enable-avx2) avx2_opt="yes"
;;
--disable-avx512f) avx512f_opt="no"
;;
--enable-avx512f) avx512f_opt="yes"
;;
--disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
echo "$0: $opt is obsolete, virtio-blk data-plane is always on" >&2
;;
@ -1062,54 +982,6 @@ for opt do
;;
--disable-pvrdma) pvrdma="no"
;;
--disable-tpm) tpm="no"
;;
--enable-tpm) tpm="yes"
;;
--disable-live-block-migration) live_block_migration="no"
;;
--enable-live-block-migration) live_block_migration="yes"
;;
--disable-numa) numa="no"
;;
--enable-numa) numa="yes"
;;
--disable-replication) replication="no"
;;
--enable-replication) replication="yes"
;;
--disable-bochs) bochs="no"
;;
--enable-bochs) bochs="yes"
;;
--disable-cloop) cloop="no"
;;
--enable-cloop) cloop="yes"
;;
--disable-dmg) dmg="no"
;;
--enable-dmg) dmg="yes"
;;
--disable-qcow1) qcow1="no"
;;
--enable-qcow1) qcow1="yes"
;;
--disable-vdi) vdi="no"
;;
--enable-vdi) vdi="yes"
;;
--disable-vvfat) vvfat="no"
;;
--enable-vvfat) vvfat="yes"
;;
--disable-qed) qed="no"
;;
--enable-qed) qed="yes"
;;
--disable-parallels) parallels="no"
;;
--enable-parallels) parallels="yes"
;;
--disable-vhost-user) vhost_user="no"
;;
--enable-vhost-user) vhost_user="yes"
@ -1135,10 +1007,6 @@ for opt do
--with-git-submodules=*)
git_submodules_action="$optarg"
;;
--enable-debug-mutex) debug_mutex=yes
;;
--disable-debug-mutex) debug_mutex=no
;;
--enable-plugins) if test "$mingw32" = "yes"; then
error_exit "TCG plugins not currently supported on Windows platforms"
else
@ -1153,10 +1021,6 @@ for opt do
;;
--gdb=*) gdb_bin="$optarg"
;;
--enable-rng-none) rng_none=yes
;;
--disable-rng-none) rng_none=no
;;
--enable-keyring) secret_keyring="yes"
;;
--disable-keyring) secret_keyring="no"
@ -1165,10 +1029,6 @@ for opt do
;;
--disable-gio) gio=no
;;
--enable-slirp-smbd) slirp_smbd=yes
;;
--disable-slirp-smbd) slirp_smbd=no
;;
# backwards compatibility options
--enable-trace-backend=*) meson_option_parse "--enable-trace-backends=$optarg" "$optarg"
;;
@ -1369,21 +1229,13 @@ Advanced options (experts only):
--block-drv-ro-whitelist=L
set block driver read-only whitelist
(by default affects only QEMU, not tools like qemu-img)
--enable-block-drv-whitelist-in-tools
use block whitelist also in tools instead of only QEMU
--with-trace-file=NAME Full PATH,NAME of file to store traces
Default:trace-<pid>
--cpu=CPU Build for host CPU [$cpu]
--with-coroutine=BACKEND coroutine backend. Supported options:
ucontext, sigaltstack, windows
--enable-gcov enable test coverage analysis with gcov
--with-vss-sdk=SDK-path enable Windows VSS support in QEMU Guest Agent
--with-win-sdk=SDK-path path to Windows Platform SDK (to build VSS .tlb)
--tls-priority default TLS protocol/cipher priority string
--enable-gprof QEMU profiling with gprof
--enable-profiler profiler support
--enable-debug-stack-usage
track the maximum stack usage of stacks created by qemu_alloc_stack
--enable-plugins
enable plugins via shared library loading
--disable-containers don't use containers for cross-building
@ -1395,7 +1247,6 @@ cat << EOF
user supported user emulation targets
linux-user all linux usermode emulation targets
bsd-user all BSD usermode emulation targets
guest-agent build the QEMU Guest Agent
pie Position Independent Executables
modules modules support (non-Windows)
module-upgrades try to load modules from alternate paths for upgrades
@ -1404,7 +1255,6 @@ cat << EOF
lto Enable Link-Time Optimization.
safe-stack SafeStack Stack Smash Protection. Depends on
clang/llvm >= 3.7 and requires coroutine backend ucontext.
membarrier membarrier system call (for Linux 4.14+ or Windows)
rdma Enable RDMA-based migration
pvrdma Enable PVRDMA support
vhost-net vhost-net kernel acceleration support
@ -1414,29 +1264,8 @@ cat << EOF
vhost-kernel vhost kernel backend support
vhost-user vhost-user backend support
vhost-vdpa vhost-vdpa kernel backend support
live-block-migration Block migration in the main migration stream
coroutine-pool coroutine freelist (better performance)
tpm TPM support
numa libnuma support
avx2 AVX2 optimization support
avx512f AVX512F optimization support
replication replication support
opengl opengl support
qom-cast-debug cast debugging support
tools build qemu-io, qemu-nbd and qemu-img tools
bochs bochs image format support
cloop cloop image format support
dmg dmg image format support
qcow1 qcow v1 image format support
vdi vdi image format support
vvfat vvfat image format support
qed qed image format support
parallels parallels image format support
crypto-afalg Linux AF_ALG crypto backend driver
debug-mutex mutex debugging support
rng-none dummy RNG, avoid using /dev/(u)random and getrandom()
gio libgio support
slirp-smbd use smbd (at path --smbd=*) in slirp networking
NOTE: The object files are built at the place where configure is launched
EOF
@ -1838,16 +1667,6 @@ else
exit 1
fi
##########################################
# system tools
if test -z "$want_tools"; then
if test "$softmmu" = "no"; then
want_tools=no
else
want_tools=yes
fi
fi
#########################################
# vhost interdependencies and host support
@ -2437,21 +2256,6 @@ if test "$modules" = yes; then
fi
fi
##########################################
# TPM emulation is only on POSIX
if test "$tpm" = ""; then
if test "$mingw32" = "yes"; then
tpm=no
else
tpm=yes
fi
elif test "$tpm" = "yes"; then
if test "$mingw32" = "yes" ; then
error_exit "TPM emulation only available on POSIX systems"
fi
fi
##########################################
# fdt probe
@ -2491,26 +2295,6 @@ EOF
fi
fi
##########################################
# libnuma probe
if test "$numa" != "no" ; then
cat > $TMPC << EOF
#include <numa.h>
int main(void) { return numa_available(); }
EOF
if compile_prog "" "-lnuma" ; then
numa=yes
numa_libs="-lnuma"
else
if test "$numa" = "yes" ; then
feature_not_found "numa" "install numactl devel"
fi
numa=no
fi
fi
# check for usbfs
have_usbfs=no
if test "$linux_user" = "yes"; then
@ -2535,85 +2319,6 @@ EOF
fi
fi
##########################################
# check if we have VSS SDK headers for win
guest_agent_with_vss="no"
if test "$mingw32" = "yes" && test "$guest_agent" != "no" && \
test "$vss_win32_sdk" != "no" ; then
case "$vss_win32_sdk" in
"") vss_win32_include="-isystem $source_path" ;;
*\ *) # The SDK is installed in "Program Files" by default, but we cannot
# handle path with spaces. So we symlink the headers into ".sdk/vss".
vss_win32_include="-isystem $source_path/.sdk/vss"
symlink "$vss_win32_sdk/inc" "$source_path/.sdk/vss/inc"
;;
*) vss_win32_include="-isystem $vss_win32_sdk"
esac
cat > $TMPC << EOF
#define __MIDL_user_allocate_free_DEFINED__
#include <inc/win2003/vss.h>
int main(void) { return VSS_CTX_BACKUP; }
EOF
if compile_prog "$vss_win32_include" "" ; then
guest_agent_with_vss="yes"
QEMU_CFLAGS="$QEMU_CFLAGS $vss_win32_include"
libs_qga="-lole32 -loleaut32 -lshlwapi -lstdc++ -Wl,--enable-stdcall-fixup $libs_qga"
qga_vss_provider="qga/vss-win32/qga-vss.dll qga/vss-win32/qga-vss.tlb"
else
if test "$vss_win32_sdk" != "" ; then
echo "ERROR: Please download and install Microsoft VSS SDK:"
echo "ERROR: http://www.microsoft.com/en-us/download/details.aspx?id=23490"
echo "ERROR: On POSIX-systems, you can extract the SDK headers by:"
echo "ERROR: scripts/extract-vsssdk-headers setup.exe"
echo "ERROR: The headers are extracted in the directory \`inc'."
feature_not_found "VSS support"
fi
fi
fi
##########################################
# lookup Windows platform SDK (if not specified)
# The SDK is needed only to build .tlb (type library) file of guest agent
# VSS provider from the source. It is usually unnecessary because the
# pre-compiled .tlb file is included.
if test "$mingw32" = "yes" && test "$guest_agent" != "no" && \
test "$guest_agent_with_vss" = "yes" ; then
if test -z "$win_sdk"; then
programfiles="$PROGRAMFILES"
test -n "$PROGRAMW6432" && programfiles="$PROGRAMW6432"
if test -n "$programfiles"; then
win_sdk=$(ls -d "$programfiles/Microsoft SDKs/Windows/v"* | tail -1) 2>/dev/null
else
feature_not_found "Windows SDK"
fi
elif test "$win_sdk" = "no"; then
win_sdk=""
fi
fi
##########################################
# check if mingw environment provides a recent ntddscsi.h
guest_agent_ntddscsi="no"
if test "$mingw32" = "yes" && test "$guest_agent" != "no"; then
cat > $TMPC << EOF
#include <windows.h>
#include <ntddscsi.h>
int main(void) {
#if !defined(IOCTL_SCSI_GET_ADDRESS)
#error Missing required ioctl definitions
#endif
SCSI_ADDRESS addr = { .Lun = 0, .TargetId = 0, .PathId = 0 };
return addr.Lun;
}
EOF
if compile_prog "" "" ; then
guest_agent_ntddscsi=yes
libs_qga="-lsetupapi -lcfgmgr32 $libs_qga"
fi
fi
##########################################
# capstone
@ -2679,17 +2384,6 @@ else
esac
fi
if test "$coroutine_pool" = ""; then
coroutine_pool=yes
fi
if test "$debug_stack_usage" = "yes"; then
if test "$coroutine_pool" = "yes"; then
echo "WARN: disabling coroutine pool for stack usage debugging"
coroutine_pool=no
fi
fi
##################################################
# SafeStack
@ -2752,85 +2446,6 @@ else # "$safe_stack" = ""
fi
fi
########################################
# check if cpuid.h is usable.
cat > $TMPC << EOF
#include <cpuid.h>
int main(void) {
unsigned a, b, c, d;
unsigned max = __get_cpuid_max(0, 0);
if (max >= 1) {
__cpuid(1, a, b, c, d);
}
if (max >= 7) {
__cpuid_count(7, 0, a, b, c, d);
}
return 0;
}
EOF
if compile_prog "" "" ; then
cpuid_h=yes
fi
##########################################
# avx2 optimization requirement check
#
# There is no point enabling this if cpuid.h is not usable,
# since we won't be able to select the new routines.
if test "$cpuid_h" = "yes" && test "$avx2_opt" != "no"; then
cat > $TMPC << EOF
#pragma GCC push_options
#pragma GCC target("avx2")
#include <cpuid.h>
#include <immintrin.h>
static int bar(void *a) {
__m256i x = *(__m256i *)a;
return _mm256_testz_si256(x, x);
}
int main(int argc, char *argv[]) { return bar(argv[0]); }
EOF
if compile_object "-Werror" ; then
avx2_opt="yes"
else
avx2_opt="no"
fi
fi
##########################################
# avx512f optimization requirement check
#
# There is no point enabling this if cpuid.h is not usable,
# since we won't be able to select the new routines.
# by default, it is turned off.
# if user explicitly want to enable it, check environment
if test "$cpuid_h" = "yes" && test "$avx512f_opt" = "yes"; then
cat > $TMPC << EOF
#pragma GCC push_options
#pragma GCC target("avx512f")
#include <cpuid.h>
#include <immintrin.h>
static int bar(void *a) {
__m512i x = *(__m512i *)a;
return _mm512_test_epi64_mask(x, x);
}
int main(int argc, char *argv[])
{
return bar(argv[0]);
}
EOF
if ! compile_object "-Werror" ; then
avx512f_opt="no"
fi
else
avx512f_opt="no"
fi
########################################
# check if __[u]int128_t is usable.
@ -2926,63 +2541,6 @@ if test "$fortify_source" != "no"; then
fi
fi
##########################################
# check for usable membarrier system call
if test "$membarrier" = "yes"; then
have_membarrier=no
if test "$mingw32" = "yes" ; then
have_membarrier=yes
elif test "$linux" = "yes" ; then
cat > $TMPC << EOF
#include <linux/membarrier.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdlib.h>
int main(void) {
syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
exit(0);
}
EOF
if compile_prog "" "" ; then
have_membarrier=yes
fi
fi
if test "$have_membarrier" = "no"; then
feature_not_found "membarrier" "membarrier system call not available"
fi
else
# Do not enable it by default even for Mingw32, because it doesn't
# work on Wine.
membarrier=no
fi
##########################################
# check for usable AF_ALG environment
have_afalg=no
cat > $TMPC << EOF
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_alg.h>
int main(void) {
int sock;
sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
return sock;
}
EOF
if compile_prog "" "" ; then
have_afalg=yes
fi
if test "$crypto_afalg" = "yes"
then
if test "$have_afalg" != "yes"
then
error_exit "AF_ALG requested but could not be detected"
fi
fi
##########################################
# checks for sanitizers
@ -3064,19 +2622,6 @@ case "$slirp" in
;;
esac
# Check for slirp smbd dupport
: ${smbd=${SMBD-/usr/sbin/smbd}}
if test "$slirp_smbd" != "no" ; then
if test "$mingw32" = "yes" ; then
if test "$slirp_smbd" = "yes" ; then
error_exit "Host smbd not supported on this platform."
fi
slirp_smbd=no
else
slirp_smbd=yes
fi
fi
##########################################
# check for usable __NR_keyctl syscall
@ -3132,11 +2677,6 @@ alpha)
;;
esac
if test "$gprof" = "yes" ; then
QEMU_CFLAGS="-p $QEMU_CFLAGS"
QEMU_LDFLAGS="-p $QEMU_LDFLAGS"
fi
if test "$have_asan" = "yes"; then
QEMU_CFLAGS="-fsanitize=address $QEMU_CFLAGS"
QEMU_LDFLAGS="-fsanitize=address $QEMU_LDFLAGS"
@ -3188,20 +2728,6 @@ if test "$mingw32" = "yes" ; then
done
fi
# Probe for guest agent support/options
if [ "$guest_agent" != "no" ]; then
if [ "$softmmu" = no -a "$want_tools" = no ] ; then
guest_agent=no
elif [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then
guest_agent=yes
elif [ "$guest_agent" != yes ]; then
guest_agent=no
else
error_exit "Guest agent is not supported on this platform"
fi
fi
# Guest agent Windows MSI package
if test "$QEMU_GA_MANUFACTURER" = ""; then
@ -3302,14 +2828,6 @@ if test "$debug_tcg" = "yes" ; then
fi
if test "$mingw32" = "yes" ; then
echo "CONFIG_WIN32=y" >> $config_host_mak
if test "$guest_agent_with_vss" = "yes" ; then
echo "CONFIG_QGA_VSS=y" >> $config_host_mak
echo "QGA_VSS_PROVIDER=$qga_vss_provider" >> $config_host_mak
echo "WIN_SDK=\"$win_sdk\"" >> $config_host_mak
fi
if test "$guest_agent_ntddscsi" = "yes" ; then
echo "CONFIG_QGA_NTDDSCSI=y" >> $config_host_mak
fi
echo "QEMU_GA_MSI_MINGW_DLL_PATH=${QEMU_GA_MSI_MINGW_DLL_PATH}" >> $config_host_mak
echo "QEMU_GA_MANUFACTURER=${QEMU_GA_MANUFACTURER}" >> $config_host_mak
echo "QEMU_GA_DISTRO=${QEMU_GA_DISTRO}" >> $config_host_mak
@ -3332,27 +2850,8 @@ fi
if test "$static" = "yes" ; then
echo "CONFIG_STATIC=y" >> $config_host_mak
fi
if test "$profiler" = "yes" ; then
echo "CONFIG_PROFILER=y" >> $config_host_mak
fi
if test "$want_tools" = "yes" ; then
echo "CONFIG_TOOLS=y" >> $config_host_mak
fi
if test "$guest_agent" = "yes" ; then
echo "CONFIG_GUEST_AGENT=y" >> $config_host_mak
fi
if test "$slirp_smbd" = "yes" ; then
echo "CONFIG_SLIRP_SMBD=y" >> $config_host_mak
echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
fi
if test "$gprof" = "yes" ; then
echo "CONFIG_GPROF=y" >> $config_host_mak
fi
echo "CONFIG_BDRV_RW_WHITELIST=$block_drv_rw_whitelist" >> $config_host_mak
echo "CONFIG_BDRV_RO_WHITELIST=$block_drv_ro_whitelist" >> $config_host_mak
if test "$block_drv_whitelist_tools" = "yes" ; then
echo "CONFIG_BDRV_WHITELIST_TOOLS=y" >> $config_host_mak
fi
qemu_version=$(head $source_path/VERSION)
echo "PKGVERSION=$pkgversion" >>$config_host_mak
echo "SRC_PATH=$source_path" >> $config_host_mak
@ -3418,9 +2917,6 @@ fi
if test "$vhost_user_fs" = "yes" ; then
echo "CONFIG_VHOST_USER_FS=y" >> $config_host_mak
fi
if test "$membarrier" = "yes" ; then
echo "CONFIG_MEMBARRIER=y" >> $config_host_mak
fi
if test "$tcg" = "enabled" -a "$tcg_interpreter" = "true" ; then
echo "CONFIG_TCG_INTERPRETER=y" >> $config_host_mak
fi
@ -3431,37 +2927,12 @@ if test "$opengl" = "yes" ; then
echo "OPENGL_LIBS=$opengl_libs" >> $config_host_mak
fi
if test "$avx2_opt" = "yes" ; then
echo "CONFIG_AVX2_OPT=y" >> $config_host_mak
fi
if test "$avx512f_opt" = "yes" ; then
echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak
fi
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
echo "CONFIG_BSD=y" >> $config_host_mak
fi
if test "$qom_cast_debug" = "yes" ; then
echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
fi
echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
if test "$coroutine_pool" = "yes" ; then
echo "CONFIG_COROUTINE_POOL=1" >> $config_host_mak
else
echo "CONFIG_COROUTINE_POOL=0" >> $config_host_mak
fi
if test "$debug_stack_usage" = "yes" ; then
echo "CONFIG_DEBUG_STACK_USAGE=y" >> $config_host_mak
fi
if test "$crypto_afalg" = "yes" ; then
echo "CONFIG_AF_ALG=y" >> $config_host_mak
fi
if test "$have_asan_iface_fiber" = "yes" ; then
echo "CONFIG_ASAN_IFACE_FIBER=y" >> $config_host_mak
@ -3471,10 +2942,6 @@ if test "$have_tsan" = "yes" && test "$have_tsan_iface_fiber" = "yes" ; then
echo "CONFIG_TSAN=y" >> $config_host_mak
fi
if test "$cpuid_h" = "yes" ; then
echo "CONFIG_CPUID_H=y" >> $config_host_mak
fi
if test "$int128" = "yes" ; then
echo "CONFIG_INT128=y" >> $config_host_mak
fi
@ -3487,14 +2954,6 @@ if test "$cmpxchg128" = "yes" ; then
echo "CONFIG_CMPXCHG128=y" >> $config_host_mak
fi
if test "$live_block_migration" = "yes" ; then
echo "CONFIG_LIVE_BLOCK_MIGRATION=y" >> $config_host_mak
fi
if test "$tpm" = "yes"; then
echo 'CONFIG_TPM=y' >> $config_host_mak
fi
if test "$rdma" = "yes" ; then
echo "CONFIG_RDMA=y" >> $config_host_mak
echo "RDMA_LIBS=$rdma_libs" >> $config_host_mak
@ -3504,39 +2963,6 @@ if test "$pvrdma" = "yes" ; then
echo "CONFIG_PVRDMA=y" >> $config_host_mak
fi
if test "$replication" = "yes" ; then
echo "CONFIG_REPLICATION=y" >> $config_host_mak
fi
if test "$debug_mutex" = "yes" ; then
echo "CONFIG_DEBUG_MUTEX=y" >> $config_host_mak
fi
if test "$bochs" = "yes" ; then
echo "CONFIG_BOCHS=y" >> $config_host_mak
fi
if test "$cloop" = "yes" ; then
echo "CONFIG_CLOOP=y" >> $config_host_mak
fi
if test "$dmg" = "yes" ; then
echo "CONFIG_DMG=y" >> $config_host_mak
fi
if test "$qcow1" = "yes" ; then
echo "CONFIG_QCOW1=y" >> $config_host_mak
fi
if test "$vdi" = "yes" ; then
echo "CONFIG_VDI=y" >> $config_host_mak
fi
if test "$vvfat" = "yes" ; then
echo "CONFIG_VVFAT=y" >> $config_host_mak
fi
if test "$qed" = "yes" ; then
echo "CONFIG_QED=y" >> $config_host_mak
fi
if test "$parallels" = "yes" ; then
echo "CONFIG_PARALLELS=y" >> $config_host_mak
fi
if test "$plugins" = "yes" ; then
echo "CONFIG_PLUGIN=y" >> $config_host_mak
fi
@ -3567,9 +2993,6 @@ echo "MESON=$meson" >> $config_host_mak
echo "NINJA=$ninja" >> $config_host_mak
echo "CC=$cc" >> $config_host_mak
echo "HOST_CC=$host_cc" >> $config_host_mak
if $iasl -h > /dev/null 2>&1; then
echo "CONFIG_IASL=$iasl" >> $config_host_mak
fi
echo "AR=$ar" >> $config_host_mak
echo "AS=$as" >> $config_host_mak
echo "CCAS=$ccas" >> $config_host_mak
@ -3586,11 +3009,6 @@ echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
echo "STRIP=$strip" >> $config_host_mak
echo "EXESUF=$EXESUF" >> $config_host_mak
echo "LIBS_QGA=$libs_qga" >> $config_host_mak
if test "$rng_none" = "yes"; then
echo "CONFIG_RNG_NONE=y" >> $config_host_mak
fi
# use included Linux headers
if test "$linux" = "yes" ; then
@ -3640,11 +3058,6 @@ if test "$default_targets" = "yes"; then
echo "CONFIG_DEFAULT_TARGETS=y" >> $config_host_mak
fi
if test "$numa" = "yes"; then
echo "CONFIG_NUMA=y" >> $config_host_mak
echo "NUMA_LIBS=$numa_libs" >> $config_host_mak
fi
if test "$ccache_cpp2" = "yes"; then
echo "export CCACHE_CPP2=y" >> $config_host_mak
fi
@ -3797,8 +3210,10 @@ if test "$skip_meson" = no; then
-Daudio_drv_list=$audio_drv_list \
-Ddefault_devices=$default_devices \
-Ddocdir="$docdir" \
-Diasl="$($iasl -h >/dev/null 2>&1 && printf %s "$iasl")" \
-Dqemu_firmwarepath="$firmwarepath" \
-Dqemu_suffix="$qemu_suffix" \
-Dsmbd="$smbd" \
-Dsphinx_build="$sphinx_build" \
-Dtrace_file="$trace_file" \
-Doptimization=$(if test "$debug" = yes; then echo 0; else echo 2; fi) \

View File

@ -1,5 +1,4 @@
if 'CONFIG_TOOLS' in config_host and virgl.found() and gbm.found() \
and 'CONFIG_LINUX' in config_host and pixman.found()
if have_vhost_user_gpu
executable('vhost-user-gpu', files('vhost-user-gpu.c', 'virgl.c', 'vugbm.c'),
dependencies: [qemuutil, pixman, gbm, virgl, vhost_user, opengl],
install: true,

View File

@ -35,7 +35,9 @@ else
endif
crypto_ss.add(when: 'CONFIG_SECRET_KEYRING', if_true: files('secret_keyring.c'))
crypto_ss.add(when: 'CONFIG_AF_ALG', if_true: files('afalg.c', 'cipher-afalg.c', 'hash-afalg.c'))
if have_afalg
crypto_ss.add(if_true: files('afalg.c', 'cipher-afalg.c', 'hash-afalg.c'))
endif
crypto_ss.add(when: gnutls, if_true: files('tls-cipher-suites.c'))
util_ss.add(files('aes.c'))
@ -48,7 +50,7 @@ if gcrypt.found()
util_ss.add(gcrypt, files('random-gcrypt.c'))
elif gnutls.found()
util_ss.add(gnutls, files('random-gnutls.c'))
elif 'CONFIG_RNG_NONE' in config_host
elif get_option('rng_none')
util_ss.add(files('random-none.c'))
else
util_ss.add(files('random-platform.c'))

View File

@ -192,11 +192,15 @@ declares its dependencies in different ways:
no directive and are not used in the Makefile either; they only appear
as conditions for ``default y`` directives.
QEMU currently has two device groups, ``PCI_DEVICES`` and
``TEST_DEVICES``. PCI devices usually have a ``default y if
QEMU currently has three device groups, ``PCI_DEVICES``, ``I2C_DEVICES``,
and ``TEST_DEVICES``. PCI devices usually have a ``default y if
PCI_DEVICES`` directive rather than just ``default y``. This lets
some boards (notably s390) easily support a subset of PCI devices,
for example only VFIO (passthrough) and virtio-pci devices.
``I2C_DEVICES`` is similar to ``PCI_DEVICES``. It contains i2c devices
that users might reasonably want to plug in to an i2c bus on any
board (and not ones which are very board-specific or that need
to be wired up in a way that can't be done on the command line).
``TEST_DEVICES`` instead is used for devices that are rarely used on
production virtual machines, but provide useful hooks to test QEMU
or KVM.
@ -301,7 +305,7 @@ and also listed as follows in the top-level meson.build's host_kconfig
variable::
host_kconfig = \
('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
(have_tpm ? ['CONFIG_TPM=y'] : []) + \
('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
(have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
...

View File

@ -210,24 +210,61 @@
'data' : { 'filename' : 'str',
'format' : 'BlockdevDriver' } }
##
# @FirmwareFlashType:
#
# Describes how the firmware build handles code versus variable
# persistence.
#
# @split: the executable file contains code while the NVRAM
# template provides variable storage. The executable
# must be configured read-only and can be shared between
# multiple guests. The NVRAM template must be cloned
# for each new guest and configured read-write.
#
# @combined: the executable file contains both code and
# variable storage. The executable must be cloned
# for each new guest and configured read-write.
# No NVRAM template will be specified.
#
# @stateless: the executable file contains code and variable
# storage is not persisted. The executable must
# be configured read-only and can be shared
# between multiple guests. No NVRAM template
# will be specified.
#
# Since: 7.0.0
##
{ 'enum': 'FirmwareFlashMode',
'data': [ 'split', 'combined', 'stateless' ] }
##
# @FirmwareMappingFlash:
#
# Describes loading and mapping properties for the firmware executable
# and its accompanying NVRAM file, when @FirmwareDevice is @flash.
#
# @executable: Identifies the firmware executable. The firmware
# executable may be shared by multiple virtual machine
# definitions. The preferred corresponding QEMU command
# line options are
# @mode: Describes how the firmware build handles code versus variable
# storage. If not present, it must be treated as if it was
# configured with value ``split``. Since: 7.0.0
#
# @executable: Identifies the firmware executable. The @mode
# indicates whether there will be an associated
# NVRAM template present. The preferred
# corresponding QEMU command line options are
# -drive if=none,id=pflash0,readonly=on,file=@executable.@filename,format=@executable.@format
# -machine pflash0=pflash0
# or equivalent -blockdev instead of -drive.
# or equivalent -blockdev instead of -drive. When
# @mode is ``combined`` the executable must be
# cloned before use and configured with readonly=off.
# With QEMU versions older than 4.0, you have to use
# -drive if=pflash,unit=0,readonly=on,file=@executable.@filename,format=@executable.@format
#
# @nvram-template: Identifies the NVRAM template compatible with
# @executable. Management software instantiates an
# @executable, when @mode is set to ``split``,
# otherwise it should not be present.
# Management software instantiates an
# individual copy -- a specific NVRAM file -- from
# @nvram-template.@filename for each new virtual
# machine definition created. @nvram-template.@filename
@ -246,8 +283,9 @@
# Since: 3.0
##
{ 'struct' : 'FirmwareMappingFlash',
'data' : { 'executable' : 'FirmwareFlashFile',
'nvram-template' : 'FirmwareFlashFile' } }
'data' : { '*mode': 'FirmwareFlashMode',
'executable' : 'FirmwareFlashFile',
'*nvram-template' : 'FirmwareFlashFile' } }
##
# @FirmwareMappingKernel:

View File

@ -37,8 +37,6 @@ endif
if build_docs
SPHINX_ARGS += ['-Dversion=' + meson.project_version(), '-Drelease=' + config_host['PKGVERSION']]
have_ga = have_tools and config_host.has_key('CONFIG_GUEST_AGENT')
man_pages = {
'qemu-ga.8': (have_ga ? 'man8' : ''),
'qemu-ga-ref.7': (have_ga ? 'man7' : ''),

View File

@ -21,6 +21,7 @@ Hyperscale applications. The following machines are based on this chip :
- ``quanta-gbs-bmc`` Quanta GBS server BMC
- ``quanta-gsj`` Quanta GSJ server BMC
- ``kudo-bmc`` Fii USA Kudo server BMC
- ``mori-bmc`` Fii USA Mori server BMC
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
variants of NPCM750 and NPCM730, respectively. These are currently not

View File

@ -778,10 +778,32 @@ The optional *HOST_KEY_CHECK* parameter controls how the remote
host's key is checked. The default is ``yes`` which means to use
the local ``.ssh/known_hosts`` file. Setting this to ``no``
turns off known-hosts checking. Or you can check that the host key
matches a specific fingerprint:
``host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8``
(``sha1:`` can also be used as a prefix, but note that OpenSSH
tools only use MD5 to print fingerprints).
matches a specific fingerprint. The fingerprint can be provided in
``md5``, ``sha1``, or ``sha256`` format, however, it is strongly
recommended to only use ``sha256``, since the other options are
considered insecure by modern standards. The fingerprint value
must be given as a hex encoded string::
host_key_check=sha256:04ce2ae89ff4295a6b9c4111640bdcb3297858ee55cb434d9dd88796e93aa795
The key string may optionally contain ":" separators between
each pair of hex digits.
The ``$HOME/.ssh/known_hosts`` file contains the base64 encoded
host keys. These can be converted into the format needed for
QEMU using a command such as::
$ for key in `grep 10.33.8.112 known_hosts | awk '{print $3}'`
do
echo $key | base64 -d | sha256sum
done
6c3aa525beda9dc83eadfbd7e5ba7d976ecb59575d1633c87cd06ed2ed6e366f -
12214fd9ea5b408086f98ecccd9958609bd9ac7c0ea316734006bc7818b45dc8 -
d36420137bcbd101209ef70c3b15dc07362fbe0fa53c5b135eba6e6afa82f0ce -
Note that there can be multiple keys present per host, each with
different key ciphers. Care is needed to pick the key fingerprint
that matches the cipher QEMU will negotiate with the remote server.
Currently authentication must be done using ssh-agent. Other
authentication methods may be supported in future.

View File

@ -104,6 +104,13 @@ Options
* posix_acl|no_posix_acl -
Enable/disable posix acl support. Posix ACLs are disabled by default.
* security_label|no_security_label -
Enable/disable security label support. Security labels are disabled by
default. This will allow client to send a MAC label of file during
file creation. Typically this is expected to be SELinux security
label. Server will try to set that label on newly created file
atomically wherever possible.
.. option:: --socket-path=PATH
Listen on vhost-user UNIX domain socket at PATH.
@ -348,6 +355,31 @@ client arguments or lists returned from the host. This stops
the client seeing any 'security.' attributes on the server and
stops it setting any.
SELinux support
---------------
One can enable support for SELinux by running virtiofsd with option
"-o security_label". But this will try to save guest's security context
in xattr security.selinux on host and it might fail if host's SELinux
policy does not permit virtiofsd to do this operation.
Hence, it is preferred to remap guest's "security.selinux" xattr to say
"trusted.virtiofs.security.selinux" on host.
"-o xattrmap=:map:security.selinux:trusted.virtiofs.:"
This will make sure that guest and host's SELinux xattrs on same file
remain separate and not interfere with each other. And will allow both
host and guest to implement their own separate SELinux policies.
Setting trusted xattr on host requires CAP_SYS_ADMIN. So one will need
add this capability to daemon.
"-o modcaps=+sys_admin"
Giving CAP_SYS_ADMIN increases the risk on system. Now virtiofsd is more
powerful and if gets compromised, it can do lot of damage to host system.
So keep this trade-off in my mind while making a decision.
Examples
--------

View File

@ -182,7 +182,12 @@ static int synth_opendir(FsContext *ctx,
V9fsSynthOpenState *synth_open;
V9fsSynthNode *node = *(V9fsSynthNode **)fs_path->data;
synth_open = g_malloc(sizeof(*synth_open));
/*
* V9fsSynthOpenState contains 'struct dirent' which have OS-specific
* properties, thus it's zero cleared on allocation here and below
* in synth_open.
*/
synth_open = g_new0(V9fsSynthOpenState, 1);
synth_open->node = node;
node->open_count++;
fs->private = synth_open;
@ -220,7 +225,14 @@ static void synth_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
static void synth_direntry(V9fsSynthNode *node,
struct dirent *entry, off_t off)
{
strcpy(entry->d_name, node->name);
size_t sz = strlen(node->name) + 1;
/*
* 'entry' is always inside of V9fsSynthOpenState which have NAME_MAX
* back padding. Ensure we do not overflow it.
*/
g_assert(sizeof(struct dirent) + NAME_MAX >=
offsetof(struct dirent, d_name) + sz);
memcpy(entry->d_name, node->name, sz);
entry->d_ino = node->attr->inode;
entry->d_off = off + 1;
}
@ -266,7 +278,7 @@ static int synth_open(FsContext *ctx, V9fsPath *fs_path,
V9fsSynthOpenState *synth_open;
V9fsSynthNode *node = *(V9fsSynthNode **)fs_path->data;
synth_open = g_malloc(sizeof(*synth_open));
synth_open = g_new0(V9fsSynthOpenState, 1);
synth_open->node = node;
node->open_count++;
fs->private = synth_open;

View File

@ -41,6 +41,11 @@ typedef struct V9fsSynthOpenState {
off_t offset;
V9fsSynthNode *node;
struct dirent dent;
/*
* Ensure there is enough space for 'dent' above, some systems have a
* d_name size of just 1, which would cause a buffer overrun.
*/
char dent_trailing_space[NAME_MAX];
} V9fsSynthOpenState;
int qemu_v9fs_synth_mkdir(V9fsSynthNode *parent, int mode,

View File

@ -143,8 +143,7 @@ static int do_readdir_many(V9fsPDU *pdu, V9fsFidState *fidp,
} else {
e = e->next = g_malloc0(sizeof(V9fsDirEnt));
}
e->dent = g_malloc0(sizeof(struct dirent));
memcpy(e->dent, dent, sizeof(struct dirent));
e->dent = qemu_dirent_dup(dent);
/* perform a full stat() for directory entry if requested by caller */
if (dostat) {

View File

@ -1,6 +1,5 @@
#include "qemu/osdep.h"
#include "hw/acpi/memory_hotplug.h"
#include "hw/acpi/pc-hotplug.h"
#include "hw/mem/pc-dimm.h"
#include "hw/qdev-core.h"
#include "migration/vmstate.h"

View File

@ -25,7 +25,9 @@ acpi_ss.add(when: 'CONFIG_ACPI_X86_ICH', if_true: files('ich9.c', 'tco.c'))
acpi_ss.add(when: 'CONFIG_ACPI_ERST', if_true: files('erst.c'))
acpi_ss.add(when: 'CONFIG_IPMI', if_true: files('ipmi.c'), if_false: files('ipmi-stub.c'))
acpi_ss.add(when: 'CONFIG_PC', if_false: files('acpi-x86-stub.c'))
acpi_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
if have_tpm
acpi_ss.add(files('tpm.c'))
endif
softmmu_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-build-stub.c', 'ghes-stub.c'))
softmmu_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss)
softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('acpi-stub.c', 'aml-build-stub.c',

View File

@ -46,6 +46,7 @@ config DIGIC
config EXYNOS4
bool
imply I2C_DEVICES
select A9MPCORE
select I2C
select LAN9118
@ -184,6 +185,7 @@ config REALVIEW
bool
imply PCI_DEVICES
imply PCI_TESTDEV
imply I2C_DEVICES
select SMC91C111
select LAN9118
select A9MPCORE
@ -229,6 +231,7 @@ config SABRELITE
config STELLARIS
bool
imply I2C_DEVICES
select ARM_V7M
select CMSDK_APB_WATCHDOG
select I2C
@ -406,6 +409,7 @@ config NPCM7XX
config FSL_IMX25
bool
imply I2C_DEVICES
select IMX
select IMX_FEC
select IMX_I2C
@ -414,6 +418,7 @@ config FSL_IMX25
config FSL_IMX31
bool
imply I2C_DEVICES
select SERIAL
select IMX
select IMX_I2C
@ -422,6 +427,7 @@ config FSL_IMX31
config FSL_IMX6
bool
imply I2C_DEVICES
select A9MPCORE
select IMX
select IMX_FEC
@ -450,6 +456,7 @@ config ASPEED_SOC
config MPS2
bool
imply I2C_DEVICES
select ARMSSE
select LAN9118
select MPS2_FPGAIO
@ -466,6 +473,7 @@ config FSL_IMX7
bool
imply PCI_DEVICES
imply TEST_DEVICES
imply I2C_DEVICES
select A15MPCORE
select PCI
select IMX
@ -481,6 +489,7 @@ config ARM_SMMUV3
config FSL_IMX6UL
bool
imply I2C_DEVICES
select A15MPCORE
select IMX
select IMX_FEC
@ -495,6 +504,7 @@ config MICROBIT
config NRF51_SOC
bool
imply I2C_DEVICES
select I2C
select ARM_V7M
select UNIMP

View File

@ -284,6 +284,12 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
return;
}
/* cpuclk must be connected; refclk is optional */
if (!clock_has_source(s->cpuclk)) {
error_setg(errp, "armv7m: cpuclk must be connected");
return;
}
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
s->cpu = ARM_CPU(object_new_with_props(s->cpu_type, OBJECT(s), "cpu",
@ -420,8 +426,18 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
&s->sysreg_ns_mem);
}
/* Create and map the systick devices */
qdev_connect_clock_in(DEVICE(&s->systick[M_REG_NS]), "refclk", s->refclk);
/*
* Create and map the systick devices. Note that we only connect
* refclk if it has been connected to us; otherwise the systick
* device gets the wrong answer for clock_has_source(refclk), because
* it has an immediate source (the ARMv7M's clock object) but not
* an ultimate source, and then it won't correctly auto-select the
* CPU clock as its only possible clock source.
*/
if (clock_has_source(s->refclk)) {
qdev_connect_clock_in(DEVICE(&s->systick[M_REG_NS]), "refclk",
s->refclk);
}
qdev_connect_clock_in(DEVICE(&s->systick[M_REG_NS]), "cpuclk", s->cpuclk);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), errp)) {
return;
@ -438,8 +454,10 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
*/
object_initialize_child(OBJECT(dev), "systick-reg-s",
&s->systick[M_REG_S], TYPE_SYSTICK);
if (clock_has_source(s->refclk)) {
qdev_connect_clock_in(DEVICE(&s->systick[M_REG_S]), "refclk",
s->refclk);
}
qdev_connect_clock_in(DEVICE(&s->systick[M_REG_S]), "cpuclk",
s->cpuclk);

View File

@ -34,6 +34,7 @@
#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
@ -429,6 +430,21 @@ static void kudo_bmc_init(MachineState *machine)
npcm7xx_load_kernel(machine, soc);
}
static void mori_bmc_init(MachineState *machine)
{
NPCM7xxState *soc;
soc = npcm7xx_create_soc(machine, MORI_BMC_POWER_ON_STRAPS);
npcm7xx_connect_dram(soc, machine->ram);
qdev_realize(DEVICE(soc), NULL, &error_fatal);
npcm7xx_load_bootrom(machine, soc);
npcm7xx_connect_flash(&soc->fiu[1], 0, "mx66u51235f",
drive_get(IF_MTD, 3, 0));
npcm7xx_load_kernel(machine, soc);
}
static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char *type)
{
NPCM7xxClass *sc = NPCM7XX_CLASS(object_class_by_name(type));
@ -501,6 +517,18 @@ static void kudo_bmc_machine_class_init(ObjectClass *oc, void *data)
mc->default_ram_size = 1 * GiB;
};
static void mori_bmc_machine_class_init(ObjectClass *oc, void *data)
{
NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
MachineClass *mc = MACHINE_CLASS(oc);
npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
mc->desc = "Mori BMC (Cortex-A9)";
mc->init = mori_bmc_init;
mc->default_ram_size = 1 * GiB;
}
static const TypeInfo npcm7xx_machine_types[] = {
{
.name = TYPE_NPCM7XX_MACHINE,
@ -525,6 +553,10 @@ static const TypeInfo npcm7xx_machine_types[] = {
.name = MACHINE_TYPE_NAME("kudo-bmc"),
.parent = TYPE_NPCM7XX_MACHINE,
.class_init = kudo_bmc_machine_class_init,
}, {
.name = MACHINE_TYPE_NAME("mori-bmc"),
.parent = TYPE_NPCM7XX_MACHINE,
.class_init = mori_bmc_machine_class_init,
},
};

View File

@ -24,6 +24,7 @@
#include "chardev/char.h"
#include "qemu/cutils.h"
#include "qemu/bswap.h"
#include "qemu/hw-version.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"

View File

@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qapi/error.h"

View File

@ -207,7 +207,7 @@ static void generic_loader_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static TypeInfo generic_loader_info = {
static const TypeInfo generic_loader_info = {
.name = TYPE_GENERIC_LOADER,
.parent = TYPE_DEVICE,
.instance_size = sizeof(GenericLoaderState),

View File

@ -129,7 +129,7 @@ static void guest_loader_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static TypeInfo guest_loader_info = {
static const TypeInfo guest_loader_info = {
.name = TYPE_GUEST_LOADER,
.parent = TYPE_DEVICE,
.instance_size = sizeof(GuestLoaderState),

View File

@ -14,7 +14,6 @@
#include "sysemu/cpu-timers.h"
#include "sysemu/qtest.h"
#include "block/aio.h"
#include "sysemu/cpus.h"
#include "hw/clock.h"
#define DELTA_ADJUST 1

View File

@ -454,7 +454,7 @@ static void bcm2835_fb_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2835_fb;
}
static TypeInfo bcm2835_fb_info = {
static const TypeInfo bcm2835_fb_info = {
.name = TYPE_BCM2835_FB,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835FBState),

View File

@ -113,7 +113,7 @@ static void i2c_ddc_class_init(ObjectClass *oc, void *data)
isc->send = i2c_ddc_tx;
}
static TypeInfo i2c_ddc_info = {
static const TypeInfo i2c_ddc_info = {
.name = TYPE_I2CDDC,
.parent = TYPE_I2C_SLAVE,
.instance_size = sizeof(I2CDDCState),

View File

@ -782,14 +782,14 @@ static void macfb_nubus_class_init(ObjectClass *klass, void *data)
device_class_set_props(dc, macfb_nubus_properties);
}
static TypeInfo macfb_sysbus_info = {
static const TypeInfo macfb_sysbus_info = {
.name = TYPE_MACFB,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MacfbSysBusState),
.class_init = macfb_sysbus_class_init,
};
static TypeInfo macfb_nubus_info = {
static const TypeInfo macfb_nubus_info = {
.name = TYPE_NUBUS_MACFB,
.parent = TYPE_NUBUS_DEVICE,
.instance_size = sizeof(MacfbNubusState),

View File

@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/hw.h"
#include "hw/irq.h"
#include "ui/console.h"

View File

@ -220,7 +220,7 @@ static void virtio_vga_base_class_init(ObjectClass *klass, void *data)
virtio_vga_set_big_endian_fb);
}
static TypeInfo virtio_vga_base_info = {
static const TypeInfo virtio_vga_base_info = {
.name = TYPE_VIRTIO_VGA_BASE,
.parent = TYPE_VIRTIO_PCI,
.instance_size = sizeof(VirtIOVGABase),

View File

@ -394,7 +394,7 @@ static void bcm2835_dma_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2835_dma;
}
static TypeInfo bcm2835_dma_info = {
static const TypeInfo bcm2835_dma_info = {
.name = TYPE_BCM2835_DMA,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835DMAState),

View File

@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/arm/omap.h"

View File

@ -1,6 +1,11 @@
config I2C
bool
config I2C_DEVICES
# Device group for i2c devices which can reasonably be user-plugged
# to any board's i2c bus
bool
config SMBUS
bool
select I2C

View File

@ -867,7 +867,7 @@ static void isa_bridge_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_ISA;
};
static TypeInfo isa_bridge_info = {
static const TypeInfo isa_bridge_info = {
.name = "igd-passthrough-isa-bridge",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),

View File

@ -167,7 +167,7 @@ static void sgx_epc_class_init(ObjectClass *oc, void *data)
mdc->fill_device_info = sgx_epc_md_fill_device_info;
}
static TypeInfo sgx_epc_info = {
static const TypeInfo sgx_epc_info = {
.name = TYPE_SGX_EPC,
.parent = TYPE_DEVICE,
.instance_size = sizeof(SGXEPCDevice),

View File

@ -29,6 +29,7 @@
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/timer.h"
#include "qemu/hw-version.h"
#include "sysemu/sysemu.h"
#include "sysemu/blockdev.h"
#include "sysemu/dma.h"

View File

@ -114,6 +114,8 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
[INPUT_BUTTON_LEFT] = 0x01,
[INPUT_BUTTON_RIGHT] = 0x02,
[INPUT_BUTTON_MIDDLE] = 0x04,
[INPUT_BUTTON_SIDE] = 0x08,
[INPUT_BUTTON_EXTRA] = 0x10,
};
HIDState *hs = (HIDState *)dev;
HIDPointerEvent *e;

View File

@ -20,6 +20,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/hw.h"
#include "audio/audio.h"
#include "qemu/timer.h"

View File

@ -227,7 +227,7 @@ static void bcm2835_ic_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2835_ic;
}
static TypeInfo bcm2835_ic_info = {
static const TypeInfo bcm2835_ic_info = {
.name = TYPE_BCM2835_IC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835ICState),

View File

@ -392,7 +392,7 @@ static void bcm2836_control_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2836_control;
}
static TypeInfo bcm2836_control_info = {
static const TypeInfo bcm2836_control_info = {
.name = TYPE_BCM2836_CONTROL,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2836ControlState),

View File

@ -85,7 +85,7 @@ static void ipmi_interface_class_init(ObjectClass *class, void *data)
ik->do_hw_op = ipmi_do_hw_op;
}
static TypeInfo ipmi_interface_type_info = {
static const TypeInfo ipmi_interface_type_info = {
.name = TYPE_IPMI_INTERFACE,
.parent = TYPE_INTERFACE,
.class_size = sizeof(IPMIInterfaceClass),
@ -120,7 +120,7 @@ static void bmc_class_init(ObjectClass *oc, void *data)
device_class_set_props(dc, ipmi_bmc_properties);
}
static TypeInfo ipmi_bmc_type_info = {
static const TypeInfo ipmi_bmc_type_info = {
.name = TYPE_IPMI_BMC,
.parent = TYPE_DEVICE,
.instance_size = sizeof(IPMIBmc),

View File

@ -181,10 +181,25 @@ static MemoryRegion *nvdimm_md_get_memory_region(MemoryDeviceState *md,
static void nvdimm_realize(PCDIMMDevice *dimm, Error **errp)
{
NVDIMMDevice *nvdimm = NVDIMM(dimm);
NVDIMMClass *ndc = NVDIMM_GET_CLASS(nvdimm);
if (!nvdimm->nvdimm_mr) {
nvdimm_prepare_memory_region(nvdimm, errp);
}
if (ndc->realize) {
ndc->realize(nvdimm, errp);
}
}
static void nvdimm_unrealize(PCDIMMDevice *dimm)
{
NVDIMMDevice *nvdimm = NVDIMM(dimm);
NVDIMMClass *ndc = NVDIMM_GET_CLASS(nvdimm);
if (ndc->unrealize) {
ndc->unrealize(nvdimm);
}
}
/*
@ -240,6 +255,7 @@ static void nvdimm_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);
ddc->realize = nvdimm_realize;
ddc->unrealize = nvdimm_unrealize;
mdc->get_memory_region = nvdimm_md_get_memory_region;
device_class_set_props(dc, nvdimm_properties);
@ -248,7 +264,7 @@ static void nvdimm_class_init(ObjectClass *oc, void *data)
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static TypeInfo nvdimm_info = {
static const TypeInfo nvdimm_info = {
.name = TYPE_NVDIMM,
.parent = TYPE_PC_DIMM,
.class_size = sizeof(NVDIMMClass),

View File

@ -216,6 +216,11 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp)
static void pc_dimm_unrealize(DeviceState *dev)
{
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
if (ddc->unrealize) {
ddc->unrealize(dimm);
}
host_memory_backend_set_mapped(dimm->hostmem, false);
}
@ -286,7 +291,7 @@ static void pc_dimm_class_init(ObjectClass *oc, void *data)
mdc->fill_device_info = pc_dimm_md_fill_device_info;
}
static TypeInfo pc_dimm_info = {
static const TypeInfo pc_dimm_info = {
.name = TYPE_PC_DIMM,
.parent = TYPE_DEVICE,
.instance_size = sizeof(PCDIMMDevice),

View File

@ -323,7 +323,7 @@ static void bcm2835_mbox_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2835_mbox;
}
static TypeInfo bcm2835_mbox_info = {
static const TypeInfo bcm2835_mbox_info = {
.name = TYPE_BCM2835_MBOX,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835MboxState),

View File

@ -144,7 +144,7 @@ static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2835_powermgt;
}
static TypeInfo bcm2835_powermgt_info = {
static const TypeInfo bcm2835_powermgt_info = {
.name = TYPE_BCM2835_POWERMGT,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835PowerMgtState),

View File

@ -421,7 +421,7 @@ static void bcm2835_property_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2835_property;
}
static TypeInfo bcm2835_property_info = {
static const TypeInfo bcm2835_property_info = {
.name = TYPE_BCM2835_PROPERTY,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835PropertyState),

View File

@ -131,7 +131,7 @@ static void bcm2835_rng_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2835_rng;
}
static TypeInfo bcm2835_rng_info = {
static const TypeInfo bcm2835_rng_info = {
.name = TYPE_BCM2835_RNG,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835RngState),

View File

@ -77,7 +77,7 @@ static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static TypeInfo pvpanic_isa_info = {
static const TypeInfo pvpanic_isa_info = {
.name = TYPE_PVPANIC_ISA_DEVICE,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(PVPanicISAState),

View File

@ -74,7 +74,7 @@ static void pvpanic_pci_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static TypeInfo pvpanic_pci_info = {
static const TypeInfo pvpanic_pci_info = {
.name = TYPE_PVPANIC_PCI_DEVICE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PVPanicPCIState),

View File

@ -430,7 +430,7 @@ static void etsec_class_init(ObjectClass *klass, void *data)
dc->user_creatable = true;
}
static TypeInfo etsec_info = {
static const TypeInfo etsec_info = {
.name = TYPE_ETSEC_COMMON,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(eTSEC),

View File

@ -54,7 +54,7 @@ struct EEPROMState {
static
int at24c_eeprom_event(I2CSlave *s, enum i2c_event event)
{
EEPROMState *ee = container_of(s, EEPROMState, parent_obj);
EEPROMState *ee = AT24C_EE(s);
switch (event) {
case I2C_START_SEND:

View File

@ -449,6 +449,11 @@ static target_ulong pegasos2_rtas(PowerPCCPU *cpu, Pegasos2MachineState *pm,
}
}
static bool pegasos2_cpu_in_nested(PowerPCCPU *cpu)
{
return false;
}
static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
{
Pegasos2MachineState *pm = PEGASOS2_MACHINE(vhyp);
@ -504,6 +509,7 @@ static void pegasos2_machine_class_init(ObjectClass *oc, void *data)
mc->default_ram_id = "pegasos2.ram";
mc->default_ram_size = 512 * MiB;
vhc->cpu_in_nested = pegasos2_cpu_in_nested;
vhc->hypercall = pegasos2_hypercall;
vhc->cpu_exec_enter = vhyp_nop;
vhc->cpu_exec_exit = vhyp_nop;

View File

@ -1072,7 +1072,7 @@ clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
}
/* Create new timer */
tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_decr_cb, cpu);
if (env->has_hv_mode) {
if (env->has_hv_mode && !cpu->vhyp) {
tb_env->hdecr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_hdecr_cb,
cpu);
} else {
@ -1083,6 +1083,27 @@ clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
return &cpu_ppc_set_tb_clk;
}
/* cpu_ppc_hdecr_init may be used if the timer is not used by HDEC emulation */
void cpu_ppc_hdecr_init(CPUPPCState *env)
{
PowerPCCPU *cpu = env_archcpu(env);
assert(env->tb_env->hdecr_timer == NULL);
env->tb_env->hdecr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
&cpu_ppc_hdecr_cb, cpu);
}
void cpu_ppc_hdecr_exit(CPUPPCState *env)
{
PowerPCCPU *cpu = env_archcpu(env);
timer_free(env->tb_env->hdecr_timer);
env->tb_env->hdecr_timer = NULL;
cpu_ppc_hdecr_lower(cpu);
}
/*****************************************************************************/
/* PowerPC 40x timers */

View File

@ -300,7 +300,7 @@ static void prep_systemio_class_initfn(ObjectClass *klass, void *data)
device_class_set_props(dc, prep_systemio_properties);
}
static TypeInfo prep_systemio800_info = {
static const TypeInfo prep_systemio800_info = {
.name = TYPE_PREP_SYSTEMIO,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(PrepSystemIoState),

View File

@ -1270,6 +1270,8 @@ static void emulate_spapr_hypercall(PPCVirtualHypervisor *vhyp,
/* The TCG path should also be holding the BQL at this point */
g_assert(qemu_mutex_iothread_locked());
g_assert(!vhyp_cpu_in_nested(cpu));
if (msr_pr) {
hcall_dprintf("Hypercall made with MSR[PR]=1\n");
env->gpr[3] = H_PRIVILEGE;
@ -1309,13 +1311,40 @@ void spapr_set_all_lpcrs(target_ulong value, target_ulong mask)
}
}
static void spapr_get_pate(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry)
static bool spapr_get_pate(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu,
target_ulong lpid, ppc_v3_pate_t *entry)
{
SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
if (!spapr_cpu->in_nested) {
assert(lpid == 0);
/* Copy PATE1:GR into PATE0:HR */
entry->dw0 = spapr->patb_entry & PATE0_HR;
entry->dw1 = spapr->patb_entry;
} else {
uint64_t patb, pats;
assert(lpid != 0);
patb = spapr->nested_ptcr & PTCR_PATB;
pats = spapr->nested_ptcr & PTCR_PATS;
/* Calculate number of entries */
pats = 1ull << (pats + 12 - 4);
if (pats <= lpid) {
return false;
}
/* Grab entry */
patb += 16 * lpid;
entry->dw0 = ldq_phys(CPU(cpu)->as, patb);
entry->dw1 = ldq_phys(CPU(cpu)->as, patb + 8);
}
return true;
}
#define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2))
@ -1634,6 +1663,8 @@ static void spapr_machine_reset(MachineState *machine)
spapr->ov5_cas = spapr_ovec_clone(spapr->ov5);
}
spapr_nvdimm_finish_flushes();
/* DRC reset may cause a device to be unplugged. This will cause troubles
* if this device is used by another device (eg, a running vhost backend
* will crash QEMU if the DIMM holding the vring goes away). To avoid such
@ -4465,6 +4496,13 @@ PowerPCCPU *spapr_find_cpu(int vcpu_id)
return NULL;
}
static bool spapr_cpu_in_nested(PowerPCCPU *cpu)
{
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
return spapr_cpu->in_nested;
}
static void spapr_cpu_exec_enter(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
{
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
@ -4573,6 +4611,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
fwc->get_dev_path = spapr_get_fw_dev_path;
nc->nmi_monitor_handler = spapr_nmi;
smc->phb_placement = spapr_phb_placement;
vhc->cpu_in_nested = spapr_cpu_in_nested;
vhc->deliver_hv_excp = spapr_exit_nested;
vhc->hypercall = emulate_spapr_hypercall;
vhc->hpt_mask = spapr_hpt_mask;
vhc->map_hptes = spapr_map_hptes;

View File

@ -444,19 +444,23 @@ static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
{
ERRP_GUARD();
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
CPUPPCState *env = &cpu->env;
if (!val) {
/* capability disabled by default */
return;
}
if (tcg_enabled()) {
error_setg(errp, "No Nested KVM-HV support in TCG");
if (!(env->insns_flags2 & PPC2_ISA300)) {
error_setg(errp, "Nested-HV only supported on POWER9 and later");
error_append_hint(errp, "Try appending -machine cap-nested-hv=off\n");
} else if (kvm_enabled()) {
return;
}
if (kvm_enabled()) {
if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0,
spapr->max_compat_pvr)) {
error_setg(errp, "Nested KVM-HV only supported on POWER9");
error_setg(errp, "Nested-HV only supported on POWER9 and later");
error_append_hint(errp,
"Try appending -machine max-cpu-compat=power9\n");
return;
@ -464,7 +468,7 @@ static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
if (!kvmppc_has_cap_nested_kvm_hv()) {
error_setg(errp,
"KVM implementation does not support Nested KVM-HV");
"KVM implementation does not support Nested-HV");
error_append_hint(errp,
"Try appending -machine cap-nested-hv=off\n");
} else if (kvmppc_set_cap_nested_kvm_hv(val) < 0) {

View File

@ -261,12 +261,12 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
return false;
}
/* Set time-base frequency to 512 MHz */
cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
cpu_ppc_set_vhyp(cpu, PPC_VIRTUAL_HYPERVISOR(spapr));
kvmppc_set_papr(cpu);
/* Set time-base frequency to 512 MHz. vhyp must be set first. */
cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ);
if (spapr_irq_cpu_intc_create(spapr, cpu, errp) < 0) {
qdev_unrealize(DEVICE(cpu));
return false;

View File

@ -9,6 +9,7 @@
#include "qemu/error-report.h"
#include "exec/exec-all.h"
#include "helper_regs.h"
#include "hw/ppc/ppc.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "mmu-hash64.h"
@ -1497,6 +1498,333 @@ static void hypercall_register_softmmu(void)
}
#endif
/* TCG only */
#define PRTS_MASK 0x1f
static target_ulong h_set_ptbl(PowerPCCPU *cpu,
SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
target_ulong ptcr = args[0];
if (!spapr_get_cap(spapr, SPAPR_CAP_NESTED_KVM_HV)) {
return H_FUNCTION;
}
if ((ptcr & PRTS_MASK) + 12 - 4 > 12) {
return H_PARAMETER;
}
spapr->nested_ptcr = ptcr; /* Save new partition table */
return H_SUCCESS;
}
static target_ulong h_tlb_invalidate(PowerPCCPU *cpu,
SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
/*
* The spapr virtual hypervisor nested HV implementation retains no L2
* translation state except for TLB. And the TLB is always invalidated
* across L1<->L2 transitions, so nothing is required here.
*/
return H_SUCCESS;
}
static target_ulong h_copy_tofrom_guest(PowerPCCPU *cpu,
SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
/*
* This HCALL is not required, L1 KVM will take a slow path and walk the
* page tables manually to do the data copy.
*/
return H_FUNCTION;
}
/*
* When this handler returns, the environment is switched to the L2 guest
* and TCG begins running that. spapr_exit_nested() performs the switch from
* L2 back to L1 and returns from the H_ENTER_NESTED hcall.
*/
static target_ulong h_enter_nested(PowerPCCPU *cpu,
SpaprMachineState *spapr,
target_ulong opcode,
target_ulong *args)
{
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
target_ulong hv_ptr = args[0];
target_ulong regs_ptr = args[1];
target_ulong hdec, now = cpu_ppc_load_tbl(env);
target_ulong lpcr, lpcr_mask;
struct kvmppc_hv_guest_state *hvstate;
struct kvmppc_hv_guest_state hv_state;
struct kvmppc_pt_regs *regs;
hwaddr len;
uint64_t cr;
int i;
if (spapr->nested_ptcr == 0) {
return H_NOT_AVAILABLE;
}
len = sizeof(*hvstate);
hvstate = address_space_map(CPU(cpu)->as, hv_ptr, &len, false,
MEMTXATTRS_UNSPECIFIED);
if (len != sizeof(*hvstate)) {
address_space_unmap(CPU(cpu)->as, hvstate, len, 0, false);
return H_PARAMETER;
}
memcpy(&hv_state, hvstate, len);
address_space_unmap(CPU(cpu)->as, hvstate, len, len, false);
/*
* We accept versions 1 and 2. Version 2 fields are unused because TCG
* does not implement DAWR*.
*/
if (hv_state.version > HV_GUEST_STATE_VERSION) {
return H_PARAMETER;
}
spapr_cpu->nested_host_state = g_try_malloc(sizeof(CPUPPCState));
if (!spapr_cpu->nested_host_state) {
return H_NO_MEM;
}
memcpy(spapr_cpu->nested_host_state, env, sizeof(CPUPPCState));
len = sizeof(*regs);
regs = address_space_map(CPU(cpu)->as, regs_ptr, &len, false,
MEMTXATTRS_UNSPECIFIED);
if (!regs || len != sizeof(*regs)) {
address_space_unmap(CPU(cpu)->as, regs, len, 0, false);
g_free(spapr_cpu->nested_host_state);
return H_P2;
}
len = sizeof(env->gpr);
assert(len == sizeof(regs->gpr));
memcpy(env->gpr, regs->gpr, len);
env->lr = regs->link;
env->ctr = regs->ctr;
cpu_write_xer(env, regs->xer);
cr = regs->ccr;
for (i = 7; i >= 0; i--) {
env->crf[i] = cr & 15;
cr >>= 4;
}
env->msr = regs->msr;
env->nip = regs->nip;
address_space_unmap(CPU(cpu)->as, regs, len, len, false);
env->cfar = hv_state.cfar;
assert(env->spr[SPR_LPIDR] == 0);
env->spr[SPR_LPIDR] = hv_state.lpid;
lpcr_mask = LPCR_DPFD | LPCR_ILE | LPCR_AIL | LPCR_LD | LPCR_MER;
lpcr = (env->spr[SPR_LPCR] & ~lpcr_mask) | (hv_state.lpcr & lpcr_mask);
lpcr |= LPCR_HR | LPCR_UPRT | LPCR_GTSE | LPCR_HVICE | LPCR_HDICE;
lpcr &= ~LPCR_LPES0;
env->spr[SPR_LPCR] = lpcr & pcc->lpcr_mask;
env->spr[SPR_PCR] = hv_state.pcr;
/* hv_state.amor is not used */
env->spr[SPR_DPDES] = hv_state.dpdes;
env->spr[SPR_HFSCR] = hv_state.hfscr;
hdec = hv_state.hdec_expiry - now;
spapr_cpu->nested_tb_offset = hv_state.tb_offset;
/* TCG does not implement DAWR*, CIABR, PURR, SPURR, IC, VTB, HEIR SPRs*/
env->spr[SPR_SRR0] = hv_state.srr0;
env->spr[SPR_SRR1] = hv_state.srr1;
env->spr[SPR_SPRG0] = hv_state.sprg[0];
env->spr[SPR_SPRG1] = hv_state.sprg[1];
env->spr[SPR_SPRG2] = hv_state.sprg[2];
env->spr[SPR_SPRG3] = hv_state.sprg[3];
env->spr[SPR_BOOKS_PID] = hv_state.pidr;
env->spr[SPR_PPR] = hv_state.ppr;
cpu_ppc_hdecr_init(env);
cpu_ppc_store_hdecr(env, hdec);
/*
* The hv_state.vcpu_token is not needed. It is used by the KVM
* implementation to remember which L2 vCPU last ran on which physical
* CPU so as to invalidate process scope translations if it is moved
* between physical CPUs. For now TLBs are always flushed on L1<->L2
* transitions so this is not a problem.
*
* Could validate that the same vcpu_token does not attempt to run on
* different L1 vCPUs at the same time, but that would be a L1 KVM bug
* and it's not obviously worth a new data structure to do it.
*/
env->tb_env->tb_offset += spapr_cpu->nested_tb_offset;
spapr_cpu->in_nested = true;
hreg_compute_hflags(env);
tlb_flush(cs);
env->reserve_addr = -1; /* Reset the reservation */
/*
* The spapr hcall helper sets env->gpr[3] to the return value, but at
* this point the L1 is not returning from the hcall but rather we
* start running the L2, so r3 must not be clobbered, so return env->gpr[3]
* to leave it unchanged.
*/
return env->gpr[3];
}
void spapr_exit_nested(PowerPCCPU *cpu, int excp)
{
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
target_ulong r3_return = env->excp_vectors[excp]; /* hcall return value */
target_ulong hv_ptr = spapr_cpu->nested_host_state->gpr[4];
target_ulong regs_ptr = spapr_cpu->nested_host_state->gpr[5];
struct kvmppc_hv_guest_state *hvstate;
struct kvmppc_pt_regs *regs;
hwaddr len;
uint64_t cr;
int i;
assert(spapr_cpu->in_nested);
cpu_ppc_hdecr_exit(env);
len = sizeof(*hvstate);
hvstate = address_space_map(CPU(cpu)->as, hv_ptr, &len, true,
MEMTXATTRS_UNSPECIFIED);
if (len != sizeof(*hvstate)) {
address_space_unmap(CPU(cpu)->as, hvstate, len, 0, true);
r3_return = H_PARAMETER;
goto out_restore_l1;
}
hvstate->cfar = env->cfar;
hvstate->lpcr = env->spr[SPR_LPCR];
hvstate->pcr = env->spr[SPR_PCR];
hvstate->dpdes = env->spr[SPR_DPDES];
hvstate->hfscr = env->spr[SPR_HFSCR];
if (excp == POWERPC_EXCP_HDSI) {
hvstate->hdar = env->spr[SPR_HDAR];
hvstate->hdsisr = env->spr[SPR_HDSISR];
hvstate->asdr = env->spr[SPR_ASDR];
} else if (excp == POWERPC_EXCP_HISI) {
hvstate->asdr = env->spr[SPR_ASDR];
}
/* HEIR should be implemented for HV mode and saved here. */
hvstate->srr0 = env->spr[SPR_SRR0];
hvstate->srr1 = env->spr[SPR_SRR1];
hvstate->sprg[0] = env->spr[SPR_SPRG0];
hvstate->sprg[1] = env->spr[SPR_SPRG1];
hvstate->sprg[2] = env->spr[SPR_SPRG2];
hvstate->sprg[3] = env->spr[SPR_SPRG3];
hvstate->pidr = env->spr[SPR_BOOKS_PID];
hvstate->ppr = env->spr[SPR_PPR];
/* Is it okay to specify write length larger than actual data written? */
address_space_unmap(CPU(cpu)->as, hvstate, len, len, true);
len = sizeof(*regs);
regs = address_space_map(CPU(cpu)->as, regs_ptr, &len, true,
MEMTXATTRS_UNSPECIFIED);
if (!regs || len != sizeof(*regs)) {
address_space_unmap(CPU(cpu)->as, regs, len, 0, true);
r3_return = H_P2;
goto out_restore_l1;
}
len = sizeof(env->gpr);
assert(len == sizeof(regs->gpr));
memcpy(regs->gpr, env->gpr, len);
regs->link = env->lr;
regs->ctr = env->ctr;
regs->xer = cpu_read_xer(env);
cr = 0;
for (i = 0; i < 8; i++) {
cr |= (env->crf[i] & 15) << (4 * (7 - i));
}
regs->ccr = cr;
if (excp == POWERPC_EXCP_MCHECK ||
excp == POWERPC_EXCP_RESET ||
excp == POWERPC_EXCP_SYSCALL) {
regs->nip = env->spr[SPR_SRR0];
regs->msr = env->spr[SPR_SRR1] & env->msr_mask;
} else {
regs->nip = env->spr[SPR_HSRR0];
regs->msr = env->spr[SPR_HSRR1] & env->msr_mask;
}
/* Is it okay to specify write length larger than actual data written? */
address_space_unmap(CPU(cpu)->as, regs, len, len, true);
out_restore_l1:
memcpy(env->gpr, spapr_cpu->nested_host_state->gpr, sizeof(env->gpr));
env->lr = spapr_cpu->nested_host_state->lr;
env->ctr = spapr_cpu->nested_host_state->ctr;
memcpy(env->crf, spapr_cpu->nested_host_state->crf, sizeof(env->crf));
env->cfar = spapr_cpu->nested_host_state->cfar;
env->xer = spapr_cpu->nested_host_state->xer;
env->so = spapr_cpu->nested_host_state->so;
env->ov = spapr_cpu->nested_host_state->ov;
env->ov32 = spapr_cpu->nested_host_state->ov32;
env->ca32 = spapr_cpu->nested_host_state->ca32;
env->msr = spapr_cpu->nested_host_state->msr;
env->nip = spapr_cpu->nested_host_state->nip;
assert(env->spr[SPR_LPIDR] != 0);
env->spr[SPR_LPCR] = spapr_cpu->nested_host_state->spr[SPR_LPCR];
env->spr[SPR_LPIDR] = spapr_cpu->nested_host_state->spr[SPR_LPIDR];
env->spr[SPR_PCR] = spapr_cpu->nested_host_state->spr[SPR_PCR];
env->spr[SPR_DPDES] = 0;
env->spr[SPR_HFSCR] = spapr_cpu->nested_host_state->spr[SPR_HFSCR];
env->spr[SPR_SRR0] = spapr_cpu->nested_host_state->spr[SPR_SRR0];
env->spr[SPR_SRR1] = spapr_cpu->nested_host_state->spr[SPR_SRR1];
env->spr[SPR_SPRG0] = spapr_cpu->nested_host_state->spr[SPR_SPRG0];
env->spr[SPR_SPRG1] = spapr_cpu->nested_host_state->spr[SPR_SPRG1];
env->spr[SPR_SPRG2] = spapr_cpu->nested_host_state->spr[SPR_SPRG2];
env->spr[SPR_SPRG3] = spapr_cpu->nested_host_state->spr[SPR_SPRG3];
env->spr[SPR_BOOKS_PID] = spapr_cpu->nested_host_state->spr[SPR_BOOKS_PID];
env->spr[SPR_PPR] = spapr_cpu->nested_host_state->spr[SPR_PPR];
/*
* Return the interrupt vector address from H_ENTER_NESTED to the L1
* (or error code).
*/
env->gpr[3] = r3_return;
env->tb_env->tb_offset -= spapr_cpu->nested_tb_offset;
spapr_cpu->in_nested = false;
hreg_compute_hflags(env);
tlb_flush(cs);
env->reserve_addr = -1; /* Reset the reservation */
g_free(spapr_cpu->nested_host_state);
spapr_cpu->nested_host_state = NULL;
}
static void hypercall_register_types(void)
{
hypercall_register_softmmu();
@ -1552,6 +1880,11 @@ static void hypercall_register_types(void)
spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support);
spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt);
spapr_register_hypercall(KVMPPC_H_SET_PARTITION_TABLE, h_set_ptbl);
spapr_register_hypercall(KVMPPC_H_ENTER_NESTED, h_enter_nested);
spapr_register_hypercall(KVMPPC_H_TLB_INVALIDATE, h_tlb_invalidate);
spapr_register_hypercall(KVMPPC_H_COPY_TOFROM_GUEST, h_copy_tofrom_guest);
}
type_init(hypercall_register_types)

View File

@ -685,7 +685,7 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data)
spapr_register_hypercall(H_STUFF_TCE, h_stuff_tce);
}
static TypeInfo spapr_tce_table_info = {
static const TypeInfo spapr_tce_table_info = {
.name = TYPE_SPAPR_TCE_TABLE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(SpaprTceTable),

View File

@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "hw/ppc/spapr_drc.h"
#include "hw/ppc/spapr_nvdimm.h"
@ -30,6 +31,10 @@
#include "hw/ppc/fdt.h"
#include "qemu/range.h"
#include "hw/ppc/spapr_numa.h"
#include "block/thread-pool.h"
#include "migration/vmstate.h"
#include "qemu/pmem.h"
#include "hw/qdev-properties.h"
/* DIMM health bitmap bitmap indicators. Taken from kernel's papr_scm.c */
/* SCM device is unable to persist memory contents */
@ -47,11 +52,25 @@
/* Have an explicit check for alignment */
QEMU_BUILD_BUG_ON(SPAPR_MINIMUM_SCM_BLOCK_SIZE % SPAPR_MEMORY_BLOCK_SIZE);
#define TYPE_SPAPR_NVDIMM "spapr-nvdimm"
OBJECT_DECLARE_TYPE(SpaprNVDIMMDevice, SPAPRNVDIMMClass, SPAPR_NVDIMM)
struct SPAPRNVDIMMClass {
/* private */
NVDIMMClass parent_class;
/* public */
void (*realize)(NVDIMMDevice *dimm, Error **errp);
void (*unrealize)(NVDIMMDevice *dimm, Error **errp);
};
bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
uint64_t size, Error **errp)
{
const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
const MachineState *ms = MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(nvdimm);
MemoryRegion *mr = host_memory_backend_get_memory(dimm->hostmem);
g_autofree char *uuidstr = NULL;
QemuUUID uuid;
int ret;
@ -89,6 +108,14 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
return false;
}
if (object_dynamic_cast(OBJECT(nvdimm), TYPE_SPAPR_NVDIMM) &&
(memory_region_get_fd(mr) < 0)) {
error_setg(errp, "spapr-nvdimm device requires the "
"memdev %s to be of memory-backend-file type",
object_get_canonical_path_component(OBJECT(dimm->hostmem)));
return false;
}
return true;
}
@ -160,6 +187,20 @@ static int spapr_dt_nvdimm(SpaprMachineState *spapr, void *fdt,
"operating-system")));
_FDT(fdt_setprop(fdt, child_offset, "ibm,cache-flush-required", NULL, 0));
if (object_dynamic_cast(OBJECT(nvdimm), TYPE_SPAPR_NVDIMM)) {
bool is_pmem = false, pmem_override = false;
PCDIMMDevice *dimm = PC_DIMM(nvdimm);
HostMemoryBackend *hostmem = dimm->hostmem;
is_pmem = object_property_get_bool(OBJECT(hostmem), "pmem", NULL);
pmem_override = object_property_get_bool(OBJECT(nvdimm),
"pmem-override", NULL);
if (!is_pmem || pmem_override) {
_FDT(fdt_setprop(fdt, child_offset, "ibm,hcall-flush-required",
NULL, 0));
}
}
return child_offset;
}
@ -375,6 +416,293 @@ static target_ulong h_scm_bind_mem(PowerPCCPU *cpu, SpaprMachineState *spapr,
return H_SUCCESS;
}
typedef struct SpaprNVDIMMDeviceFlushState {
uint64_t continue_token;
int64_t hcall_ret;
uint32_t drcidx;
QLIST_ENTRY(SpaprNVDIMMDeviceFlushState) node;
} SpaprNVDIMMDeviceFlushState;
typedef struct SpaprNVDIMMDevice SpaprNVDIMMDevice;
struct SpaprNVDIMMDevice {
/* private */
NVDIMMDevice parent_obj;
bool hcall_flush_required;
uint64_t nvdimm_flush_token;
QLIST_HEAD(, SpaprNVDIMMDeviceFlushState) pending_nvdimm_flush_states;
QLIST_HEAD(, SpaprNVDIMMDeviceFlushState) completed_nvdimm_flush_states;
/* public */
/*
* The 'on' value for this property forced the qemu to enable the hcall
* flush for the nvdimm device even if the backend is a pmem
*/
bool pmem_override;
};
static int flush_worker_cb(void *opaque)
{
SpaprNVDIMMDeviceFlushState *state = opaque;
SpaprDrc *drc = spapr_drc_by_index(state->drcidx);
PCDIMMDevice *dimm = PC_DIMM(drc->dev);
HostMemoryBackend *backend = MEMORY_BACKEND(dimm->hostmem);
int backend_fd = memory_region_get_fd(&backend->mr);
if (object_property_get_bool(OBJECT(backend), "pmem", NULL)) {
MemoryRegion *mr = host_memory_backend_get_memory(dimm->hostmem);
void *ptr = memory_region_get_ram_ptr(mr);
size_t size = object_property_get_uint(OBJECT(dimm), PC_DIMM_SIZE_PROP,
NULL);
/* flush pmem backend */
pmem_persist(ptr, size);
} else {
/* flush raw backing image */
if (qemu_fdatasync(backend_fd) < 0) {
error_report("papr_scm: Could not sync nvdimm to backend file: %s",
strerror(errno));
return H_HARDWARE;
}
}
return H_SUCCESS;
}
static void spapr_nvdimm_flush_completion_cb(void *opaque, int hcall_ret)
{
SpaprNVDIMMDeviceFlushState *state = opaque;
SpaprDrc *drc = spapr_drc_by_index(state->drcidx);
SpaprNVDIMMDevice *s_nvdimm = SPAPR_NVDIMM(drc->dev);
state->hcall_ret = hcall_ret;
QLIST_REMOVE(state, node);
QLIST_INSERT_HEAD(&s_nvdimm->completed_nvdimm_flush_states, state, node);
}
static int spapr_nvdimm_flush_post_load(void *opaque, int version_id)
{
SpaprNVDIMMDevice *s_nvdimm = (SpaprNVDIMMDevice *)opaque;
SpaprNVDIMMDeviceFlushState *state;
ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());
HostMemoryBackend *backend = MEMORY_BACKEND(PC_DIMM(s_nvdimm)->hostmem);
bool is_pmem = object_property_get_bool(OBJECT(backend), "pmem", NULL);
bool pmem_override = object_property_get_bool(OBJECT(s_nvdimm),
"pmem-override", NULL);
bool dest_hcall_flush_required = pmem_override || !is_pmem;
if (!s_nvdimm->hcall_flush_required && dest_hcall_flush_required) {
error_report("The file backend for the spapr-nvdimm device %s at "
"source is a pmem, use pmem=on and pmem-override=off to "
"continue.", DEVICE(s_nvdimm)->id);
return -EINVAL;
}
if (s_nvdimm->hcall_flush_required && !dest_hcall_flush_required) {
error_report("The guest expects hcall-flush support for the "
"spapr-nvdimm device %s, use pmem_override=on to "
"continue.", DEVICE(s_nvdimm)->id);
return -EINVAL;
}
QLIST_FOREACH(state, &s_nvdimm->pending_nvdimm_flush_states, node) {
thread_pool_submit_aio(pool, flush_worker_cb, state,
spapr_nvdimm_flush_completion_cb, state);
}
return 0;
}
static const VMStateDescription vmstate_spapr_nvdimm_flush_state = {
.name = "spapr_nvdimm_flush_state",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT64(continue_token, SpaprNVDIMMDeviceFlushState),
VMSTATE_INT64(hcall_ret, SpaprNVDIMMDeviceFlushState),
VMSTATE_UINT32(drcidx, SpaprNVDIMMDeviceFlushState),
VMSTATE_END_OF_LIST()
},
};
const VMStateDescription vmstate_spapr_nvdimm_states = {
.name = "spapr_nvdimm_states",
.version_id = 1,
.minimum_version_id = 1,
.post_load = spapr_nvdimm_flush_post_load,
.fields = (VMStateField[]) {
VMSTATE_BOOL(hcall_flush_required, SpaprNVDIMMDevice),
VMSTATE_UINT64(nvdimm_flush_token, SpaprNVDIMMDevice),
VMSTATE_QLIST_V(completed_nvdimm_flush_states, SpaprNVDIMMDevice, 1,
vmstate_spapr_nvdimm_flush_state,
SpaprNVDIMMDeviceFlushState, node),
VMSTATE_QLIST_V(pending_nvdimm_flush_states, SpaprNVDIMMDevice, 1,
vmstate_spapr_nvdimm_flush_state,
SpaprNVDIMMDeviceFlushState, node),
VMSTATE_END_OF_LIST()
},
};
/*
* Assign a token and reserve it for the new flush state.
*/
static SpaprNVDIMMDeviceFlushState *spapr_nvdimm_init_new_flush_state(
SpaprNVDIMMDevice *spapr_nvdimm)
{
SpaprNVDIMMDeviceFlushState *state;
state = g_malloc0(sizeof(*state));
spapr_nvdimm->nvdimm_flush_token++;
/* Token zero is presumed as no job pending. Assert on overflow to zero */
g_assert(spapr_nvdimm->nvdimm_flush_token != 0);
state->continue_token = spapr_nvdimm->nvdimm_flush_token;
QLIST_INSERT_HEAD(&spapr_nvdimm->pending_nvdimm_flush_states, state, node);
return state;
}
/*
* spapr_nvdimm_finish_flushes
* Waits for all pending flush requests to complete
* their execution and free the states
*/
void spapr_nvdimm_finish_flushes(void)
{
SpaprNVDIMMDeviceFlushState *state, *next;
GSList *list, *nvdimms;
/*
* Called on reset path, the main loop thread which calls
* the pending BHs has gotten out running in the reset path,
* finally reaching here. Other code path being guest
* h_client_architecture_support, thats early boot up.
*/
nvdimms = nvdimm_get_device_list();
for (list = nvdimms; list; list = list->next) {
NVDIMMDevice *nvdimm = list->data;
if (object_dynamic_cast(OBJECT(nvdimm), TYPE_SPAPR_NVDIMM)) {
SpaprNVDIMMDevice *s_nvdimm = SPAPR_NVDIMM(nvdimm);
while (!QLIST_EMPTY(&s_nvdimm->pending_nvdimm_flush_states)) {
aio_poll(qemu_get_aio_context(), true);
}
QLIST_FOREACH_SAFE(state, &s_nvdimm->completed_nvdimm_flush_states,
node, next) {
QLIST_REMOVE(state, node);
g_free(state);
}
}
}
g_slist_free(nvdimms);
}
/*
* spapr_nvdimm_get_flush_status
* Fetches the status of the hcall worker and returns
* H_LONG_BUSY_ORDER_10_MSEC if the worker is still running.
*/
static int spapr_nvdimm_get_flush_status(SpaprNVDIMMDevice *s_nvdimm,
uint64_t token)
{
SpaprNVDIMMDeviceFlushState *state, *node;
QLIST_FOREACH(state, &s_nvdimm->pending_nvdimm_flush_states, node) {
if (state->continue_token == token) {
return H_LONG_BUSY_ORDER_10_MSEC;
}
}
QLIST_FOREACH_SAFE(state, &s_nvdimm->completed_nvdimm_flush_states,
node, node) {
if (state->continue_token == token) {
int ret = state->hcall_ret;
QLIST_REMOVE(state, node);
g_free(state);
return ret;
}
}
/* If not found in complete list too, invalid token */
return H_P2;
}
/*
* H_SCM_FLUSH
* Input: drc_index, continue-token
* Out: continue-token
* Return Value: H_SUCCESS, H_Parameter, H_P2, H_LONG_BUSY_ORDER_10_MSEC,
* H_UNSUPPORTED
*
* Given a DRC Index Flush the data to backend NVDIMM device. The hcall returns
* H_LONG_BUSY_ORDER_10_MSEC when the flush takes longer time and the hcall
* needs to be issued multiple times in order to be completely serviced. The
* continue-token from the output to be passed in the argument list of
* subsequent hcalls until the hcall is completely serviced at which point
* H_SUCCESS or other error is returned.
*/
static target_ulong h_scm_flush(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
int ret;
uint32_t drc_index = args[0];
uint64_t continue_token = args[1];
SpaprDrc *drc = spapr_drc_by_index(drc_index);
PCDIMMDevice *dimm;
HostMemoryBackend *backend = NULL;
SpaprNVDIMMDeviceFlushState *state;
ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());
int fd;
if (!drc || !drc->dev ||
spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PMEM) {
return H_PARAMETER;
}
dimm = PC_DIMM(drc->dev);
if (!object_dynamic_cast(OBJECT(dimm), TYPE_SPAPR_NVDIMM)) {
return H_PARAMETER;
}
if (continue_token == 0) {
bool is_pmem = false, pmem_override = false;
backend = MEMORY_BACKEND(dimm->hostmem);
fd = memory_region_get_fd(&backend->mr);
if (fd < 0) {
return H_UNSUPPORTED;
}
is_pmem = object_property_get_bool(OBJECT(backend), "pmem", NULL);
pmem_override = object_property_get_bool(OBJECT(dimm),
"pmem-override", NULL);
if (is_pmem && !pmem_override) {
return H_UNSUPPORTED;
}
state = spapr_nvdimm_init_new_flush_state(SPAPR_NVDIMM(dimm));
if (!state) {
return H_HARDWARE;
}
state->drcidx = drc_index;
thread_pool_submit_aio(pool, flush_worker_cb, state,
spapr_nvdimm_flush_completion_cb, state);
continue_token = state->continue_token;
}
ret = spapr_nvdimm_get_flush_status(SPAPR_NVDIMM(dimm), continue_token);
if (H_IS_LONG_BUSY(ret)) {
args[0] = continue_token;
}
return ret;
}
static target_ulong h_scm_unbind_mem(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
@ -523,6 +851,70 @@ static void spapr_scm_register_types(void)
spapr_register_hypercall(H_SCM_UNBIND_MEM, h_scm_unbind_mem);
spapr_register_hypercall(H_SCM_UNBIND_ALL, h_scm_unbind_all);
spapr_register_hypercall(H_SCM_HEALTH, h_scm_health);
spapr_register_hypercall(H_SCM_FLUSH, h_scm_flush);
}
type_init(spapr_scm_register_types)
static void spapr_nvdimm_realize(NVDIMMDevice *dimm, Error **errp)
{
SpaprNVDIMMDevice *s_nvdimm = SPAPR_NVDIMM(dimm);
HostMemoryBackend *backend = MEMORY_BACKEND(PC_DIMM(dimm)->hostmem);
bool is_pmem = object_property_get_bool(OBJECT(backend), "pmem", NULL);
bool pmem_override = object_property_get_bool(OBJECT(dimm), "pmem-override",
NULL);
if (!is_pmem || pmem_override) {
s_nvdimm->hcall_flush_required = true;
}
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
&vmstate_spapr_nvdimm_states, dimm);
}
static void spapr_nvdimm_unrealize(NVDIMMDevice *dimm)
{
vmstate_unregister(NULL, &vmstate_spapr_nvdimm_states, dimm);
}
static Property spapr_nvdimm_properties[] = {
#ifdef CONFIG_LIBPMEM
DEFINE_PROP_BOOL("pmem-override", SpaprNVDIMMDevice, pmem_override, false),
#endif
DEFINE_PROP_END_OF_LIST(),
};
static void spapr_nvdimm_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
NVDIMMClass *nvc = NVDIMM_CLASS(oc);
nvc->realize = spapr_nvdimm_realize;
nvc->unrealize = spapr_nvdimm_unrealize;
device_class_set_props(dc, spapr_nvdimm_properties);
}
static void spapr_nvdimm_init(Object *obj)
{
SpaprNVDIMMDevice *s_nvdimm = SPAPR_NVDIMM(obj);
s_nvdimm->hcall_flush_required = false;
QLIST_INIT(&s_nvdimm->pending_nvdimm_flush_states);
QLIST_INIT(&s_nvdimm->completed_nvdimm_flush_states);
}
static TypeInfo spapr_nvdimm_info = {
.name = TYPE_SPAPR_NVDIMM,
.parent = TYPE_NVDIMM,
.class_init = spapr_nvdimm_class_init,
.class_size = sizeof(SPAPRNVDIMMClass),
.instance_size = sizeof(SpaprNVDIMMDevice),
.instance_init = spapr_nvdimm_init,
};
static void spapr_nvdimm_register_types(void)
{
type_register_static(&spapr_nvdimm_info);
}
type_init(spapr_nvdimm_register_types)

View File

@ -16,6 +16,7 @@
#include "exec/cpu-common.h"
#include "exec/ram_addr.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "hw/remote/mpqemu-link.h"
#include "hw/remote/proxy-memory-listener.h"

View File

@ -1,10 +1,12 @@
config DS1338
bool
depends on I2C
default y if I2C_DEVICES
config M41T80
bool
depends on I2C
default y if I2C_DEVICES
config M48T59
bool

View File

@ -1392,7 +1392,7 @@ static const TypeInfo s390_pci_device_info = {
.class_init = s390_pci_device_class_init,
};
static TypeInfo s390_pci_iommu_info = {
static const TypeInfo s390_pci_iommu_info = {
.name = TYPE_S390_PCI_IOMMU,
.parent = TYPE_OBJECT,
.instance_size = sizeof(S390PCIIOMMU),

View File

@ -460,7 +460,7 @@ static void sclp_class_init(ObjectClass *oc, void *data)
sc->service_interrupt = service_interrupt;
}
static TypeInfo sclp_info = {
static const TypeInfo sclp_info = {
.name = TYPE_SCLP,
.parent = TYPE_DEVICE,
.instance_init = sclp_init,

View File

@ -147,7 +147,7 @@ static void kvm_s390_tod_init(Object *obj)
td->stopped = false;
}
static TypeInfo kvm_s390_tod_info = {
static const TypeInfo kvm_s390_tod_info = {
.name = TYPE_KVM_S390_TOD,
.parent = TYPE_S390_TOD,
.instance_size = sizeof(S390TODState),

View File

@ -73,7 +73,7 @@ static void qemu_s390_tod_init(Object *obj)
}
}
static TypeInfo qemu_s390_tod_info = {
static const TypeInfo qemu_s390_tod_info = {
.name = TYPE_QEMU_S390_TOD,
.parent = TYPE_S390_TOD,
.instance_size = sizeof(S390TODState),

View File

@ -123,7 +123,7 @@ static void s390_tod_class_init(ObjectClass *oc, void *data)
dc->user_creatable = false;
}
static TypeInfo s390_tod_info = {
static const TypeInfo s390_tod_info = {
.name = TYPE_S390_TOD,
.parent = TYPE_DEVICE,
.instance_size = sizeof(S390TODState),

View File

@ -2352,7 +2352,7 @@ static void lsi53c810_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_LSI_53C810;
}
static TypeInfo lsi53c810_info = {
static const TypeInfo lsi53c810_info = {
.name = TYPE_LSI53C810,
.parent = TYPE_LSI53C895A,
.class_init = lsi53c810_class_init,

View File

@ -28,6 +28,7 @@
#include "hw/pci/msix.h"
#include "qemu/iov.h"
#include "qemu/module.h"
#include "qemu/hw-version.h"
#include "hw/scsi/scsi.h"
#include "scsi/constants.h"
#include "trace.h"

View File

@ -3,6 +3,7 @@
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/hw-version.h"
#include "hw/qdev-properties.h"
#include "hw/scsi/scsi.h"
#include "migration/qemu-file-types.h"

View File

@ -25,6 +25,7 @@
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/hw-version.h"
#include "hw/scsi/scsi.h"
#include "migration/qemu-file-types.h"
#include "migration/vmstate.h"

View File

@ -835,7 +835,7 @@ static void allwinner_sdhost_sun5i_class_init(ObjectClass *klass, void *data)
sc->max_desc_size = 64 * KiB;
}
static TypeInfo allwinner_sdhost_info = {
static const TypeInfo allwinner_sdhost_info = {
.name = TYPE_AW_SDHOST,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_init = allwinner_sdhost_init,

View File

@ -198,7 +198,7 @@ static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
device_class_set_props(dc, aspeed_sdhci_properties);
}
static TypeInfo aspeed_sdhci_info = {
static const TypeInfo aspeed_sdhci_info = {
.name = TYPE_ASPEED_SDHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(AspeedSDHCIState),

View File

@ -436,7 +436,7 @@ static void bcm2835_sdhost_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2835_sdhost;
}
static TypeInfo bcm2835_sdhost_info = {
static const TypeInfo bcm2835_sdhost_info = {
.name = TYPE_BCM2835_SDHOST,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835SDHostState),

View File

@ -175,7 +175,7 @@ static void cadence_sdhci_class_init(ObjectClass *classp, void *data)
dc->vmsd = &vmstate_cadence_sdhci;
}
static TypeInfo cadence_sdhci_info = {
static const TypeInfo cadence_sdhci_info = {
.name = TYPE_CADENCE_SDHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(CadenceSDHCIState),

View File

@ -166,7 +166,7 @@ static void npcm7xx_sdhci_instance_init(Object *obj)
TYPE_SYSBUS_SDHCI);
}
static TypeInfo npcm7xx_sdhci_info = {
static const TypeInfo npcm7xx_sdhci_info = {
.name = TYPE_NPCM7XX_SDHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCM7xxSDHCIState),

View File

@ -1,18 +1,22 @@
config TMP105
bool
depends on I2C
default y if I2C_DEVICES
config TMP421
bool
depends on I2C
default y if I2C_DEVICES
config DPS310
bool
depends on I2C
default y if I2C_DEVICES
config EMC141X
bool
depends on I2C
default y if I2C_DEVICES
config ADM1272
bool
@ -25,3 +29,4 @@ config MAX34451
config LSM303DLHC_MAG
bool
depends on I2C
default y if I2C_DEVICES

View File

@ -318,6 +318,12 @@ static void a9_gtimer_realize(DeviceState *dev, Error **errp)
}
}
static bool vmstate_a9_gtimer_control_needed(void *opaque)
{
A9GTimerState *s = opaque;
return s->control != 0;
}
static const VMStateDescription vmstate_a9_gtimer_per_cpu = {
.name = "arm.cortex-a9-global-timer.percpu",
.version_id = 1,
@ -331,6 +337,17 @@ static const VMStateDescription vmstate_a9_gtimer_per_cpu = {
}
};
static const VMStateDescription vmstate_a9_gtimer_control = {
.name = "arm.cortex-a9-global-timer.control",
.version_id = 1,
.minimum_version_id = 1,
.needed = vmstate_a9_gtimer_control_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT32(control, A9GTimerState),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_a9_gtimer = {
.name = "arm.cortex-a9-global-timer",
.version_id = 1,
@ -344,6 +361,10 @@ static const VMStateDescription vmstate_a9_gtimer = {
1, vmstate_a9_gtimer_per_cpu,
A9GTimerPerCPU),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {
&vmstate_a9_gtimer_control,
NULL
}
};

View File

@ -18,6 +18,7 @@
#include "qemu/module.h"
#include "qapi/error.h"
#include "exec/address-spaces.h"
#include "hw/qdev-properties.h"
#include "hw/pci/pci_ids.h"
#include "hw/acpi/tpm.h"

View File

@ -14,9 +14,9 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "cpu.h"
#include "sysemu/memory_mapping.h"
#include "migration/vmstate.h"
#include "hw/qdev-core.h"
#include "hw/acpi/tpm.h"
#include "tpm_ppi.h"
#include "trace.h"
@ -44,7 +44,7 @@ void tpm_ppi_reset(TPMPPI *tpmppi)
}
}
void tpm_ppi_init(TPMPPI *tpmppi, struct MemoryRegion *m,
void tpm_ppi_init(TPMPPI *tpmppi, MemoryRegion *m,
hwaddr addr, Object *obj)
{
tpmppi->buf = qemu_memalign(qemu_real_host_page_size,

View File

@ -12,7 +12,7 @@
#ifndef TPM_TPM_PPI_H
#define TPM_TPM_PPI_H
#include "exec/address-spaces.h"
#include "exec/memory.h"
typedef struct TPMPPI {
MemoryRegion ram;
@ -29,7 +29,7 @@ typedef struct TPMPPI {
* Register the TPM PPI memory region at @addr on the given address
* space for the object @obj.
**/
void tpm_ppi_init(TPMPPI *tpmppi, struct MemoryRegion *m,
void tpm_ppi_init(TPMPPI *tpmppi, MemoryRegion *m,
hwaddr addr, Object *obj);
/**

View File

@ -461,14 +461,14 @@ static const uint8_t qemu_mouse_hid_report_descriptor[] = {
0xa1, 0x00, /* Collection (Physical) */
0x05, 0x09, /* Usage Page (Button) */
0x19, 0x01, /* Usage Minimum (1) */
0x29, 0x03, /* Usage Maximum (3) */
0x29, 0x05, /* Usage Maximum (5) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x95, 0x03, /* Report Count (3) */
0x95, 0x05, /* Report Count (5) */
0x75, 0x01, /* Report Size (1) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */
0x75, 0x05, /* Report Size (5) */
0x75, 0x03, /* Report Size (3) */
0x81, 0x01, /* Input (Constant) */
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x30, /* Usage (X) */

View File

@ -2106,7 +2106,7 @@ static void usb_mtp_class_initfn(ObjectClass *klass, void *data)
device_class_set_props(dc, mtp_properties);
}
static TypeInfo mtp_info = {
static const TypeInfo mtp_info = {
.name = TYPE_USB_MTP,
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(MTPState),

View File

@ -1801,7 +1801,7 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
static TypeInfo usb_host_dev_info = {
static const TypeInfo usb_host_dev_info = {
.name = TYPE_USB_HOST_DEVICE,
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHostDevice),

View File

@ -199,7 +199,7 @@ static void vfio_pci_igd_lpc_bridge_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_ISA;
}
static TypeInfo vfio_pci_igd_lpc_bridge_info = {
static const TypeInfo vfio_pci_igd_lpc_bridge_info = {
.name = "vfio-pci-igd-lpc-bridge",
.parent = TYPE_PCI_DEVICE,
.class_init = vfio_pci_igd_lpc_bridge_class_init,

View File

@ -17,6 +17,7 @@
#include "qemu/iov.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "qemu/madvise.h"
#include "hw/virtio/virtio.h"
#include "hw/mem/pc-dimm.h"
#include "hw/qdev-properties.h"

View File

@ -182,7 +182,7 @@ static void virtio_pmem_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static TypeInfo virtio_pmem_info = {
static const TypeInfo virtio_pmem_info = {
.name = TYPE_VIRTIO_PMEM,
.parent = TYPE_VIRTIO_DEVICE,
.class_size = sizeof(VirtIOPMEMClass),

View File

@ -40,8 +40,6 @@ typedef ram_addr_t tb_page_addr_t;
#define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
#endif
#include "qemu/log.h"
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns);
void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb,
target_ulong *data);

View File

@ -21,6 +21,8 @@
#ifndef CONFIG_USER_ONLY
#include "cpu-common.h"
#include "qemu/rcu.h"
#include "exec/ramlist.h"
struct RAMBlock {
struct rcu_head rcu;

View File

@ -2,6 +2,7 @@
#define HW_MCF_H
/* Motorola ColdFire device prototypes. */
#include "exec/hwaddr.h"
#include "target/m68k/cpu-qom.h"
/* mcf_uart.c */

View File

@ -103,6 +103,8 @@ struct NVDIMMClass {
/* write @size bytes from @buf to NVDIMM label data at @offset. */
void (*write_label_data)(NVDIMMDevice *nvdimm, const void *buf,
uint64_t size, uint64_t offset);
void (*realize)(NVDIMMDevice *nvdimm, Error **errp);
void (*unrealize)(NVDIMMDevice *nvdimm);
};
#define NVDIMM_DSM_MEM_FILE "etc/acpi/nvdimm-mem"

View File

@ -63,6 +63,7 @@ struct PCDIMMDeviceClass {
/* public */
void (*realize)(PCDIMMDevice *dimm, Error **errp);
void (*unrealize)(PCDIMMDevice *dimm);
};
void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,

View File

@ -54,6 +54,9 @@ struct ppc_tb_t {
uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset);
clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq);
void cpu_ppc_hdecr_init(CPUPPCState *env);
void cpu_ppc_hdecr_exit(CPUPPCState *env);
/* Embedded PowerPC DCR management */
typedef uint32_t (*dcr_read_cb)(void *opaque, int dcrn);
typedef void (*dcr_write_cb)(void *opaque, int dcrn, uint32_t val);

View File

@ -197,6 +197,9 @@ struct SpaprMachineState {
bool has_graphics;
uint32_t vsmt; /* Virtual SMT mode (KVM's "core stride") */
/* Nested HV support (TCG only) */
uint64_t nested_ptcr;
Notifier epow_notifier;
QTAILQ_HEAD(, SpaprEventLogEntry) pending_events;
bool use_hotplug_event_source;
@ -341,6 +344,7 @@ struct SpaprMachineState {
#define H_P7 -60
#define H_P8 -61
#define H_P9 -62
#define H_UNSUPPORTED -67
#define H_OVERLAP -68
#define H_UNSUPPORTED_FLAG -256
#define H_MULTI_THREADS_ACTIVE -9005
@ -559,8 +563,9 @@ struct SpaprMachineState {
#define H_SCM_UNBIND_ALL 0x3FC
#define H_SCM_HEALTH 0x400
#define H_RPT_INVALIDATE 0x448
#define H_SCM_FLUSH 0x44C
#define MAX_HCALL_OPCODE H_RPT_INVALIDATE
#define MAX_HCALL_OPCODE H_SCM_FLUSH
/* The hcalls above are standardized in PAPR and implemented by pHyp
* as well.
@ -577,7 +582,14 @@ struct SpaprMachineState {
#define KVMPPC_H_UPDATE_DT (KVMPPC_HCALL_BASE + 0x3)
/* 0x4 was used for KVMPPC_H_UPDATE_PHANDLE in SLOF */
#define KVMPPC_H_VOF_CLIENT (KVMPPC_HCALL_BASE + 0x5)
#define KVMPPC_HCALL_MAX KVMPPC_H_VOF_CLIENT
/* Platform-specific hcalls used for nested HV KVM */
#define KVMPPC_H_SET_PARTITION_TABLE (KVMPPC_HCALL_BASE + 0x800)
#define KVMPPC_H_ENTER_NESTED (KVMPPC_HCALL_BASE + 0x804)
#define KVMPPC_H_TLB_INVALIDATE (KVMPPC_HCALL_BASE + 0x808)
#define KVMPPC_H_COPY_TOFROM_GUEST (KVMPPC_HCALL_BASE + 0x80C)
#define KVMPPC_HCALL_MAX KVMPPC_H_COPY_TOFROM_GUEST
/*
* The hcall range 0xEF00 to 0xEF80 is reserved for use in facilitating
@ -587,6 +599,65 @@ struct SpaprMachineState {
#define SVM_H_TPM_COMM 0xEF10
#define SVM_HCALL_MAX SVM_H_TPM_COMM
/*
* Register state for entering a nested guest with H_ENTER_NESTED.
* New member must be added at the end.
*/
struct kvmppc_hv_guest_state {
uint64_t version; /* version of this structure layout, must be first */
uint32_t lpid;
uint32_t vcpu_token;
/* These registers are hypervisor privileged (at least for writing) */
uint64_t lpcr;
uint64_t pcr;
uint64_t amor;
uint64_t dpdes;
uint64_t hfscr;
int64_t tb_offset;
uint64_t dawr0;
uint64_t dawrx0;
uint64_t ciabr;
uint64_t hdec_expiry;
uint64_t purr;
uint64_t spurr;
uint64_t ic;
uint64_t vtb;
uint64_t hdar;
uint64_t hdsisr;
uint64_t heir;
uint64_t asdr;
/* These are OS privileged but need to be set late in guest entry */
uint64_t srr0;
uint64_t srr1;
uint64_t sprg[4];
uint64_t pidr;
uint64_t cfar;
uint64_t ppr;
/* Version 1 ends here */
uint64_t dawr1;
uint64_t dawrx1;
/* Version 2 ends here */
};
/* Latest version of hv_guest_state structure */
#define HV_GUEST_STATE_VERSION 2
/* Linux 64-bit powerpc pt_regs struct, used by nested HV */
struct kvmppc_pt_regs {
uint64_t gpr[32];
uint64_t nip;
uint64_t msr;
uint64_t orig_gpr3; /* Used for restarting system calls */
uint64_t ctr;
uint64_t link;
uint64_t xer;
uint64_t ccr;
uint64_t softe; /* Soft enabled/disabled */
uint64_t trap; /* Reason for being here */
uint64_t dar; /* Fault registers */
uint64_t dsisr; /* on 4xx/Book-E used for ESR */
uint64_t result; /* Result of a system call */
};
typedef struct SpaprDeviceTreeUpdateHeader {
uint32_t version_id;
@ -604,6 +675,9 @@ typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, SpaprMachineState *sm,
void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn);
target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
target_ulong *args);
void spapr_exit_nested(PowerPCCPU *cpu, int excp);
target_ulong softmmu_resize_hpt_prepare(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong shift);
target_ulong softmmu_resize_hpt_commit(PowerPCCPU *cpu, SpaprMachineState *spapr,

View File

@ -48,6 +48,11 @@ typedef struct SpaprCpuState {
bool prod; /* not migrated, only used to improve dispatch latencies */
struct ICPState *icp;
struct XiveTCTX *tctx;
/* Fields for nested-HV support */
bool in_nested; /* true while the L2 is executing */
CPUPPCState *nested_host_state; /* holds the L1 state while L2 executes */
int64_t nested_tb_offset; /* L1->L2 TB offset */
} SpaprCpuState;
static inline SpaprCpuState *spapr_cpu_state(PowerPCCPU *cpu)

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