* NetBSD NVMM support

* RateLimit mutex
 * Prepare for Meson 0.57 upgrade
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmCROukUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroOFXgf/ThwuBCbwC6pwoHpZzFXHdJRXIqHa
 iKTqjCLymz9NQBRTaMeG5CWjXl4o9syHLzEXLQxuQaynHK8AjbyeMSllBVLzBUme
 TU9AY3qwLShRJm3XGXkuUilFE+IR8FXWFgrTOsZXgbT+JQlkCgiuhCRqfAcDEgi/
 F5SNqlMzPNvF6G0FY9DFBBkoKF4YWROx25SgNl3fxgWwC94px/a22BXTVpOxaClZ
 HE/H+kbJH5sD2dOJR5cqbgFg7eBemNdxO3tSbR6WoP9pcvVPx0Dgh5hUJb5+pUXY
 fV5O5zZ+CdyNjWM4yAHg0y8kOlnqrLwv7pH+NdqWFaWiZ9uCSrVFR13ejQ==
 =sKO4
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging

* NetBSD NVMM support
* RateLimit mutex
* Prepare for Meson 0.57 upgrade

# gpg: Signature made Tue 04 May 2021 13:15:37 BST
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini-gitlab/tags/for-upstream:
  glib-compat: accept G_TEST_SLOW environment variable
  gitlab-ci: use --meson=internal for CFI jobs
  configure: handle meson options that have changed type
  configure: reindent meson invocation
  slirp: add configure option to disable smbd
  ratelimit: protect with a mutex
  Add NVMM Accelerator: add maintainers for NetBSD/NVMM
  Add NVMM accelerator: acceleration enlightenments
  Add NVMM accelerator: x86 CPU support
  Add NVMM accelerator: configure and build logic
  oslib-win32: do not rely on macro to get redefined function name

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-05-06 18:56:17 +01:00
commit 4cc10cae64
21 changed files with 1561 additions and 59 deletions

View File

@ -19,17 +19,21 @@ include:
before_script: before_script:
- JOBS=$(expr $(nproc) + 1) - JOBS=$(expr $(nproc) + 1)
script: script:
- if test -n "$LD_JOBS";
then
scripts/git-submodule.sh update meson ;
fi
- mkdir build - mkdir build
- cd build - cd build
- if test -n "$TARGETS"; - if test -n "$TARGETS";
then then
../configure --enable-werror --disable-docs $CONFIGURE_ARGS --target-list="$TARGETS" ; ../configure --enable-werror --disable-docs ${LD_JOBS:+--meson=internal} $CONFIGURE_ARGS --target-list="$TARGETS" ;
else else
../configure --enable-werror --disable-docs $CONFIGURE_ARGS ; ../configure --enable-werror --disable-docs ${LD_JOBS:+--meson=internal} $CONFIGURE_ARGS ;
fi || { cat config.log meson-logs/meson-log.txt && exit 1; } fi || { cat config.log meson-logs/meson-log.txt && exit 1; }
- if test -n "$LD_JOBS"; - if test -n "$LD_JOBS";
then then
meson configure . -Dbackend_max_links="$LD_JOBS" ; ../meson/meson.py configure . -Dbackend_max_links="$LD_JOBS" ;
fi || exit 1; fi || exit 1;
- make -j"$JOBS" - make -j"$JOBS"
- if test -n "$MAKE_CHECK_ARGS"; - if test -n "$MAKE_CHECK_ARGS";

View File

