* Various fixes
* libdaxctl support to correctly align devdax character devices (Jingqi) * initial-all-set support for live migration (Jay) * forbid '-numa node, mem' for 5.1 and newer machine types (Igor) * x87 fixes (Joseph) * Tighten memory_region_access_valid (Michael) and fix fallout (myself) * Replay fixes (Pavel) -----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAl71+zkUHHBib256aW5p QHJlZGhhdC5jb20ACgkQv/vSX3jHroO4MAgAo/aPLzCXJTzFOP88TclEETfSUeyG GFs6mAEJpoNnkAzY+y6ZIjtbp346UZB2KMxHTQcd7p2tO+jXSDPpr0UBLqU95j0/ ucOnP1X9E5ee8P5Z7bXeGCtkfEippI5/TU+gHlx/SKeyVHdMKBsWCg/9LN5JXMJR ncQ6MxkU8huOksOLL32dxh1OqtdDiBoq9rswmHFXwDcRuIkteTlQo3Ze9BSb8t04 7ZImKXNr+wIaq/xXAqltYNGhHoi31Rz+W8W7T84tYNr7wI1LWaLi2jzQ2qJthAdq 25zXVz5QJjcfIemlrV03PN8IZfKqTfnOvf+DNW1ns/EdflQem/Mb0Q9KOg== =NfSA -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging * Various fixes * libdaxctl support to correctly align devdax character devices (Jingqi) * initial-all-set support for live migration (Jay) * forbid '-numa node, mem' for 5.1 and newer machine types (Igor) * x87 fixes (Joseph) * Tighten memory_region_access_valid (Michael) and fix fallout (myself) * Replay fixes (Pavel) # gpg: Signature made Fri 26 Jun 2020 14:42:17 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/tags/for-upstream: (31 commits) i386: Mask SVM features if nested SVM is disabled ibex_uart: fix XOR-as-pow vmport: move compat properties to hw_compat_5_0 hyperv: vmbus: Remove the 2nd IRQ kvm: i386: allow TSC to differ by NTP correction bounds without TSC scaling numa: forbid '-numa node, mem' for 5.1 and newer machine types osdep: Make MIN/MAX evaluate arguments only once target/i386: Add notes for versioned CPU models target/i386: reimplement fpatan using floatx80 operations target/i386: reimplement fyl2x using floatx80 operations target/i386: reimplement fyl2xp1 using floatx80 operations target/i386: reimplement fprem, fprem1 using floatx80 operations softfloat: return low bits of quotient from floatx80_modrem softfloat: do not set denominator high bit for floatx80 remainder softfloat: do not return pseudo-denormal from floatx80 remainder softfloat: fix floatx80 remainder pseudo-denormal check for zero softfloat: merge floatx80_mod and floatx80_rem target/i386: reimplement f2xm1 using floatx80 operations xen: Actually fix build without passthrough Makefile: Install qemu-[qmp/ga]-ref.* into the directory "interop" ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3591ddd399
10
Makefile
10
Makefile
@ -873,8 +873,9 @@ install-sphinxdocs: sphinxdocs
|
|||||||
install-doc: $(DOCS) install-sphinxdocs
|
install-doc: $(DOCS) install-sphinxdocs
|
||||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
|
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
|
||||||
$(INSTALL_DATA) $(MANUAL_BUILDDIR)/index.html "$(DESTDIR)$(qemu_docdir)"
|
$(INSTALL_DATA) $(MANUAL_BUILDDIR)/index.html "$(DESTDIR)$(qemu_docdir)"
|
||||||
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.html "$(DESTDIR)$(qemu_docdir)"
|
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/interop"
|
||||||
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.txt "$(DESTDIR)$(qemu_docdir)"
|
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.html "$(DESTDIR)$(qemu_docdir)/interop"
|
||||||
|
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.txt "$(DESTDIR)$(qemu_docdir)/interop"
|
||||||
ifdef CONFIG_POSIX
|
ifdef CONFIG_POSIX
|
||||||
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
|
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
|
||||||
$(INSTALL_DATA) $(MANUAL_BUILDDIR)/system/qemu.1 "$(DESTDIR)$(mandir)/man1"
|
$(INSTALL_DATA) $(MANUAL_BUILDDIR)/system/qemu.1 "$(DESTDIR)$(mandir)/man1"
|
||||||
@ -892,8 +893,9 @@ ifdef CONFIG_TRACE_SYSTEMTAP
|
|||||||
endif
|
endif
|
||||||
ifneq (,$(findstring qemu-ga,$(TOOLS)))
|
ifneq (,$(findstring qemu-ga,$(TOOLS)))
|
||||||
$(INSTALL_DATA) $(MANUAL_BUILDDIR)/interop/qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
|
$(INSTALL_DATA) $(MANUAL_BUILDDIR)/interop/qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
|
||||||
$(INSTALL_DATA) docs/interop/qemu-ga-ref.html "$(DESTDIR)$(qemu_docdir)"
|
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/interop"
|
||||||
$(INSTALL_DATA) docs/interop/qemu-ga-ref.txt "$(DESTDIR)$(qemu_docdir)"
|
$(INSTALL_DATA) docs/interop/qemu-ga-ref.html "$(DESTDIR)$(qemu_docdir)/interop"
|
||||||
|
$(INSTALL_DATA) docs/interop/qemu-ga-ref.txt "$(DESTDIR)$(qemu_docdir)/interop"
|
||||||
$(INSTALL_DATA) docs/interop/qemu-ga-ref.7 "$(DESTDIR)$(mandir)/man7"
|
$(INSTALL_DATA) docs/interop/qemu-ga-ref.7 "$(DESTDIR)$(mandir)/man7"
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -101,7 +101,7 @@ struct KVMState
|
|||||||
bool kernel_irqchip_required;
|
bool kernel_irqchip_required;
|
||||||
OnOffAuto kernel_irqchip_split;
|
OnOffAuto kernel_irqchip_split;
|
||||||
bool sync_mmu;
|
bool sync_mmu;
|
||||||
bool manual_dirty_log_protect;
|
uint64_t manual_dirty_log_protect;
|
||||||
/* The man page (and posix) say ioctl numbers are signed int, but
|
/* The man page (and posix) say ioctl numbers are signed int, but
|
||||||
* they're not. Linux, glibc and *BSD all treat ioctl numbers as
|
* they're not. Linux, glibc and *BSD all treat ioctl numbers as
|
||||||
* unsigned, and treating them as signed here can break things */
|
* unsigned, and treating them as signed here can break things */
|
||||||
@ -1995,6 +1995,7 @@ static int kvm_init(MachineState *ms)
|
|||||||
int ret;
|
int ret;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
const char *kvm_type;
|
const char *kvm_type;
|
||||||
|
uint64_t dirty_log_manual_caps;
|
||||||
|
|
||||||
s = KVM_STATE(ms->accelerator);
|
s = KVM_STATE(ms->accelerator);
|
||||||
|
|
||||||
@ -2120,14 +2121,20 @@ static int kvm_init(MachineState *ms)
|
|||||||
s->coalesced_pio = s->coalesced_mmio &&
|
s->coalesced_pio = s->coalesced_mmio &&
|
||||||
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
|
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
|
||||||
|
|
||||||
s->manual_dirty_log_protect =
|
dirty_log_manual_caps =
|
||||||
kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
|
kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
|
||||||
if (s->manual_dirty_log_protect) {
|
dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
|
||||||
ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0, 1);
|
KVM_DIRTY_LOG_INITIALLY_SET);
|
||||||
|
s->manual_dirty_log_protect = dirty_log_manual_caps;
|
||||||
|
if (dirty_log_manual_caps) {
|
||||||
|
ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
|
||||||
|
dirty_log_manual_caps);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
warn_report("Trying to enable KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 "
|
warn_report("Trying to enable capability %"PRIu64" of "
|
||||||
"but failed. Falling back to the legacy mode. ");
|
"KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
|
||||||
s->manual_dirty_log_protect = false;
|
"Falling back to the legacy mode. ",
|
||||||
|
dirty_log_manual_caps);
|
||||||
|
s->manual_dirty_log_protect = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2582,9 +2582,9 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
|
|||||||
/* This function should never be called with addresses outside the
|
/* This function should never be called with addresses outside the
|
||||||
guest address space. If this assert fires, it probably indicates
|
guest address space. If this assert fires, it probably indicates
|
||||||
a missing call to h2g_valid. */
|
a missing call to h2g_valid. */
|
||||||
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
|
if (TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS) {
|
||||||
assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
|
assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
|
||||||
#endif
|
}
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
29
configure
vendored
29
configure
vendored
@ -518,6 +518,7 @@ plugins="no"
|
|||||||
fuzzing="no"
|
fuzzing="no"
|
||||||
rng_none="no"
|
rng_none="no"
|
||||||
secret_keyring=""
|
secret_keyring=""
|
||||||
|
libdaxctl=""
|
||||||
|
|
||||||
supported_cpu="no"
|
supported_cpu="no"
|
||||||
supported_os="no"
|
supported_os="no"
|
||||||
@ -1626,6 +1627,10 @@ for opt do
|
|||||||
;;
|
;;
|
||||||
--disable-keyring) secret_keyring="no"
|
--disable-keyring) secret_keyring="no"
|
||||||
;;
|
;;
|
||||||
|
--enable-libdaxctl) libdaxctl=yes
|
||||||
|
;;
|
||||||
|
--disable-libdaxctl) libdaxctl=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"
|
||||||
@ -1927,6 +1932,7 @@ disabled with --disable-FEATURE, default is enabled if available:
|
|||||||
libpmem libpmem support
|
libpmem libpmem support
|
||||||
xkbcommon xkbcommon support
|
xkbcommon xkbcommon support
|
||||||
rng-none dummy RNG, avoid using /dev/(u)random and getrandom()
|
rng-none dummy RNG, avoid using /dev/(u)random and getrandom()
|
||||||
|
libdaxctl libdaxctl support
|
||||||
|
|
||||||
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
|
||||||
@ -6360,6 +6366,24 @@ if test "$libpmem" != "no"; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
##########################################
|
||||||
|
# check for libdaxctl
|
||||||
|
|
||||||
|
if test "$libdaxctl" != "no"; then
|
||||||
|
if $pkg_config --atleast-version=57 "libdaxctl"; then
|
||||||
|
libdaxctl="yes"
|
||||||
|
libdaxctl_libs=$($pkg_config --libs libdaxctl)
|
||||||
|
libdaxctl_cflags=$($pkg_config --cflags libdaxctl)
|
||||||
|
libs_softmmu="$libs_softmmu $libdaxctl_libs"
|
||||||
|
QEMU_CFLAGS="$QEMU_CFLAGS $libdaxctl_cflags"
|
||||||
|
else
|
||||||
|
if test "$libdaxctl" = "yes" ; then
|
||||||
|
feature_not_found "libdaxctl" "Install libdaxctl"
|
||||||
|
fi
|
||||||
|
libdaxctl="no"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# check for slirp
|
# check for slirp
|
||||||
|
|
||||||
@ -6967,6 +6991,7 @@ echo "parallels support $parallels"
|
|||||||
echo "sheepdog support $sheepdog"
|
echo "sheepdog support $sheepdog"
|
||||||
echo "capstone $capstone"
|
echo "capstone $capstone"
|
||||||
echo "libpmem support $libpmem"
|
echo "libpmem support $libpmem"
|
||||||
|
echo "libdaxctl support $libdaxctl"
|
||||||
echo "libudev $libudev"
|
echo "libudev $libudev"
|
||||||
echo "default devices $default_devices"
|
echo "default devices $default_devices"
|
||||||
echo "plugin support $plugins"
|
echo "plugin support $plugins"
|
||||||
@ -7800,6 +7825,10 @@ if test "$libpmem" = "yes" ; then
|
|||||||
echo "CONFIG_LIBPMEM=y" >> $config_host_mak
|
echo "CONFIG_LIBPMEM=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$libdaxctl" = "yes" ; then
|
||||||
|
echo "CONFIG_LIBDAXCTL=y" >> $config_host_mak
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$bochs" = "yes" ; then
|
if test "$bochs" = "yes" ; then
|
||||||
echo "CONFIG_BOCHS=y" >> $config_host_mak
|
echo "CONFIG_BOCHS=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
15
cpus.c
15
cpus.c
@ -1374,6 +1374,13 @@ static int64_t tcg_get_icount_limit(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void notify_aio_contexts(void)
|
||||||
|
{
|
||||||
|
/* Wake up other AioContexts. */
|
||||||
|
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
|
||||||
|
qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_icount_deadline(void)
|
static void handle_icount_deadline(void)
|
||||||
{
|
{
|
||||||
assert(qemu_in_vcpu_thread());
|
assert(qemu_in_vcpu_thread());
|
||||||
@ -1382,9 +1389,7 @@ static void handle_icount_deadline(void)
|
|||||||
QEMU_TIMER_ATTR_ALL);
|
QEMU_TIMER_ATTR_ALL);
|
||||||
|
|
||||||
if (deadline == 0) {
|
if (deadline == 0) {
|
||||||
/* Wake up other AioContexts. */
|
notify_aio_contexts();
|
||||||
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
|
|
||||||
qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1407,6 +1412,10 @@ static void prepare_icount_for_run(CPUState *cpu)
|
|||||||
cpu->icount_extra = cpu->icount_budget - insns_left;
|
cpu->icount_extra = cpu->icount_budget - insns_left;
|
||||||
|
|
||||||
replay_mutex_lock();
|
replay_mutex_lock();
|
||||||
|
|
||||||
|
if (cpu->icount_budget == 0 && replay_has_checkpoint()) {
|
||||||
|
notify_aio_contexts();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
<li><a href="tools/index.html">Tools Guide</a></li>
|
<li><a href="tools/index.html">Tools Guide</a></li>
|
||||||
<li><a href="interop/index.html">System Emulation Management and Interoperability Guide</a></li>
|
<li><a href="interop/index.html">System Emulation Management and Interoperability Guide</a></li>
|
||||||
<li><a href="specs/index.html">System Emulation Guest Hardware Specifications</a></li>
|
<li><a href="specs/index.html">System Emulation Guest Hardware Specifications</a></li>
|
||||||
<li><a href="qemu-qmp-ref.html">QMP Reference Manual</a></li>
|
<li><a href="interop/qemu-qmp-ref.html">QMP Reference Manual</a></li>
|
||||||
<li><a href="qemu-ga-ref.html">Guest Agent Protocol Reference</a></li>
|
<li><a href="interop/qemu-ga-ref.html">Guest Agent Protocol Reference</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -132,6 +132,16 @@ address to the page size (getpagesize(2)) by default. However, some
|
|||||||
types of backends may require an alignment different than the page
|
types of backends may require an alignment different than the page
|
||||||
size. In that case, QEMU v2.12.0 and later provide 'align' option to
|
size. In that case, QEMU v2.12.0 and later provide 'align' option to
|
||||||
memory-backend-file to allow users to specify the proper alignment.
|
memory-backend-file to allow users to specify the proper alignment.
|
||||||
|
For device dax (e.g., /dev/dax0.0), this alignment needs to match the
|
||||||
|
alignment requirement of the device dax. The NUM of 'align=NUM' option
|
||||||
|
must be larger than or equal to the 'align' of device dax.
|
||||||
|
We can use one of the following commands to show the 'align' of device dax.
|
||||||
|
|
||||||
|
ndctl list -X
|
||||||
|
daxctl list -R
|
||||||
|
|
||||||
|
In order to get the proper 'align' of device dax, you need to install
|
||||||
|
the library 'libdaxctl'.
|
||||||
|
|
||||||
For example, device dax require the 2 MB alignment, so we can use
|
For example, device dax require the 2 MB alignment, so we can use
|
||||||
following QEMU command line options to use it (/dev/dax0.0) as the
|
following QEMU command line options to use it (/dev/dax0.0) as the
|
||||||
|
@ -95,23 +95,6 @@ error in the future.
|
|||||||
The ``-realtime mlock=on|off`` argument has been replaced by the
|
The ``-realtime mlock=on|off`` argument has been replaced by the
|
||||||
``-overcommit mem-lock=on|off`` argument.
|
``-overcommit mem-lock=on|off`` argument.
|
||||||
|
|
||||||
``-numa node,mem=``\ *size* (since 4.1)
|
|
||||||
'''''''''''''''''''''''''''''''''''''''
|
|
||||||
|
|
||||||
The parameter ``mem`` of ``-numa node`` is used to assign a part of
|
|
||||||
guest RAM to a NUMA node. But when using it, it's impossible to manage specified
|
|
||||||
RAM chunk on the host side (like bind it to a host node, setting bind policy, ...),
|
|
||||||
so guest end-ups with the fake NUMA configuration with suboptiomal performance.
|
|
||||||
However since 2014 there is an alternative way to assign RAM to a NUMA node
|
|
||||||
using parameter ``memdev``, which does the same as ``mem`` and adds
|
|
||||||
means to actualy manage node RAM on the host side. Use parameter ``memdev``
|
|
||||||
with *memory-backend-ram* backend as an replacement for parameter ``mem``
|
|
||||||
to achieve the same fake NUMA effect or a properly configured
|
|
||||||
*memory-backend-file* backend to actually benefit from NUMA configuration.
|
|
||||||
In future new machine versions will not accept the option but it will still
|
|
||||||
work with old machine types. User can check QAPI schema to see if the legacy
|
|
||||||
option is supported by looking at MachineInfo::numa-mem-supported property.
|
|
||||||
|
|
||||||
``-numa`` node (without memory specified) (since 4.1)
|
``-numa`` node (without memory specified) (since 4.1)
|
||||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''
|
'''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||||
|
|
||||||
@ -553,3 +536,23 @@ long starting at 1MiB, the old command::
|
|||||||
can be rewritten as::
|
can be rewritten as::
|
||||||
|
|
||||||
qemu-nbd -t --image-opts driver=raw,offset=1M,size=100M,file.driver=qcow2,file.file.driver=file,file.file.filename=file.qcow2
|
qemu-nbd -t --image-opts driver=raw,offset=1M,size=100M,file.driver=qcow2,file.file.driver=file,file.file.filename=file.qcow2
|
||||||
|
|
||||||
|
Command line options
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
``-numa node,mem=``\ *size* (removed in 5.1)
|
||||||
|
''''''''''''''''''''''''''''''''''''''''''''
|
||||||
|
|
||||||
|
The parameter ``mem`` of ``-numa node`` was used to assign a part of
|
||||||
|
guest RAM to a NUMA node. But when using it, it's impossible to manage a specified
|
||||||
|
RAM chunk on the host side (like bind it to a host node, setting bind policy, ...),
|
||||||
|
so the guest ends up with the fake NUMA configuration with suboptiomal performance.
|
||||||
|
However since 2014 there is an alternative way to assign RAM to a NUMA node
|
||||||
|
using parameter ``memdev``, which does the same as ``mem`` and adds
|
||||||
|
means to actually manage node RAM on the host side. Use parameter ``memdev``
|
||||||
|
with *memory-backend-ram* backend as replacement for parameter ``mem``
|
||||||
|
to achieve the same fake NUMA effect or a properly configured
|
||||||
|
*memory-backend-file* backend to actually benefit from NUMA configuration.
|
||||||
|
New machine versions (since 5.1) will not accept the option but it will still
|
||||||
|
work with old machine types. User can check the QAPI schema to see if the legacy
|
||||||
|
option is supported by looking at MachineInfo::numa-mem-supported property.
|
||||||
|
54
exec.c
54
exec.c
@ -77,6 +77,10 @@
|
|||||||
|
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIBDAXCTL
|
||||||
|
#include <daxctl/libdaxctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
//#define DEBUG_SUBPAGE
|
//#define DEBUG_SUBPAGE
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
@ -1745,6 +1749,46 @@ static int64_t get_file_size(int fd)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int64_t get_file_align(int fd)
|
||||||
|
{
|
||||||
|
int64_t align = -1;
|
||||||
|
#if defined(__linux__) && defined(CONFIG_LIBDAXCTL)
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (fstat(fd, &st) < 0) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special handling for devdax character devices */
|
||||||
|
if (S_ISCHR(st.st_mode)) {
|
||||||
|
g_autofree char *path = NULL;
|
||||||
|
g_autofree char *rpath = NULL;
|
||||||
|
struct daxctl_ctx *ctx;
|
||||||
|
struct daxctl_region *region;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
path = g_strdup_printf("/sys/dev/char/%d:%d",
|
||||||
|
major(st.st_rdev), minor(st.st_rdev));
|
||||||
|
rpath = realpath(path, NULL);
|
||||||
|
|
||||||
|
rc = daxctl_new(&ctx);
|
||||||
|
if (rc) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
daxctl_region_foreach(ctx, region) {
|
||||||
|
if (strstr(rpath, daxctl_region_get_path(region))) {
|
||||||
|
align = daxctl_region_get_align(region);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
daxctl_unref(ctx);
|
||||||
|
}
|
||||||
|
#endif /* defined(__linux__) && defined(CONFIG_LIBDAXCTL) */
|
||||||
|
|
||||||
|
return align;
|
||||||
|
}
|
||||||
|
|
||||||
static int file_ram_open(const char *path,
|
static int file_ram_open(const char *path,
|
||||||
const char *region_name,
|
const char *region_name,
|
||||||
bool *created,
|
bool *created,
|
||||||
@ -2296,7 +2340,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
|
|||||||
{
|
{
|
||||||
RAMBlock *new_block;
|
RAMBlock *new_block;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
int64_t file_size;
|
int64_t file_size, file_align;
|
||||||
|
|
||||||
/* Just support these ram flags by now. */
|
/* Just support these ram flags by now. */
|
||||||
assert((ram_flags & ~(RAM_SHARED | RAM_PMEM)) == 0);
|
assert((ram_flags & ~(RAM_SHARED | RAM_PMEM)) == 0);
|
||||||
@ -2332,6 +2376,14 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file_align = get_file_align(fd);
|
||||||
|
if (file_align > 0 && mr && file_align > mr->align) {
|
||||||
|
error_setg(errp, "backing store align 0x%" PRIx64
|
||||||
|
" is larger than 'align' option 0x%" PRIx64,
|
||||||
|
file_align, mr->align);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
new_block = g_malloc0(sizeof(*new_block));
|
new_block = g_malloc0(sizeof(*new_block));
|
||||||
new_block->mr = mr;
|
new_block->mr = mr;
|
||||||
new_block->used_length = size;
|
new_block->used_length = size;
|
||||||
|
@ -5697,22 +5697,27 @@ floatx80 floatx80_div(floatx80 a, floatx80 b, float_status *status)
|
|||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Returns the remainder of the extended double-precision floating-point value
|
| Returns the remainder of the extended double-precision floating-point value
|
||||||
| `a' with respect to the corresponding value `b'. The operation is performed
|
| `a' with respect to the corresponding value `b'. The operation is performed
|
||||||
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
|
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic,
|
||||||
|
| if 'mod' is false; if 'mod' is true, return the remainder based on truncating
|
||||||
|
| the quotient toward zero instead. '*quotient' is set to the low 64 bits of
|
||||||
|
| the absolute value of the integer quotient.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
floatx80 floatx80_modrem(floatx80 a, floatx80 b, bool mod, uint64_t *quotient,
|
||||||
|
float_status *status)
|
||||||
{
|
{
|
||||||
bool aSign, zSign;
|
bool aSign, zSign;
|
||||||
int32_t aExp, bExp, expDiff;
|
int32_t aExp, bExp, expDiff, aExpOrig;
|
||||||
uint64_t aSig0, aSig1, bSig;
|
uint64_t aSig0, aSig1, bSig;
|
||||||
uint64_t q, term0, term1, alternateASig0, alternateASig1;
|
uint64_t q, term0, term1, alternateASig0, alternateASig1;
|
||||||
|
|
||||||
|
*quotient = 0;
|
||||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||||
float_raise(float_flag_invalid, status);
|
float_raise(float_flag_invalid, status);
|
||||||
return floatx80_default_nan(status);
|
return floatx80_default_nan(status);
|
||||||
}
|
}
|
||||||
aSig0 = extractFloatx80Frac( a );
|
aSig0 = extractFloatx80Frac( a );
|
||||||
aExp = extractFloatx80Exp( a );
|
aExpOrig = aExp = extractFloatx80Exp( a );
|
||||||
aSign = extractFloatx80Sign( a );
|
aSign = extractFloatx80Sign( a );
|
||||||
bSig = extractFloatx80Frac( b );
|
bSig = extractFloatx80Frac( b );
|
||||||
bExp = extractFloatx80Exp( b );
|
bExp = extractFloatx80Exp( b );
|
||||||
@ -5727,6 +5732,13 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
|||||||
if ((uint64_t)(bSig << 1)) {
|
if ((uint64_t)(bSig << 1)) {
|
||||||
return propagateFloatx80NaN(a, b, status);
|
return propagateFloatx80NaN(a, b, status);
|
||||||
}
|
}
|
||||||
|
if (aExp == 0 && aSig0 >> 63) {
|
||||||
|
/*
|
||||||
|
* Pseudo-denormal argument must be returned in normalized
|
||||||
|
* form.
|
||||||
|
*/
|
||||||
|
return packFloatx80(aSign, 1, aSig0);
|
||||||
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
if ( bExp == 0 ) {
|
if ( bExp == 0 ) {
|
||||||
@ -5738,19 +5750,27 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
|||||||
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
|
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
|
||||||
}
|
}
|
||||||
if ( aExp == 0 ) {
|
if ( aExp == 0 ) {
|
||||||
if ( (uint64_t) ( aSig0<<1 ) == 0 ) return a;
|
if ( aSig0 == 0 ) return a;
|
||||||
normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
|
normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
|
||||||
}
|
}
|
||||||
bSig |= UINT64_C(0x8000000000000000);
|
|
||||||
zSign = aSign;
|
zSign = aSign;
|
||||||
expDiff = aExp - bExp;
|
expDiff = aExp - bExp;
|
||||||
aSig1 = 0;
|
aSig1 = 0;
|
||||||
if ( expDiff < 0 ) {
|
if ( expDiff < 0 ) {
|
||||||
if ( expDiff < -1 ) return a;
|
if ( mod || expDiff < -1 ) {
|
||||||
|
if (aExp == 1 && aExpOrig == 0) {
|
||||||
|
/*
|
||||||
|
* Pseudo-denormal argument must be returned in
|
||||||
|
* normalized form.
|
||||||
|
*/
|
||||||
|
return packFloatx80(aSign, aExp, aSig0);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
|
shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
|
||||||
expDiff = 0;
|
expDiff = 0;
|
||||||
}
|
}
|
||||||
q = ( bSig <= aSig0 );
|
*quotient = q = ( bSig <= aSig0 );
|
||||||
if ( q ) aSig0 -= bSig;
|
if ( q ) aSig0 -= bSig;
|
||||||
expDiff -= 64;
|
expDiff -= 64;
|
||||||
while ( 0 < expDiff ) {
|
while ( 0 < expDiff ) {
|
||||||
@ -5760,6 +5780,8 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
|||||||
sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
|
sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
|
||||||
shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
|
shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
|
||||||
expDiff -= 62;
|
expDiff -= 62;
|
||||||
|
*quotient <<= 62;
|
||||||
|
*quotient += q;
|
||||||
}
|
}
|
||||||
expDiff += 64;
|
expDiff += 64;
|
||||||
if ( 0 < expDiff ) {
|
if ( 0 < expDiff ) {
|
||||||
@ -5773,19 +5795,28 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
|||||||
++q;
|
++q;
|
||||||
sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
|
sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
|
||||||
}
|
}
|
||||||
|
if (expDiff < 64) {
|
||||||
|
*quotient <<= expDiff;
|
||||||
|
} else {
|
||||||
|
*quotient = 0;
|
||||||
|
}
|
||||||
|
*quotient += q;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
term1 = 0;
|
term1 = 0;
|
||||||
term0 = bSig;
|
term0 = bSig;
|
||||||
}
|
}
|
||||||
sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
|
if (!mod) {
|
||||||
if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
|
||||||
|| ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
||||||
&& ( q & 1 ) )
|
|| ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
||||||
) {
|
&& ( q & 1 ) )
|
||||||
aSig0 = alternateASig0;
|
) {
|
||||||
aSig1 = alternateASig1;
|
aSig0 = alternateASig0;
|
||||||
zSign = ! zSign;
|
aSig1 = alternateASig1;
|
||||||
|
zSign = ! zSign;
|
||||||
|
++*quotient;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
normalizeRoundAndPackFloatx80(
|
normalizeRoundAndPackFloatx80(
|
||||||
@ -5793,6 +5824,30 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Returns the remainder of the extended double-precision floating-point value
|
||||||
|
| `a' with respect to the corresponding value `b'. The operation is performed
|
||||||
|
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
||||||
|
{
|
||||||
|
uint64_t quotient;
|
||||||
|
return floatx80_modrem(a, b, false, "ient, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Returns the remainder of the extended double-precision floating-point value
|
||||||
|
| `a' with respect to the corresponding value `b', with the quotient truncated
|
||||||
|
| toward zero.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
|
||||||
|
{
|
||||||
|
uint64_t quotient;
|
||||||
|
return floatx80_modrem(a, b, true, "ient, status);
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Returns the square root of the extended double-precision floating-point
|
| Returns the square root of the extended double-precision floating-point
|
||||||
| value `a'. The operation is performed according to the IEC/IEEE Standard
|
| value `a'. The operation is performed according to the IEC/IEEE Standard
|
||||||
|
@ -2320,7 +2320,6 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
hc->plug = virt_machine_device_plug_cb;
|
hc->plug = virt_machine_device_plug_cb;
|
||||||
hc->unplug_request = virt_machine_device_unplug_request_cb;
|
hc->unplug_request = virt_machine_device_unplug_request_cb;
|
||||||
hc->unplug = virt_machine_device_unplug_cb;
|
hc->unplug = virt_machine_device_unplug_cb;
|
||||||
mc->numa_mem_supported = true;
|
|
||||||
mc->nvdimm_supported = true;
|
mc->nvdimm_supported = true;
|
||||||
mc->auto_enable_numa_with_memhp = true;
|
mc->auto_enable_numa_with_memhp = true;
|
||||||
mc->default_ram_id = "mach-virt.ram";
|
mc->default_ram_id = "mach-virt.ram";
|
||||||
@ -2434,6 +2433,7 @@ static void virt_machine_5_0_options(MachineClass *mc)
|
|||||||
{
|
{
|
||||||
virt_machine_5_1_options(mc);
|
virt_machine_5_1_options(mc);
|
||||||
compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
||||||
|
mc->numa_mem_supported = true;
|
||||||
}
|
}
|
||||||
DEFINE_VIRT_MACHINE(5, 0)
|
DEFINE_VIRT_MACHINE(5, 0)
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ static void ibex_uart_write(void *opaque, hwaddr addr,
|
|||||||
if (value & UART_CTRL_NCO) {
|
if (value & UART_CTRL_NCO) {
|
||||||
uint64_t baud = ((value & UART_CTRL_NCO) >> 16);
|
uint64_t baud = ((value & UART_CTRL_NCO) >> 16);
|
||||||
baud *= 1000;
|
baud *= 1000;
|
||||||
baud /= 2 ^ 20;
|
baud >>= 20;
|
||||||
|
|
||||||
s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
|
s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
|
|
||||||
GlobalProperty hw_compat_5_0[] = {
|
GlobalProperty hw_compat_5_0[] = {
|
||||||
{ "virtio-balloon-device", "page-poison", "false" },
|
{ "virtio-balloon-device", "page-poison", "false" },
|
||||||
|
{ "vmport", "x-read-set-eax", "off" },
|
||||||
|
{ "vmport", "x-signal-unsupported-cmd", "off" },
|
||||||
|
{ "vmport", "x-report-vmx-type", "off" },
|
||||||
|
{ "vmport", "x-cmds-v2", "off" },
|
||||||
};
|
};
|
||||||
const size_t hw_compat_5_0_len = G_N_ELEMENTS(hw_compat_5_0);
|
const size_t hw_compat_5_0_len = G_N_ELEMENTS(hw_compat_5_0);
|
||||||
|
|
||||||
@ -45,10 +49,6 @@ GlobalProperty hw_compat_4_2[] = {
|
|||||||
{ "qxl", "revision", "4" },
|
{ "qxl", "revision", "4" },
|
||||||
{ "qxl-vga", "revision", "4" },
|
{ "qxl-vga", "revision", "4" },
|
||||||
{ "fw_cfg", "acpi-mr-restore", "false" },
|
{ "fw_cfg", "acpi-mr-restore", "false" },
|
||||||
{ "vmport", "x-read-set-eax", "off" },
|
|
||||||
{ "vmport", "x-signal-unsupported-cmd", "off" },
|
|
||||||
{ "vmport", "x-report-vmx-type", "off" },
|
|
||||||
{ "vmport", "x-cmds-v2", "off" },
|
|
||||||
};
|
};
|
||||||
const size_t hw_compat_4_2_len = G_N_ELEMENTS(hw_compat_4_2);
|
const size_t hw_compat_4_2_len = G_N_ELEMENTS(hw_compat_4_2);
|
||||||
|
|
||||||
|
@ -117,6 +117,13 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node->has_mem) {
|
if (node->has_mem) {
|
||||||
|
if (!mc->numa_mem_supported) {
|
||||||
|
error_setg(errp, "Parameter -numa node,mem is not supported by this"
|
||||||
|
" machine type");
|
||||||
|
error_append_hint(errp, "Use -numa node,memdev instead\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
numa_info[nodenr].node_mem = node->mem;
|
numa_info[nodenr].node_mem = node->mem;
|
||||||
if (!qtest_enabled()) {
|
if (!qtest_enabled()) {
|
||||||
warn_report("Parameter -numa node,mem is deprecated,"
|
warn_report("Parameter -numa node,mem is deprecated,"
|
||||||
|
@ -2741,8 +2741,7 @@ static const VMStateDescription vmstate_vmbus_bridge = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static Property vmbus_bridge_props[] = {
|
static Property vmbus_bridge_props[] = {
|
||||||
DEFINE_PROP_UINT8("irq0", VMBusBridge, irq0, 7),
|
DEFINE_PROP_UINT8("irq", VMBusBridge, irq, 7),
|
||||||
DEFINE_PROP_UINT8("irq1", VMBusBridge, irq1, 13),
|
|
||||||
DEFINE_PROP_END_OF_LIST()
|
DEFINE_PROP_END_OF_LIST()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -967,9 +967,7 @@ static Aml *build_vmbus_device_aml(VMBusBridge *vmbus_bridge)
|
|||||||
aml_append(dev, aml_name_decl("_PS3", aml_int(0x0)));
|
aml_append(dev, aml_name_decl("_PS3", aml_int(0x0)));
|
||||||
|
|
||||||
crs = aml_resource_template();
|
crs = aml_resource_template();
|
||||||
aml_append(crs, aml_irq_no_flags(vmbus_bridge->irq0));
|
aml_append(crs, aml_irq_no_flags(vmbus_bridge->irq));
|
||||||
/* FIXME: newer HyperV gets by with only one IRQ */
|
|
||||||
aml_append(crs, aml_irq_no_flags(vmbus_bridge->irq1));
|
|
||||||
aml_append(dev, aml_name_decl("_CRS", crs));
|
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
|
@ -1980,7 +1980,6 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
hc->unplug = pc_machine_device_unplug_cb;
|
hc->unplug = pc_machine_device_unplug_cb;
|
||||||
mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE;
|
mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE;
|
||||||
mc->nvdimm_supported = true;
|
mc->nvdimm_supported = true;
|
||||||
mc->numa_mem_supported = true;
|
|
||||||
mc->default_ram_id = "pc.ram";
|
mc->default_ram_id = "pc.ram";
|
||||||
|
|
||||||
object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size",
|
object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size",
|
||||||
|
@ -441,6 +441,7 @@ static void pc_i440fx_5_0_machine_options(MachineClass *m)
|
|||||||
pc_i440fx_5_1_machine_options(m);
|
pc_i440fx_5_1_machine_options(m);
|
||||||
m->alias = NULL;
|
m->alias = NULL;
|
||||||
m->is_default = false;
|
m->is_default = false;
|
||||||
|
m->numa_mem_supported = true;
|
||||||
compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
||||||
compat_props_add(m->compat_props, pc_compat_5_0, pc_compat_5_0_len);
|
compat_props_add(m->compat_props, pc_compat_5_0, pc_compat_5_0_len);
|
||||||
}
|
}
|
||||||
|
@ -369,6 +369,7 @@ static void pc_q35_5_0_machine_options(MachineClass *m)
|
|||||||
{
|
{
|
||||||
pc_q35_5_1_machine_options(m);
|
pc_q35_5_1_machine_options(m);
|
||||||
m->alias = NULL;
|
m->alias = NULL;
|
||||||
|
m->numa_mem_supported = true;
|
||||||
compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
compat_props_add(m->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
||||||
compat_props_add(m->compat_props, pc_compat_5_0, pc_compat_5_0_len);
|
compat_props_add(m->compat_props, pc_compat_5_0, pc_compat_5_0_len);
|
||||||
}
|
}
|
||||||
|
@ -4510,7 +4510,6 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
* in which LMBs are represented and hot-added
|
* in which LMBs are represented and hot-added
|
||||||
*/
|
*/
|
||||||
mc->numa_mem_align_shift = 28;
|
mc->numa_mem_align_shift = 28;
|
||||||
mc->numa_mem_supported = true;
|
|
||||||
mc->auto_enable_numa = true;
|
mc->auto_enable_numa = true;
|
||||||
|
|
||||||
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
|
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
|
||||||
@ -4598,6 +4597,7 @@ static void spapr_machine_5_0_class_options(MachineClass *mc)
|
|||||||
{
|
{
|
||||||
spapr_machine_5_1_class_options(mc);
|
spapr_machine_5_1_class_options(mc);
|
||||||
compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
||||||
|
mc->numa_mem_supported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_SPAPR_MACHINE(5_0, "5.0", false);
|
DEFINE_SPAPR_MACHINE(5_0, "5.0", false);
|
||||||
|
@ -54,10 +54,6 @@
|
|||||||
#define MEGASAS_FLAG_USE_QUEUE64 1
|
#define MEGASAS_FLAG_USE_QUEUE64 1
|
||||||
#define MEGASAS_MASK_USE_QUEUE64 (1 << MEGASAS_FLAG_USE_QUEUE64)
|
#define MEGASAS_MASK_USE_QUEUE64 (1 << MEGASAS_FLAG_USE_QUEUE64)
|
||||||
|
|
||||||
static const char *mfi_frame_desc[] = {
|
|
||||||
"MFI init", "LD Read", "LD Write", "LD SCSI", "PD SCSI",
|
|
||||||
"MFI Doorbell", "MFI Abort", "MFI SMP", "MFI Stop"};
|
|
||||||
|
|
||||||
typedef struct MegasasCmd {
|
typedef struct MegasasCmd {
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
@ -183,6 +179,20 @@ static void megasas_frame_set_scsi_status(MegasasState *s,
|
|||||||
stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, scsi_status), v);
|
stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, scsi_status), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char *mfi_frame_desc(unsigned int cmd)
|
||||||
|
{
|
||||||
|
static const char *mfi_frame_descs[] = {
|
||||||
|
"MFI init", "LD Read", "LD Write", "LD SCSI", "PD SCSI",
|
||||||
|
"MFI Doorbell", "MFI Abort", "MFI SMP", "MFI Stop"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cmd < ARRAY_SIZE(mfi_frame_descs)) {
|
||||||
|
return mfi_frame_descs[cmd];
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Context is considered opaque, but the HBA firmware is running
|
* Context is considered opaque, but the HBA firmware is running
|
||||||
* in little endian mode. So convert it to little endian, too.
|
* in little endian mode. So convert it to little endian, too.
|
||||||
@ -1670,25 +1680,25 @@ static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd,
|
|||||||
if (is_logical) {
|
if (is_logical) {
|
||||||
if (target_id >= MFI_MAX_LD || lun_id != 0) {
|
if (target_id >= MFI_MAX_LD || lun_id != 0) {
|
||||||
trace_megasas_scsi_target_not_present(
|
trace_megasas_scsi_target_not_present(
|
||||||
mfi_frame_desc[frame_cmd], is_logical, target_id, lun_id);
|
mfi_frame_desc(frame_cmd), is_logical, target_id, lun_id);
|
||||||
return MFI_STAT_DEVICE_NOT_FOUND;
|
return MFI_STAT_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sdev = scsi_device_find(&s->bus, 0, target_id, lun_id);
|
sdev = scsi_device_find(&s->bus, 0, target_id, lun_id);
|
||||||
|
|
||||||
cmd->iov_size = le32_to_cpu(cmd->frame->header.data_len);
|
cmd->iov_size = le32_to_cpu(cmd->frame->header.data_len);
|
||||||
trace_megasas_handle_scsi(mfi_frame_desc[frame_cmd], is_logical,
|
trace_megasas_handle_scsi(mfi_frame_desc(frame_cmd), is_logical,
|
||||||
target_id, lun_id, sdev, cmd->iov_size);
|
target_id, lun_id, sdev, cmd->iov_size);
|
||||||
|
|
||||||
if (!sdev || (megasas_is_jbod(s) && is_logical)) {
|
if (!sdev || (megasas_is_jbod(s) && is_logical)) {
|
||||||
trace_megasas_scsi_target_not_present(
|
trace_megasas_scsi_target_not_present(
|
||||||
mfi_frame_desc[frame_cmd], is_logical, target_id, lun_id);
|
mfi_frame_desc(frame_cmd), is_logical, target_id, lun_id);
|
||||||
return MFI_STAT_DEVICE_NOT_FOUND;
|
return MFI_STAT_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cdb_len > 16) {
|
if (cdb_len > 16) {
|
||||||
trace_megasas_scsi_invalid_cdb_len(
|
trace_megasas_scsi_invalid_cdb_len(
|
||||||
mfi_frame_desc[frame_cmd], is_logical,
|
mfi_frame_desc(frame_cmd), is_logical,
|
||||||
target_id, lun_id, cdb_len);
|
target_id, lun_id, cdb_len);
|
||||||
megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
|
megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
|
||||||
cmd->frame->header.scsi_status = CHECK_CONDITION;
|
cmd->frame->header.scsi_status = CHECK_CONDITION;
|
||||||
@ -1706,7 +1716,7 @@ static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd,
|
|||||||
cmd->req = scsi_req_new(sdev, cmd->index, lun_id, cdb, cmd);
|
cmd->req = scsi_req_new(sdev, cmd->index, lun_id, cdb, cmd);
|
||||||
if (!cmd->req) {
|
if (!cmd->req) {
|
||||||
trace_megasas_scsi_req_alloc_failed(
|
trace_megasas_scsi_req_alloc_failed(
|
||||||
mfi_frame_desc[frame_cmd], target_id, lun_id);
|
mfi_frame_desc(frame_cmd), target_id, lun_id);
|
||||||
megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
|
megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
|
||||||
cmd->frame->header.scsi_status = BUSY;
|
cmd->frame->header.scsi_status = BUSY;
|
||||||
s->event_count++;
|
s->event_count++;
|
||||||
@ -1751,17 +1761,17 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
trace_megasas_handle_io(cmd->index,
|
trace_megasas_handle_io(cmd->index,
|
||||||
mfi_frame_desc[frame_cmd], target_id, lun_id,
|
mfi_frame_desc(frame_cmd), target_id, lun_id,
|
||||||
(unsigned long)lba_start, (unsigned long)lba_count);
|
(unsigned long)lba_start, (unsigned long)lba_count);
|
||||||
if (!sdev) {
|
if (!sdev) {
|
||||||
trace_megasas_io_target_not_present(cmd->index,
|
trace_megasas_io_target_not_present(cmd->index,
|
||||||
mfi_frame_desc[frame_cmd], target_id, lun_id);
|
mfi_frame_desc(frame_cmd), target_id, lun_id);
|
||||||
return MFI_STAT_DEVICE_NOT_FOUND;
|
return MFI_STAT_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cdb_len > 16) {
|
if (cdb_len > 16) {
|
||||||
trace_megasas_scsi_invalid_cdb_len(
|
trace_megasas_scsi_invalid_cdb_len(
|
||||||
mfi_frame_desc[frame_cmd], 1, target_id, lun_id, cdb_len);
|
mfi_frame_desc(frame_cmd), 1, target_id, lun_id, cdb_len);
|
||||||
megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
|
megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
|
||||||
cmd->frame->header.scsi_status = CHECK_CONDITION;
|
cmd->frame->header.scsi_status = CHECK_CONDITION;
|
||||||
s->event_count++;
|
s->event_count++;
|
||||||
@ -1781,7 +1791,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
|
|||||||
lun_id, cdb, cmd);
|
lun_id, cdb, cmd);
|
||||||
if (!cmd->req) {
|
if (!cmd->req) {
|
||||||
trace_megasas_scsi_req_alloc_failed(
|
trace_megasas_scsi_req_alloc_failed(
|
||||||
mfi_frame_desc[frame_cmd], target_id, lun_id);
|
mfi_frame_desc(frame_cmd), target_id, lun_id);
|
||||||
megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
|
megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
|
||||||
cmd->frame->header.scsi_status = BUSY;
|
cmd->frame->header.scsi_status = BUSY;
|
||||||
s->event_count++;
|
s->event_count++;
|
||||||
|
@ -214,7 +214,7 @@ struct XHCIState {
|
|||||||
uint32_t dcbaap_high;
|
uint32_t dcbaap_high;
|
||||||
uint32_t config;
|
uint32_t config;
|
||||||
|
|
||||||
USBPort uports[MAX(MAXPORTS_2, MAXPORTS_3)];
|
USBPort uports[MAX_CONST(MAXPORTS_2, MAXPORTS_3)];
|
||||||
XHCIPort ports[MAXPORTS];
|
XHCIPort ports[MAXPORTS];
|
||||||
XHCISlot slots[MAXSLOTS];
|
XHCISlot slots[MAXSLOTS];
|
||||||
uint32_t numports;
|
uint32_t numports;
|
||||||
|
@ -4,4 +4,4 @@ common-obj-y += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o xen-bus.o xen-b
|
|||||||
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
|
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
|
||||||
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
|
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
|
||||||
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt_load_rom.o
|
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt_load_rom.o
|
||||||
obj-$(call $(lnot, $(CONFIG_XEN_PCI_PASSTHROUGH))) += xen_pt_stub.o
|
obj-$(call lnot,$(CONFIG_XEN_PCI_PASSTHROUGH)) += xen_pt_stub.o
|
||||||
|
@ -133,8 +133,8 @@ typedef struct HDGeometry {
|
|||||||
#define BDRV_SECTOR_BITS 9
|
#define BDRV_SECTOR_BITS 9
|
||||||
#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
|
#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
|
||||||
|
|
||||||
#define BDRV_REQUEST_MAX_SECTORS MIN(SIZE_MAX >> BDRV_SECTOR_BITS, \
|
#define BDRV_REQUEST_MAX_SECTORS MIN_CONST(SIZE_MAX >> BDRV_SECTOR_BITS, \
|
||||||
INT_MAX >> BDRV_SECTOR_BITS)
|
INT_MAX >> BDRV_SECTOR_BITS)
|
||||||
#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
|
#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -176,11 +176,9 @@ extern unsigned long reserved_va;
|
|||||||
* avoid setting bits at the top of guest addresses that might need
|
* avoid setting bits at the top of guest addresses that might need
|
||||||
* to be used for tags.
|
* to be used for tags.
|
||||||
*/
|
*/
|
||||||
#if MIN(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32
|
#define GUEST_ADDR_MAX_ \
|
||||||
# define GUEST_ADDR_MAX_ UINT32_MAX
|
((MIN_CONST(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) ? \
|
||||||
#else
|
UINT32_MAX : ~0ul)
|
||||||
# define GUEST_ADDR_MAX_ (~0ul)
|
|
||||||
#endif
|
|
||||||
#define GUEST_ADDR_MAX (reserved_va ? reserved_va - 1 : GUEST_ADDR_MAX_)
|
#define GUEST_ADDR_MAX (reserved_va ? reserved_va - 1 : GUEST_ADDR_MAX_)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -102,8 +102,13 @@ typedef uint64_t target_ulong;
|
|||||||
* Skylake's Level-2 STLB has 16 1G entries.
|
* Skylake's Level-2 STLB has 16 1G entries.
|
||||||
* Also, make sure we do not size the TLB past the guest's address space.
|
* Also, make sure we do not size the TLB past the guest's address space.
|
||||||
*/
|
*/
|
||||||
# define CPU_TLB_DYN_MAX_BITS \
|
# ifdef TARGET_PAGE_BITS_VARY
|
||||||
|
# define CPU_TLB_DYN_MAX_BITS \
|
||||||
MIN(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS)
|
MIN(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS)
|
||||||
|
# else
|
||||||
|
# define CPU_TLB_DYN_MAX_BITS \
|
||||||
|
MIN_CONST(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS)
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
typedef struct CPUTLBEntry {
|
typedef struct CPUTLBEntry {
|
||||||
|
@ -687,6 +687,9 @@ floatx80 floatx80_add(floatx80, floatx80, float_status *status);
|
|||||||
floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
|
floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
|
||||||
floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
|
floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
|
||||||
floatx80 floatx80_div(floatx80, floatx80, float_status *status);
|
floatx80 floatx80_div(floatx80, floatx80, float_status *status);
|
||||||
|
floatx80 floatx80_modrem(floatx80, floatx80, bool, uint64_t *,
|
||||||
|
float_status *status);
|
||||||
|
floatx80 floatx80_mod(floatx80, floatx80, float_status *status);
|
||||||
floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
|
floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
|
||||||
floatx80 floatx80_sqrt(floatx80, float_status *status);
|
floatx80 floatx80_sqrt(floatx80, float_status *status);
|
||||||
FloatRelation floatx80_compare(floatx80, floatx80, float_status *status);
|
FloatRelation floatx80_compare(floatx80, floatx80, float_status *status);
|
||||||
|
@ -19,8 +19,7 @@ typedef struct VMBus VMBus;
|
|||||||
typedef struct VMBusBridge {
|
typedef struct VMBusBridge {
|
||||||
SysBusDevice parent_obj;
|
SysBusDevice parent_obj;
|
||||||
|
|
||||||
uint8_t irq0;
|
uint8_t irq;
|
||||||
uint8_t irq1;
|
|
||||||
|
|
||||||
VMBus *bus;
|
VMBus *bus;
|
||||||
} VMBusBridge;
|
} VMBusBridge;
|
||||||
|
@ -236,18 +236,55 @@ extern int daemon(int, int);
|
|||||||
#define SIZE_MAX ((size_t)-1)
|
#define SIZE_MAX ((size_t)-1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MIN
|
/*
|
||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
* Two variations of MIN/MAX macros. The first is for runtime use, and
|
||||||
#endif
|
* evaluates arguments only once (so it is safe even with side
|
||||||
#ifndef MAX
|
* effects), but will not work in constant contexts (such as array
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
* size declarations) because of the '{}'. The second is for constant
|
||||||
#endif
|
* expression use, where evaluating arguments twice is safe because
|
||||||
|
* the result is going to be constant anyway, but will not work in a
|
||||||
|
* runtime context because of a void expression where a value is
|
||||||
|
* expected. Thus, both gcc and clang will fail to compile if you use
|
||||||
|
* the wrong macro (even if the error may seem a bit cryptic).
|
||||||
|
*
|
||||||
|
* Note that neither form is usable as an #if condition; if you truly
|
||||||
|
* need to write conditional code that depends on a minimum or maximum
|
||||||
|
* determined by the pre-processor instead of the compiler, you'll
|
||||||
|
* have to open-code it.
|
||||||
|
*/
|
||||||
|
#undef MIN
|
||||||
|
#define MIN(a, b) \
|
||||||
|
({ \
|
||||||
|
typeof(1 ? (a) : (b)) _a = (a), _b = (b); \
|
||||||
|
_a < _b ? _a : _b; \
|
||||||
|
})
|
||||||
|
#define MIN_CONST(a, b) \
|
||||||
|
__builtin_choose_expr( \
|
||||||
|
__builtin_constant_p(a) && __builtin_constant_p(b), \
|
||||||
|
(a) < (b) ? (a) : (b), \
|
||||||
|
((void)0))
|
||||||
|
#undef MAX
|
||||||
|
#define MAX(a, b) \
|
||||||
|
({ \
|
||||||
|
typeof(1 ? (a) : (b)) _a = (a), _b = (b); \
|
||||||
|
_a > _b ? _a : _b; \
|
||||||
|
})
|
||||||
|
#define MAX_CONST(a, b) \
|
||||||
|
__builtin_choose_expr( \
|
||||||
|
__builtin_constant_p(a) && __builtin_constant_p(b), \
|
||||||
|
(a) > (b) ? (a) : (b), \
|
||||||
|
((void)0))
|
||||||
|
|
||||||
/* Minimum function that returns zero only iff both values are zero.
|
/*
|
||||||
* Intended for use with unsigned values only. */
|
* Minimum function that returns zero only if both values are zero.
|
||||||
|
* Intended for use with unsigned values only.
|
||||||
|
*/
|
||||||
#ifndef MIN_NON_ZERO
|
#ifndef MIN_NON_ZERO
|
||||||
#define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \
|
#define MIN_NON_ZERO(a, b) \
|
||||||
((b) == 0 ? (a) : (MIN(a, b))))
|
({ \
|
||||||
|
typeof(1 ? (a) : (b)) _a = (a), _b = (b); \
|
||||||
|
_a == 0 ? _b : (_b == 0 || _b > _a) ? _a : _b; \
|
||||||
|
})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Round number down to multiple */
|
/* Round number down to multiple */
|
||||||
|
29
memory.c
29
memory.c
@ -1352,35 +1352,24 @@ bool memory_region_access_valid(MemoryRegion *mr,
|
|||||||
bool is_write,
|
bool is_write,
|
||||||
MemTxAttrs attrs)
|
MemTxAttrs attrs)
|
||||||
{
|
{
|
||||||
int access_size_min, access_size_max;
|
if (mr->ops->valid.accepts
|
||||||
int access_size, i;
|
&& !mr->ops->valid.accepts(mr->opaque, addr, size, is_write, attrs)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
|
if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mr->ops->valid.accepts) {
|
/* Treat zero as compatibility all valid */
|
||||||
|
if (!mr->ops->valid.max_access_size) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
access_size_min = mr->ops->valid.min_access_size;
|
if (size > mr->ops->valid.max_access_size
|
||||||
if (!mr->ops->valid.min_access_size) {
|
|| size < mr->ops->valid.min_access_size) {
|
||||||
access_size_min = 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
access_size_max = mr->ops->valid.max_access_size;
|
|
||||||
if (!mr->ops->valid.max_access_size) {
|
|
||||||
access_size_max = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
access_size = MAX(MIN(size, access_size_max), access_size_min);
|
|
||||||
for (i = 0; i < size; i += access_size) {
|
|
||||||
if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
|
|
||||||
is_write, attrs)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|
||||||
#define IO_BUF_SIZE 32768
|
#define IO_BUF_SIZE 32768
|
||||||
#define MAX_IOV_SIZE MIN(IOV_MAX, 64)
|
#define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 64)
|
||||||
|
|
||||||
struct QEMUFile {
|
struct QEMUFile {
|
||||||
const QEMUFileOps *ops;
|
const QEMUFileOps *ops;
|
||||||
|
@ -239,10 +239,11 @@ SRST
|
|||||||
-numa node,nodeid=0 -numa node,nodeid=1 \
|
-numa node,nodeid=0 -numa node,nodeid=1 \
|
||||||
-numa cpu,node-id=0,socket-id=0 -numa cpu,node-id=1,socket-id=1
|
-numa cpu,node-id=0,socket-id=0 -numa cpu,node-id=1,socket-id=1
|
||||||
|
|
||||||
'\ ``mem``\ ' assigns a given RAM amount to a node. '\ ``memdev``\ '
|
Legacy '\ ``mem``\ ' assigns a given RAM amount to a node (not supported
|
||||||
assigns RAM from a given memory backend device to a node. If
|
for 5.1 and newer machine types). '\ ``memdev``\ ' assigns RAM from
|
||||||
'\ ``mem``\ ' and '\ ``memdev``\ ' are omitted in all nodes, RAM is
|
a given memory backend device to a node. If '\ ``mem``\ ' and
|
||||||
split equally between them.
|
'\ ``memdev``\ ' are omitted in all nodes, RAM is split equally between them.
|
||||||
|
|
||||||
|
|
||||||
'\ ``mem``\ ' and '\ ``memdev``\ ' are mutually exclusive.
|
'\ ``mem``\ ' and '\ ``memdev``\ ' are mutually exclusive.
|
||||||
Furthermore, if one node uses '\ ``memdev``\ ', all of them have to
|
Furthermore, if one node uses '\ ``memdev``\ ', all of them have to
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
/* Current version of the replay mechanism.
|
/* Current version of the replay mechanism.
|
||||||
Increase it when file format changes. */
|
Increase it when file format changes. */
|
||||||
#define REPLAY_VERSION 0xe02009
|
#define REPLAY_VERSION 0xe0200a
|
||||||
/* Size of replay log header */
|
/* Size of replay log header */
|
||||||
#define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t))
|
#define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t))
|
||||||
|
|
||||||
|
@ -1404,6 +1404,10 @@ static FeatureDep feature_dependencies[] = {
|
|||||||
.from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_VMFUNC },
|
.from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_VMFUNC },
|
||||||
.to = { FEAT_VMX_VMFUNC, ~0ull },
|
.to = { FEAT_VMX_VMFUNC, ~0ull },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.from = { FEAT_8000_0001_ECX, CPUID_EXT3_SVM },
|
||||||
|
.to = { FEAT_SVM, ~0ull },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct X86RegisterInfo32 {
|
typedef struct X86RegisterInfo32 {
|
||||||
@ -3135,6 +3139,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
|||||||
.versions = (X86CPUVersionDefinition[]) {
|
.versions = (X86CPUVersionDefinition[]) {
|
||||||
{ .version = 1 },
|
{ .version = 1 },
|
||||||
{ .version = 2,
|
{ .version = 2,
|
||||||
|
.note = "ARCH_CAPABILITIES",
|
||||||
.props = (PropValue[]) {
|
.props = (PropValue[]) {
|
||||||
{ "arch-capabilities", "on" },
|
{ "arch-capabilities", "on" },
|
||||||
{ "rdctl-no", "on" },
|
{ "rdctl-no", "on" },
|
||||||
@ -3146,6 +3151,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
|||||||
},
|
},
|
||||||
{ .version = 3,
|
{ .version = 3,
|
||||||
.alias = "Cascadelake-Server-noTSX",
|
.alias = "Cascadelake-Server-noTSX",
|
||||||
|
.note = "ARCH_CAPABILITIES, no TSX",
|
||||||
.props = (PropValue[]) {
|
.props = (PropValue[]) {
|
||||||
{ "hle", "off" },
|
{ "hle", "off" },
|
||||||
{ "rtm", "off" },
|
{ "rtm", "off" },
|
||||||
@ -3367,6 +3373,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
|||||||
{ .version = 1 },
|
{ .version = 1 },
|
||||||
{
|
{
|
||||||
.version = 2,
|
.version = 2,
|
||||||
|
.note = "no TSX",
|
||||||
.alias = "Icelake-Client-noTSX",
|
.alias = "Icelake-Client-noTSX",
|
||||||
.props = (PropValue[]) {
|
.props = (PropValue[]) {
|
||||||
{ "hle", "off" },
|
{ "hle", "off" },
|
||||||
@ -3484,6 +3491,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
|||||||
{ .version = 1 },
|
{ .version = 1 },
|
||||||
{
|
{
|
||||||
.version = 2,
|
.version = 2,
|
||||||
|
.note = "no TSX",
|
||||||
.alias = "Icelake-Server-noTSX",
|
.alias = "Icelake-Server-noTSX",
|
||||||
.props = (PropValue[]) {
|
.props = (PropValue[]) {
|
||||||
{ "hle", "off" },
|
{ "hle", "off" },
|
||||||
@ -3604,6 +3612,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
|||||||
{ .version = 1 },
|
{ .version = 1 },
|
||||||
{
|
{
|
||||||
.version = 2,
|
.version = 2,
|
||||||
|
.note = "no MPX, no MONITOR",
|
||||||
.props = (PropValue[]) {
|
.props = (PropValue[]) {
|
||||||
{ "monitor", "off" },
|
{ "monitor", "off" },
|
||||||
{ "mpx", "off" },
|
{ "mpx", "off" },
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -740,26 +740,62 @@ static bool hyperv_enabled(X86CPU *cpu)
|
|||||||
cpu->hyperv_features || cpu->hyperv_passthrough);
|
cpu->hyperv_features || cpu->hyperv_passthrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether target_freq is within conservative
|
||||||
|
* ntp correctable bounds (250ppm) of freq
|
||||||
|
*/
|
||||||
|
static inline bool freq_within_bounds(int freq, int target_freq)
|
||||||
|
{
|
||||||
|
int max_freq = freq + (freq * 250 / 1000000);
|
||||||
|
int min_freq = freq - (freq * 250 / 1000000);
|
||||||
|
|
||||||
|
if (target_freq >= min_freq && target_freq <= max_freq) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int kvm_arch_set_tsc_khz(CPUState *cs)
|
static int kvm_arch_set_tsc_khz(CPUState *cs)
|
||||||
{
|
{
|
||||||
X86CPU *cpu = X86_CPU(cs);
|
X86CPU *cpu = X86_CPU(cs);
|
||||||
CPUX86State *env = &cpu->env;
|
CPUX86State *env = &cpu->env;
|
||||||
int r;
|
int r, cur_freq;
|
||||||
|
bool set_ioctl = false;
|
||||||
|
|
||||||
if (!env->tsc_khz) {
|
if (!env->tsc_khz) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = kvm_check_extension(cs->kvm_state, KVM_CAP_TSC_CONTROL) ?
|
cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
|
||||||
|
kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) : -ENOTSUP;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If TSC scaling is supported, attempt to set TSC frequency.
|
||||||
|
*/
|
||||||
|
if (kvm_check_extension(cs->kvm_state, KVM_CAP_TSC_CONTROL)) {
|
||||||
|
set_ioctl = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If desired TSC frequency is within bounds of NTP correction,
|
||||||
|
* attempt to set TSC frequency.
|
||||||
|
*/
|
||||||
|
if (cur_freq != -ENOTSUP && freq_within_bounds(cur_freq, env->tsc_khz)) {
|
||||||
|
set_ioctl = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = set_ioctl ?
|
||||||
kvm_vcpu_ioctl(cs, KVM_SET_TSC_KHZ, env->tsc_khz) :
|
kvm_vcpu_ioctl(cs, KVM_SET_TSC_KHZ, env->tsc_khz) :
|
||||||
-ENOTSUP;
|
-ENOTSUP;
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
/* When KVM_SET_TSC_KHZ fails, it's an error only if the current
|
/* When KVM_SET_TSC_KHZ fails, it's an error only if the current
|
||||||
* TSC frequency doesn't match the one we want.
|
* TSC frequency doesn't match the one we want.
|
||||||
*/
|
*/
|
||||||
int cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
|
cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
|
||||||
kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
|
kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
|
||||||
-ENOTSUP;
|
-ENOTSUP;
|
||||||
if (cur_freq <= 0 || cur_freq != env->tsc_khz) {
|
if (cur_freq <= 0 || cur_freq != env->tsc_khz) {
|
||||||
warn_report("TSC frequency mismatch between "
|
warn_report("TSC frequency mismatch between "
|
||||||
"VM (%" PRId64 " kHz) and host (%d kHz), "
|
"VM (%" PRId64 " kHz) and host (%d kHz), "
|
||||||
|
@ -42,89 +42,6 @@ static floatx80 propagateFloatx80NaNOneArg(floatx80 a, float_status *status)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the modulo remainder of the extended double-precision floating-point
|
|
||||||
* value `a' with respect to the corresponding value `b'.
|
|
||||||
*/
|
|
||||||
|
|
||||||
floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
|
|
||||||
{
|
|
||||||
bool aSign, zSign;
|
|
||||||
int32_t aExp, bExp, expDiff;
|
|
||||||
uint64_t aSig0, aSig1, bSig;
|
|
||||||
uint64_t qTemp, term0, term1;
|
|
||||||
|
|
||||||
aSig0 = extractFloatx80Frac(a);
|
|
||||||
aExp = extractFloatx80Exp(a);
|
|
||||||
aSign = extractFloatx80Sign(a);
|
|
||||||
bSig = extractFloatx80Frac(b);
|
|
||||||
bExp = extractFloatx80Exp(b);
|
|
||||||
|
|
||||||
if (aExp == 0x7FFF) {
|
|
||||||
if ((uint64_t) (aSig0 << 1)
|
|
||||||
|| ((bExp == 0x7FFF) && (uint64_t) (bSig << 1))) {
|
|
||||||
return propagateFloatx80NaN(a, b, status);
|
|
||||||
}
|
|
||||||
goto invalid;
|
|
||||||
}
|
|
||||||
if (bExp == 0x7FFF) {
|
|
||||||
if ((uint64_t) (bSig << 1)) {
|
|
||||||
return propagateFloatx80NaN(a, b, status);
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
if (bExp == 0) {
|
|
||||||
if (bSig == 0) {
|
|
||||||
invalid:
|
|
||||||
float_raise(float_flag_invalid, status);
|
|
||||||
return floatx80_default_nan(status);
|
|
||||||
}
|
|
||||||
normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
|
|
||||||
}
|
|
||||||
if (aExp == 0) {
|
|
||||||
if ((uint64_t) (aSig0 << 1) == 0) {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0);
|
|
||||||
}
|
|
||||||
bSig |= UINT64_C(0x8000000000000000);
|
|
||||||
zSign = aSign;
|
|
||||||
expDiff = aExp - bExp;
|
|
||||||
aSig1 = 0;
|
|
||||||
if (expDiff < 0) {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
qTemp = (bSig <= aSig0);
|
|
||||||
if (qTemp) {
|
|
||||||
aSig0 -= bSig;
|
|
||||||
}
|
|
||||||
expDiff -= 64;
|
|
||||||
while (0 < expDiff) {
|
|
||||||
qTemp = estimateDiv128To64(aSig0, aSig1, bSig);
|
|
||||||
qTemp = (2 < qTemp) ? qTemp - 2 : 0;
|
|
||||||
mul64To128(bSig, qTemp, &term0, &term1);
|
|
||||||
sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
|
|
||||||
shortShift128Left(aSig0, aSig1, 62, &aSig0, &aSig1);
|
|
||||||
expDiff -= 62;
|
|
||||||
}
|
|
||||||
expDiff += 64;
|
|
||||||
if (0 < expDiff) {
|
|
||||||
qTemp = estimateDiv128To64(aSig0, aSig1, bSig);
|
|
||||||
qTemp = (2 < qTemp) ? qTemp - 2 : 0;
|
|
||||||
qTemp >>= 64 - expDiff;
|
|
||||||
mul64To128(bSig, qTemp << (64 - expDiff), &term0, &term1);
|
|
||||||
sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
|
|
||||||
shortShift128Left(0, bSig, 64 - expDiff, &term0, &term1);
|
|
||||||
while (le128(term0, term1, aSig0, aSig1)) {
|
|
||||||
++qTemp;
|
|
||||||
sub128(aSig0, aSig1, term0, term1, &aSig0, &aSig1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
normalizeRoundAndPackFloatx80(
|
|
||||||
80, zSign, bExp + expDiff, aSig0, aSig1, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the mantissa of the extended double-precision floating-point
|
* Returns the mantissa of the extended double-precision floating-point
|
||||||
* value `a'.
|
* value `a'.
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#define TARGET_M68K_SOFTFLOAT_H
|
#define TARGET_M68K_SOFTFLOAT_H
|
||||||
#include "fpu/softfloat.h"
|
#include "fpu/softfloat.h"
|
||||||
|
|
||||||
floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status);
|
|
||||||
floatx80 floatx80_getman(floatx80 a, float_status *status);
|
floatx80 floatx80_getman(floatx80 a, float_status *status);
|
||||||
floatx80 floatx80_getexp(floatx80 a, float_status *status);
|
floatx80 floatx80_getexp(floatx80 a, float_status *status);
|
||||||
floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status);
|
floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status);
|
||||||
|
@ -186,7 +186,7 @@ void qpci_unplug_acpi_device_test(QTestState *qts, const char *id, uint8_t slot)
|
|||||||
g_assert(!qdict_haskey(response, "error"));
|
g_assert(!qdict_haskey(response, "error"));
|
||||||
qobject_unref(response);
|
qobject_unref(response);
|
||||||
|
|
||||||
qtest_outb(qts, ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot);
|
qtest_outl(qts, ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot);
|
||||||
|
|
||||||
qtest_qmp_eventwait(qts, "DEVICE_DELETED");
|
qtest_qmp_eventwait(qts, "DEVICE_DELETED");
|
||||||
}
|
}
|
||||||
|
@ -256,7 +256,7 @@ int main(int argc, char **argv)
|
|||||||
"-cpu 486,+invtsc", "xlevel", 0x80000007);
|
"-cpu 486,+invtsc", "xlevel", 0x80000007);
|
||||||
/* CPUID[8000_000A].EDX: */
|
/* CPUID[8000_000A].EDX: */
|
||||||
add_cpuid_test("x86/cpuid/auto-xlevel/486/npt",
|
add_cpuid_test("x86/cpuid/auto-xlevel/486/npt",
|
||||||
"-cpu 486,+npt", "xlevel", 0x8000000A);
|
"-cpu 486,+svm,+npt", "xlevel", 0x8000000A);
|
||||||
/* CPUID[C000_0001].EDX: */
|
/* CPUID[C000_0001].EDX: */
|
||||||
add_cpuid_test("x86/cpuid/auto-xlevel2/phenom/xstore",
|
add_cpuid_test("x86/cpuid/auto-xlevel2/phenom/xstore",
|
||||||
"-cpu phenom,+xstore", "xlevel2", 0xC0000001);
|
"-cpu phenom,+xstore", "xlevel2", 0xC0000001);
|
||||||
@ -348,7 +348,7 @@ int main(int argc, char **argv)
|
|||||||
"-machine pc-i440fx-2.4 -cpu SandyBridge,",
|
"-machine pc-i440fx-2.4 -cpu SandyBridge,",
|
||||||
"xlevel", 0x80000008);
|
"xlevel", 0x80000008);
|
||||||
add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-on",
|
add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-on",
|
||||||
"-machine pc-i440fx-2.4 -cpu SandyBridge,+npt",
|
"-machine pc-i440fx-2.4 -cpu SandyBridge,+svm,+npt",
|
||||||
"xlevel", 0x80000008);
|
"xlevel", 0x80000008);
|
||||||
|
|
||||||
/* Test feature parsing */
|
/* Test feature parsing */
|
||||||
|
@ -96,7 +96,7 @@ static void pci_ehci_port_1(void)
|
|||||||
static void pci_ehci_config(void)
|
static void pci_ehci_config(void)
|
||||||
{
|
{
|
||||||
/* hands over all ports from companion uhci to ehci */
|
/* hands over all ports from companion uhci to ehci */
|
||||||
qpci_io_writew(ehci1.dev, ehci1.bar, 0x60, 1);
|
qpci_io_writel(ehci1.dev, ehci1.bar, 0x60, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pci_uhci_port_2(void)
|
static void pci_uhci_port_2(void)
|
||||||
|
1140
tests/tcg/i386/test-i386-f2xm1.c
Normal file
1140
tests/tcg/i386/test-i386-f2xm1.c
Normal file
File diff suppressed because it is too large
Load Diff
1071
tests/tcg/i386/test-i386-fpatan.c
Normal file
1071
tests/tcg/i386/test-i386-fpatan.c
Normal file
File diff suppressed because it is too large
Load Diff
1161
tests/tcg/i386/test-i386-fyl2x.c
Normal file
1161
tests/tcg/i386/test-i386-fyl2x.c
Normal file
File diff suppressed because it is too large
Load Diff
1156
tests/tcg/i386/test-i386-fyl2xp1.c
Normal file
1156
tests/tcg/i386/test-i386-fyl2xp1.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -98,6 +98,16 @@ unsigned long qemu_getauxval(unsigned long type)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
#include <sys/auxv.h>
|
||||||
|
|
||||||
|
unsigned long qemu_getauxval(unsigned long type)
|
||||||
|
{
|
||||||
|
unsigned long aux = 0;
|
||||||
|
elf_aux_info(type, &aux, sizeof(aux));
|
||||||
|
return aux;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
unsigned long qemu_getauxval(unsigned long type)
|
unsigned long qemu_getauxval(unsigned long type)
|
||||||
|
@ -501,7 +501,6 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
|
|||||||
bool progress = false;
|
bool progress = false;
|
||||||
QEMUTimerCB *cb;
|
QEMUTimerCB *cb;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
bool need_replay_checkpoint = false;
|
|
||||||
|
|
||||||
if (!atomic_read(&timer_list->active_timers)) {
|
if (!atomic_read(&timer_list->active_timers)) {
|
||||||
return false;
|
return false;
|
||||||
@ -517,16 +516,6 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case QEMU_CLOCK_VIRTUAL:
|
case QEMU_CLOCK_VIRTUAL:
|
||||||
if (replay_mode != REPLAY_MODE_NONE) {
|
|
||||||
/* Checkpoint for virtual clock is redundant in cases where
|
|
||||||
* it's being triggered with only non-EXTERNAL timers, because
|
|
||||||
* these timers don't change guest state directly.
|
|
||||||
* Since it has conditional dependence on specific timers, it is
|
|
||||||
* subject to race conditions and requires special handling.
|
|
||||||
* See below.
|
|
||||||
*/
|
|
||||||
need_replay_checkpoint = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case QEMU_CLOCK_HOST:
|
case QEMU_CLOCK_HOST:
|
||||||
if (!replay_checkpoint(CHECKPOINT_CLOCK_HOST)) {
|
if (!replay_checkpoint(CHECKPOINT_CLOCK_HOST)) {
|
||||||
@ -559,19 +548,16 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
|
|||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (need_replay_checkpoint
|
/* Checkpoint for virtual clock is redundant in cases where
|
||||||
&& !(ts->attributes & QEMU_TIMER_ATTR_EXTERNAL)) {
|
* it's being triggered with only non-EXTERNAL timers, because
|
||||||
/* once we got here, checkpoint clock only once */
|
* these timers don't change guest state directly.
|
||||||
need_replay_checkpoint = false;
|
*/
|
||||||
|
if (replay_mode != REPLAY_MODE_NONE
|
||||||
|
&& timer_list->clock->type == QEMU_CLOCK_VIRTUAL
|
||||||
|
&& !(ts->attributes & QEMU_TIMER_ATTR_EXTERNAL)
|
||||||
|
&& !replay_checkpoint(CHECKPOINT_CLOCK_VIRTUAL)) {
|
||||||
qemu_mutex_unlock(&timer_list->active_timers_lock);
|
qemu_mutex_unlock(&timer_list->active_timers_lock);
|
||||||
if (!replay_checkpoint(CHECKPOINT_CLOCK_VIRTUAL)) {
|
goto out;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
qemu_mutex_lock(&timer_list->active_timers_lock);
|
|
||||||
/* The lock was released; start over again in case the list was
|
|
||||||
* modified.
|
|
||||||
*/
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove timer from the list before calling the callback */
|
/* remove timer from the list before calling the callback */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user