Miscellaneous bugfixes, including crash fixes from Alexey, Peter M. and

Thomas.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQEcBAABAgAGBQJay3qbAAoJEL/70l94x66D7LwIAIDjHDULzCy/u+m/uFyTn7rD
 zyDhQTWgHP6OQ+TqixIDDszeasev/PWmiC6Bp+NG6ZIG102+XTREciSW+X7B6mct
 OqI/5xpjoqzKj2LrTeCnm754Xv7Ilz9kxZ1MKlGqjnRzdmykDRx7RNLqGBohL4EI
 nnF3iiOiT4ECY/aLgeRLfufJqj9zHr8hQ3om+2zMqntPfqc3Eg0eCpgb7uGMRDq8
 nWLecnDtqmBWhXDJCPngxDavBQqHDAmq1aj9ppJPLS+nB6pez0DvHMI6Gg3K4fIl
 2ybJse5FbOj/+PsM1Ae5g8TcWz607mVgtE+crKxLDmffg+YjbO9raqWigZoIw2Y=
 =aMIC
 -----END PGP SIGNATURE-----

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

Miscellaneous bugfixes, including crash fixes from Alexey, Peter M. and
Thomas.

# gpg: Signature made Mon 09 Apr 2018 15:37:15 BST
# gpg:                using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# 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:
  Add missing bit for SSE instr in VEX decoding
  maint: Add .mailmap entries for patches claiming list authorship
  dump: Fix build with newer gcc
  device-crash-test: Remove fixed isa-fdc entry
  qemu-pr-helper: Write pidfile more often
  qemu-pr-helper: Daemonize before dropping privileges
  virtio-serial: fix heapover-flow
  kvmclock: fix clock_is_reliable on migration from QEMU < 2.9
  hw/dma/i82374: Avoid double creation of the 82374 controller
  hw/scsi: support SCSI-2 passthrough without PI
  scsi-disk: allow customizing the SCSI version
  scsi-disk: Don't enlarge min_io_size to max_io_size
  configure: Add missing configure options to help text
  i386/hyperv: error out if features requested but unsupported
  i386/hyperv: add hv-frequencies cpu property
  target/i386: WHPX: set CPUID_EXT_HYPERVISOR bit
  memfd: fix vhost-user-test on non-memfd capable host
  scripts/checkpatch.pl: Bug fix
  target/i386: Fix andn instruction
  sys_membarrier: fix up include directives

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-04-09 17:29:09 +01:00
commit 915d34c5f9
20 changed files with 300 additions and 59 deletions

View file

@ -1,6 +1,7 @@
# This mailmap just translates the weird addresses from the original import into git
# into proper addresses so that they are counted properly in git shortlog output.
#
# This mailmap fixes up author names/addresses.
# The first section translates weird addresses from the original git import
# into proper addresses so that they are counted properly by git shortlog.
Andrzej Zaborowski <balrogg@gmail.com> balrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>
Anthony Liguori <anthony@codemonkey.ws> aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com>
@ -15,10 +16,19 @@ Paul Burton <paul.burton@mips.com> <paul.burton@imgtec.com>
Paul Burton <paul.burton@mips.com> <paul@archlinuxmips.org>
Thiemo Seufer <ths@networkno.de> ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
malc <av1474@comtv.ru> malc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>
# There is also a:
# (no author) <(no author)@c046a42c-6fe2-441c-8c8c-71466251a162>
# for the cvs2svn initialization commit e63c3dc74bf.
#
# Next, translate a few commits where mailman rewrote the From: line due
# to strict SPF, although we prefer to avoid adding more entries like that.
Ed Swierk <eswierk@skyportsystems.com> Ed Swierk via Qemu-devel <qemu-devel@nongnu.org>
Ian McKellar <ianloic@google.com> Ian McKellar via Qemu-devel <qemu-devel@nongnu.org>
Julia Suvorova <jusual@mail.ru> Julia Suvorova via Qemu-devel <qemu-devel@nongnu.org>
Justin Terry (VM) <juterry@microsoft.com> Justin Terry (VM) via Qemu-devel <qemu-devel@nongnu.org>
# Also list preferred name forms where people have changed their
# git author config
Daniel P. Berrangé <berrange@redhat.com>

