mirror of
https://github.com/qemu/qemu.git
synced 2024-11-29 06:43:37 +08:00
* 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_DIR) "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) $(MANUAL_BUILDDIR)/index.html "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.html "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.txt "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/interop"
|
||||
$(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
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
|
||||
$(INSTALL_DATA) $(MANUAL_BUILDDIR)/system/qemu.1 "$(DESTDIR)$(mandir)/man1"
|
||||
@ -892,8 +893,9 @@ ifdef CONFIG_TRACE_SYSTEMTAP
|
||||
endif
|
||||
ifneq (,$(findstring qemu-ga,$(TOOLS)))
|
||||
$(INSTALL_DATA) $(MANUAL_BUILDDIR)/interop/qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
|
||||
$(INSTALL_DATA) docs/interop/qemu-ga-ref.html "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) docs/interop/qemu-ga-ref.txt "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/interop"
|
||||
$(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"
|
||||
endif
|
||||
endif
|
||||
|
@ -101,7 +101,7 @@ struct KVMState
|
||||
bool kernel_irqchip_required;
|
||||
OnOffAuto kernel_irqchip_split;
|
||||
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
|
||||
* they're not. Linux, glibc and *BSD all treat ioctl numbers as
|
||||
* unsigned, and treating them as signed here can break things */
|
||||
@ -1995,6 +1995,7 @@ static int kvm_init(MachineState *ms)
|
||||
int ret;
|
||||
int type = 0;
|
||||
const char *kvm_type;
|
||||
uint64_t dirty_log_manual_caps;
|
||||
|
||||
s = KVM_STATE(ms->accelerator);
|
||||
|
||||
@ -2120,14 +2121,20 @@ static int kvm_init(MachineState *ms)
|
||||
s->coalesced_pio = s->coalesced_mmio &&
|
||||
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);
|
||||
if (s->manual_dirty_log_protect) {
|
||||
ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0, 1);
|
||||
dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
|
||||
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) {
|
||||
warn_report("Trying to enable KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 "
|
||||
"but failed. Falling back to the legacy mode. ");
|
||||
s->manual_dirty_log_protect = false;
|
||||
warn_report("Trying to enable capability %"PRIu64" of "
|
||||
"KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
|
||||
"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
|
||||
guest address space. If this assert fires, it probably indicates
|
||||
a missing call to h2g_valid. */
|
||||
#if TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS
|
||||
assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
|
||||
#endif
|
||||
if (TARGET_ABI_BITS > L1_MAP_ADDR_SPACE_BITS) {
|
||||
assert(start < ((target_ulong)1 << L1_MAP_ADDR_SPACE_BITS));
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
|
29
configure
vendored
29
configure
vendored
@ -518,6 +518,7 @@ plugins="no"
|
||||
fuzzing="no"
|
||||
rng_none="no"
|
||||
secret_keyring=""
|
||||
libdaxctl=""
|
||||
|
||||
supported_cpu="no"
|
||||
supported_os="no"
|
||||
@ -1626,6 +1627,10 @@ for opt do
|
||||
;;
|
||||
--disable-keyring) secret_keyring="no"
|
||||
;;
|
||||
--enable-libdaxctl) libdaxctl=yes
|
||||
;;
|
||||
--disable-libdaxctl) libdaxctl=no
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown option $opt"
|
||||
echo "Try '$0 --help' for more information"
|
||||
@ -1927,6 +1932,7 @@ disabled with --disable-FEATURE, default is enabled if available:
|
||||
libpmem libpmem support
|
||||
xkbcommon xkbcommon support
|
||||
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
|
||||
EOF
|
||||
@ -6360,6 +6366,24 @@ if test "$libpmem" != "no"; then
|
||||
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
|
||||
|
||||
@ -6967,6 +6991,7 @@ echo "parallels support $parallels"
|
||||
echo "sheepdog support $sheepdog"
|
||||
echo "capstone $capstone"
|
||||
echo "libpmem support $libpmem"
|
||||
echo "libdaxctl support $libdaxctl"
|
||||
echo "libudev $libudev"
|
||||
echo "default devices $default_devices"
|
||||
echo "plugin support $plugins"
|
||||
@ -7800,6 +7825,10 @@ if test "$libpmem" = "yes" ; then
|
||||
echo "CONFIG_LIBPMEM=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$libdaxctl" = "yes" ; then
|
||||
echo "CONFIG_LIBDAXCTL=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$bochs" = "yes" ; then
|
||||
echo "CONFIG_BOCHS=y" >> $config_host_mak
|
||||
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)
|
||||
{
|
||||
assert(qemu_in_vcpu_thread());
|
||||
@ -1382,9 +1389,7 @@ static void handle_icount_deadline(void)
|
||||
QEMU_TIMER_ATTR_ALL);
|
||||
|
||||
if (deadline == 0) {
|
||||
/* Wake up other AioContexts. */
|
||||
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
|
||||
qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
|
||||
notify_aio_contexts();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1407,6 +1412,10 @@ static void prepare_icount_for_run(CPUState *cpu)
|
||||
cpu->icount_extra = cpu->icount_budget - insns_left;
|
||||
|
||||
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="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="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-qmp-ref.html">QMP Reference Manual</a></li>
|
||||
<li><a href="interop/qemu-ga-ref.html">Guest Agent Protocol Reference</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</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
|
||||
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.
|
||||
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
|
||||
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
|
||||
``-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)
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
@ -553,3 +536,23 @@ long starting at 1MiB, the old command::
|
||||
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
|
||||
|
||||
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"
|
||||
|
||||
#ifdef CONFIG_LIBDAXCTL
|
||||
#include <daxctl/libdaxctl.h>
|
||||
#endif
|
||||
|
||||
//#define DEBUG_SUBPAGE
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
@ -1745,6 +1749,46 @@ static int64_t get_file_size(int fd)
|
||||
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,
|
||||
const char *region_name,
|
||||
bool *created,
|
||||
@ -2296,7 +2340,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
|
||||
{
|
||||
RAMBlock *new_block;
|
||||
Error *local_err = NULL;
|
||||
int64_t file_size;
|
||||
int64_t file_size, file_align;
|
||||
|
||||
/* Just support these ram flags by now. */
|
||||
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;
|
||||
}
|
||||
|
||||
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->mr = mr;
|
||||
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
|
||||
| `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;
|
||||
int32_t aExp, bExp, expDiff;
|
||||
int32_t aExp, bExp, expDiff, aExpOrig;
|
||||
uint64_t aSig0, aSig1, bSig;
|
||||
uint64_t q, term0, term1, alternateASig0, alternateASig1;
|
||||
|
||||
*quotient = 0;
|
||||
if (floatx80_invalid_encoding(a) || floatx80_invalid_encoding(b)) {
|
||||
float_raise(float_flag_invalid, status);
|
||||
return floatx80_default_nan(status);
|
||||
}
|
||||
aSig0 = extractFloatx80Frac( a );
|
||||
aExp = extractFloatx80Exp( a );
|
||||
aExpOrig = aExp = extractFloatx80Exp( a );
|
||||
aSign = extractFloatx80Sign( a );
|
||||
bSig = extractFloatx80Frac( b );
|
||||
bExp = extractFloatx80Exp( b );
|
||||
@ -5727,6 +5732,13 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
||||
if ((uint64_t)(bSig << 1)) {
|
||||
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;
|
||||
}
|
||||
if ( bExp == 0 ) {
|
||||
@ -5738,19 +5750,27 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
||||
normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
|
||||
}
|
||||
if ( aExp == 0 ) {
|
||||
if ( (uint64_t) ( aSig0<<1 ) == 0 ) return a;
|
||||
if ( aSig0 == 0 ) return a;
|
||||
normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
|
||||
}
|
||||
bSig |= UINT64_C(0x8000000000000000);
|
||||
zSign = aSign;
|
||||
expDiff = aExp - bExp;
|
||||
aSig1 = 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 );
|
||||
expDiff = 0;
|
||||
}
|
||||
q = ( bSig <= aSig0 );
|
||||
*quotient = q = ( bSig <= aSig0 );
|
||||
if ( q ) aSig0 -= bSig;
|
||||
expDiff -= 64;
|
||||
while ( 0 < expDiff ) {
|
||||
@ -5760,6 +5780,8 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
||||
sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
|
||||
shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
|
||||
expDiff -= 62;
|
||||
*quotient <<= 62;
|
||||
*quotient += q;
|
||||
}
|
||||
expDiff += 64;
|
||||
if ( 0 < expDiff ) {
|
||||
@ -5773,19 +5795,28 @@ floatx80 floatx80_rem(floatx80 a, floatx80 b, float_status *status)
|
||||
++q;
|
||||
sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
|
||||
}
|
||||
if (expDiff < 64) {
|
||||
*quotient <<= expDiff;
|
||||
} else {
|
||||
*quotient = 0;
|
||||
}
|
||||
*quotient += q;
|
||||
}
|
||||
else {
|
||||
term1 = 0;
|
||||
term0 = bSig;
|
||||
}
|
||||
sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
|
||||
if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
||||
|| ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
||||
&& ( q & 1 ) )
|
||||
) {
|
||||
aSig0 = alternateASig0;
|
||||
aSig1 = alternateASig1;
|
||||
zSign = ! zSign;
|
||||
if (!mod) {
|
||||
sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
|
||||
if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
||||
|| ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
|
||||
&& ( q & 1 ) )
|
||||
) {
|
||||
aSig0 = alternateASig0;
|
||||
aSig1 = alternateASig1;
|
||||
zSign = ! zSign;
|
||||
++*quotient;
|
||||
}
|
||||
}
|
||||
return
|
||||
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
|
||||
| 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->unplug_request = virt_machine_device_unplug_request_cb;
|
||||
hc->unplug = virt_machine_device_unplug_cb;
|
||||
mc->numa_mem_supported = true;
|
||||
mc->nvdimm_supported = true;
|
||||
mc->auto_enable_numa_with_memhp = true;
|
||||
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);
|
||||
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)
|
||||
|
||||
|
@ -331,7 +331,7 @@ static void ibex_uart_write(void *opaque, hwaddr addr,
|
||||
if (value & UART_CTRL_NCO) {
|
||||
uint64_t baud = ((value & UART_CTRL_NCO) >> 16);
|
||||
baud *= 1000;
|
||||
baud /= 2 ^ 20;
|
||||
baud >>= 20;
|
||||
|
||||
s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
|
||||
}
|
||||
|
@ -30,6 +30,10 @@
|
||||
|
||||
GlobalProperty hw_compat_5_0[] = {
|
||||
{ "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);
|
||||
|
||||
@ -45,10 +49,6 @@ GlobalProperty hw_compat_4_2[] = {
|
||||
{ "qxl", "revision", "4" },
|
||||
{ "qxl-vga", "revision", "4" },
|
||||
{ "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);
|
||||
|
||||
|
@ -117,6 +117,13 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
|
||||
}
|
||||
|
||||
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;
|
||||
if (!qtest_enabled()) {
|
||||
warn_report("Parameter -numa node,mem is deprecated,"
|
||||
|
@ -2741,8 +2741,7 @@ static const VMStateDescription vmstate_vmbus_bridge = {
|
||||
};
|
||||
|
||||
static Property vmbus_bridge_props[] = {
|
||||
DEFINE_PROP_UINT8("irq0", VMBusBridge, irq0, 7),
|
||||
DEFINE_PROP_UINT8("irq1", VMBusBridge, irq1, 13),
|
||||
DEFINE_PROP_UINT8("irq", VMBusBridge, irq, 7),
|
||||
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)));
|
||||
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs, aml_irq_no_flags(vmbus_bridge->irq0));
|
||||
/* FIXME: newer HyperV gets by with only one IRQ */
|
||||
aml_append(crs, aml_irq_no_flags(vmbus_bridge->irq1));
|
||||
aml_append(crs, aml_irq_no_flags(vmbus_bridge->irq));
|
||||
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||
|
||||
return dev;
|
||||
|
@ -1980,7 +1980,6 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
hc->unplug = pc_machine_device_unplug_cb;
|
||||
mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE;
|
||||
mc->nvdimm_supported = true;
|
||||
mc->numa_mem_supported = true;
|
||||
mc->default_ram_id = "pc.ram";
|
||||
|
||||
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);
|
||||
m->alias = NULL;
|
||||
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, 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);
|
||||
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, 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
|
||||
*/
|
||||
mc->numa_mem_align_shift = 28;
|
||||
mc->numa_mem_supported = true;
|
||||
mc->auto_enable_numa = true;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
@ -54,10 +54,6 @@
|
||||
#define MEGASAS_FLAG_USE_QUEUE64 1
|
||||
#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 {
|
||||
uint32_t index;
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
* 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 (target_id >= MFI_MAX_LD || lun_id != 0) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
sdev = scsi_device_find(&s->bus, 0, target_id, lun_id);
|
||||
|
||||
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);
|
||||
|
||||
if (!sdev || (megasas_is_jbod(s) && is_logical)) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (cdb_len > 16) {
|
||||
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);
|
||||
megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
|
||||
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);
|
||||
if (!cmd->req) {
|
||||
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));
|
||||
cmd->frame->header.scsi_status = BUSY;
|
||||
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,
|
||||
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);
|
||||
if (!sdev) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (cdb_len > 16) {
|
||||
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));
|
||||
cmd->frame->header.scsi_status = CHECK_CONDITION;
|
||||
s->event_count++;
|
||||
@ -1781,7 +1791,7 @@ static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
|
||||
lun_id, cdb, cmd);
|
||||
if (!cmd->req) {
|
||||
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));
|
||||
cmd->frame->header.scsi_status = BUSY;
|
||||
s->event_count++;
|
||||
|
@ -214,7 +214,7 @@ struct XHCIState {
|
||||
uint32_t dcbaap_high;
|
||||
uint32_t config;
|
||||
|
||||
USBPort uports[MAX(MAXPORTS_2, MAXPORTS_3)];
|
||||
USBPort uports[MAX_CONST(MAXPORTS_2, MAXPORTS_3)];
|
||||
XHCIPort ports[MAXPORTS];
|
||||
XHCISlot slots[MAXSLOTS];
|
||||
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_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-$(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_SIZE (1ULL << BDRV_SECTOR_BITS)
|
||||
|
||||
#define BDRV_REQUEST_MAX_SECTORS MIN(SIZE_MAX >> BDRV_SECTOR_BITS, \
|
||||
INT_MAX >> BDRV_SECTOR_BITS)
|
||||
#define BDRV_REQUEST_MAX_SECTORS MIN_CONST(SIZE_MAX >> BDRV_SECTOR_BITS, \
|
||||
INT_MAX >> 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
|
||||
* to be used for tags.
|
||||
*/
|
||||
#if MIN(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32
|
||||
# define GUEST_ADDR_MAX_ UINT32_MAX
|
||||
#else
|
||||
# define GUEST_ADDR_MAX_ (~0ul)
|
||||
#endif
|
||||
#define GUEST_ADDR_MAX_ \
|
||||
((MIN_CONST(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) ? \
|
||||
UINT32_MAX : ~0ul)
|
||||
#define GUEST_ADDR_MAX (reserved_va ? reserved_va - 1 : GUEST_ADDR_MAX_)
|
||||
|
||||
#else
|
||||
|
@ -102,8 +102,13 @@ typedef uint64_t target_ulong;
|
||||
* Skylake's Level-2 STLB has 16 1G entries.
|
||||
* 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)
|
||||
# else
|
||||
# define CPU_TLB_DYN_MAX_BITS \
|
||||
MIN_CONST(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
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_mul(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_sqrt(floatx80, float_status *status);
|
||||
FloatRelation floatx80_compare(floatx80, floatx80, float_status *status);
|
||||
|
@ -19,8 +19,7 @@ typedef struct VMBus VMBus;
|
||||
typedef struct VMBusBridge {
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
uint8_t irq0;
|
||||
uint8_t irq1;
|
||||
uint8_t irq;
|
||||
|
||||
VMBus *bus;
|
||||
} VMBusBridge;
|
||||
|
@ -236,18 +236,55 @@ extern int daemon(int, int);
|
||||
#define SIZE_MAX ((size_t)-1)
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
/*
|
||||
* Two variations of MIN/MAX macros. The first is for runtime use, and
|
||||
* evaluates arguments only once (so it is safe even with side
|
||||
* effects), but will not work in constant contexts (such as array
|
||||
* size declarations) because of the '{}'. The second is for constant
|
||||
* 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
|
||||
#define MIN_NON_ZERO(a, b) ((a) == 0 ? (b) : \
|
||||
((b) == 0 ? (a) : (MIN(a, b))))
|
||||
#define MIN_NON_ZERO(a, b) \
|
||||
({ \
|
||||
typeof(1 ? (a) : (b)) _a = (a), _b = (b); \
|
||||
_a == 0 ? _b : (_b == 0 || _b > _a) ? _a : _b; \
|
||||
})
|
||||
#endif
|
||||
|
||||
/* 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,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
int access_size_min, access_size_max;
|
||||
int access_size, i;
|
||||
if (mr->ops->valid.accepts
|
||||
&& !mr->ops->valid.accepts(mr->opaque, addr, size, is_write, attrs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mr->ops->valid.accepts) {
|
||||
/* Treat zero as compatibility all valid */
|
||||
if (!mr->ops->valid.max_access_size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
access_size_min = mr->ops->valid.min_access_size;
|
||||
if (!mr->ops->valid.min_access_size) {
|
||||
access_size_min = 1;
|
||||
if (size > mr->ops->valid.max_access_size
|
||||
|| size < mr->ops->valid.min_access_size) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "qapi/error.h"
|
||||
|
||||
#define IO_BUF_SIZE 32768
|
||||
#define MAX_IOV_SIZE MIN(IOV_MAX, 64)
|
||||
#define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 64)
|
||||
|
||||
struct QEMUFile {
|
||||
const QEMUFileOps *ops;
|
||||
|
@ -239,10 +239,11 @@ SRST
|
||||
-numa node,nodeid=0 -numa node,nodeid=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``\ '
|
||||
assigns RAM from a given memory backend device to a node. If
|
||||
'\ ``mem``\ ' and '\ ``memdev``\ ' are omitted in all nodes, RAM is
|
||||
split equally between them.
|
||||
Legacy '\ ``mem``\ ' assigns a given RAM amount to a node (not supported
|
||||
for 5.1 and newer machine types). '\ ``memdev``\ ' assigns RAM from
|
||||
a given memory backend device to a node. If '\ ``mem``\ ' and
|
||||
'\ ``memdev``\ ' are omitted in all nodes, RAM is split equally between them.
|
||||
|
||||
|
||||
'\ ``mem``\ ' and '\ ``memdev``\ ' are mutually exclusive.
|
||||
Furthermore, if one node uses '\ ``memdev``\ ', all of them have to
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
/* Current version of the replay mechanism.
|
||||
Increase it when file format changes. */
|
||||
#define REPLAY_VERSION 0xe02009
|
||||
#define REPLAY_VERSION 0xe0200a
|
||||
/* Size of replay log header */
|
||||
#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 },
|
||||
.to = { FEAT_VMX_VMFUNC, ~0ull },
|
||||
},
|
||||
{
|
||||
.from = { FEAT_8000_0001_ECX, CPUID_EXT3_SVM },
|
||||
.to = { FEAT_SVM, ~0ull },
|
||||
},
|
||||
};
|
||||
|
||||
typedef struct X86RegisterInfo32 {
|
||||
@ -3135,6 +3139,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
.versions = (X86CPUVersionDefinition[]) {
|
||||
{ .version = 1 },
|
||||
{ .version = 2,
|
||||
.note = "ARCH_CAPABILITIES",
|
||||
.props = (PropValue[]) {
|
||||
{ "arch-capabilities", "on" },
|
||||
{ "rdctl-no", "on" },
|
||||
@ -3146,6 +3151,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
},
|
||||
{ .version = 3,
|
||||
.alias = "Cascadelake-Server-noTSX",
|
||||
.note = "ARCH_CAPABILITIES, no TSX",
|
||||
.props = (PropValue[]) {
|
||||
{ "hle", "off" },
|
||||
{ "rtm", "off" },
|
||||
@ -3367,6 +3373,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
{ .version = 1 },
|
||||
{
|
||||
.version = 2,
|
||||
.note = "no TSX",
|
||||
.alias = "Icelake-Client-noTSX",
|
||||
.props = (PropValue[]) {
|
||||
{ "hle", "off" },
|
||||
@ -3484,6 +3491,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
{ .version = 1 },
|
||||
{
|
||||
.version = 2,
|
||||
.note = "no TSX",
|
||||
.alias = "Icelake-Server-noTSX",
|
||||
.props = (PropValue[]) {
|
||||
{ "hle", "off" },
|
||||
@ -3604,6 +3612,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
{ .version = 1 },
|
||||
{
|
||||
.version = 2,
|
||||
.note = "no MPX, no MONITOR",
|
||||
.props = (PropValue[]) {
|
||||
{ "monitor", "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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
CPUX86State *env = &cpu->env;
|
||||
int r;
|
||||
int r, cur_freq;
|
||||
bool set_ioctl = false;
|
||||
|
||||
if (!env->tsc_khz) {
|
||||
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) :
|
||||
-ENOTSUP;
|
||||
|
||||
if (r < 0) {
|
||||
/* When KVM_SET_TSC_KHZ fails, it's an error only if the current
|
||||
* TSC frequency doesn't match the one we want.
|
||||
*/
|
||||
int cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
|
||||
kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
|
||||
-ENOTSUP;
|
||||
cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
|
||||
kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
|
||||
-ENOTSUP;
|
||||
if (cur_freq <= 0 || cur_freq != env->tsc_khz) {
|
||||
warn_report("TSC frequency mismatch between "
|
||||
"VM (%" PRId64 " kHz) and host (%d kHz), "
|
||||
|
@ -42,89 +42,6 @@ static floatx80 propagateFloatx80NaNOneArg(floatx80 a, float_status *status)
|
||||
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
|
||||
* value `a'.
|
||||
|
@ -23,7 +23,6 @@
|
||||
#define TARGET_M68K_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_getexp(floatx80 a, 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"));
|
||||
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");
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ int main(int argc, char **argv)
|
||||
"-cpu 486,+invtsc", "xlevel", 0x80000007);
|
||||
/* CPUID[8000_000A].EDX: */
|
||||
add_cpuid_test("x86/cpuid/auto-xlevel/486/npt",
|
||||
"-cpu 486,+npt", "xlevel", 0x8000000A);
|
||||
"-cpu 486,+svm,+npt", "xlevel", 0x8000000A);
|
||||
/* CPUID[C000_0001].EDX: */
|
||||
add_cpuid_test("x86/cpuid/auto-xlevel2/phenom/xstore",
|
||||
"-cpu phenom,+xstore", "xlevel2", 0xC0000001);
|
||||
@ -348,7 +348,7 @@ int main(int argc, char **argv)
|
||||
"-machine pc-i440fx-2.4 -cpu SandyBridge,",
|
||||
"xlevel", 0x80000008);
|
||||
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);
|
||||
|
||||
/* Test feature parsing */
|
||||
|
@ -96,7 +96,7 @@ static void pci_ehci_port_1(void)
|
||||
static void pci_ehci_config(void)
|
||||
{
|
||||
/* 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)
|
||||
|
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;
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
unsigned long qemu_getauxval(unsigned long type)
|
||||
|
@ -501,7 +501,6 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
|
||||
bool progress = false;
|
||||
QEMUTimerCB *cb;
|
||||
void *opaque;
|
||||
bool need_replay_checkpoint = false;
|
||||
|
||||
if (!atomic_read(&timer_list->active_timers)) {
|
||||
return false;
|
||||
@ -517,16 +516,6 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
case QEMU_CLOCK_HOST:
|
||||
if (!replay_checkpoint(CHECKPOINT_CLOCK_HOST)) {
|
||||
@ -559,19 +548,16 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (need_replay_checkpoint
|
||||
&& !(ts->attributes & QEMU_TIMER_ATTR_EXTERNAL)) {
|
||||
/* once we got here, checkpoint clock only once */
|
||||
need_replay_checkpoint = false;
|
||||
/* 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.
|
||||
*/
|
||||
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);
|
||||
if (!replay_checkpoint(CHECKPOINT_CLOCK_VIRTUAL)) {
|
||||
goto out;
|
||||
}
|
||||
qemu_mutex_lock(&timer_list->active_timers_lock);
|
||||
/* The lock was released; start over again in case the list was
|
||||
* modified.
|
||||
*/
|
||||
continue;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* remove timer from the list before calling the callback */
|
||||
|
Loading…
Reference in New Issue
Block a user