aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-04-09 17:29:09 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-04-09 17:29:10 +0100
commit915d34c5f99b0ab91517c69f54272bfdb6ca2b32 (patch)
tree52128c9a63fcd283e1a267452ff698b3bf119610 /hw
parenta84e937649f09d372e677b3978a933f1207513a2 (diff)
parente0014d4b3a955cfd8d517674703bfa87f340290a (diff)
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>
Diffstat (limited to 'hw')
-rw-r--r--hw/dma/i82374.c9
-rw-r--r--hw/i386/kvm/clock.c14
-rw-r--r--hw/scsi/scsi-disk.c39
-rw-r--r--hw/scsi/scsi-generic.c48
-rw-r--r--hw/virtio/vhost.c2
5 files changed, 90 insertions, 22 deletions
diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c
index 83c87d92e0..892f655a7e 100644
--- a/hw/dma/i82374.c
+++ b/hw/dma/i82374.c
@@ -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));
}
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 1707434db3..7dac319403 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -242,6 +242,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
* between:
@@ -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),
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index f5ab767ab5..ded23d36ca 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -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(),
};
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 4753f8738f..381f04e339 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -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;
-
- 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])));
+ 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])));
+ }
}
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);
}
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index a21a5a2ca1..f51bf573d5 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -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");
}