mirror of https://github.com/xemu-project/xemu.git
* 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;
|
||||
|
|
|
@ -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)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
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