diff options
Diffstat (limited to '')
| -rw-r--r-- | .mailmap | 18 | ||||
| -rwxr-xr-x | configure | 3 | ||||
| -rw-r--r-- | contrib/libvhost-user/libvhost-user.h | 1 | ||||
| -rw-r--r-- | docs/interop/vhost-user.txt | 21 | ||||
| -rw-r--r-- | dump.c | 4 | ||||
| -rw-r--r-- | gdbstub.c | 3 | ||||
| -rw-r--r-- | hw/block/vhost-user-blk.c | 4 | ||||
| -rw-r--r-- | hw/char/virtio-serial-bus.c | 7 | ||||
| -rw-r--r-- | hw/dma/i82374.c | 9 | ||||
| -rw-r--r-- | hw/i386/kvm/clock.c | 14 | ||||
| -rw-r--r-- | hw/scsi/scsi-disk.c | 39 | ||||
| -rw-r--r-- | hw/scsi/scsi-generic.c | 48 | ||||
| -rw-r--r-- | hw/virtio/vhost-user.c | 22 | ||||
| -rw-r--r-- | hw/virtio/vhost.c | 16 | ||||
| -rw-r--r-- | include/hw/scsi/scsi.h | 2 | ||||
| -rw-r--r-- | include/qemu/memfd.h | 1 | ||||
| -rw-r--r-- | include/ui/console.h | 2 | ||||
| -rwxr-xr-x | scripts/checkpatch.pl | 15 | ||||
| -rwxr-xr-x | scripts/device-crash-test | 1 | ||||
| -rw-r--r-- | scsi/qemu-pr-helper.c | 18 | ||||
| -rw-r--r-- | target/i386/cpu.c | 1 | ||||
| -rw-r--r-- | target/i386/cpu.h | 1 | ||||
| -rw-r--r-- | target/i386/kvm.c | 56 | ||||
| -rw-r--r-- | target/i386/translate.c | 6 | ||||
| -rw-r--r-- | target/i386/whpx-all.c | 79 | ||||
| -rw-r--r-- | ui/console.c | 15 | ||||
| -rw-r--r-- | ui/gtk.c | 4 | ||||
| -rw-r--r-- | ui/sdl2-gl.c | 2 | ||||
| -rw-r--r-- | ui/sdl2-input.c | 46 | ||||
| -rw-r--r-- | util/memfd.c | 34 | ||||
| -rw-r--r-- | util/sys_membarrier.c | 6 |
31 files changed, 388 insertions, 110 deletions
diff --git a/.mailmap b/.mailmap index cf689b9ec9..778a4d4e2c 100644 --- a/.mailmap +++ b/.mailmap @@ -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> diff --git a/configure b/configure index a2301dd0dc..752dd9ef32 100755 --- a/configure +++ b/configure @@ -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 diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h index 79f7a53ee8..b27075ea3b 100644 --- a/contrib/libvhost-user/libvhost-user.h +++ b/contrib/libvhost-user/libvhost-user.h @@ -50,6 +50,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6, VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7, VHOST_USER_PROTOCOL_F_PAGEFAULT = 8, + VHOST_USER_PROTOCOL_F_CONFIG = 9, VHOST_USER_PROTOCOL_F_MAX }; diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt index c058c407df..534caab18a 100644 --- a/docs/interop/vhost-user.txt +++ b/docs/interop/vhost-user.txt @@ -379,6 +379,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6 #define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7 #define VHOST_USER_PROTOCOL_F_PAGEFAULT 8 +#define VHOST_USER_PROTOCOL_F_CONFIG 9 Master message types -------------------- @@ -664,7 +665,8 @@ Master message types Master payload: virtio device config space Slave payload: virtio device config space - Submitted by the vhost-user master to fetch the contents of the virtio + When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, this message is + submitted by the vhost-user master to fetch the contents of the virtio device configuration space, vhost-user slave's payload size MUST match master's request, vhost-user slave uses zero length of payload to indicate an error to vhost-user master. The vhost-user master may @@ -677,7 +679,8 @@ Master message types Master payload: virtio device config space Slave payload: N/A - Submitted by the vhost-user master when the Guest changes the virtio + When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, this message is + submitted by the vhost-user master when the Guest changes the virtio device configuration space and also can be used for live migration on the destination host. The vhost-user slave must check the flags field, and slaves MUST NOT accept SET_CONFIG for read-only @@ -766,13 +769,13 @@ Slave message types Slave payload: N/A Master payload: N/A - Vhost-user slave sends such messages to notify that the virtio device's - configuration space has changed, for those host devices which can support - such feature, host driver can send VHOST_USER_GET_CONFIG message to slave - to get the latest content. If VHOST_USER_PROTOCOL_F_REPLY_ACK is - negotiated, and slave set the VHOST_USER_NEED_REPLY flag, master must - respond with zero when operation is successfully completed, or non-zero - otherwise. + When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, vhost-user slave sends + such messages to notify that the virtio device's configuration space has + changed, for those host devices which can support such feature, host + driver can send VHOST_USER_GET_CONFIG message to slave to get the latest + content. If VHOST_USER_PROTOCOL_F_REPLY_ACK is negotiated, and slave set + the VHOST_USER_NEED_REPLY flag, master must respond with zero when + operation is successfully completed, or non-zero otherwise. VHOST_USER_PROTOCOL_F_REPLY_ACK: ------------------------------- diff --git a/dump.c b/dump.c index 669f715274..b54cd42b21 100644 --- a/dump.c +++ b/dump.c @@ -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); diff --git a/gdbstub.c b/gdbstub.c index a76b2fa481..3c3807358c 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -507,6 +507,7 @@ static inline int tohex(int v) return v - 10 + 'a'; } +/* writes 2*len+1 bytes in buf */ static void memtohex(char *buf, const uint8_t *mem, int len) { int i, c; @@ -999,8 +1000,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) const char *p; uint32_t thread; int ch, reg_size, type, res; - char buf[MAX_PACKET_LENGTH]; uint8_t mem_buf[MAX_PACKET_LENGTH]; + char buf[sizeof(mem_buf) + 1 /* trailing NUL */]; uint8_t *registers; target_ulong addr, len; diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index f840f07dfe..262baca432 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -259,6 +259,8 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) s->dev.vq_index = 0; s->dev.backend_features = 0; + vhost_dev_set_config_notifier(&s->dev, &blk_ops); + ret = vhost_dev_init(&s->dev, &s->chardev, VHOST_BACKEND_TYPE_USER, 0); if (ret < 0) { error_setg(errp, "vhost-user-blk: vhost initialization failed: %s", @@ -277,8 +279,6 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) s->blkcfg.num_queues = s->num_queues; } - vhost_dev_set_config_notifier(&s->dev, &blk_ops); - return; vhost_err: diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 9470bd7be7..d2dd8ab502 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -580,13 +580,16 @@ static void set_config(VirtIODevice *vdev, const uint8_t *config_data) VirtIOSerial *vser = VIRTIO_SERIAL(vdev); struct virtio_console_config *config = (struct virtio_console_config *)config_data; - uint8_t emerg_wr_lo = le32_to_cpu(config->emerg_wr); VirtIOSerialPort *port = find_first_connected_console(vser); VirtIOSerialPortClass *vsc; + uint8_t emerg_wr_lo; - if (!config->emerg_wr) { + if (!virtio_has_feature(vser->host_features, + VIRTIO_CONSOLE_F_EMERG_WRITE) || !config->emerg_wr) { return; } + + emerg_wr_lo = le32_to_cpu(config->emerg_wr); /* Make sure we don't misdetect an emergency write when the guest * does a short config write after an emergency write. */ config->emerg_wr = 0; 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-user.c b/hw/virtio/vhost-user.c index 44aea5c0a8..38da8692bb 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -46,6 +46,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6, VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7, VHOST_USER_PROTOCOL_F_PAGEFAULT = 8, + VHOST_USER_PROTOCOL_F_CONFIG = 9, VHOST_USER_PROTOCOL_F_MAX }; @@ -1211,6 +1212,17 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque) dev->protocol_features = protocol_features & VHOST_USER_PROTOCOL_FEATURE_MASK; + + if (!dev->config_ops || !dev->config_ops->vhost_dev_config_notifier) { + /* Don't acknowledge CONFIG feature if device doesn't support it */ + dev->protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_CONFIG); + } else if (!(protocol_features & + (1ULL << VHOST_USER_PROTOCOL_F_CONFIG))) { + error_report("Device expects VHOST_USER_PROTOCOL_F_CONFIG " + "but backend does not support it."); + return -1; + } + err = vhost_user_set_protocol_features(dev, dev->protocol_features); if (err < 0) { return err; @@ -1405,6 +1417,11 @@ static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config, .hdr.size = VHOST_USER_CONFIG_HDR_SIZE + config_len, }; + if (!virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_CONFIG)) { + return -1; + } + if (config_len > VHOST_USER_MAX_CONFIG_SIZE) { return -1; } @@ -1448,6 +1465,11 @@ static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data, .hdr.size = VHOST_USER_CONFIG_HDR_SIZE + size, }; + if (!virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_CONFIG)) { + return -1; + } + if (reply_supported) { msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK; } diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 250f886acb..f51bf573d5 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -595,10 +595,15 @@ static void vhost_region_add_section(struct vhost_dev *dev, prev_sec->offset_within_address_space, prev_sec->offset_within_region); } else { - error_report("%s: Overlapping but not coherent sections " - "at %"PRIx64, - __func__, mrs_gpa); - return; + /* adjoining regions are fine, but overlapping ones with + * different blocks/offsets shouldn't happen + */ + if (mrs_gpa != prev_gpa_end + 1) { + error_report("%s: Overlapping but not coherent sections " + "at %"PRIx64, + __func__, mrs_gpa); + return; + } } } } @@ -1223,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"); } @@ -1451,7 +1456,6 @@ int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data, void vhost_dev_set_config_notifier(struct vhost_dev *hdev, const VhostDevConfigOps *ops) { - assert(hdev->vhost_ops); hdev->config_ops = ops; } diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 7ecaddac9d..e35137ea78 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -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; diff --git a/include/qemu/memfd.h b/include/qemu/memfd.h index de10198ed6..49e79634da 100644 --- a/include/qemu/memfd.h +++ b/include/qemu/memfd.h @@ -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); diff --git a/include/ui/console.h b/include/ui/console.h index 6d2c052068..37a8d68d29 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -99,7 +99,7 @@ void hmp_mouse_set(Monitor *mon, const QDict *qdict); #define QEMU_KEY_CTRL_PAGEDOWN 0xe407 void kbd_put_keysym_console(QemuConsole *s, int keysym); -bool kbd_put_qcode_console(QemuConsole *s, int qcode); +bool kbd_put_qcode_console(QemuConsole *s, int qcode, bool ctrl); void kbd_put_string_console(QemuConsole *s, const char *str, int len); void kbd_put_keysym(int keysym); diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 57daae05ea..d52207a3cc 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -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); } } diff --git a/scripts/device-crash-test b/scripts/device-crash-test index 24c7bf5a16..5d17dc68dd 100755 --- a/scripts/device-crash-test +++ b/scripts/device-crash-test @@ -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}, diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c index 21e1b8ea60..d0f83176e1 100644 --- a/scsi/qemu-pr-helper.c +++ b/scsi/qemu-pr-helper.c @@ -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,20 +1083,22 @@ int main(int argc, char **argv) accept_client, NULL, NULL); -#ifdef CONFIG_LIBCAP - if (drop_privileges() < 0) { - error_report("Failed to drop privileges: %s", strerror(errno)); - exit(EXIT_FAILURE); - } -#endif - 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)); + exit(EXIT_FAILURE); } +#endif state = RUNNING; do { diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 555ae79d29..1a6b082b6f 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -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), diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 78db1b833a..1b219fafc4 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -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; diff --git a/target/i386/kvm.c b/target/i386/kvm.c index d23fff12f5..6c49954e68 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -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_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 && has_msr_hv_crash) { + 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) { diff --git a/target/i386/translate.c b/target/i386/translate.c index 0135415d92..c9ed8dc709 100644 --- a/target/i386/translate.c +++ b/target/i386/translate.c @@ -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; diff --git a/target/i386/whpx-all.c b/target/i386/whpx-all.c index bf33d320bf..58435178a4 100644 --- a/target/i386/whpx-all.c +++ b/target/i386/whpx-all.c @@ -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); diff --git a/ui/console.c b/ui/console.c index 530a491987..3fb2f4e09f 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1191,11 +1191,22 @@ static const int qcode_to_keysym[Q_KEY_CODE__MAX] = { [Q_KEY_CODE_BACKSPACE] = QEMU_KEY_BACKSPACE, }; -bool kbd_put_qcode_console(QemuConsole *s, int qcode) +static const int ctrl_qcode_to_keysym[Q_KEY_CODE__MAX] = { + [Q_KEY_CODE_UP] = QEMU_KEY_CTRL_UP, + [Q_KEY_CODE_DOWN] = QEMU_KEY_CTRL_DOWN, + [Q_KEY_CODE_RIGHT] = QEMU_KEY_CTRL_RIGHT, + [Q_KEY_CODE_LEFT] = QEMU_KEY_CTRL_LEFT, + [Q_KEY_CODE_HOME] = QEMU_KEY_CTRL_HOME, + [Q_KEY_CODE_END] = QEMU_KEY_CTRL_END, + [Q_KEY_CODE_PGUP] = QEMU_KEY_CTRL_PAGEUP, + [Q_KEY_CODE_PGDN] = QEMU_KEY_CTRL_PAGEDOWN, +}; + +bool kbd_put_qcode_console(QemuConsole *s, int qcode, bool ctrl) { int keysym; - keysym = qcode_to_keysym[qcode]; + keysym = ctrl ? ctrl_qcode_to_keysym[qcode] : qcode_to_keysym[qcode]; if (keysym == 0) { return false; } diff --git a/ui/gtk.c b/ui/gtk.c index ef5bc42094..e98ac4d2fc 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -1197,12 +1197,12 @@ static gboolean gd_text_key_down(GtkWidget *widget, QemuConsole *con = vc->gfx.dcl.con; if (key->keyval == GDK_KEY_Delete) { - kbd_put_qcode_console(con, Q_KEY_CODE_DELETE); + kbd_put_qcode_console(con, Q_KEY_CODE_DELETE, false); } else if (key->length) { kbd_put_string_console(con, key->string, key->length); } else { int qcode = gd_map_keycode(key->hardware_keycode); - kbd_put_qcode_console(con, qcode); + kbd_put_qcode_console(con, qcode, false); } return TRUE; } diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c index 5e1073a084..c3683e6b65 100644 --- a/ui/sdl2-gl.c +++ b/ui/sdl2-gl.c @@ -32,8 +32,6 @@ #include "ui/sdl2.h" #include "sysemu/sysemu.h" -#include <epoxy/gl.h> - static void sdl2_set_scanout_mode(struct sdl2_console *scon, bool scanout) { if (scon->scanout_mode == scanout) { diff --git a/ui/sdl2-input.c b/ui/sdl2-input.c index 605d781971..1378b63dd9 100644 --- a/ui/sdl2-input.c +++ b/ui/sdl2-input.c @@ -60,32 +60,8 @@ void sdl2_process_key(struct sdl2_console *scon, qcode = qemu_input_map_usb_to_qcode[ev->keysym.scancode]; - if (!qemu_console_is_graphic(con)) { - if (ev->type == SDL_KEYDOWN) { - switch (ev->keysym.scancode) { - case SDL_SCANCODE_RETURN: - kbd_put_keysym_console(con, '\n'); - break; - case SDL_SCANCODE_BACKSPACE: - kbd_put_keysym_console(con, QEMU_KEY_BACKSPACE); - break; - default: - kbd_put_qcode_console(con, qcode); - break; - } - } - return; - } - + /* modifier state tracking */ switch (ev->keysym.scancode) { -#if 0 - case SDL_SCANCODE_NUMLOCKCLEAR: - case SDL_SCANCODE_CAPSLOCK: - /* SDL does not send the key up event, so we generate it */ - qemu_input_event_send_key_qcode(con, qcode, true); - qemu_input_event_send_key_qcode(con, qcode, false); - return; -#endif case SDL_SCANCODE_LCTRL: case SDL_SCANCODE_LSHIFT: case SDL_SCANCODE_LALT: @@ -99,8 +75,26 @@ void sdl2_process_key(struct sdl2_console *scon, } else { modifiers_state[ev->keysym.scancode] = 1; } - /* fall though */ + break; default: + /* nothing */ + break; + } + + if (!qemu_console_is_graphic(con)) { + bool ctrl = (modifiers_state[SDL_SCANCODE_LCTRL] || + modifiers_state[SDL_SCANCODE_RCTRL]); + if (ev->type == SDL_KEYDOWN) { + switch (ev->keysym.scancode) { + case SDL_SCANCODE_RETURN: + kbd_put_keysym_console(con, '\n'); + break; + default: + kbd_put_qcode_console(con, qcode, ctrl); + break; + } + } + } else { qemu_input_event_send_key_qcode(con, qcode, ev->type == SDL_KEYDOWN); } diff --git a/util/memfd.c b/util/memfd.c index 07d579ea7d..b3ecbac19e 100644 --- a/util/memfd.c +++ b/util/memfd.c @@ -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 +} diff --git a/util/sys_membarrier.c b/util/sys_membarrier.c index 8dcb53e63e..1362c0c4c5 100644 --- a/util/sys_membarrier.c +++ b/util/sys_membarrier.c @@ -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> |