mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 10:34:58 -06:00
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:
commit
915d34c5f9
20 changed files with 300 additions and 59 deletions
18
.mailmap
18
.mailmap
|
@ -1,6 +1,7 @@
|
||||||
# This mailmap just translates the weird addresses from the original import into git
|
# This mailmap fixes up author names/addresses.
|
||||||
# into proper addresses so that they are counted properly in git shortlog output.
|
|
||||||
#
|
# 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>
|
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> aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
|
||||||
Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com>
|
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>
|
Paul Burton <paul.burton@mips.com> <paul@archlinuxmips.org>
|
||||||
Thiemo Seufer <ths@networkno.de> ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
|
Thiemo Seufer <ths@networkno.de> ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
|
||||||
malc <av1474@comtv.ru> malc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>
|
malc <av1474@comtv.ru> malc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>
|
||||||
|
|
||||||
# There is also a:
|
# There is also a:
|
||||||
# (no author) <(no author)@c046a42c-6fe2-441c-8c8c-71466251a162>
|
# (no author) <(no author)@c046a42c-6fe2-441c-8c8c-71466251a162>
|
||||||
# for the cvs2svn initialization commit e63c3dc74bf.
|
# 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
|
# Also list preferred name forms where people have changed their
|
||||||
# git author config
|
# git author config
|
||||||
Daniel P. Berrangé <berrange@redhat.com>
|
Daniel P. Berrangé <berrange@redhat.com>
|
||||||
|
|
3
configure
vendored
3
configure
vendored
|
@ -1497,16 +1497,19 @@ Advanced options (experts only):
|
||||||
--install=INSTALL use specified install [$install]
|
--install=INSTALL use specified install [$install]
|
||||||
--python=PYTHON use specified python [$python]
|
--python=PYTHON use specified python [$python]
|
||||||
--smbd=SMBD use specified smbd [$smbd]
|
--smbd=SMBD use specified smbd [$smbd]
|
||||||
|
--with-git=GIT use specified git [$git]
|
||||||
--static enable static build [$static]
|
--static enable static build [$static]
|
||||||
--mandir=PATH install man pages in PATH
|
--mandir=PATH install man pages in PATH
|
||||||
--datadir=PATH install firmware in PATH$confsuffix
|
--datadir=PATH install firmware in PATH$confsuffix
|
||||||
--docdir=PATH install documentation in PATH$confsuffix
|
--docdir=PATH install documentation in PATH$confsuffix
|
||||||
--bindir=PATH install binaries in PATH
|
--bindir=PATH install binaries in PATH
|
||||||
--libdir=PATH install libraries in PATH
|
--libdir=PATH install libraries in PATH
|
||||||
|
--libexecdir=PATH install helper binaries in PATH
|
||||||
--sysconfdir=PATH install config in PATH$confsuffix
|
--sysconfdir=PATH install config in PATH$confsuffix
|
||||||
--localstatedir=PATH install local state in PATH (set at runtime on win32)
|
--localstatedir=PATH install local state in PATH (set at runtime on win32)
|
||||||
--firmwarepath=PATH search PATH for firmware files
|
--firmwarepath=PATH search PATH for firmware files
|
||||||
--with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]
|
--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-debug enable common debug build options
|
||||||
--enable-sanitizers enable default sanitizers
|
--enable-sanitizers enable default sanitizers
|
||||||
--disable-strip disable stripping binaries
|
--disable-strip disable stripping binaries
|
||||||
|
|
4
dump.c
4
dump.c
|
@ -814,7 +814,7 @@ static void create_header32(DumpState *s, Error **errp)
|
||||||
size = sizeof(DiskDumpHeader32);
|
size = sizeof(DiskDumpHeader32);
|
||||||
dh = g_malloc0(size);
|
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);
|
dh->header_version = cpu_to_dump32(s, 6);
|
||||||
block_size = s->dump_info.page_size;
|
block_size = s->dump_info.page_size;
|
||||||
dh->block_size = cpu_to_dump32(s, block_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);
|
size = sizeof(DiskDumpHeader64);
|
||||||
dh = g_malloc0(size);
|
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);
|
dh->header_version = cpu_to_dump32(s, 6);
|
||||||
block_size = s->dump_info.page_size;
|
block_size = s->dump_info.page_size;
|
||||||
dh->block_size = cpu_to_dump32(s, block_size);
|
dh->block_size = cpu_to_dump32(s, block_size);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
#include "hw/isa/isa.h"
|
#include "hw/isa/isa.h"
|
||||||
#include "hw/dma/i8257.h"
|
#include "hw/dma/i8257.h"
|
||||||
|
|
||||||
|
@ -118,13 +119,19 @@ static const MemoryRegionPortio i82374_portio_list[] = {
|
||||||
static void i82374_realize(DeviceState *dev, Error **errp)
|
static void i82374_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
I82374State *s = I82374(dev);
|
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,
|
portio_list_init(&s->port_list, OBJECT(s), i82374_portio_list, s,
|
||||||
"i82374");
|
"i82374");
|
||||||
portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj),
|
portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj),
|
||||||
s->iobase);
|
s->iobase);
|
||||||
|
|
||||||
i8257_dma_init(isa_bus_from_device(ISA_DEVICE(dev)), true);
|
|
||||||
memset(s->commands, 0, sizeof(s->commands));
|
memset(s->commands, 0, sizeof(s->commands));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
* When migrating, read the clock just before migration,
|
||||||
* so that the guest clock counts during the events
|
* so that the guest clock counts during the events
|
||||||
|
@ -268,6 +281,7 @@ static const VMStateDescription kvmclock_vmsd = {
|
||||||
.name = "kvmclock",
|
.name = "kvmclock",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
|
.pre_load = kvmclock_pre_load,
|
||||||
.pre_save = kvmclock_pre_save,
|
.pre_save = kvmclock_pre_save,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT64(clock, KVMClockState),
|
VMSTATE_UINT64(clock, KVMClockState),
|
||||||
|
|
|
@ -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
|
/* min_io_size and opt_io_size can't be greater than
|
||||||
* max_io_sectors */
|
* max_io_sectors */
|
||||||
min_io_size =
|
if (min_io_size) {
|
||||||
MIN_NON_ZERO(min_io_size, max_io_sectors);
|
min_io_size = MIN(min_io_size, max_io_sectors);
|
||||||
opt_io_size =
|
}
|
||||||
MIN_NON_ZERO(opt_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 */
|
/* required VPD size with unmap support */
|
||||||
buflen = 0x40;
|
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
|
* block characteristics VPD page by default. Not all of SPC-3
|
||||||
* is actually implemented, but we're good enough.
|
* 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 */
|
outbuf[3] = 2 | 0x10; /* Format 2, HiSup */
|
||||||
|
|
||||||
if (buflen > 36) {
|
if (buflen > 36) {
|
||||||
|
@ -2191,7 +2193,11 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
|
||||||
case READ_12:
|
case READ_12:
|
||||||
case READ_16:
|
case READ_16:
|
||||||
DPRINTF("Read (sector %" PRId64 ", count %u)\n", r->req.cmd.lba, len);
|
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;
|
goto illegal_request;
|
||||||
}
|
}
|
||||||
if (!check_lba_range(s, r->req.cmd.lba, len)) {
|
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;
|
* As far as DMA is concerned, we can treat it the same as a write;
|
||||||
* scsi_block_do_sgio will send VERIFY commands.
|
* 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;
|
goto illegal_request;
|
||||||
}
|
}
|
||||||
if (!check_lba_range(s, r->req.cmd.lba, len)) {
|
if (!check_lba_range(s, r->req.cmd.lba, len)) {
|
||||||
|
@ -2268,6 +2274,8 @@ static void scsi_disk_reset(DeviceState *dev)
|
||||||
/* reset tray statuses */
|
/* reset tray statuses */
|
||||||
s->tray_locked = 0;
|
s->tray_locked = 0;
|
||||||
s->tray_open = 0;
|
s->tray_open = 0;
|
||||||
|
|
||||||
|
s->qdev.scsi_version = s->qdev.default_scsi_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scsi_disk_resize_cb(void *opaque)
|
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)
|
static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
|
||||||
{
|
{
|
||||||
SCSIBlockReq *r = (SCSIBlockReq *)req;
|
SCSIBlockReq *r = (SCSIBlockReq *)req;
|
||||||
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
|
||||||
|
|
||||||
r->cmd = req->cmd.buf[0];
|
r->cmd = req->cmd.buf[0];
|
||||||
switch (r->cmd >> 5) {
|
switch (r->cmd >> 5) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -2837,8 +2847,11 @@ static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->cdb1 & 0xe0) {
|
/* Protection information is not supported. For SCSI versions 2 and
|
||||||
/* Protection information is not supported. */
|
* 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));
|
scsi_check_condition(&r->req, SENSE_CODE(INVALID_FIELD));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2950,6 +2963,8 @@ static Property scsi_hd_properties[] = {
|
||||||
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
|
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
|
||||||
DEFAULT_MAX_IO_SIZE),
|
DEFAULT_MAX_IO_SIZE),
|
||||||
DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
|
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_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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_UINT16("port_index", SCSIDiskState, port_index, 0),
|
||||||
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
|
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
|
||||||
DEFAULT_MAX_IO_SIZE),
|
DEFAULT_MAX_IO_SIZE),
|
||||||
|
DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
|
||||||
|
5),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3023,6 +3040,8 @@ static Property scsi_block_properties[] = {
|
||||||
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk),
|
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk),
|
||||||
DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false),
|
DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false),
|
||||||
DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0),
|
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(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3063,6 +3082,8 @@ static Property scsi_disk_properties[] = {
|
||||||
DEFAULT_MAX_UNMAP_SIZE),
|
DEFAULT_MAX_UNMAP_SIZE),
|
||||||
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
|
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
|
||||||
DEFAULT_MAX_IO_SIZE),
|
DEFAULT_MAX_IO_SIZE),
|
||||||
|
DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version,
|
||||||
|
5),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -194,17 +194,40 @@ static void scsi_read_complete(void * opaque, int ret)
|
||||||
r->buf[3] |= 0x80;
|
r->buf[3] |= 0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s->type == TYPE_DISK &&
|
if (r->req.cmd.buf[0] == INQUIRY) {
|
||||||
r->req.cmd.buf[0] == INQUIRY &&
|
/*
|
||||||
r->req.cmd.buf[2] == 0xb0) {
|
* EVPD set to zero returns the standard INQUIRY data.
|
||||||
uint32_t max_transfer =
|
*
|
||||||
blk_get_max_transfer(s->conf.blk) / s->blocksize;
|
* 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);
|
assert(max_transfer);
|
||||||
stl_be_p(&r->buf[8], max_transfer);
|
stl_be_p(&r->buf[8], max_transfer);
|
||||||
/* Also take care of the opt xfer len. */
|
/* Also take care of the opt xfer len. */
|
||||||
stl_be_p(&r->buf[12],
|
stl_be_p(&r->buf[12],
|
||||||
MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
|
MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
scsi_req_data(&r->req, len);
|
scsi_req_data(&r->req, len);
|
||||||
scsi_req_unref(&r->req);
|
scsi_req_unref(&r->req);
|
||||||
|
@ -474,6 +497,7 @@ static void scsi_generic_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
SCSIDevice *s = SCSI_DEVICE(dev);
|
SCSIDevice *s = SCSI_DEVICE(dev);
|
||||||
|
|
||||||
|
s->scsi_version = s->default_scsi_version;
|
||||||
scsi_device_purge_requests(s, SENSE_CODE(RESET));
|
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);
|
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);
|
scsi_generic_read_device_identification(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1228,7 +1228,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
||||||
if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
|
if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
|
||||||
error_setg(&hdev->migration_blocker,
|
error_setg(&hdev->migration_blocker,
|
||||||
"Migration disabled: vhost lacks VHOST_F_LOG_ALL feature.");
|
"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,
|
error_setg(&hdev->migration_blocker,
|
||||||
"Migration disabled: failed to allocate shared memory");
|
"Migration disabled: failed to allocate shared memory");
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,8 @@ struct SCSIDevice
|
||||||
uint64_t max_lba;
|
uint64_t max_lba;
|
||||||
uint64_t wwn;
|
uint64_t wwn;
|
||||||
uint64_t port_wwn;
|
uint64_t port_wwn;
|
||||||
|
int scsi_version;
|
||||||
|
int default_scsi_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const VMStateDescription vmstate_scsi_device;
|
extern const VMStateDescription vmstate_scsi_device;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
int qemu_memfd_create(const char *name, size_t size, bool hugetlb,
|
int qemu_memfd_create(const char *name, size_t size, bool hugetlb,
|
||||||
uint64_t hugetlbsize, unsigned int seals, Error **errp);
|
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,
|
void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
|
||||||
int *fd, Error **errp);
|
int *fd, Error **errp);
|
||||||
void qemu_memfd_free(void *ptr, size_t size, int fd);
|
void qemu_memfd_free(void *ptr, size_t size, int fd);
|
||||||
|
|
|
@ -2356,6 +2356,18 @@ sub process {
|
||||||
# check for missing bracing around if etc
|
# check for missing bracing around if etc
|
||||||
if ($line =~ /(^.*)\b(?:if|while|for)\b/ &&
|
if ($line =~ /(^.*)\b(?:if|while|for)\b/ &&
|
||||||
$line !~ /\#\s*if/) {
|
$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) =
|
my ($level, $endln, @chunks) =
|
||||||
ctx_statement_full($linenr, $realcnt, 1);
|
ctx_statement_full($linenr, $realcnt, 1);
|
||||||
if ($dbg_adv_apw) {
|
if ($dbg_adv_apw) {
|
||||||
|
@ -2364,7 +2376,6 @@ sub process {
|
||||||
if $#chunks >= 1;
|
if $#chunks >= 1;
|
||||||
}
|
}
|
||||||
if ($#chunks >= 0 && $level == 0) {
|
if ($#chunks >= 0 && $level == 0) {
|
||||||
my $allowed = 0;
|
|
||||||
my $seen = 0;
|
my $seen = 0;
|
||||||
my $herectx = $here . "\n";
|
my $herectx = $here . "\n";
|
||||||
my $ln = $linenr - 1;
|
my $ln = $linenr - 1;
|
||||||
|
@ -2408,7 +2419,7 @@ sub process {
|
||||||
$allowed = 1;
|
$allowed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($seen != ($#chunks + 1)) {
|
if ($seen != ($#chunks + 1) && !$allowed) {
|
||||||
ERROR("braces {} are necessary for all arms of this statement\n" . $herectx);
|
ERROR("braces {} are necessary for all arms of this statement\n" . $herectx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 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"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, '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':'isa-serial', 'loglevel':logging.ERROR, 'expected':True},
|
||||||
{'exitcode':-11, 'device':'mioe3680_pci', '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},
|
{'exitcode':-11, 'device':'pcm3680_pci', 'loglevel':logging.ERROR, 'expected':True},
|
||||||
|
|
|
@ -924,6 +924,7 @@ int main(int argc, char **argv)
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
char *trace_file = NULL;
|
char *trace_file = NULL;
|
||||||
bool daemonize = false;
|
bool daemonize = false;
|
||||||
|
bool pidfile_specified = false;
|
||||||
unsigned socket_activation;
|
unsigned socket_activation;
|
||||||
|
|
||||||
struct sigaction sa_sigterm;
|
struct sigaction sa_sigterm;
|
||||||
|
@ -954,6 +955,7 @@ int main(int argc, char **argv)
|
||||||
case 'f':
|
case 'f':
|
||||||
g_free(pidfile);
|
g_free(pidfile);
|
||||||
pidfile = g_strdup(optarg);
|
pidfile = g_strdup(optarg);
|
||||||
|
pidfile_specified = true;
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_LIBCAP
|
#ifdef CONFIG_LIBCAP
|
||||||
case 'u': {
|
case 'u': {
|
||||||
|
@ -1081,6 +1083,16 @@ int main(int argc, char **argv)
|
||||||
accept_client,
|
accept_client,
|
||||||
NULL, NULL);
|
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
|
#ifdef CONFIG_LIBCAP
|
||||||
if (drop_privileges() < 0) {
|
if (drop_privileges() < 0) {
|
||||||
error_report("Failed to drop privileges: %s", strerror(errno));
|
error_report("Failed to drop privileges: %s", strerror(errno));
|
||||||
|
@ -1088,14 +1100,6 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (daemonize) {
|
|
||||||
if (daemon(0, 0) < 0) {
|
|
||||||
error_report("Failed to daemonize: %s", strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
write_pidfile();
|
|
||||||
}
|
|
||||||
|
|
||||||
state = RUNNING;
|
state = RUNNING;
|
||||||
do {
|
do {
|
||||||
main_loop_wait(false);
|
main_loop_wait(false);
|
||||||
|
|
|
@ -4761,6 +4761,7 @@ static Property x86_cpu_properties[] = {
|
||||||
DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
|
DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false),
|
||||||
DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
|
DEFINE_PROP_BOOL("hv-synic", X86CPU, hyperv_synic, false),
|
||||||
DEFINE_PROP_BOOL("hv-stimer", X86CPU, hyperv_stimer, 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("check", X86CPU, check_cpuid, true),
|
||||||
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
|
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
|
||||||
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
|
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
|
||||||
|
|
|
@ -1296,6 +1296,7 @@ struct X86CPU {
|
||||||
bool hyperv_runtime;
|
bool hyperv_runtime;
|
||||||
bool hyperv_synic;
|
bool hyperv_synic;
|
||||||
bool hyperv_stimer;
|
bool hyperv_stimer;
|
||||||
|
bool hyperv_frequencies;
|
||||||
bool check_cpuid;
|
bool check_cpuid;
|
||||||
bool enforce_cpuid;
|
bool enforce_cpuid;
|
||||||
bool expose_kvm;
|
bool expose_kvm;
|
||||||
|
|
|
@ -632,11 +632,6 @@ static int hyperv_handle_properties(CPUState *cs)
|
||||||
X86CPU *cpu = X86_CPU(cs);
|
X86CPU *cpu = X86_CPU(cs);
|
||||||
CPUX86State *env = &cpu->env;
|
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) {
|
if (cpu->hyperv_relaxed_timing) {
|
||||||
env->features[FEAT_HYPERV_EAX] |= HV_HYPERCALL_AVAILABLE;
|
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;
|
env->features[FEAT_HYPERV_EAX] |= HV_APIC_ACCESS_AVAILABLE;
|
||||||
}
|
}
|
||||||
if (cpu->hyperv_time) {
|
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_HYPERCALL_AVAILABLE;
|
||||||
env->features[FEAT_HYPERV_EAX] |= HV_TIME_REF_COUNT_AVAILABLE;
|
env->features[FEAT_HYPERV_EAX] |= HV_TIME_REF_COUNT_AVAILABLE;
|
||||||
env->features[FEAT_HYPERV_EAX] |= HV_REFERENCE_TSC_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_GUEST_CRASH_MSR_AVAILABLE;
|
||||||
}
|
}
|
||||||
env->features[FEAT_HYPERV_EDX] |= HV_CPU_DYNAMIC_PARTITIONING_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;
|
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;
|
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;
|
env->features[FEAT_HYPERV_EAX] |= HV_VP_RUNTIME_AVAILABLE;
|
||||||
}
|
}
|
||||||
if (cpu->hyperv_synic) {
|
if (cpu->hyperv_synic) {
|
||||||
|
|
|
@ -3802,7 +3802,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||||
}
|
}
|
||||||
ot = mo_64_32(s->dflag);
|
ot = mo_64_32(s->dflag);
|
||||||
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
|
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_mov_reg_v(ot, reg, cpu_T0);
|
||||||
gen_op_update1_cc();
|
gen_op_update1_cc();
|
||||||
set_cc_op(s, CC_OP_LOGICB + ot);
|
set_cc_op(s, CC_OP_LOGICB + ot);
|
||||||
|
@ -4563,9 +4563,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||||
#endif
|
#endif
|
||||||
rex_r = (~vex2 >> 4) & 8;
|
rex_r = (~vex2 >> 4) & 8;
|
||||||
if (b == 0xc5) {
|
if (b == 0xc5) {
|
||||||
|
/* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
|
||||||
vex3 = vex2;
|
vex3 = vex2;
|
||||||
b = x86_ldub_code(env, s);
|
b = x86_ldub_code(env, s) | 0x100;
|
||||||
} else {
|
} else {
|
||||||
|
/* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
|
||||||
#ifdef TARGET_X86_64
|
#ifdef TARGET_X86_64
|
||||||
s->rex_x = (~vex2 >> 3) & 8;
|
s->rex_x = (~vex2 >> 3) & 8;
|
||||||
s->rex_b = (~vex2 >> 2) & 8;
|
s->rex_b = (~vex2 >> 2) & 8;
|
||||||
|
|
|
@ -911,12 +911,62 @@ static int whpx_vcpu_run(CPUState *cpu)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
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 WHvRunVpExitReasonNone:
|
||||||
case WHvRunVpExitReasonUnrecoverableException:
|
case WHvRunVpExitReasonUnrecoverableException:
|
||||||
case WHvRunVpExitReasonInvalidVpRegisterValue:
|
case WHvRunVpExitReasonInvalidVpRegisterValue:
|
||||||
case WHvRunVpExitReasonUnsupportedFeature:
|
case WHvRunVpExitReasonUnsupportedFeature:
|
||||||
case WHvRunVpExitReasonX64MsrAccess:
|
case WHvRunVpExitReasonX64MsrAccess:
|
||||||
case WHvRunVpExitReasonX64Cpuid:
|
|
||||||
case WHvRunVpExitReasonException:
|
case WHvRunVpExitReasonException:
|
||||||
default:
|
default:
|
||||||
error_report("WHPX: Unexpected VP exit code %d",
|
error_report("WHPX: Unexpected VP exit code %d",
|
||||||
|
@ -1272,6 +1322,33 @@ static int whpx_accel_init(MachineState *ms)
|
||||||
goto error;
|
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);
|
hr = WHvSetupPartition(whpx->partition);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
error_report("WHPX: Failed to setup partition, hr=%08lx", hr);
|
error_report("WHPX: Failed to setup partition, hr=%08lx", hr);
|
||||||
|
|
34
util/memfd.c
34
util/memfd.c
|
@ -173,7 +173,13 @@ enum {
|
||||||
MEMFD_TODO
|
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;
|
static int memfd_check = MEMFD_TODO;
|
||||||
|
|
||||||
|
@ -188,3 +194,29 @@ bool qemu_memfd_check(void)
|
||||||
|
|
||||||
return memfd_check == MEMFD_OK;
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
* Author: Paolo Bonzini <pbonzini@redhat.com>
|
* Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <qemu/osdep.h>
|
#include "qemu/osdep.h"
|
||||||
#include <qemu/sys_membarrier.h>
|
#include "qemu/sys_membarrier.h"
|
||||||
#include <qemu/error-report.h>
|
#include "qemu/error-report.h"
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX
|
#ifdef CONFIG_LINUX
|
||||||
#include <linux/membarrier.h>
|
#include <linux/membarrier.h>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue