diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-06-16 17:58:45 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-06-16 17:58:45 +0100 |
commit | 585fcd4b11070b3220685fc54ecca1991cdeb161 (patch) | |
tree | eac78393a02a9a0cda3571ab7bce3000e095c978 | |
parent | dc278c58fa02e5fb796dbacf02c8dde32f697015 (diff) | |
parent | 0544edd88a6acea81aefe22fd0cd9a85d1eef093 (diff) | |
download | qemu-585fcd4b11070b3220685fc54ecca1991cdeb161.zip qemu-585fcd4b11070b3220685fc54ecca1991cdeb161.tar.gz qemu-585fcd4b11070b3220685fc54ecca1991cdeb161.tar.bz2 |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* KVM startup speedup (Chao Peng)
* configure fixes and cleanups (David, Thomas)
* ctags fix (Sergey)
* NBD cleanups (Peter, Eric)
* "-L help" command line option (Richard)
* More esp.c bugfixes (me, Prasad)
* KVM_CAP_MAX_VCPU_ID support (Greg)
# gpg: Signature made Thu 16 Jun 2016 17:39:10 BST
# gpg: using RSA key 0xBFFBD25F78C7AE83
# 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: (29 commits)
vl: smp_parse: cleanups
scsi: esp: make cmdbuf big enough for maximum CDB size
scsi: esp: clean up handle_ti/esp_do_dma if s->do_cmd
scsi: esp: respect FIFO invariant after message phase
scsi: esp: check buffer length before reading scsi command
nbd: Avoid magic number for NBD max name size
nbd: Detect servers that send unexpected error values
nbd: Clean up ioctl handling of qemu-nbd -c
nbd: Group all Linux-specific ioctl code in one place
nbd: Reject unknown request flags
nbd: Improve server handling of bogus commands
nbd: Quit server after any write error
nbd: More debug typo fixes, use correct formats
nbd: Use BDRV_REQ_FUA for better FUA where supported
vl.c: Add '-L help' which lists data dirs.
KVM: use KVM_CAP_MAX_VCPU_ID
scsi-disk: Use (unsigned long) typecasts when using "%lu" format string
target-i386: kvm: cache KVM_GET_SUPPORTED_CPUID data
nbd: simplify the nbd_request and nbd_reply structs
nbd: Don't use cpu_to_*w() functions
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
77 files changed, 273 insertions, 291 deletions
@@ -498,12 +498,12 @@ test speed: all .PHONY: ctags ctags: - rm -f $@ + rm -f tags find "$(SRC_PATH)" -name '*.[hc]' -exec ctags --append {} + .PHONY: TAGS TAGS: - rm -f $@ + rm -f TAGS find "$(SRC_PATH)" -name '*.[hc]' -exec etags --append {} + cscope: diff --git a/audio/ossaudio.c b/audio/ossaudio.c index a0d9cda..0edd7ea 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -22,7 +22,6 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" -#include <sys/mman.h> #include <sys/ioctl.h> #include <sys/soundcard.h> #include "qemu-common.h" diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index 208a060..580631c 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -24,11 +24,6 @@ /* Needed for CONFIG_MADVISE */ #include "qemu/osdep.h" - -#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE) -#include <sys/mman.h> -#endif - #include "block/block_int.h" #include "qemu-common.h" #include "qcow2.h" diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index 898ee05..41a1309 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -1,7 +1,6 @@ /* This is the Linux kernel elf-loading code, ported into user space */ #include "qemu/osdep.h" -#include <sys/mman.h> #include "qemu.h" #include "disas/disas.h" diff --git a/bsd-user/main.c b/bsd-user/main.c index 9f592be..abe9a26 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -18,7 +18,6 @@ */ #include "qemu/osdep.h" #include <machine/trap.h> -#include <sys/mman.h> #include "qemu.h" #include "qemu/path.h" diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c index 6ab5334..610f91b 100644 --- a/bsd-user/mmap.c +++ b/bsd-user/mmap.c @@ -17,7 +17,6 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" -#include <sys/mman.h> #include "qemu.h" #include "qemu-common.h" diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index 47cf865..a9fe869 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "qemu/cutils.h" #include "qemu/path.h" -#include <sys/mman.h> #include <sys/syscall.h> #include <sys/param.h> #include <sys/sysctl.h> @@ -270,7 +270,6 @@ aix="no" blobs="yes" pkgversion="" pie="" -zero_malloc="" qom_cast_debug="yes" trace_backends="log" trace_file="trace" @@ -1389,11 +1388,9 @@ fi # Consult white-list to determine whether to enable werror # by default. Only enable by default for git builds -z_version=$(cut -f3 -d. $source_path/VERSION) - if test -z "$werror" ; then if test -d "$source_path/.git" -a \ - "$linux" = "yes" ; then + \( "$linux" = "yes" -o "$mingw32" = "yes" \) ; then werror="yes" else werror="no" @@ -1782,13 +1779,20 @@ fi # avx2 optimization requirement check cat > $TMPC << EOF -static void bar(void) {} +#pragma GCC push_options +#pragma GCC target("avx2") +#include <cpuid.h> +#include <immintrin.h> + +static int bar(void *a) { + return _mm256_movemask_epi8(_mm256_cmpeq_epi8(*(__m256i *)a, (__m256i){0})); +} static void *bar_ifunc(void) {return (void*) bar;} -static void foo(void) __attribute__((ifunc("bar_ifunc"))); -int main(void) { foo(); return 0; } +int foo(void *a) __attribute__((ifunc("bar_ifunc"))); +int main(int argc, char *argv[]) { return foo(argv[0]);} EOF -if compile_prog "-mavx2" "" ; then - if readelf --syms $TMPE |grep "IFUNC.*foo" >/dev/null 2>&1; then +if compile_object "" ; then + if readelf --syms $TMPO |grep "IFUNC.*foo" >/dev/null 2>&1; then avx2_opt="yes" fi fi @@ -4178,24 +4182,6 @@ if compile_prog "" "" ; then fi ########################################## -# check if we have usable SIGEV_THREAD_ID - -sigev_thread_id=no -cat > $TMPC << EOF -#include <signal.h> -int main(void) { - struct sigevent ev; - ev.sigev_notify = SIGEV_THREAD_ID; - ev._sigev_un._tid = 0; - asm volatile("" : : "g"(&ev)); - return 0; -} -EOF -if compile_prog "" "" ; then - sigev_thread_id=yes -fi - -########################################## # check if trace backend exists $python "$source_path/scripts/tracetool.py" "--backends=$trace_backends" --check-backends > /dev/null 2> /dev/null @@ -4574,16 +4560,6 @@ if test "$libnfs" != "no" ; then fi fi -# Disable zero malloc errors for official releases unless explicitly told to -# enable/disable -if test -z "$zero_malloc" ; then - if test "$z_version" = "50" ; then - zero_malloc="no" - else - zero_malloc="yes" - fi -fi - # Now we've finished running tests it's OK to add -Werror to the compiler flags if test "$werror" = "yes"; then QEMU_CFLAGS="-Werror $QEMU_CFLAGS" @@ -4862,7 +4838,6 @@ echo "preadv support $preadv" echo "fdatasync $fdatasync" echo "madvise $madvise" echo "posix_madvise $posix_madvise" -echo "sigev_thread_id $sigev_thread_id" echo "uuid support $uuid" echo "libcap-ng support $cap_ng" echo "vhost-net support $vhost_net" @@ -5277,9 +5252,6 @@ fi if test "$posix_madvise" = "yes" ; then echo "CONFIG_POSIX_MADVISE=y" >> $config_host_mak fi -if test "$sigev_thread_id" = "yes" ; then - echo "CONFIG_SIGEV_THREAD_ID=y" >> $config_host_mak -fi if test "$spice" = "yes" ; then echo "CONFIG_SPICE=y" >> $config_host_mak @@ -5342,9 +5314,6 @@ if [ "$bsd" = "yes" ] ; then echo "CONFIG_BSD=y" >> $config_host_mak fi -if test "$zero_malloc" = "yes" ; then - echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak -fi if test "$localtime_r" = "yes" ; then echo "CONFIG_LOCALTIME_R=y" >> $config_host_mak fi diff --git a/contrib/ivshmem-server/ivshmem-server.c b/contrib/ivshmem-server/ivshmem-server.c index bf4ee0b..e2f295b 100644 --- a/contrib/ivshmem-server/ivshmem-server.c +++ b/contrib/ivshmem-server/ivshmem-server.c @@ -10,7 +10,6 @@ #include "qemu/host-utils.h" #include "qemu/sockets.h" -#include <sys/mman.h> #include <sys/socket.h> #include <sys/un.h> @@ -19,7 +19,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" #ifndef _WIN32 -#include <sys/mman.h> #endif #include "qemu/cutils.h" diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index cf57814..90aca73 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -21,7 +21,6 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> -#include <sys/mman.h> #include <sys/uio.h> #include "hw/hw.h" diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index cbf1dcc..83108b0 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -22,7 +22,6 @@ #include "qemu/osdep.h" #include <sys/select.h> #include <termios.h> -#include <sys/mman.h> #include "hw/hw.h" #include "sysemu/char.h" diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 570b097..46b7d5e 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -25,7 +25,6 @@ */ #include "qemu/osdep.h" -#include <sys/mman.h> #include "hw/hw.h" #include "ui/console.h" diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index db2cbd2..dd9e73b 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -22,7 +22,6 @@ */ #include "qemu/osdep.h" #include "qapi/error.h" -#include <sys/mman.h> #include "hw/hw.h" #include "hw/i386/pc.h" #include "qemu/error-report.h" diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index 90be9f7..c4dde3a 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -36,8 +36,6 @@ #include "hw/misc/ivshmem.h" -#include <sys/mman.h> - #define PCI_VENDOR_ID_IVSHMEM PCI_VENDOR_ID_REDHAT_QUMRANET #define PCI_DEVICE_ID_IVSHMEM 0x1110 diff --git a/hw/misc/pc-testdev.c b/hw/misc/pc-testdev.c index 086893d..b81d820 100644 --- a/hw/misc/pc-testdev.c +++ b/hw/misc/pc-testdev.c @@ -36,9 +36,6 @@ */ #include "qemu/osdep.h" -#if defined(CONFIG_POSIX) -#include <sys/mman.h> -#endif #include "hw/hw.h" #include "hw/qdev.h" #include "hw/isa/isa.h" diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c index e4478be..efd43b4 100644 --- a/hw/net/net_tx_pkt.c +++ b/hw/net/net_tx_pkt.c @@ -15,6 +15,7 @@ * */ +#include "qemu/osdep.h" #include "net_tx_pkt.h" #include "net/eth.h" #include "net/checksum.h" diff --git a/hw/net/net_tx_pkt.h b/hw/net/net_tx_pkt.h index 07b9a20..212ecc6 100644 --- a/hw/net/net_tx_pkt.h +++ b/hw/net/net_tx_pkt.h @@ -18,7 +18,6 @@ #ifndef NET_TX_PKT_H #define NET_TX_PKT_H -#include "qemu/osdep.h" #include "net/eth.h" #include "exec/hwaddr.h" diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 7281730..0b4ddae 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -22,7 +22,6 @@ #include "qemu/osdep.h" #include <sys/socket.h> #include <sys/ioctl.h> -#include <sys/mman.h> #include <sys/wait.h> #include "hw/hw.h" diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index 3adb685..baa0a2c 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -98,6 +98,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen) s->dma_memory_read(s->dma_opaque, buf, dmalen); } else { dmalen = s->ti_size; + if (dmalen > TI_BUFSZ) { + return 0; + } memcpy(buf, s->ti_buf, dmalen); buf[0] = buf[2] >> 5; } @@ -219,7 +222,7 @@ static void write_response(ESPState *s) } else { s->ti_size = 2; s->ti_rptr = 0; - s->ti_wptr = 0; + s->ti_wptr = 2; s->rregs[ESP_RFLAGS] = 2; } esp_raise_irq(s); @@ -242,15 +245,12 @@ static void esp_do_dma(ESPState *s) uint32_t len; int to_device; - to_device = (s->ti_size < 0); len = s->dma_left; if (s->do_cmd) { trace_esp_do_dma(s->cmdlen, len); + assert (s->cmdlen <= sizeof(s->cmdbuf) && + len <= sizeof(s->cmdbuf) - s->cmdlen); s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); - s->ti_size = 0; - s->cmdlen = 0; - s->do_cmd = 0; - do_cmd(s, s->cmdbuf); return; } if (s->async_len == 0) { @@ -260,6 +260,7 @@ static void esp_do_dma(ESPState *s) if (len > s->async_len) { len = s->async_len; } + to_device = (s->ti_size < 0); if (to_device) { s->dma_memory_read(s->dma_opaque, s->async_buf, len); } else { @@ -315,6 +316,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len) { ESPState *s = req->hba_private; + assert(!s->do_cmd); trace_esp_transfer_data(s->dma_left, s->ti_size); s->async_len = len; s->async_buf = scsi_req_get_buf(req); @@ -345,7 +347,7 @@ static void handle_ti(ESPState *s) s->dma_counter = dmalen; if (s->do_cmd) - minlen = (dmalen < 32) ? dmalen : 32; + minlen = (dmalen < ESP_CMDBUF_SZ) ? dmalen : ESP_CMDBUF_SZ; else if (s->ti_size < 0) minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size; else @@ -355,13 +357,13 @@ static void handle_ti(ESPState *s) s->dma_left = minlen; s->rregs[ESP_RSTAT] &= ~STAT_TC; esp_do_dma(s); - } else if (s->do_cmd) { + } + if (s->do_cmd) { trace_esp_handle_ti_cmd(s->cmdlen); s->ti_size = 0; s->cmdlen = 0; s->do_cmd = 0; do_cmd(s, s->cmdbuf); - return; } } @@ -449,7 +451,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) break; case ESP_FIFO: if (s->do_cmd) { - if (s->cmdlen < TI_BUFSZ) { + if (s->cmdlen < ESP_CMDBUF_SZ) { s->cmdbuf[s->cmdlen++] = val & 0xff; } else { trace_esp_error_fifo_overrun(); diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 1881969..36f8a85 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2060,13 +2060,13 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) } break; case MODE_SELECT: - DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer); + DPRINTF("Mode Select(6) (len %lu)\n", (unsigned long)r->req.cmd.xfer); break; case MODE_SELECT_10: - DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer); + DPRINTF("Mode Select(10) (len %lu)\n", (unsigned long)r->req.cmd.xfer); break; case UNMAP: - DPRINTF("Unmap (len %lu)\n", (long)r->req.cmd.xfer); + DPRINTF("Unmap (len %lu)\n", (unsigned long)r->req.cmd.xfer); break; case VERIFY_10: case VERIFY_12: @@ -2080,7 +2080,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) case WRITE_SAME_16: DPRINTF("WRITE SAME %d (len %lu)\n", req->cmd.buf[0] == WRITE_SAME_10 ? 10 : 16, - (long)r->req.cmd.xfer); + (unsigned long)r->req.cmd.xfer); break; default: DPRINTF("Unknown SCSI command (%2.2x=%s)\n", buf[0], diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c index 8fa47ed..0fd34c6 100644 --- a/hw/usb/xen-usb.c +++ b/hw/usb/xen-usb.c @@ -21,7 +21,6 @@ #include "qemu/osdep.h" #include <libusb.h> -#include <sys/mman.h> #include "qemu-common.h" #include "qemu/config-file.h" diff --git a/hw/vfio/common.c b/hw/vfio/common.c index e51ed3a..5ff5e92 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -20,7 +20,6 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> -#include <sys/mman.h> #include <linux/vfio.h> #include "hw/vfio/vfio-common.h" diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index deab0c6..53b87b7 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -21,7 +21,6 @@ #include "qemu/osdep.h" #include <linux/vfio.h> #include <sys/ioctl.h> -#include <sys/mman.h> #include "hw/pci/msi.h" #include "hw/pci/msix.h" diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 8c15e09..557d3f9 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -27,10 +27,6 @@ #include "qapi-event.h" #include "trace.h" -#if defined(__linux__) -#include <sys/mman.h> -#endif - #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio-access.h" diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index c63f9df..e7ce724 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -23,7 +23,6 @@ */ #include "qemu/osdep.h" -#include <sys/mman.h> #include <sys/signal.h> #include "hw/hw.h" diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c index 9a16f2b..62add06 100644 --- a/hw/xen/xen_pt_msi.c +++ b/hw/xen/xen_pt_msi.c @@ -10,7 +10,6 @@ */ #include "qemu/osdep.h" -#include <sys/mman.h> #include "hw/xen/xen_backend.h" #include "xen_pt.h" diff --git a/include/block/nbd.h b/include/block/nbd.h index b86a976..df1f804 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -25,19 +25,20 @@ #include "io/channel-socket.h" #include "crypto/tlscreds.h" +/* Note: these are _NOT_ the same as the network representation of an NBD + * request and reply! + */ struct nbd_request { - uint32_t magic; - uint32_t type; uint64_t handle; uint64_t from; uint32_t len; -} QEMU_PACKED; + uint32_t type; +}; struct nbd_reply { - uint32_t magic; - uint32_t error; uint64_t handle; -} QEMU_PACKED; + uint32_t error; +}; #define NBD_FLAG_HAS_FLAGS (1 << 0) /* Flags are there */ #define NBD_FLAG_READ_ONLY (1 << 1) /* Device is read-only */ @@ -76,6 +77,12 @@ enum { /* Maximum size of a single READ/WRITE data buffer */ #define NBD_MAX_BUFFER_SIZE (32 * 1024 * 1024) +/* Maximum size of an export name. The NBD spec requires 256 and + * suggests that servers support up to 4096, but we stick to only the + * required size so that we can stack-allocate the names, and because + * going larger would require an audit of more code to make sure we + * aren't overflowing some other buffer. */ +#define NBD_MAX_NAME_SIZE 256 ssize_t nbd_wr_syncv(QIOChannel *ioc, struct iovec *iov, diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h index 6c79527..d2c4886 100644 --- a/include/hw/scsi/esp.h +++ b/include/hw/scsi/esp.h @@ -14,6 +14,7 @@ void esp_init(hwaddr espaddr, int it_shift, #define ESP_REGS 16 #define TI_BUFSZ 16 +#define ESP_CMDBUF_SZ 32 typedef struct ESPState ESPState; @@ -31,7 +32,7 @@ struct ESPState { SCSIBus bus; SCSIDevice *current_dev; SCSIRequest *current_req; - uint8_t cmdbuf[TI_BUFSZ]; + uint8_t cmdbuf[ESP_CMDBUF_SZ]; uint32_t cmdlen; uint32_t do_cmd; diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 6937694..e63da28 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -197,8 +197,6 @@ void qemu_anon_ram_free(void *ptr, size_t size); #if defined(CONFIG_MADVISE) -#include <sys/mman.h> - #define QEMU_MADV_WILLNEED MADV_WILLNEED #define QEMU_MADV_DONTNEED MADV_DONTNEED #ifdef MADV_DONTFORK diff --git a/include/qemu/qdist.h b/include/qemu/qdist.h index f30050c..54ece76 100644 --- a/include/qemu/qdist.h +++ b/include/qemu/qdist.h @@ -7,7 +7,6 @@ #ifndef QEMU_QDIST_H #define QEMU_QDIST_H -#include "qemu/osdep.h" #include "qemu-common.h" #include "qemu/bitops.h" diff --git a/include/qemu/qht.h b/include/qemu/qht.h index aec60aa..70bfc68 100644 --- a/include/qemu/qht.h +++ b/include/qemu/qht.h @@ -7,7 +7,6 @@ #ifndef QEMU_QHT_H #define QEMU_QHT_H -#include "qemu/osdep.h" #include "qemu/seqlock.h" #include "qemu/thread.h" #include "qemu/qdist.h" diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h index 07e3e5a..9c7dfdf 100644 --- a/include/sysemu/os-posix.h +++ b/include/sysemu/os-posix.h @@ -26,6 +26,7 @@ #ifndef QEMU_OS_POSIX_H #define QEMU_OS_POSIX_H +#include <sys/mman.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/tcp.h> @@ -15,7 +15,6 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> -#include <sys/mman.h> #include <linux/kvm.h> @@ -1520,10 +1519,16 @@ static int kvm_max_vcpus(KVMState *s) return (ret) ? ret : kvm_recommended_vcpus(s); } +static int kvm_max_vcpu_id(KVMState *s) +{ + int ret = kvm_check_extension(s, KVM_CAP_MAX_VCPU_ID); + return (ret) ? ret : kvm_max_vcpus(s); +} + bool kvm_vcpu_id_is_valid(int vcpu_id) { KVMState *s = KVM_STATE(current_machine->accelerator); - return vcpu_id >= 0 && vcpu_id < kvm_max_vcpus(s); + return vcpu_id >= 0 && vcpu_id < kvm_max_vcpu_id(s); } static int kvm_init(MachineState *ms) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index bb2558f..f807baf 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2,7 +2,6 @@ #include "qemu/osdep.h" #include <sys/param.h> -#include <sys/mman.h> #include <sys/resource.h> #include "qemu.h" diff --git a/linux-user/flatload.c b/linux-user/flatload.c index f9139c3..48ad1c5 100644 --- a/linux-user/flatload.c +++ b/linux-user/flatload.c @@ -34,7 +34,6 @@ /****************************************************************************/ #include "qemu/osdep.h" -#include <sys/mman.h> #include "qemu.h" #include "flat.h" diff --git a/linux-user/main.c b/linux-user/main.c index f8a8764..b9a4e0e 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -18,7 +18,6 @@ */ #include "qemu/osdep.h" #include "qemu-version.h" -#include <sys/mman.h> #include <sys/syscall.h> #include <sys/resource.h> diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 3519147..c4371d9 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -17,7 +17,6 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" -#include <sys/mman.h> #include <linux/mman.h> #include <linux/unistd.h> diff --git a/linux-user/strace.c b/linux-user/strace.c index c5980a1..4046b81 100644 --- a/linux-user/strace.c +++ b/linux-user/strace.c @@ -5,7 +5,6 @@ #include <sys/shm.h> #include <sys/select.h> #include <sys/mount.h> -#include <sys/mman.h> #include <sched.h> #include "qemu.h" diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 71ccbd9..1c17b74 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -32,7 +32,6 @@ #include <sys/personality.h> #include <sys/prctl.h> #include <sys/resource.h> -#include <sys/mman.h> #include <sys/swap.h> #include <linux/capability.h> #include <sched.h> diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c index 47250b6..abe8c60 100644 --- a/migration/postcopy-ram.c +++ b/migration/postcopy-ram.c @@ -51,7 +51,6 @@ struct PostcopyDiscardState { #if defined(__linux__) #include <poll.h> -#include <sys/mman.h> #include <sys/ioctl.h> #include <sys/syscall.h> #include <asm/types.h> /* for __u64 */ diff --git a/nbd/client.c b/nbd/client.c index 31b88f3..287487c 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -33,8 +33,10 @@ static int nbd_errno_to_system_errno(int err) return ENOMEM; case NBD_ENOSPC: return ENOSPC; - case NBD_EINVAL: default: + TRACE("Squashing unexpected error %d to EINVAL", err); + /* fallthrough */ + case NBD_EINVAL: return EINVAL; } } @@ -109,25 +111,27 @@ static int nbd_handle_reply_err(QIOChannel *ioc, uint32_t opt, uint32_t type, switch (type) { case NBD_REP_ERR_UNSUP: - TRACE("server doesn't understand request %d, attempting fallback", - opt); + TRACE("server doesn't understand request %" PRIx32 + ", attempting fallback", opt); result = 0; goto cleanup; case NBD_REP_ERR_POLICY: - error_setg(errp, "Denied by server for option %x", opt); + error_setg(errp, "Denied by server for option %" PRIx32, opt); break; case NBD_REP_ERR_INVALID: - error_setg(errp, "Invalid data length for option %x", opt); + error_setg(errp, "Invalid data length for option %" PRIx32, opt); break; case NBD_REP_ERR_TLS_REQD: - error_setg(errp, "TLS negotiation required before option %x", opt); + error_setg(errp, "TLS negotiation required before option %" PRIx32, + opt); break; default: - error_setg(errp, "Unknown error code when asking for option %x", opt); + error_setg(errp, "Unknown error code when asking for option %" PRIx32, + opt); break; } @@ -165,7 +169,7 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) } opt = be32_to_cpu(opt); if (opt != NBD_OPT_LIST) { - error_setg(errp, "Unexpected option type %x expected %x", + error_setg(errp, "Unexpected option type %" PRIx32 " expected %x", opt, NBD_OPT_LIST); return -1; } @@ -206,8 +210,8 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) error_setg(errp, "incorrect option name length"); return -1; } - if (namelen > 255) { - error_setg(errp, "export name length too long %d", namelen); + if (namelen > NBD_MAX_NAME_SIZE) { + error_setg(errp, "export name length too long %" PRIu32, namelen); return -1; } @@ -234,7 +238,7 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) g_free(buf); } } else { - error_setg(errp, "Unexpected reply type %x expected %x", + error_setg(errp, "Unexpected reply type %" PRIx32 " expected %x", type, NBD_REP_SERVER); return -1; } @@ -349,7 +353,7 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, } opt = be32_to_cpu(opt); if (opt != NBD_OPT_STARTTLS) { - error_setg(errp, "Unexpected option type %x expected %x", + error_setg(errp, "Unexpected option type %" PRIx32 " expected %x", opt, NBD_OPT_STARTTLS); return NULL; } @@ -361,7 +365,7 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, } type = be32_to_cpu(type); if (type != NBD_REP_ACK) { - error_setg(errp, "Server rejected request to start TLS %x", + error_setg(errp, "Server rejected request to start TLS %" PRIx32, type); return NULL; } @@ -373,7 +377,7 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, } length = be32_to_cpu(length); if (length != 0) { - error_setg(errp, "Start TLS response was not zero %x", + error_setg(errp, "Start TLS response was not zero %" PRIu32, length); return NULL; } @@ -384,7 +388,7 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, return NULL; } data.loop = g_main_loop_new(g_main_context_default(), FALSE); - TRACE("Starting TLS hanshake"); + TRACE("Starting TLS handshake"); qio_channel_tls_handshake(tioc, nbd_tls_handshake, &data, @@ -474,7 +478,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags, } globalflags = be16_to_cpu(globalflags); *flags = globalflags << 16; - TRACE("Global flags are %x", globalflags); + TRACE("Global flags are %" PRIx32, globalflags); if (globalflags & NBD_FLAG_FIXED_NEWSTYLE) { fixedNewStyle = true; TRACE("Server supports fixed new style"); @@ -550,7 +554,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags, } exportflags = be16_to_cpu(exportflags); *flags |= exportflags; - TRACE("Export flags are %x", exportflags); + TRACE("Export flags are %" PRIx16, exportflags); } else if (magic == NBD_CLIENT_MAGIC) { if (name) { error_setg(errp, "Server does not support export names"); @@ -572,7 +576,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint32_t *flags, error_setg(errp, "Failed to read export flags"); goto fail; } - *flags = be32_to_cpup(flags); + *flags = be32_to_cpu(*flags); } else { error_setg(errp, "Bad magic received"); goto fail; @@ -591,9 +595,15 @@ fail: #ifdef __linux__ int nbd_init(int fd, QIOChannelSocket *sioc, uint32_t flags, off_t size) { + unsigned long sectors = size / BDRV_SECTOR_SIZE; + if (size / BDRV_SECTOR_SIZE != sectors) { + LOG("Export size %lld too large for 32-bit kernel", (long long) size); + return -E2BIG; + } + TRACE("Setting NBD socket"); - if (ioctl(fd, NBD_SET_SOCK, sioc->fd) < 0) { + if (ioctl(fd, NBD_SET_SOCK, (unsigned long) sioc->fd) < 0) { int serrno = errno; LOG("Failed to set NBD socket"); return -serrno; @@ -601,21 +611,25 @@ int nbd_init(int fd, QIOChannelSocket *sioc, uint32_t flags, off_t size) TRACE("Setting block size to %lu", (unsigned long)BDRV_SECTOR_SIZE); - if (ioctl(fd, NBD_SET_BLKSIZE, (size_t)BDRV_SECTOR_SIZE) < 0) { + if (ioctl(fd, NBD_SET_BLKSIZE, (unsigned long)BDRV_SECTOR_SIZE) < 0) { int serrno = errno; LOG("Failed setting NBD block size"); return -serrno; } - TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE)); + TRACE("Setting size to %lu block(s)", sectors); + if (size % BDRV_SECTOR_SIZE) { + TRACE("Ignoring trailing %d bytes of export", + (int) (size % BDRV_SECTOR_SIZE)); + } - if (ioctl(fd, NBD_SET_SIZE_BLOCKS, (size_t)(size / BDRV_SECTOR_SIZE)) < 0) { + if (ioctl(fd, NBD_SET_SIZE_BLOCKS, sectors) < 0) { int serrno = errno; LOG("Failed setting size (in blocks)"); return -serrno; } - if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) { + if (ioctl(fd, NBD_SET_FLAGS, (unsigned long) flags) < 0) { if (errno == ENOTTY) { int read_only = (flags & NBD_FLAG_READ_ONLY) != 0; TRACE("Setting readonly attribute"); @@ -665,6 +679,15 @@ int nbd_client(int fd) errno = serrno; return ret; } + +int nbd_disconnect(int fd) +{ + ioctl(fd, NBD_CLEAR_QUE); + ioctl(fd, NBD_DISCONNECT); + ioctl(fd, NBD_CLEAR_SOCK); + return 0; +} + #else int nbd_init(int fd, QIOChannelSocket *ioc, uint32_t flags, off_t size) { @@ -675,6 +698,10 @@ int nbd_client(int fd) { return -ENOTSUP; } +int nbd_disconnect(int fd) +{ + return -ENOTSUP; +} #endif ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request) @@ -683,14 +710,15 @@ ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request) ssize_t ret; TRACE("Sending request to server: " - "{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}", + "{ .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64 + ", .type=%" PRIu16 " }", request->from, request->len, request->handle, request->type); - cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC); - cpu_to_be32w((uint32_t*)(buf + 4), request->type); - cpu_to_be64w((uint64_t*)(buf + 8), request->handle); - cpu_to_be64w((uint64_t*)(buf + 16), request->from); - cpu_to_be32w((uint32_t*)(buf + 24), request->len); + stl_be_p(buf, NBD_REQUEST_MAGIC); + stl_be_p(buf + 4, request->type); + stq_be_p(buf + 8, request->handle); + stq_be_p(buf + 16, request->from); + stl_be_p(buf + 24, request->len); ret = write_sync(ioc, buf, sizeof(buf)); if (ret < 0) { @@ -726,18 +754,18 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, struct nbd_reply *reply) [ 7 .. 15] handle */ - magic = be32_to_cpup((uint32_t*)buf); - reply->error = be32_to_cpup((uint32_t*)(buf + 4)); - reply->handle = be64_to_cpup((uint64_t*)(buf + 8)); + magic = ldl_be_p(buf); + reply->error = ldl_be_p(buf + 4); + reply->handle = ldq_be_p(buf + 8); reply->error = nbd_errno_to_system_errno(reply->error); - TRACE("Got reply: " - "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }", + TRACE("Got reply: { magic = 0x%" PRIx32 ", .error = % " PRId32 + ", handle = %" PRIu64" }", magic, reply->error, reply->handle); if (magic != NBD_REPLY_MAGIC) { - LOG("invalid magic (got 0x%x)", magic); + LOG("invalid magic (got 0x%" PRIx32 ")", magic); return -EINVAL; } return 0; diff --git a/nbd/server.c b/nbd/server.c index b2cfeb9..a677e26 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -52,6 +52,7 @@ struct NBDRequest { QSIMPLEQ_ENTRY(NBDRequest) entry; NBDClient *client; uint8_t *data; + bool complete; }; struct NBDExport { @@ -196,7 +197,7 @@ static int nbd_negotiate_send_rep(QIOChannel *ioc, uint32_t type, uint32_t opt) uint64_t magic; uint32_t len; - TRACE("Reply opt=%x type=%x", type, opt); + TRACE("Reply opt=%" PRIx32 " type=%" PRIx32, type, opt); magic = cpu_to_be64(NBD_REP_MAGIC); if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) != sizeof(magic)) { @@ -226,7 +227,7 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp) uint64_t magic, name_len; uint32_t opt, type, len; - TRACE("Advertizing export name '%s'", exp->name ? exp->name : ""); + TRACE("Advertising export name '%s'", exp->name ? exp->name : ""); name_len = strlen(exp->name); magic = cpu_to_be64(NBD_REP_MAGIC); if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) != sizeof(magic)) { @@ -285,13 +286,13 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length) static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length) { int rc = -EINVAL; - char name[256]; + char name[NBD_MAX_NAME_SIZE + 1]; /* Client sends: [20 .. xx] export name (length bytes) */ TRACE("Checking length"); - if (length > 255) { + if (length >= sizeof(name)) { LOG("Bad length received"); goto fail; } @@ -334,7 +335,10 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, return NULL; } - nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK, NBD_OPT_STARTTLS); + if (nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK, + NBD_OPT_STARTTLS) < 0) { + return NULL; + } tioc = qio_channel_tls_new_server(ioc, client->tlscreds, @@ -392,12 +396,12 @@ static int nbd_negotiate_options(NBDClient *client) TRACE("Checking client flags"); be32_to_cpus(&flags); if (flags & NBD_FLAG_C_FIXED_NEWSTYLE) { - TRACE("Support supports fixed newstyle handshake"); + TRACE("Client supports fixed newstyle handshake"); fixedNewstyle = true; flags &= ~NBD_FLAG_C_FIXED_NEWSTYLE; } if (flags != 0) { - TRACE("Unknown client flags 0x%x received", flags); + TRACE("Unknown client flags 0x%" PRIx32 " received", flags); return -EIO; } @@ -431,12 +435,12 @@ static int nbd_negotiate_options(NBDClient *client) } length = be32_to_cpu(length); - TRACE("Checking option 0x%x", clientflags); + TRACE("Checking option 0x%" PRIx32, clientflags); if (client->tlscreds && client->ioc == (QIOChannel *)client->sioc) { QIOChannel *tioc; if (!fixedNewstyle) { - TRACE("Unsupported option 0x%x", clientflags); + TRACE("Unsupported option 0x%" PRIx32, clientflags); return -EINVAL; } switch (clientflags) { @@ -455,12 +459,16 @@ static int nbd_negotiate_options(NBDClient *client) return -EINVAL; default: - TRACE("Option 0x%x not permitted before TLS", clientflags); + TRACE("Option 0x%" PRIx32 " not permitted before TLS", + clientflags); if (nbd_negotiate_drop_sync(client->ioc, length) != length) { return -EIO; } - nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_TLS_REQD, - clientflags); + ret = nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_TLS_REQD, + clientflags); + if (ret < 0) { + return ret; + } break; } } else if (fixedNewstyle) { @@ -484,21 +492,29 @@ static int nbd_negotiate_options(NBDClient *client) } if (client->tlscreds) { TRACE("TLS already enabled"); - nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_INVALID, - clientflags); + ret = nbd_negotiate_send_rep(client->ioc, + NBD_REP_ERR_INVALID, + clientflags); } else { TRACE("TLS not configured"); - nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_POLICY, - clientflags); + ret = nbd_negotiate_send_rep(client->ioc, + NBD_REP_ERR_POLICY, + clientflags); + } + if (ret < 0) { + return ret; } break; default: - TRACE("Unsupported option 0x%x", clientflags); + TRACE("Unsupported option 0x%" PRIx32, clientflags); if (nbd_negotiate_drop_sync(client->ioc, length) != length) { return -EIO; } - nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_UNSUP, - clientflags); + ret = nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_UNSUP, + clientflags); + if (ret < 0) { + return ret; + } break; } } else { @@ -511,7 +527,7 @@ static int nbd_negotiate_options(NBDClient *client) return nbd_negotiate_handle_export_name(client, length); default: - TRACE("Unsupported option 0x%x", clientflags); + TRACE("Unsupported option 0x%" PRIx32, clientflags); return -EINVAL; } } @@ -560,6 +576,8 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) oldStyle = client->exp != NULL && !client->tlscreds; if (oldStyle) { assert ((client->exp->nbdflags & ~65535) == 0); + TRACE("advertising size %" PRIu64 " and flags %x", + client->exp->size, client->exp->nbdflags | myflags); stq_be_p(buf + 8, NBD_CLIENT_MAGIC); stq_be_p(buf + 16, client->exp->size); stw_be_p(buf + 26, client->exp->nbdflags | myflags); @@ -589,6 +607,8 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) } assert ((client->exp->nbdflags & ~65535) == 0); + TRACE("advertising size %" PRIu64 " and flags %x", + client->exp->size, client->exp->nbdflags | myflags); stq_be_p(buf + 18, client->exp->size); stw_be_p(buf + 26, client->exp->nbdflags | myflags); if (nbd_negotiate_write(client->ioc, buf + 18, sizeof(buf) - 18) != @@ -604,24 +624,6 @@ fail: return rc; } -#ifdef __linux__ - -int nbd_disconnect(int fd) -{ - ioctl(fd, NBD_CLEAR_QUE); - ioctl(fd, NBD_DISCONNECT); - ioctl(fd, NBD_CLEAR_SOCK); - return 0; -} - -#else - -int nbd_disconnect(int fd) -{ - return -ENOTSUP; -} -#endif - static ssize_t nbd_receive_request(QIOChannel *ioc, struct nbd_request *request) { uint8_t buf[NBD_REQUEST_SIZE]; @@ -646,18 +648,18 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, struct nbd_request *request) [24 .. 27] len */ - magic = be32_to_cpup((uint32_t*)buf); - request->type = be32_to_cpup((uint32_t*)(buf + 4)); - request->handle = be64_to_cpup((uint64_t*)(buf + 8)); - request->from = be64_to_cpup((uint64_t*)(buf + 16)); - request->len = be32_to_cpup((uint32_t*)(buf + 24)); + magic = ldl_be_p(buf); + request->type = ldl_be_p(buf + 4); + request->handle = ldq_be_p(buf + 8); + request->from = ldq_be_p(buf + 16); + request->len = ldl_be_p(buf + 24); - TRACE("Got request: " - "{ magic = 0x%x, .type = %d, from = %" PRIu64" , len = %u }", + TRACE("Got request: { magic = 0x%" PRIx32 ", .type = %" PRIx32 + ", from = %" PRIu64 " , len = %" PRIu32 " }", magic, request->type, request->from, request->len); if (magic != NBD_REQUEST_MAGIC) { - LOG("invalid magic (got 0x%x)", magic); + LOG("invalid magic (got 0x%" PRIx32 ")", magic); return -EINVAL; } return 0; @@ -670,7 +672,8 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, struct nbd_reply *reply) reply->error = system_errno_to_nbd_errno(reply->error); - TRACE("Sending response to client: { .error = %d, handle = %" PRIu64 " }", + TRACE("Sending response to client: { .error = %" PRId32 + ", handle = %" PRIu64 " }", reply->error, reply->handle); /* Reply @@ -969,7 +972,13 @@ static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply, return rc; } -static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *request) +/* Collect a client request. Return 0 if request looks valid, -EAGAIN + * to keep trying the collection, -EIO to drop connection right away, + * and any other negative value to report an error to the client + * (although the caller may still need to disconnect after reporting + * the error). */ +static ssize_t nbd_co_receive_request(NBDRequest *req, + struct nbd_request *request) { NBDClient *client = req->client; uint32_t command; @@ -987,19 +996,34 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque goto out; } + TRACE("Decoding type"); + + command = request->type & NBD_CMD_MASK_COMMAND; + if (command != NBD_CMD_WRITE) { + /* No payload, we are ready to read the next request. */ + req->complete = true; + } + + if (command == NBD_CMD_DISC) { + /* Special case: we're going to disconnect without a reply, + * whether or not flags, from, or len are bogus */ + TRACE("Request type is DISCONNECT"); + rc = -EIO; + goto out; + } + + /* Check for sanity in the parameters, part 1. Defer as many + * checks as possible until after reading any NBD_CMD_WRITE + * payload, so we can try and keep the connection alive. */ if ((request->from + request->len) < request->from) { - LOG("integer overflow detected! " - "you're probably being attacked"); + LOG("integer overflow detected, you're probably being attacked"); rc = -EINVAL; goto out; } - TRACE("Decoding type"); - - command = request->type & NBD_CMD_MASK_COMMAND; if (command == NBD_CMD_READ || command == NBD_CMD_WRITE) { if (request->len > NBD_MAX_BUFFER_SIZE) { - LOG("len (%u) is larger than max len (%u)", + LOG("len (%" PRIu32" ) is larger than max len (%u)", request->len, NBD_MAX_BUFFER_SIZE); rc = -EINVAL; goto out; @@ -1012,14 +1036,30 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque } } if (command == NBD_CMD_WRITE) { - TRACE("Reading %u byte(s)", request->len); + TRACE("Reading %" PRIu32 " byte(s)", request->len); if (read_sync(client->ioc, req->data, request->len) != request->len) { LOG("reading from socket failed"); rc = -EIO; goto out; } + req->complete = true; + } + + /* Sanity checks, part 2. */ + if (request->from + request->len > client->exp->size) { + LOG("operation past EOF; From: %" PRIu64 ", Len: %" PRIu32 + ", Size: %" PRIu64, request->from, request->len, + (uint64_t)client->exp->size); + rc = command == NBD_CMD_WRITE ? -ENOSPC : -EINVAL; + goto out; } + if (request->type & ~NBD_CMD_MASK_COMMAND & ~NBD_CMD_FLAG_FUA) { + LOG("unsupported flags (got 0x%x)", + request->type & ~NBD_CMD_MASK_COMMAND); + return -EINVAL; + } + rc = 0; out: @@ -1038,6 +1078,7 @@ static void nbd_trip(void *opaque) struct nbd_reply reply; ssize_t ret; uint32_t command; + int flags; TRACE("Reading request."); if (client->closing) { @@ -1061,14 +1102,6 @@ static void nbd_trip(void *opaque) goto error_reply; } command = request.type & NBD_CMD_MASK_COMMAND; - if (command != NBD_CMD_DISC && (request.from + request.len) > exp->size) { - LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64 - ", Offset: %" PRIu64 "\n", - request.from, request.len, - (uint64_t)exp->size, (uint64_t)exp->dev_offset); - LOG("requested operation past EOF--bad client?"); - goto invalid_request; - } if (client->closing) { /* @@ -1099,7 +1132,7 @@ static void nbd_trip(void *opaque) goto error_reply; } - TRACE("Read %u byte(s)", request.len); + TRACE("Read %" PRIu32" byte(s)", request.len); if (nbd_co_send_reply(req, &reply, request.len) < 0) goto out; break; @@ -1114,31 +1147,27 @@ static void nbd_trip(void *opaque) TRACE("Writing to device"); + flags = 0; + if (request.type & NBD_CMD_FLAG_FUA) { + flags |= BDRV_REQ_FUA; + } ret = blk_pwrite(exp->blk, request.from + exp->dev_offset, - req->data, request.len, 0); + req->data, request.len, flags); if (ret < 0) { LOG("writing to file failed"); reply.error = -ret; goto error_reply; } - if (request.type & NBD_CMD_FLAG_FUA) { - ret = blk_co_flush(exp->blk); - if (ret < 0) { - LOG("flush failed"); - reply.error = -ret; - goto error_reply; - } - } - if (nbd_co_send_reply(req, &reply, 0) < 0) { goto out; } break; + case NBD_CMD_DISC: - TRACE("Request type is DISCONNECT"); - errno = 0; - goto out; + /* unreachable, thanks to special case in nbd_co_receive_request() */ + abort(); + case NBD_CMD_FLUSH: TRACE("Request type is FLUSH"); @@ -1173,11 +1202,13 @@ static void nbd_trip(void *opaque) } break; default: - LOG("invalid request type (%u) received", request.type); - invalid_request: + LOG("invalid request type (%" PRIu32 ") received", request.type); reply.error = EINVAL; error_reply: - if (nbd_co_send_reply(req, &reply, 0) < 0) { + /* We must disconnect after NBD_CMD_WRITE if we did not + * read the payload. + */ + if (nbd_co_send_reply(req, &reply, 0) < 0 || !req->complete) { goto out; } break; diff --git a/net/netmap.c b/net/netmap.c index 6cc0db5..64967b9 100644 --- a/net/netmap.c +++ b/net/netmap.c @@ -26,7 +26,6 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> #include <net/if.h> -#include <sys/mman.h> #define NETMAP_WITH_LIBS #include <net/netmap.h> #include <net/netmap_user.h> @@ -26,7 +26,6 @@ #include "qemu/osdep.h" #include <sys/wait.h> /*needed for MAP_POPULATE before including qemu-options.h */ -#include <sys/mman.h> #include <pwd.h> #include <grp.h> #include <libgen.h> diff --git a/qemu-char.c b/qemu-char.c index b13ecbb..c926e9a 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -47,7 +47,6 @@ #include <sys/times.h> #include <sys/wait.h> #include <termios.h> -#include <sys/mman.h> #include <sys/ioctl.h> #include <sys/resource.h> #include <sys/socket.h> @@ -154,8 +154,8 @@ static void read_partition(uint8_t *p, struct partition_record *r) r->end_cylinder = p[7] | ((p[6] << 2) & 0x300); r->end_sector = p[6] & 0x3f; - r->start_sector_abs = le32_to_cpup((uint32_t *)(p + 8)); - r->nb_sectors_abs = le32_to_cpup((uint32_t *)(p + 12)); + r->start_sector_abs = ldl_le_p(p + 8); + r->nb_sectors_abs = ldl_le_p(p + 12); } static int find_partition(BlockBackend *blk, int partition, diff --git a/qemu-options.hx b/qemu-options.hx index 0e42ba5..17f15ad 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3214,6 +3214,8 @@ STEXI @item -L @var{path} @findex -L Set the directory for the BIOS, VGA BIOS and keymaps. + +To list all the data directories, use @code{-L help}. ETEXI DEF("bios", HAS_ARG, QEMU_OPTION_bios, \ diff --git a/scripts/clean-includes b/scripts/clean-includes index 37b73b5..4412a55 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -105,6 +105,8 @@ for f in "$@"; do *include/qemu/osdep.h | \ *include/qemu/compiler.h | \ *include/glib-compat.h | \ + *include/sysemu/os-posix.h | \ + *include/sysemu/os-win32.h | \ *include/standard-headers/ ) # Removing include lines from osdep.h itself would be counterproductive. echo "SKIPPING $f (special case header)" @@ -145,6 +147,7 @@ for f in "$@"; do <stdlib.h> <stdio.h> <string.h> <strings.h> <inttypes.h> <limits.h> <unistd.h> <time.h> <ctype.h> <errno.h> <fcntl.h> <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> + <sys/stat.h> <sys/time.h> <assert.h> <signal.h> <glib.h> <sys/mman.h> "sysemu/os-posix.h, sysemu/os-win32.h "glib-compat.h" "qemu/typedefs.h" ))' "$f" diff --git a/target-arm/kvm.c b/target-arm/kvm.c index 83da447..5c2bd7a 100644 --- a/target-arm/kvm.c +++ b/target-arm/kvm.c @@ -10,7 +10,6 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> -#include <sys/mman.h> #include <linux/kvm.h> diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c index c35c676..069da0c 100644 --- a/target-arm/kvm32.c +++ b/target-arm/kvm32.c @@ -10,7 +10,6 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> -#include <sys/mman.h> #include <linux/kvm.h> diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c index 2d6a310..5faa76c 100644 --- a/target-arm/kvm64.c +++ b/target-arm/kvm64.c @@ -11,7 +11,6 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> -#include <sys/mman.h> #include <sys/ptrace.h> #include <linux/elf.h> diff --git a/target-i386/kvm.c b/target-i386/kvm.c index abf50e6..ff92b1d 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -15,7 +15,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include <sys/ioctl.h> -#include <sys/mman.h> #include <sys/utsname.h> #include <linux/kvm.h> @@ -107,6 +106,8 @@ static int has_xsave; static int has_xcrs; static int has_pit_state2; +static struct kvm_cpuid2 *cpuid_cache; + int kvm_has_pit_state2(void) { return has_pit_state2; @@ -200,9 +201,14 @@ static struct kvm_cpuid2 *get_supported_cpuid(KVMState *s) { struct kvm_cpuid2 *cpuid; int max = 1; + + if (cpuid_cache != NULL) { + return cpuid_cache; + } while ((cpuid = try_get_cpuid(s, max)) == NULL) { max *= 2; } + cpuid_cache = cpuid; return cpuid; } @@ -320,8 +326,6 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, ret |= cpuid_1_edx & CPUID_EXT2_AMD_ALIASES; } - g_free(cpuid); - /* fallback for older kernels */ if ((function == KVM_CPUID_FEATURES) && !found) { ret = get_para_features(s); diff --git a/target-mips/kvm.c b/target-mips/kvm.c index a854e4d..f3f832d 100644 --- a/target-mips/kvm.c +++ b/target-mips/kvm.c @@ -11,7 +11,6 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> -#include <sys/mman.h> #include <linux/kvm.h> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 6c15361..1620864 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -17,7 +17,6 @@ #include "qemu/osdep.h" #include <dirent.h> #include <sys/ioctl.h> -#include <sys/mman.h> #include <sys/vfs.h> #include <linux/kvm.h> diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index f108cd3..45e94ca 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -23,7 +23,6 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> -#include <sys/mman.h> #include <linux/kvm.h> #include <asm/ptrace.h> diff --git a/tests/e1000e-test.c b/tests/e1000e-test.c index dbf4859..d497b08 100644 --- a/tests/e1000e-test.c +++ b/tests/e1000e-test.c @@ -25,7 +25,6 @@ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu-common.h" #include "libqos/pci-pc.h" diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c index bff999c..c1d9b3e 100644 --- a/tests/i440fx-test.c +++ b/tests/i440fx-test.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include <sys/mman.h> #include "libqtest.h" #include "libqos/pci.h" diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c index 010860a..0957ee7 100644 --- a/tests/ivshmem-test.c +++ b/tests/ivshmem-test.c @@ -10,7 +10,6 @@ #include "qemu/osdep.h" #include <glib/gstdio.h> -#include <sys/mman.h> #include "contrib/ivshmem-server/ivshmem-server.h" #include "libqos/pci-pc.h" #include "libqtest.h" diff --git a/tests/postcopy-test.c b/tests/postcopy-test.c index 9ff88ee..35d5180 100644 --- a/tests/postcopy-test.c +++ b/tests/postcopy-test.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "libqtest.h" #include "qemu/option.h" @@ -26,7 +25,6 @@ const unsigned end_address = 100 * 1024 * 1024; bool got_stop; #if defined(__linux__) -#include <sys/mman.h> #include <sys/syscall.h> #include <sys/vfs.h> #endif diff --git a/tests/qht-bench.c b/tests/qht-bench.c index ad8efbc..76360a0 100644 --- a/tests/qht-bench.c +++ b/tests/qht-bench.c @@ -5,7 +5,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/processor.h" #include "qemu/atomic.h" #include "qemu/qht.h" diff --git a/tests/test-qdist.c b/tests/test-qdist.c index a67f260..0298986 100644 --- a/tests/test-qdist.c +++ b/tests/test-qdist.c @@ -5,7 +5,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/qdist.h" #include <math.h> diff --git a/tests/test-qht-par.c b/tests/test-qht-par.c index f09e004..d8a83ca 100644 --- a/tests/test-qht-par.c +++ b/tests/test-qht-par.c @@ -5,7 +5,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #define TEST_QHT_STRING "tests/qht-bench 1>/dev/null 2>&1 -R -S0.1 -D10000 -N1 " diff --git a/tests/test-qht.c b/tests/test-qht.c index c8eb930..f1d6283 100644 --- a/tests/test-qht.c +++ b/tests/test-qht.c @@ -5,7 +5,6 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" -#include <glib.h> #include "qemu/qht.h" #define N 5000 diff --git a/tests/vhost-user-bridge.c b/tests/vhost-user-bridge.c index 0779ba26..57c8f91 100644 --- a/tests/vhost-user-bridge.c +++ b/tests/vhost-user-bridge.c @@ -33,7 +33,6 @@ #include <sys/socket.h> #include <sys/un.h> #include <sys/unistd.h> -#include <sys/mman.h> #include <sys/eventfd.h> #include <arpa/inet.h> #include <netdb.h> diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index 2724fe9..b2b1665 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -17,7 +17,6 @@ #include "sysemu/sysemu.h" #include <linux/vhost.h> -#include <sys/mman.h> #include <sys/vfs.h> #include <qemu/sockets.h> diff --git a/translate-all.c b/translate-all.c index e8b88b4..3f402df 100644 --- a/translate-all.c +++ b/translate-all.c @@ -18,8 +18,6 @@ */ #ifdef _WIN32 #include <windows.h> -#else -#include <sys/mman.h> #endif #include "qemu/osdep.h" diff --git a/util/cutils.c b/util/cutils.c index 43d1afb..5830a68 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -256,13 +256,7 @@ static size_t buffer_find_nonzero_offset_inner(const void *buf, size_t len) return i * sizeof(VECTYPE); } -/* - * GCC before version 4.9 has a bug which will cause the target - * attribute work incorrectly and failed to compile in some case, - * restrict the gcc version to 4.9+ to prevent the failure. - */ - -#if defined CONFIG_AVX2_OPT && QEMU_GNUC_PREREQ(4, 9) +#if defined CONFIG_AVX2_OPT #pragma GCC push_options #pragma GCC target("avx2") #include <cpuid.h> diff --git a/util/memfd.c b/util/memfd.c index b374238..4571d1a 100644 --- a/util/memfd.c +++ b/util/memfd.c @@ -29,8 +29,6 @@ #include <glib/gprintf.h> -#include <sys/mman.h> - #include "qemu/memfd.h" #ifdef CONFIG_MEMFD diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 0b4cc7f..629d97a 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" #include <qemu/mmap-alloc.h> -#include <sys/mman.h> #define HUGETLBFS_MAGIC 0x958458f6 diff --git a/util/osdep.c b/util/osdep.c index 9a7a439..ff004e8 100644 --- a/util/osdep.c +++ b/util/osdep.c @@ -25,10 +25,6 @@ /* Needed early for CONFIG_BSD etc. */ -#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE) -#include <sys/mman.h> -#endif - #ifdef CONFIG_SOLARIS #include <sys/statvfs.h> /* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 4adde93..e2e1d4d 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -36,7 +36,6 @@ #include "trace.h" #include "qapi/error.h" #include "qemu/sockets.h" -#include <sys/mman.h> #include <libgen.h> #include <sys/signal.h> #include "qemu/cutils.h" diff --git a/util/qdist.c b/util/qdist.c index 4ea2e34..56f5738 100644 --- a/util/qdist.c +++ b/util/qdist.c @@ -6,6 +6,7 @@ * License: GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ +#include "qemu/osdep.h" #include "qemu/qdist.h" #include <math.h> @@ -65,6 +65,7 @@ * + Corbet, "Relativistic hash tables, part 1: Algorithms", @ lwn.net, 2014. * https://lwn.net/Articles/612021/ */ +#include "qemu/osdep.h" #include "qemu/qht.h" #include "qemu/atomic.h" #include "qemu/rcu.h" @@ -154,7 +154,7 @@ CharDriverState *sclp_hds[MAX_SCLP_CONSOLES]; int win2k_install_hack = 0; int singlestep = 0; int smp_cpus = 1; -int max_cpus = 0; +int max_cpus = 1; int smp_cores = 1; int smp_threads = 1; int acpi_enabled = 1; @@ -1218,7 +1218,6 @@ static QemuOptsList qemu_smp_opts = { static void smp_parse(QemuOpts *opts) { if (opts) { - unsigned cpus = qemu_opt_get_number(opts, "cpus", 0); unsigned sockets = qemu_opt_get_number(opts, "sockets", 0); unsigned cores = qemu_opt_get_number(opts, "cores", 0); @@ -1246,6 +1245,17 @@ static void smp_parse(QemuOpts *opts) } max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus); + + if (max_cpus > MAX_CPUMASK_BITS) { + error_report("unsupported number of maxcpus"); + exit(1); + } + + if (max_cpus < cpus) { + error_report("maxcpus must be equal to or greater than smp"); + exit(1); + } + if (sockets * cores * threads > max_cpus) { error_report("cpu topology: " "sockets (%u) * cores (%u) * threads (%u) > " @@ -1255,25 +1265,11 @@ static void smp_parse(QemuOpts *opts) } smp_cpus = cpus; - smp_cores = cores > 0 ? cores : 1; - smp_threads = threads > 0 ? threads : 1; - - } - - if (max_cpus == 0) { - max_cpus = smp_cpus; - } - - if (max_cpus > MAX_CPUMASK_BITS) { - error_report("unsupported number of maxcpus"); - exit(1); - } - if (max_cpus < smp_cpus) { - error_report("maxcpus must be equal to or greater than smp"); - exit(1); + smp_cores = cores; + smp_threads = threads; } - if (smp_cpus > 1 || smp_cores > 1 || smp_threads > 1) { + if (smp_cpus > 1) { Error *blocker = NULL; error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp"); replay_add_blocker(blocker); @@ -2968,6 +2964,7 @@ int main(int argc, char **argv, char **envp) FILE *vmstate_dump_file = NULL; Error *main_loop_err = NULL; Error *err = NULL; + bool list_data_dirs = false; qemu_init_cpu_loop(); qemu_mutex_lock_iothread(); @@ -3354,7 +3351,9 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_GDB, optarg); break; case QEMU_OPTION_L: - if (data_dir_idx < ARRAY_SIZE(data_dir)) { + if (is_help_option(optarg)) { + list_data_dirs = true; + } else if (data_dir_idx < ARRAY_SIZE(data_dir)) { data_dir[data_dir_idx++] = optarg; } break; @@ -4086,6 +4085,14 @@ int main(int argc, char **argv, char **envp) data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR; } + /* -L help lists the data directories and exits. */ + if (list_data_dirs) { + for (i = 0; i < data_dir_idx; i++) { + printf("%s\n", data_dir[i]); + } + exit(0); + } + smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL)); machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */ @@ -9,7 +9,6 @@ */ #include "qemu/osdep.h" -#include <sys/mman.h> #include "cpu.h" #include "hw/pci/pci.h" diff --git a/xen-mapcache.c b/xen-mapcache.c index 49f394a..8f3a592 100644 --- a/xen-mapcache.c +++ b/xen-mapcache.c @@ -17,7 +17,6 @@ #include "qemu/bitmap.h" #include <xen/hvm/params.h> -#include <sys/mman.h> #include "sysemu/xen-mapcache.h" #include "trace.h" |