* 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:
Peter Maydell 2020-06-26 16:55:20 +01:00
commit 3591ddd399
47 changed files with 6218 additions and 377 deletions

View File

@ -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

View File

@ -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;
}
}

View File

@ -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
View File

@ -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
View File

@ -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();
}
}
}

View File

@ -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>

View File

@ -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

View File

@ -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
View File

@ -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;

View File

@ -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, &quotient, 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, &quotient, status);
}
/*----------------------------------------------------------------------------
| Returns the square root of the extended double-precision floating-point
| value `a'. The operation is performed according to the IEC/IEEE Standard

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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,"

View File

@ -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()
};

View File

@ -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;

View File

@ -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",

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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++;

View File

@ -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;

View File

@ -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

View File

@ -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)
/*

View File

@ -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

View File

@ -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 {

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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), "

View File

@ -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'.

View File

@ -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);

View File

@ -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");
}

View File

@ -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 */

View File

@ -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

View File

@ -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)

View File

@ -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 */