3
configure vendored
View file

@ -1497,16 +1497,19 @@ Advanced options (experts only):
--install=INSTALL use specified install [$install]
--python=PYTHON use specified python [$python]
--smbd=SMBD use specified smbd [$smbd]
--with-git=GIT use specified git [$git]
--static enable static build [$static]
--mandir=PATH install man pages in PATH
--datadir=PATH install firmware in PATH$confsuffix
--docdir=PATH install documentation in PATH$confsuffix
--bindir=PATH install binaries in PATH
--libdir=PATH install libraries in PATH
--libexecdir=PATH install helper binaries in PATH
--sysconfdir=PATH install config in PATH$confsuffix
--localstatedir=PATH install local state in PATH (set at runtime on win32)
--firmwarepath=PATH search PATH for firmware files
--with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]
--with-pkgversion=VERS use specified string as sub-version of the package
--enable-debug enable common debug build options
--enable-sanitizers enable default sanitizers
--disable-strip disable stripping binaries

4
dump.c
View file

@ -814,7 +814,7 @@ static void create_header32(DumpState *s, Error **errp)
size = sizeof(DiskDumpHeader32);
dh = g_malloc0(size);
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
dh->header_version = cpu_to_dump32(s, 6);
block_size = s->dump_info.page_size;
dh->block_size = cpu_to_dump32(s, block_size);
@ -926,7 +926,7 @@ static void create_header64(DumpState *s, Error **errp)
size = sizeof(DiskDumpHeader64);
dh = g_malloc0(size);
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
dh->header_version = cpu_to_dump32(s, 6);
block_size = s->dump_info.page_size;
dh->block_size = cpu_to_dump32(s, block_size);

View file

@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/isa/isa.h"
#include "hw/dma/i8257.h"
@ -118,13 +119,19 @@ static const MemoryRegionPortio i82374_portio_list[] = {
static void i82374_realize(DeviceState *dev, Error **errp)
{
I82374State *s = I82374(dev);
ISABus *isa_bus = isa_bus_from_device(ISA_DEVICE(dev));
if (isa_get_dma(isa_bus, 0)) {
error_setg(errp, "DMA already initialized on ISA bus");
return;
}
i8257_dma_init(isa_bus, true);
portio_list_init(&s->port_list, OBJECT(s), i82374_portio_list, s,
"i82374");
portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj),
s->iobase);
i8257_dma_init(isa_bus_from_device(ISA_DEVICE(dev)), true);
memset(s->commands, 0, sizeof(s->commands));
}

View file