@ -510,6 +510,15 @@ F: accel/stubs/hax-stub.c
F: include/sysemu/hax.h F: include/sysemu/hax.h
F: target/i386/hax/ F: target/i386/hax/
Guest CPU Cores (NVMM)
----------------------
NetBSD Virtual Machine Monitor (NVMM) CPU support
M: Kamil Rytarowski <kamil@netbsd.org>
M: Reinoud Zandijk <reinoud@netbsd.org>
S: Maintained
F: include/sysemu/nvmm.h
F: target/i386/nvmm/
Hosts Hosts
----- -----
LINUX LINUX
@ -530,6 +539,8 @@ F: include/qemu/*posix*.h
NETBSD NETBSD
M: Kamil Rytarowski <kamil@netbsd.org> M: Kamil Rytarowski <kamil@netbsd.org>
M: Reinoud Zandijk <reinoud@netbsd.org>
M: Ryo ONODERA <ryoon@netbsd.org>
S: Maintained S: Maintained
K: ^Subject:.*(?i)NetBSD K: ^Subject:.*(?i)NetBSD

View File

@ -1,6 +1,9 @@
config WHPX config WHPX
bool bool
config NVMM
bool
config HAX config HAX
bool bool

View File

@ -230,6 +230,7 @@ void block_copy_state_free(BlockCopyState *s)
return; return;
} }
ratelimit_destroy(&s->rate_limit);
bdrv_release_dirty_bitmap(s->copy_bitmap); bdrv_release_dirty_bitmap(s->copy_bitmap);
shres_destroy(s->mem); shres_destroy(s->mem);
g_free(s); g_free(s);
@ -289,6 +290,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
s->copy_size = MAX(s->cluster_size, BLOCK_COPY_MAX_BUFFER); s->copy_size = MAX(s->cluster_size, BLOCK_COPY_MAX_BUFFER);
} }
ratelimit_init(&s->rate_limit);
QLIST_INIT(&s->tasks); QLIST_INIT(&s->tasks);
QLIST_INIT(&s->calls); QLIST_INIT(&s->calls);

View File

@ -87,6 +87,7 @@ void block_job_free(Job *job)
block_job_remove_all_bdrv(bjob); block_job_remove_all_bdrv(bjob);
blk_unref(bjob->blk); blk_unref(bjob->blk);
ratelimit_destroy(&bjob->limit);
error_free(bjob->blocker); error_free(bjob->blocker);
} }
@ -442,6 +443,8 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
assert(job->job.driver->free == &block_job_free); assert(job->job.driver->free == &block_job_free);
assert(job->job.driver->user_resume == &block_job_user_resume); assert(job->job.driver->user_resume == &block_job_user_resume);
ratelimit_init(&job->limit);
job->blk = blk; job->blk = blk;
job->finalize_cancelled_notifier.notify = block_job_event_cancelled; job->finalize_cancelled_notifier.notify = block_job_event_cancelled;

117
configure vendored
View File

@ -352,6 +352,7 @@ kvm="auto"
hax="auto" hax="auto"
hvf="auto" hvf="auto"
whpx="auto" whpx="auto"
nvmm="auto"
rdma="$default_feature" rdma="$default_feature"
pvrdma="$default_feature" pvrdma="$default_feature"
gprof="no" gprof="no"
@ -463,6 +464,7 @@ gettext="auto"
fuse="auto" fuse="auto"
fuse_lseek="auto" fuse_lseek="auto"
multiprocess="auto" multiprocess="auto"
slirp_smbd="$default_feature"
malloc_trim="auto" malloc_trim="auto"
gio="$default_feature" gio="$default_feature"
@ -835,8 +837,6 @@ do
fi fi
done done
: ${smbd=${SMBD-/usr/sbin/smbd}}
# Default objcc to clang if available, otherwise use CC # Default objcc to clang if available, otherwise use CC
if has clang; then if has clang; then
objcc=clang objcc=clang
@ -1107,6 +1107,10 @@ for opt do
;; ;;
--enable-hvf) hvf="enabled" --enable-hvf) hvf="enabled"
;; ;;
--disable-nvmm) nvmm="disabled"
;;
--enable-nvmm) nvmm="enabled"
;;
--disable-whpx) whpx="disabled" --disable-whpx) whpx="disabled"
;; ;;
--enable-whpx) whpx="enabled" --enable-whpx) whpx="enabled"
@ -1565,6 +1569,10 @@ for opt do
;; ;;
--disable-gio) gio=no --disable-gio) gio=no
;; ;;
--enable-slirp-smbd) slirp_smbd=yes
;;
--disable-slirp-smbd) slirp_smbd=no
;;
*) *)
echo "ERROR: unknown option $opt" echo "ERROR: unknown option $opt"
echo "Try '$0 --help' for more information" echo "Try '$0 --help' for more information"
@ -1848,6 +1856,7 @@ disabled with --disable-FEATURE, default is enabled if available
kvm KVM acceleration support kvm KVM acceleration support
hax HAX acceleration support hax HAX acceleration support
hvf Hypervisor.framework acceleration support hvf Hypervisor.framework acceleration support
nvmm NVMM acceleration support
whpx Windows Hypervisor Platform acceleration support whpx Windows Hypervisor Platform acceleration support
rdma Enable RDMA-based migration rdma Enable RDMA-based migration
pvrdma Enable PVRDMA support pvrdma Enable PVRDMA support
@ -1919,6 +1928,7 @@ disabled with --disable-FEATURE, default is enabled if available
fuse-lseek SEEK_HOLE/SEEK_DATA support for FUSE exports fuse-lseek SEEK_HOLE/SEEK_DATA support for FUSE exports
multiprocess Out of process device emulation support multiprocess Out of process device emulation support
gio libgio support 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 NOTE: The object files are built at the place where configure is launched
EOF EOF
@ -5255,6 +5265,19 @@ case "$slirp" in
;; ;;
esac 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 # check for usable __NR_keyctl syscall
@ -5530,7 +5553,10 @@ fi
if test "$guest_agent" = "yes" ; then if test "$guest_agent" = "yes" ; then
echo "CONFIG_GUEST_AGENT=y" >> $config_host_mak echo "CONFIG_GUEST_AGENT=y" >> $config_host_mak
fi fi
echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak 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 "$vde" = "yes" ; then if test "$vde" = "yes" ; then
echo "CONFIG_VDE=y" >> $config_host_mak echo "CONFIG_VDE=y" >> $config_host_mak
echo "VDE_LIBS=$vde_libs" >> $config_host_mak echo "VDE_LIBS=$vde_libs" >> $config_host_mak
@ -6319,33 +6345,33 @@ for rom in seabios; do
done done
if test "$skip_meson" = no; then if test "$skip_meson" = no; then
cross="config-meson.cross.new" cross="config-meson.cross.new"
meson_quote() { meson_quote() {
echo "'$(echo $* | sed "s/ /','/g")'" echo "'$(echo $* | sed "s/ /','/g")'"
} }
echo "# Automatically generated by configure - do not modify" > $cross echo "# Automatically generated by configure - do not modify" > $cross
echo "[properties]" >> $cross echo "[properties]" >> $cross
test -z "$cxx" && echo "link_language = 'c'" >> $cross test -z "$cxx" && echo "link_language = 'c'" >> $cross
echo "[built-in options]" >> $cross echo "[built-in options]" >> $cross
echo "c_args = [${CFLAGS:+$(meson_quote $CFLAGS)}]" >> $cross echo "c_args = [${CFLAGS:+$(meson_quote $CFLAGS)}]" >> $cross
echo "cpp_args = [${CXXFLAGS:+$(meson_quote $CXXFLAGS)}]" >> $cross echo "cpp_args = [${CXXFLAGS:+$(meson_quote $CXXFLAGS)}]" >> $cross
echo "c_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross echo "c_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
echo "[binaries]" >> $cross echo "[binaries]" >> $cross
echo "c = [$(meson_quote $cc)]" >> $cross echo "c = [$(meson_quote $cc)]" >> $cross
test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross
test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross
echo "ar = [$(meson_quote $ar)]" >> $cross echo "ar = [$(meson_quote $ar)]" >> $cross
echo "nm = [$(meson_quote $nm)]" >> $cross echo "nm = [$(meson_quote $nm)]" >> $cross
echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
echo "ranlib = [$(meson_quote $ranlib)]" >> $cross echo "ranlib = [$(meson_quote $ranlib)]" >> $cross
if has $sdl2_config; then if has $sdl2_config; then
echo "sdl2-config = [$(meson_quote $sdl2_config)]" >> $cross echo "sdl2-config = [$(meson_quote $sdl2_config)]" >> $cross
fi fi
echo "strip = [$(meson_quote $strip)]" >> $cross echo "strip = [$(meson_quote $strip)]" >> $cross
echo "windres = [$(meson_quote $windres)]" >> $cross echo "windres = [$(meson_quote $windres)]" >> $cross
if test "$cross_compile" = "yes"; then if test "$cross_compile" = "yes"; then
cross_arg="--cross-file config-meson.cross" cross_arg="--cross-file config-meson.cross"
echo "[host_machine]" >> $cross echo "[host_machine]" >> $cross
if test "$mingw32" = "yes" ; then if test "$mingw32" = "yes" ; then
@ -6377,17 +6403,17 @@ if test "$cross_compile" = "yes"; then
else else
echo "endian = 'little'" >> $cross echo "endian = 'little'" >> $cross
fi fi
else else
cross_arg="--native-file config-meson.cross" cross_arg="--native-file config-meson.cross"
fi fi
mv $cross config-meson.cross mv $cross config-meson.cross
rm -rf meson-private meson-info meson-logs rm -rf meson-private meson-info meson-logs
unset staticpic unset staticpic
if ! version_ge "$($meson --version)" 0.56.0; then if ! version_ge "$($meson --version)" 0.56.0; then
staticpic=$(if test "$pie" = yes; then echo true; else echo false; fi) staticpic=$(if test "$pie" = yes; then echo true; else echo false; fi)
fi fi
NINJA=$ninja $meson setup \ NINJA=$ninja $meson setup \
--prefix "$prefix" \ --prefix "$prefix" \
--libdir "$libdir" \ --libdir "$libdir" \
--libexecdir "$libexecdir" \ --libexecdir "$libexecdir" \
@ -6410,7 +6436,7 @@ NINJA=$ninja $meson setup \
-Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \ -Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \
-Db_lto=$lto -Dcfi=$cfi -Dcfi_debug=$cfi_debug \ -Db_lto=$lto -Dcfi=$cfi -Dcfi_debug=$cfi_debug \
-Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \ -Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \
-Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf \ -Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf -Dnvmm=$nvmm \
-Dxen=$xen -Dxen_pci_passthrough=$xen_pci_passthrough -Dtcg=$tcg \ -Dxen=$xen -Dxen_pci_passthrough=$xen_pci_passthrough -Dtcg=$tcg \
-Dcocoa=$cocoa -Dgtk=$gtk -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \ -Dcocoa=$cocoa -Dgtk=$gtk -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \
-Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \ -Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \
@ -6429,9 +6455,18 @@ NINJA=$ninja $meson setup \
$cross_arg \ $cross_arg \
"$PWD" "$source_path" "$PWD" "$source_path"
if test "$?" -ne 0 ; then if test "$?" -ne 0 ; then
error_exit "meson setup failed" error_exit "meson setup failed"
fi fi
else
if test -f meson-private/cmd_line.txt; then
# Adjust old command line options whose type was changed
# Avoids having to use "setup --wipe" when Meson is upgraded
perl -i -ne '
s/^gettext = true$/gettext = auto/;
s/^gettext = false$/gettext = disabled/;
print;' meson-private/cmd_line.txt
fi
fi fi
if test -n "${deprecated_features}"; then if test -n "${deprecated_features}"; then

View File

@ -100,6 +100,23 @@ g_unix_get_passwd_entry_qemu(const gchar *user_name, GError **error)
} }
#endif /* G_OS_UNIX */ #endif /* G_OS_UNIX */
static inline bool
qemu_g_test_slow(void)
{
static int cached = -1;
if (cached == -1) {
cached = g_test_slow() || getenv("G_TEST_SLOW") != NULL;
}
return cached;
}
#undef g_test_slow
#undef g_test_thorough
#undef g_test_quick
#define g_test_slow() qemu_g_test_slow()
#define g_test_thorough() qemu_g_test_slow()
#define g_test_quick() (!qemu_g_test_slow())
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif

View File

@ -14,9 +14,11 @@
#ifndef QEMU_RATELIMIT_H #ifndef QEMU_RATELIMIT_H
#define QEMU_RATELIMIT_H #define QEMU_RATELIMIT_H
#include "qemu/lockable.h"
#include "qemu/timer.h" #include "qemu/timer.h"
typedef struct { typedef struct {
QemuMutex lock;
int64_t slice_start_time; int64_t slice_start_time;
int64_t slice_end_time; int64_t slice_end_time;
uint64_t slice_quota; uint64_t slice_quota;
@ -40,6 +42,7 @@ static inline int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
double delay_slices; double delay_slices;
QEMU_LOCK_GUARD(&limit->lock);
assert(limit->slice_quota && limit->slice_ns); assert(limit->slice_quota && limit->slice_ns);
if (limit->slice_end_time < now) { if (limit->slice_end_time < now) {
@ -65,9 +68,20 @@ static inline int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
return limit->slice_end_time - now; return limit->slice_end_time - now;
} }
static inline void ratelimit_init(RateLimit *limit)
{
qemu_mutex_init(&limit->lock);
}
static inline void ratelimit_destroy(RateLimit *limit)
{
qemu_mutex_destroy(&limit->lock);
}
static inline void ratelimit_set_speed(RateLimit *limit, uint64_t speed, static inline void ratelimit_set_speed(RateLimit *limit, uint64_t speed,
uint64_t slice_ns) uint64_t slice_ns)
{ {
QEMU_LOCK_GUARD(&limit->lock);
limit->slice_ns = slice_ns; limit->slice_ns = slice_ns;
limit->slice_quota = MAX(((double)speed * slice_ns) / 1000000000ULL, 1); limit->slice_quota = MAX(((double)speed * slice_ns) / 1000000000ULL, 1);
} }

View File

@ -16,6 +16,7 @@
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "sysemu/hvf.h" #include "sysemu/hvf.h"
#include "sysemu/whpx.h" #include "sysemu/whpx.h"
#include "sysemu/nvmm.h"
void cpu_synchronize_state(CPUState *cpu); void cpu_synchronize_state(CPUState *cpu);
void cpu_synchronize_post_reset(CPUState *cpu); void cpu_synchronize_post_reset(CPUState *cpu);

26
include/sysemu/nvmm.h Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2018-2019 Maxime Villard, All rights reserved.
*
* NetBSD Virtual Machine Monitor (NVMM) accelerator support.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef QEMU_NVMM_H
#define QEMU_NVMM_H
#include "config-host.h"
#include "qemu-common.h"
#ifdef CONFIG_NVMM
int nvmm_enabled(void);
#else /* CONFIG_NVMM */
#define nvmm_enabled() (0)
#endif /* CONFIG_NVMM */
#endif /* CONFIG_NVMM */

View File

@ -87,6 +87,7 @@ if cpu in ['x86', 'x86_64']
accelerator_targets += { accelerator_targets += {
'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'], 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
'CONFIG_HVF': ['x86_64-softmmu'], 'CONFIG_HVF': ['x86_64-softmmu'],
'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'], 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
} }
endif endif
@ -170,6 +171,7 @@ version_res = []
coref = [] coref = []
iokit = [] iokit = []
emulator_link_args = [] emulator_link_args = []
nvmm =not_found
hvf = not_found hvf = not_found
if targetos == 'windows' if targetos == 'windows'
socket = cc.find_library('ws2_32') socket = cc.find_library('ws2_32')
@ -227,6 +229,14 @@ if not get_option('hax').disabled()
accelerators += 'CONFIG_HAX' accelerators += 'CONFIG_HAX'
endif endif
endif endif
if targetos == 'netbsd'
if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
endif
if nvmm.found()
accelerators += 'CONFIG_NVMM'
endif
endif
tcg_arch = config_host['ARCH'] tcg_arch = config_host['ARCH']
if not get_option('tcg').disabled() if not get_option('tcg').disabled()
@ -270,6 +280,9 @@ endif
if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled() if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
error('HVF not available on this platform') error('HVF not available on this platform')
endif endif
if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
error('NVMM not available on this platform')
endif
if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled() if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
error('WHPX not available on this platform') error('WHPX not available on this platform')
endif endif
@ -2456,7 +2469,7 @@ summary_info += {'genisoimage': config_host['GENISOIMAGE']}
if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT') if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
summary_info += {'wixl': wixl.found() ? wixl.full_path() : false} summary_info += {'wixl': wixl.found() ? wixl.full_path() : false}
endif endif
if slirp_opt != 'disabled' if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']} summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
endif endif
summary(summary_info, bool_yn: true, section: 'Host binaries') summary(summary_info, bool_yn: true, section: 'Host binaries')
@ -2581,6 +2594,7 @@ if have_system
summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')} summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')} summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
if config_host.has_key('CONFIG_XEN_BACKEND') if config_host.has_key('CONFIG_XEN_BACKEND')
summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']} summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}

View File

@ -33,6 +33,8 @@ option('whpx', type: 'feature', value: 'auto',
description: 'WHPX acceleration support') description: 'WHPX acceleration support')
option('hvf', type: 'feature', value: 'auto', option('hvf', type: 'feature', value: 'auto',
description: 'HVF acceleration support') description: 'HVF acceleration support')
option('nvmm', type: 'feature', value: 'auto',
description: 'NVMM acceleration support')
option('xen', type: 'feature', value: 'auto', option('xen', type: 'feature', value: 'auto',
description: 'Xen backend support') description: 'Xen backend support')
option('xen_pci_passthrough', type: 'feature', value: 'auto', option('xen_pci_passthrough', type: 'feature', value: 'auto',

View File

@ -27,7 +27,7 @@
#include "net/slirp.h" #include "net/slirp.h"
#ifndef _WIN32 #if defined(CONFIG_SLIRP_SMBD)
#include <pwd.h> #include <pwd.h>
#include <sys/wait.h> #include <sys/wait.h>
#endif #endif
@ -91,7 +91,7 @@ typedef struct SlirpState {
Slirp *slirp; Slirp *slirp;
Notifier poll_notifier; Notifier poll_notifier;
Notifier exit_notifier; Notifier exit_notifier;
#ifndef _WIN32 #if defined(CONFIG_SLIRP_SMBD)
gchar *smb_dir; gchar *smb_dir;
#endif #endif
GSList *fwd; GSList *fwd;
@ -104,7 +104,7 @@ static QTAILQ_HEAD(, SlirpState) slirp_stacks =
static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp); static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp);
static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp); static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp);
#ifndef _WIN32 #if defined(CONFIG_SLIRP_SMBD)
static int slirp_smb(SlirpState *s, const char *exported_dir, static int slirp_smb(SlirpState *s, const char *exported_dir,
struct in_addr vserver_addr, Error **errp); struct in_addr vserver_addr, Error **errp);
static void slirp_smb_cleanup(SlirpState *s); static void slirp_smb_cleanup(SlirpState *s);
@ -377,7 +377,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
struct in6_addr ip6_prefix; struct in6_addr ip6_prefix;
struct in6_addr ip6_host; struct in6_addr ip6_host;
struct in6_addr ip6_dns; struct in6_addr ip6_dns;
#ifndef _WIN32 #if defined(CONFIG_SLIRP_SMBD)
struct in_addr smbsrv = { .s_addr = 0 }; struct in_addr smbsrv = { .s_addr = 0 };
#endif #endif
NetClientState *nc; NetClientState *nc;
@ -487,7 +487,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
return -1; return -1;
} }
#ifndef _WIN32 #if defined(CONFIG_SLIRP_SMBD)
if (vsmbserver && !inet_aton(vsmbserver, &smbsrv)) { if (vsmbserver && !inet_aton(vsmbserver, &smbsrv)) {
error_setg(errp, "Failed to parse SMB address"); error_setg(errp, "Failed to parse SMB address");
return -1; return -1;
@ -602,7 +602,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
} }
} }
} }
#ifndef _WIN32 #if defined(CONFIG_SLIRP_SMBD)
if (smb_export) { if (smb_export) {
if (slirp_smb(s, smb_export, smbsrv, errp) < 0) { if (slirp_smb(s, smb_export, smbsrv, errp) < 0) {
goto error; goto error;
@ -794,7 +794,7 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
} }
#ifndef _WIN32 #if defined(CONFIG_SLIRP_SMBD)
/* automatic user mode samba server configuration */ /* automatic user mode samba server configuration */
static void slirp_smb_cleanup(SlirpState *s) static void slirp_smb_cleanup(SlirpState *s)
@ -909,7 +909,7 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
return 0; return 0;
} }
#endif /* !defined(_WIN32) */ #endif /* defined(CONFIG_SLIRP_SMBD) */
static int guestfwd_can_read(void *opaque) static int guestfwd_can_read(void *opaque)
{ {

View File

@ -26,7 +26,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
"-machine [type=]name[,prop[=value][,...]]\n" "-machine [type=]name[,prop[=value][,...]]\n"
" selects emulated machine ('-machine help' for list)\n" " selects emulated machine ('-machine help' for list)\n"
" property accel=accel1[:accel2[:...]] selects accelerator\n" " property accel=accel1[:accel2[:...]] selects accelerator\n"
" supported accelerators are kvm, xen, hax, hvf, whpx or tcg (default: tcg)\n" " supported accelerators are kvm, xen, hax, hvf, nvmm, whpx or tcg (default: tcg)\n"
" vmport=on|off|auto controls emulation of vmport (default: auto)\n" " vmport=on|off|auto controls emulation of vmport (default: auto)\n"
" dump-guest-core=on|off include guest memory in a core dump (default=on)\n" " dump-guest-core=on|off include guest memory in a core dump (default=on)\n"
" mem-merge=on|off controls memory merge support (default: on)\n" " mem-merge=on|off controls memory merge support (default: on)\n"
@ -58,7 +58,7 @@ SRST
``accel=accels1[:accels2[:...]]`` ``accel=accels1[:accels2[:...]]``
This is used to enable an accelerator. Depending on the target This is used to enable an accelerator. Depending on the target
architecture, kvm, xen, hax, hvf, whpx or tcg can be available. architecture, kvm, xen, hax, hvf, nvmm, whpx or tcg can be available.
By default, tcg is used. If there is more than one accelerator By default, tcg is used. If there is more than one accelerator
specified, the next one is used if the previous one fails to specified, the next one is used if the previous one fails to
initialize. initialize.
@ -135,7 +135,7 @@ ERST
DEF("accel", HAS_ARG, QEMU_OPTION_accel, DEF("accel", HAS_ARG, QEMU_OPTION_accel,
"-accel [accel=]accelerator[,prop[=value][,...]]\n" "-accel [accel=]accelerator[,prop[=value][,...]]\n"
" select accelerator (kvm, xen, hax, hvf, whpx or tcg; use 'help' for a list)\n" " select accelerator (kvm, xen, hax, hvf, nvmm, whpx or tcg; use 'help' for a list)\n"
" igd-passthru=on|off (enable Xen integrated Intel graphics passthrough, default=off)\n" " igd-passthru=on|off (enable Xen integrated Intel graphics passthrough, default=off)\n"
" kernel-irqchip=on|off|split controls accelerated irqchip support (default=on)\n" " kernel-irqchip=on|off|split controls accelerated irqchip support (default=on)\n"
" kvm-shadow-mem=size of KVM shadow MMU in bytes\n" " kvm-shadow-mem=size of KVM shadow MMU in bytes\n"
@ -145,7 +145,7 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
SRST SRST
``-accel name[,prop=value[,...]]`` ``-accel name[,prop=value[,...]]``
This is used to enable an accelerator. Depending on the target This is used to enable an accelerator. Depending on the target
architecture, kvm, xen, hax, hvf, whpx or tcg can be available. By architecture, kvm, xen, hax, hvf, nvmm, whpx or tcg can be available. By
default, tcg is used. If there is more than one accelerator default, tcg is used. If there is more than one accelerator
specified, the next one is used if the previous one fails to specified, the next one is used if the previous one fails to
initialize. initialize.

View File

@ -495,7 +495,7 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
X86CPU *cpu = env_archcpu(env); X86CPU *cpu = env_archcpu(env);
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
if (kvm_enabled() || whpx_enabled()) { if (kvm_enabled() || whpx_enabled() || nvmm_enabled()) {
env->tpr_access_type = access; env->tpr_access_type = access;
cpu_interrupt(cs, CPU_INTERRUPT_TPR); cpu_interrupt(cs, CPU_INTERRUPT_TPR);

View File

@ -19,6 +19,7 @@ i386_softmmu_ss.add(files(
subdir('kvm') subdir('kvm')
subdir('hax') subdir('hax')
subdir('whpx') subdir('whpx')
subdir('nvmm')
subdir('hvf') subdir('hvf')
subdir('tcg') subdir('tcg')

View File

@ -0,0 +1,8 @@
i386_softmmu_ss.add(when: 'CONFIG_NVMM', if_true:
files(
'nvmm-all.c',
'nvmm-accel-ops.c',
)
)
i386_softmmu_ss.add(when: 'CONFIG_NVMM', if_true: nvmm)

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) 2018-2019 Maxime Villard, All rights reserved.
*
* NetBSD Virtual Machine Monitor (NVMM) accelerator for QEMU.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "sysemu/kvm_int.h"
#include "qemu/main-loop.h"
#include "sysemu/cpus.h"
#include "qemu/guest-random.h"
#include "sysemu/nvmm.h"
#include "nvmm-accel-ops.h"
static void *qemu_nvmm_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
int r;
assert(nvmm_enabled());
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
current_cpu = cpu;
r = nvmm_init_vcpu(cpu);
if (r < 0) {
fprintf(stderr, "nvmm_init_vcpu failed: %s\n", strerror(-r));
exit(1);
}
/* signal CPU creation */
cpu_thread_signal_created(cpu);
qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
if (cpu_can_run(cpu)) {
r = nvmm_vcpu_exec(cpu);
if (r == EXCP_DEBUG) {
cpu_handle_guest_debug(cpu);
}
}
while (cpu_thread_is_idle(cpu)) {
qemu_cond_wait_iothread(cpu->halt_cond);
}
qemu_wait_io_event_common(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
nvmm_destroy_vcpu(cpu);
cpu_thread_signal_destroyed(cpu);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
}
static void nvmm_start_vcpu_thread(CPUState *cpu)
{
char thread_name[VCPU_THREAD_NAME_SIZE];
cpu->thread = g_malloc0(sizeof(QemuThread));
cpu->halt_cond = g_malloc0(sizeof(QemuCond));
qemu_cond_init(cpu->halt_cond);
snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/NVMM",
cpu->cpu_index);
qemu_thread_create(cpu->thread, thread_name, qemu_nvmm_cpu_thread_fn,
cpu, QEMU_THREAD_JOINABLE);
}
/*
* Abort the call to run the virtual processor by another thread, and to
* return the control to that thread.
*/
static void nvmm_kick_vcpu_thread(CPUState *cpu)
{
cpu->exit_request = 1;
cpus_kick_thread(cpu);
}
static void nvmm_accel_ops_class_init(ObjectClass *oc, void *data)
{
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
ops->create_vcpu_thread = nvmm_start_vcpu_thread;
ops->kick_vcpu_thread = nvmm_kick_vcpu_thread;
ops->synchronize_post_reset = nvmm_cpu_synchronize_post_reset;
ops->synchronize_post_init = nvmm_cpu_synchronize_post_init;
ops->synchronize_state = nvmm_cpu_synchronize_state;
ops->synchronize_pre_loadvm = nvmm_cpu_synchronize_pre_loadvm;
}
static const TypeInfo nvmm_accel_ops_type = {
.name = ACCEL_OPS_NAME("nvmm"),
.parent = TYPE_ACCEL_OPS,
.class_init = nvmm_accel_ops_class_init,
.abstract = true,
};
static void nvmm_accel_ops_register_types(void)
{
type_register_static(&nvmm_accel_ops_type);
}
type_init(nvmm_accel_ops_register_types);

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2018-2019 Maxime Villard, All rights reserved.
*
* NetBSD Virtual Machine Monitor (NVMM) accelerator for QEMU.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef NVMM_CPUS_H
#define NVMM_CPUS_H
#include "sysemu/cpus.h"
int nvmm_init_vcpu(CPUState *cpu);
int nvmm_vcpu_exec(CPUState *cpu);
void nvmm_destroy_vcpu(CPUState *cpu);
void nvmm_cpu_synchronize_state(CPUState *cpu);
void nvmm_cpu_synchronize_post_reset(CPUState *cpu);
void nvmm_cpu_synchronize_post_init(CPUState *cpu);
void nvmm_cpu_synchronize_pre_loadvm(CPUState *cpu);
#endif /* NVMM_CPUS_H */

1226
target/i386/nvmm/nvmm-all.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -471,7 +471,7 @@ static int poll_rest(gboolean poll_msgs, HANDLE *handles, gint nhandles,
return 0; return 0;
} }
gint g_poll(GPollFD *fds, guint nfds, gint timeout) gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout)
{ {
HANDLE handles[MAXIMUM_WAIT_OBJECTS]; HANDLE handles[MAXIMUM_WAIT_OBJECTS];
gboolean poll_msgs = FALSE; gboolean poll_msgs = FALSE;