@ -241,6 +241,19 @@ static const VMStateDescription kvmclock_reliable_get_clock = {
}
};
/*
* When migrating, assume the source has an unreliable
* KVM_GET_CLOCK unless told otherwise.
*/
static int kvmclock_pre_load(void *opaque)
{
KVMClockState *s = opaque;
s->clock_is_reliable = false;
return 0;
}
/*
* When migrating, read the clock just before migration,
* so that the guest clock counts during the events
@ -268,6 +281,7 @@ static const VMStateDescription kvmclock_vmsd = {
.name = "kvmclock",
.version_id = 1,
.minimum_version_id = 1,
.pre_load = kvmclock_pre_load,
.pre_save = kvmclock_pre_save,
.fields = (VMStateField[]) {
VMSTATE_UINT64(clock, KVMClockState),

View file

@ -714,10 +714,12 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
/* min_io_size and opt_io_size can't be greater than
* max_io_sectors */
min_io_size =
MIN_NON_ZERO(min_io_size, max_io_sectors);
opt_io_size =
MIN_NON_ZERO(opt_io_size, max_io_sectors);
if (min_io_size) {
min_io_size = MIN(min_io_size, max_io_sectors);
}
if (opt_io_size) {
opt_io_size = MIN(opt_io_size, max_io_sectors);
}
}
/* required VPD size with unmap support */
buflen = 0x40;
@ -823,7 +825,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
* block characteristics VPD page by default. Not all of SPC-3
* is actually implemented, but we're good enough.
*/
outbuf[2] = 5;
outbuf[2] = s->qdev.default_scsi_version;
outbuf[3] = 2 | 0x10; /* Format 2, HiSup */
if (buflen > 36) {
@ -2191,7 +2193,11 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
case READ_12:
case READ_16:
DPRINTF("Read (sector %" PRId64 ", count %u)\n", r->req.cmd.lba, len);
if (r->req.cmd.buf[1] & 0xe0) {
/* Protection information is not supported. For SCSI versions 2 and
* older (as determined by snooping the guest's INQUIRY commands),
* there is no RD/WR/VRPROTECT, so skip this check in these versions.
*/
if (s->qdev.scsi_version > 2 && (r->req.cmd.buf[1] & 0xe0)) {
goto illegal_request;
}
if (!check_lba_range(s, r->req.cmd.lba, len)) {
@ -2222,7 +2228,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
* As far as DMA is concerned, we can treat it the same as a write;
* scsi_block_do_sgio will send VERIFY commands.
*/
if (r->req.cmd.buf[1] & 0xe0) {
if (s->qdev.scsi_version > 2 && (r->req.cmd.buf[1] & 0xe0)) {
goto illegal_request;
}
if (!check_lba_range(s, r->req.cmd.lba, len)) {
@ -2268,6 +2274,8 @@ static void scsi_disk_reset(DeviceState *dev)
/* reset tray statuses */
s->tray_locked = 0;
s->tray_open = 0;
s->qdev.scsi_version = s->qdev.default_scsi_version;
}
static void scsi_disk_resize_cb(void *opaque)
@ -2812,6 +2820,8 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
{
SCSIBlockReq *r = (SCSIBlockReq *)req;
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
r->cmd = req->cmd.buf[0];
switch (r->cmd >> 5) {
case 0:
@ -2837,8 +2847,11 @@ static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
abort();
}
if (r->cdb1 & 0xe0) {
/* Protection information is not supported. */
/* Protection information is not supported. For SCSI versions 2 and
* older (as determined by snooping the guest's INQUIRY commands),
* there is no RD/WR/VRPROTECT, so skip this check in these versions.
*/
if (s->qdev.scsi_version > 2 && (req->cmd.buf[1] & 0xe0)) {
scsi_check_condition(&r->req, SENSE_CODE(INVALID_FIELD));
return 0;
}
@ -2950,6 +2963,8 @@ static Property scsi_hd_properties[] = {
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
DEFAULT_MAX_IO_SIZE),
DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
5),
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
DEFINE_PROP_END_OF_LIST(),
};
@ -2995,6 +3010,8 @@ static Property scsi_cd_properties[] = {
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
DEFAULT_MAX_IO_SIZE),
DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
5),
DEFINE_PROP_END_OF_LIST(),
};
@ -3023,6 +3040,8 @@ static Property scsi_block_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk),
DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false),
DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
-1),
DEFINE_PROP_END_OF_LIST(),
};
@ -3063,6 +3082,8 @@ static Property scsi_disk_properties[] = {
DEFAULT_MAX_UNMAP_SIZE),
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
DEFAULT_MAX_IO_SIZE),
DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
5),
DEFINE_PROP_END_OF_LIST(),
};

View file

@ -194,17 +194,40 @@ static void scsi_read_complete(void * opaque, int ret)
r->buf[3] |= 0x80;
}
}
if (s->type == TYPE_DISK &&
r->req.cmd.buf[0] == INQUIRY &&
r->req.cmd.buf[2] == 0xb0) {
uint32_t max_transfer =
blk_get_max_transfer(s->conf.blk) / s->blocksize;
if (r->req.cmd.buf[0] == INQUIRY) {
/*
* EVPD set to zero returns the standard INQUIRY data.
*
* Check if scsi_version is unset (-1) to avoid re-defining it
* each time an INQUIRY with standard data is received.
* scsi_version is initialized with -1 in scsi_generic_reset
* and scsi_disk_reset, making sure that we'll set the
* scsi_version after a reset. If the version field of the
* INQUIRY response somehow changes after a guest reboot,
* we'll be able to keep track of it.
*
* On SCSI-2 and older, first 3 bits of byte 2 is the
* ANSI-approved version, while on later versions the
* whole byte 2 contains the version. Check if we're dealing
* with a newer version and, in that case, assign the
* whole byte.
*/
if (s->scsi_version == -1 && !(r->req.cmd.buf[1] & 0x01)) {
s->scsi_version = r->buf[2] & 0x07;
if (s->scsi_version > 2) {
s->scsi_version = r->buf[2];
}
}
if (s->type == TYPE_DISK && r->req.cmd.buf[2] == 0xb0) {
uint32_t max_transfer =
blk_get_max_transfer(s->conf.blk) / s->blocksize;
assert(max_transfer);
stl_be_p(&r->buf[8], max_transfer);
/* Also take care of the opt xfer len. */
stl_be_p(&r->buf[12],
MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
assert(max_transfer);
stl_be_p(&r->buf[8], max_transfer);
/* Also take care of the opt xfer len. */
stl_be_p(&r->buf[12],
MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
}
}
scsi_req_data(&r->req, len);
scsi_req_unref(&r->req);
@ -474,6 +497,7 @@ static void scsi_generic_reset(DeviceState *dev)
{
SCSIDevice *s = SCSI_DEVICE(dev);
s->scsi_version = s->default_scsi_version;
scsi_device_purge_requests(s, SENSE_CODE(RESET));
}
@ -549,6 +573,8 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
DPRINTF("block size %d\n", s->blocksize);
/* Only used by scsi-block, but initialize it nevertheless to be clean. */
s->default_scsi_version = -1;
scsi_generic_read_device_identification(s);
}

View file

@ -1228,7 +1228,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
error_setg(&hdev->migration_blocker,
"Migration disabled: vhost lacks VHOST_F_LOG_ALL feature.");
} else if (vhost_dev_log_is_shared(hdev) && !qemu_memfd_check()) {
} else if (vhost_dev_log_is_shared(hdev) && !qemu_memfd_alloc_check()) {
error_setg(&hdev->migration_blocker,
"Migration disabled: failed to allocate shared memory");
}

View file

@ -85,6 +85,8 @@ struct SCSIDevice
uint64_t max_lba;
uint64_t wwn;
uint64_t port_wwn;
int scsi_version;
int default_scsi_version;
};
extern const VMStateDescription vmstate_scsi_device;

View file

@ -18,6 +18,7 @@
int qemu_memfd_create(const char *name, size_t size, bool hugetlb,
uint64_t hugetlbsize, unsigned int seals, Error **errp);
bool qemu_memfd_alloc_check(void);
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
int *fd, Error **errp);
void qemu_memfd_free(void *ptr, size_t size, int fd);

View file

@ -2356,6 +2356,18 @@ sub process {
# check for missing bracing around if etc
if ($line =~ /(^.*)\b(?:if|while|for)\b/ &&
$line !~ /\#\s*if/) {
my $allowed = 0;
# Check the pre-context.
if ($line =~ /(\}.*?)$/) {
my $pre = $1;
if ($line !~ /else/) {
print "APW: ALLOWED: pre<$pre> line<$line>\n"
if $dbg_adv_apw;
$allowed = 1;
}
}
my ($level, $endln, @chunks) =
ctx_statement_full($linenr, $realcnt, 1);
if ($dbg_adv_apw) {
@ -2364,7 +2376,6 @@ sub process {
if $#chunks >= 1;
}
if ($#chunks >= 0 && $level == 0) {
my $allowed = 0;
my $seen = 0;
my $herectx = $here . "\n";
my $ln = $linenr - 1;
@ -2408,7 +2419,7 @@ sub process {
$allowed = 1;
}
}
if ($seen != ($#chunks + 1)) {
if ($seen != ($#chunks + 1) && !$allowed) {
ERROR("braces {} are necessary for all arms of this statement\n" . $herectx);
}
}

View file

@ -217,7 +217,6 @@ ERROR_WHITELIST = [
{'exitcode':-6, 'log':r"Object .* is not an instance of type generic-pc-machine", 'loglevel':logging.ERROR},
{'exitcode':-6, 'log':r"Object .* is not an instance of type e500-ccsr", 'loglevel':logging.ERROR},
{'exitcode':-6, 'log':r"vmstate_register_with_alias_id: Assertion `!se->compat \|\| se->instance_id == 0' failed", 'loglevel':logging.ERROR},
{'exitcode':-6, 'device':'isa-fdc', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'isa-serial', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'mioe3680_pci', 'loglevel':logging.ERROR, 'expected':True},
{'exitcode':-11, 'device':'pcm3680_pci', 'loglevel':logging.ERROR, 'expected':True},

View file

@ -924,6 +924,7 @@ int main(int argc, char **argv)
Error *local_err = NULL;
char *trace_file = NULL;
bool daemonize = false;
bool pidfile_specified = false;
unsigned socket_activation;
struct sigaction sa_sigterm;
@ -954,6 +955,7 @@ int main(int argc, char **argv)
case 'f':
g_free(pidfile);
pidfile = g_strdup(optarg);
pidfile_specified = true;
break;
#ifdef CONFIG_LIBCAP
case 'u': {
@ -1081,6 +1083,16 @@ int main(int argc, char **argv)
accept_client,
NULL, NULL);
if (daemonize) {
if (daemon(0, 0) < 0) {
error_report("Failed to daemonize: %s", strerror(errno));
exit(EXIT_FAILURE);
}
}
if (daemonize || pidfile_specified)
write_pidfile();
#ifdef CONFIG_LIBCAP
if (drop_privileges() < 0) {
error_report("Failed to drop privileges: %s", strerror(errno));
@ -1088,14 +1100,6 @@ int main(int argc, char **argv)
}
#endif
if (daemonize) {
if (daemon(0, 0) < 0) {
error_report("Failed to daemonize: %s", strerror(errno));
exit(EXIT_FAILURE);
}
write_pidfile();
}
state = RUNNING;
do {
main_loop_wait(false);

View file

@ -4761,6 +4761,7 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, false),
DEFINE_PROP_BOOL("hv-frequencies", X86CPU, hyperv_frequencies, false),
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),

View file

@ -1296,6 +1296,7 @@ struct X86CPU {
bool hyperv_runtime;
bool hyperv_synic;
bool hyperv_stimer;
bool hyperv_frequencies;
bool check_cpuid;
bool enforce_cpuid;
bool expose_kvm;

View file

@ -632,11 +632,6 @@ static int hyperv_handle_properties(CPUState *cs)
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
if (cpu->hyperv_time &&
kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_TIME) <= 0) {
cpu->hyperv_time = false;
}
if (cpu->hyperv_relaxed_timing) {
env->features[FEAT_HYPERV_EAX] |= HV_HYPERCALL_AVAILABLE;
}
@ -645,26 +640,61 @@ static int hyperv_handle_properties(CPUState *cs)
env->features[FEAT_HYPERV_EAX] |= HV_APIC_ACCESS_AVAILABLE;
}
if (cpu->hyperv_time) {
if (kvm_check_extension(cs->kvm_state, KVM_CAP_HYPERV_TIME) <= 0) {
fprintf(stderr, "Hyper-V clocksources "
"(requested by 'hv-time' cpu flag) "
"are not supported by kernel\n");
return -ENOSYS;
}
env->features[FEAT_HYPERV_EAX] |= HV_HYPERCALL_AVAILABLE;
env->features[FEAT_HYPERV_EAX] |= HV_TIME_REF_COUNT_AVAILABLE;
env->features[FEAT_HYPERV_EAX] |= HV_REFERENCE_TSC_AVAILABLE;
if (has_msr_hv_frequencies && tsc_is_stable_and_known(env)) {
env->features[FEAT_HYPERV_EAX] |= HV_ACCESS_FREQUENCY_MSRS;
env->features[FEAT_HYPERV_EDX] |= HV_FREQUENCY_MSRS_AVAILABLE;
}
}
if (cpu->hyperv_crash && has_msr_hv_crash) {
if (cpu->hyperv_frequencies) {
if (!has_msr_hv_frequencies) {
fprintf(stderr, "Hyper-V frequency MSRs "
"(requested by 'hv-frequencies' cpu flag) "
"are not supported by kernel\n");
return -ENOSYS;
}
env->features[FEAT_HYPERV_EAX] |= HV_ACCESS_FREQUENCY_MSRS;
env->features[FEAT_HYPERV_EDX] |= HV_FREQUENCY_MSRS_AVAILABLE;
}
if (cpu->hyperv_crash) {
if (!has_msr_hv_crash) {
fprintf(stderr, "Hyper-V crash MSRs "
"(requested by 'hv-crash' cpu flag) "
"are not supported by kernel\n");
return -ENOSYS;
}
env->features[FEAT_HYPERV_EDX] |= HV_GUEST_CRASH_MSR_AVAILABLE;
}
env->features[FEAT_HYPERV_EDX] |= HV_CPU_DYNAMIC_PARTITIONING_AVAILABLE;
if (cpu->hyperv_reset && has_msr_hv_reset) {
if (cpu->hyperv_reset) {
if (!has_msr_hv_reset) {
fprintf(stderr, "Hyper-V reset MSR "
"(requested by 'hv-reset' cpu flag) "
"is not supported by kernel\n");
return -ENOSYS;
}
env->features[FEAT_HYPERV_EAX] |= HV_RESET_AVAILABLE;
}
if (cpu->hyperv_vpindex && has_msr_hv_vpindex) {
if (cpu->hyperv_vpindex) {
if (!has_msr_hv_vpindex) {
fprintf(stderr, "Hyper-V VP_INDEX MSR "
"(requested by 'hv-vpindex' cpu flag) "
"is not supported by kernel\n");
return -ENOSYS;
}
env->features[FEAT_HYPERV_EAX] |= HV_VP_INDEX_AVAILABLE;
}
if (cpu->hyperv_runtime && has_msr_hv_runtime) {
if (cpu->hyperv_runtime) {
if (!has_msr_hv_runtime) {
fprintf(stderr, "Hyper-V VP_RUNTIME MSR "
"(requested by 'hv-runtime' cpu flag) "
"is not supported by kernel\n");
return -ENOSYS;
}
env->features[FEAT_HYPERV_EAX] |= HV_VP_RUNTIME_AVAILABLE;
}
if (cpu->hyperv_synic) {

View file

@ -3802,7 +3802,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
}
ot = mo_64_32(s->dflag);
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0);
tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_regs[s->vex_v]);
gen_op_mov_reg_v(ot, reg, cpu_T0);
gen_op_update1_cc();
set_cc_op(s, CC_OP_LOGICB + ot);
@ -4563,9 +4563,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
#endif
rex_r = (~vex2 >> 4) & 8;
if (b == 0xc5) {
/* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
vex3 = vex2;
b = x86_ldub_code(env, s);
b = x86_ldub_code(env, s) | 0x100;
} else {
/* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
#ifdef TARGET_X86_64
s->rex_x = (~vex2 >> 3) & 8;
s->rex_b = (~vex2 >> 2) & 8;

View file

@ -911,12 +911,62 @@ static int whpx_vcpu_run(CPUState *cpu)
ret = 1;
break;
case WHvRunVpExitReasonX64Cpuid: {
WHV_REGISTER_VALUE reg_values[5] = {0};
WHV_REGISTER_NAME reg_names[5];
UINT32 reg_count = 5;
UINT64 rip, rax, rcx, rdx, rbx;
rip = vcpu->exit_ctx.VpContext.Rip +
vcpu->exit_ctx.VpContext.InstructionLength;
switch (vcpu->exit_ctx.CpuidAccess.Rax) {
case 1:
rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax;
/* Advertise that we are running on a hypervisor */
rcx =
vcpu->exit_ctx.CpuidAccess.DefaultResultRcx |
CPUID_EXT_HYPERVISOR;
rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx;
rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx;
break;
default:
rax = vcpu->exit_ctx.CpuidAccess.DefaultResultRax;
rcx = vcpu->exit_ctx.CpuidAccess.DefaultResultRcx;
rdx = vcpu->exit_ctx.CpuidAccess.DefaultResultRdx;
rbx = vcpu->exit_ctx.CpuidAccess.DefaultResultRbx;
}
reg_names[0] = WHvX64RegisterRip;
reg_names[1] = WHvX64RegisterRax;
reg_names[2] = WHvX64RegisterRcx;
reg_names[3] = WHvX64RegisterRdx;
reg_names[4] = WHvX64RegisterRbx;
reg_values[0].Reg64 = rip;
reg_values[1].Reg64 = rax;
reg_values[2].Reg64 = rcx;
reg_values[3].Reg64 = rdx;
reg_values[4].Reg64 = rbx;
hr = WHvSetVirtualProcessorRegisters(whpx->partition,
cpu->cpu_index,
reg_names,
reg_count,
reg_values);
if (FAILED(hr)) {
error_report("WHPX: Failed to set CpuidAccess state registers,"
" hr=%08lx", hr);
}
ret = 0;
break;
}
case WHvRunVpExitReasonNone:
case WHvRunVpExitReasonUnrecoverableException:
case WHvRunVpExitReasonInvalidVpRegisterValue:
case WHvRunVpExitReasonUnsupportedFeature:
case WHvRunVpExitReasonX64MsrAccess:
case WHvRunVpExitReasonX64Cpuid:
case WHvRunVpExitReasonException:
default:
error_report("WHPX: Unexpected VP exit code %d",
@ -1272,6 +1322,33 @@ static int whpx_accel_init(MachineState *ms)
goto error;
}
memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
prop.ExtendedVmExits.X64CpuidExit = 1;
hr = WHvSetPartitionProperty(whpx->partition,
WHvPartitionPropertyCodeExtendedVmExits,
&prop,
sizeof(WHV_PARTITION_PROPERTY));
if (FAILED(hr)) {
error_report("WHPX: Failed to enable partition extended X64CpuidExit"
" hr=%08lx", hr);
ret = -EINVAL;
goto error;
}
UINT32 cpuidExitList[] = {1};
hr = WHvSetPartitionProperty(whpx->partition,
WHvPartitionPropertyCodeCpuidExitList,
cpuidExitList,
RTL_NUMBER_OF(cpuidExitList) * sizeof(UINT32));
if (FAILED(hr)) {
error_report("WHPX: Failed to set partition CpuidExitList hr=%08lx",
hr);
ret = -EINVAL;
goto error;
}
hr = WHvSetupPartition(whpx->partition);
if (FAILED(hr)) {
error_report("WHPX: Failed to setup partition, hr=%08lx", hr);

View file

@ -173,7 +173,13 @@ enum {
MEMFD_TODO
};
bool qemu_memfd_check(void)
/**
* qemu_memfd_alloc_check():
*
* Check if qemu_memfd_alloc() can allocate, including using a
* fallback implementation when host doesn't support memfd.
*/
bool qemu_memfd_alloc_check(void)
{
static int memfd_check = MEMFD_TODO;
@ -188,3 +194,29 @@ bool qemu_memfd_check(void)
return memfd_check == MEMFD_OK;
}
/**
* qemu_memfd_check():
*
* Check if host supports memfd.
*/
bool qemu_memfd_check(void)
{
#ifdef CONFIG_LINUX
static int memfd_check = MEMFD_TODO;
if (memfd_check == MEMFD_TODO) {
int mfd = memfd_create("test", 0);
if (mfd >= 0) {
memfd_check = MEMFD_OK;
close(mfd);
} else {
memfd_check = MEMFD_KO;
}
}
return memfd_check == MEMFD_OK;
#else
return false;
#endif
}

View file

@ -6,9 +6,9 @@
* Author: Paolo Bonzini <pbonzini@redhat.com>
*/
#include <qemu/osdep.h>
#include <qemu/sys_membarrier.h>
#include <qemu/error-report.h>
#include "qemu/osdep.h"
#include "qemu/sys_membarrier.h"
#include "qemu/error-report.h"
#ifdef CONFIG_LINUX
#include <linux/membarrier.h>