summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS13
-rw-r--r--Makefile14
-rw-r--r--Makefile.objs4
-rw-r--r--block.c2
-rw-r--r--block/qcow2.h2
-rw-r--r--block/vdi.c2
-rw-r--r--block/write-threshold.c2
-rw-r--r--blockjob.c2
-rwxr-xr-xconfigure21
-rw-r--r--default-configs/ppc64-softmmu.mak1
-rw-r--r--disas.c55
-rw-r--r--docs/specs/fw_cfg.txt94
-rw-r--r--docs/specs/vhost-user.txt63
-rw-r--r--docs/virtio-migration.txt106
-rw-r--r--exec.c47
-rw-r--r--hw/9pfs/codir.c2
-rw-r--r--hw/9pfs/cofile.c2
-rw-r--r--hw/9pfs/cofs.c2
-rw-r--r--hw/9pfs/coxattr.c2
-rw-r--r--hw/9pfs/virtio-9p-coth.c2
-rw-r--r--hw/9pfs/virtio-9p-coth.h2
-rw-r--r--hw/9pfs/virtio-9p.h2
-rw-r--r--hw/arm/virt.c8
-rw-r--r--hw/display/vmware_vga.c11
-rw-r--r--hw/i386/intel_iommu.c89
-rw-r--r--hw/i386/pc.c25
-rw-r--r--hw/i386/pc_piix.c2
-rw-r--r--hw/i386/pc_q35.c2
-rw-r--r--hw/input/virtio-input.c4
-rw-r--r--hw/isa/lpc_ich9.c2
-rw-r--r--hw/mem/pc-dimm.c7
-rw-r--r--hw/net/vhost_net.c35
-rw-r--r--hw/nvram/fw_cfg.c250
-rw-r--r--hw/pci-host/piix.c11
-rw-r--r--hw/pci-host/q35.c25
-rw-r--r--hw/ppc/spapr.c1
-rw-r--r--hw/s390x/ipl.c53
-rw-r--r--hw/s390x/ipl.h5
-rw-r--r--hw/s390x/s390-virtio-ccw.c44
-rw-r--r--hw/s390x/s390-virtio.c15
-rw-r--r--hw/s390x/s390-virtio.h1
-rw-r--r--hw/scsi/vhost-scsi.c7
-rw-r--r--hw/usb/bus.c9
-rw-r--r--hw/usb/dev-audio.c2
-rw-r--r--hw/usb/host-libusb.c1
-rw-r--r--hw/virtio/vhost-backend.c138
-rw-r--r--hw/virtio/vhost-user.c581
-rw-r--r--hw/virtio/vhost.c156
-rw-r--r--hw/xtensa/xtfpga.c41
-rw-r--r--include/block/block.h2
-rw-r--r--include/block/block_int.h2
-rw-r--r--include/glib-compat.h61
-rw-r--r--include/hw/i386/intel_iommu.h16
-rw-r--r--include/hw/i386/pc.h2
-rw-r--r--include/hw/nvram/fw_cfg.h16
-rw-r--r--include/hw/virtio/vhost-backend.h77
-rw-r--r--include/hw/virtio/vhost.h17
-rw-r--r--include/net/vhost_net.h1
-rw-r--r--include/qemu/buffer.h118
-rw-r--r--include/qemu/coroutine.h (renamed from include/block/coroutine.h)0
-rw-r--r--include/qemu/coroutine_int.h (renamed from include/block/coroutine_int.h)2
-rw-r--r--include/qemu/memfd.h26
-rw-r--r--include/qemu/mmap-alloc.h10
-rw-r--r--include/qemu/osdep.h16
-rw-r--r--include/qemu/sockets.h34
-rw-r--r--linux-headers/asm-arm/unistd.h448
-rw-r--r--linux-headers/asm-arm64/unistd.h16
-rw-r--r--linux-headers/asm-mips/unistd.h1063
-rw-r--r--linux-headers/asm-powerpc/unistd.h392
-rw-r--r--linux-headers/asm-s390/unistd.h404
-rw-r--r--linux-headers/asm-x86/unistd.h15
-rw-r--r--linux-headers/asm-x86/unistd_32.h377
-rw-r--r--linux-headers/asm-x86/unistd_64.h330
-rw-r--r--linux-headers/asm-x86/unistd_x32.h319
-rw-r--r--migration/qemu-file-buf.c2
-rw-r--r--migration/qemu-file-stdio.c2
-rw-r--r--migration/qemu-file-unix.c2
-rw-r--r--migration/qemu-file.c2
-rw-r--r--migration/rdma.c2
-rw-r--r--nbd.c2
-rw-r--r--net/net.c8
-rw-r--r--net/vhost-user.c36
-rw-r--r--qapi-schema.json6
-rw-r--r--qemu-char.c25
-rw-r--r--qemu-options.hx7
-rw-r--r--qemu-seccomp.c3
-rw-r--r--qga/channel-posix.c25
-rw-r--r--qga/channel-win32.c4
-rw-r--r--qga/commands-posix.c30
-rw-r--r--qga/commands-win32.c20
-rw-r--r--qga/commands.c394
-rw-r--r--qga/guest-agent-command-state.c4
-rw-r--r--qga/main.c13
-rw-r--r--qga/qapi-schema.json67
-rwxr-xr-xscripts/update-linux-headers.sh7
-rw-r--r--stubs/Makefile.objs1
-rw-r--r--stubs/vhost.c6
-rw-r--r--target-alpha/cpu.c8
-rw-r--r--target-lm32/cpu.c7
-rw-r--r--target-m68k/cpu.c9
-rw-r--r--target-mips/cpu.c9
-rw-r--r--target-moxie/cpu.c7
-rw-r--r--target-s390x/cpu.c8
-rw-r--r--target-s390x/cpu.h65
-rw-r--r--target-s390x/kvm.c32
-rw-r--r--target-s390x/misc_helper.c12
-rw-r--r--target-sh4/cpu.c11
-rw-r--r--target-sparc/cpu.c9
-rw-r--r--target-xtensa/cpu.h1
-rw-r--r--target-xtensa/helper.c8
-rw-r--r--target-xtensa/op_helper.c4
-rw-r--r--target-xtensa/overlay_tool.h5
-rw-r--r--target-xtensa/translate.c37
-rw-r--r--tests/Makefile3
-rw-r--r--tests/fw_cfg-test.c4
-rw-r--r--tests/libqtest.c45
-rw-r--r--tests/libqtest.h7
-rw-r--r--tests/test-coroutine.c4
-rw-r--r--tests/test-qga.c783
-rw-r--r--tests/test-vmstate.c2
-rw-r--r--tests/vhost-user-test.c372
-rw-r--r--thread-pool.c2
-rw-r--r--trace-events3
-rw-r--r--ui/vnc.c203
-rw-r--r--ui/vnc.h16
-rw-r--r--util/Makefile.objs17
-rw-r--r--util/buffer.c65
-rw-r--r--util/coroutine-gthread.c (renamed from coroutine-gthread.c)2
-rw-r--r--util/coroutine-sigaltstack.c (renamed from coroutine-sigaltstack.c)2
-rw-r--r--util/coroutine-ucontext.c (renamed from coroutine-ucontext.c)2
-rw-r--r--util/coroutine-win32.c (renamed from coroutine-win32.c)2
-rw-r--r--util/memfd.c162
-rw-r--r--util/mmap-alloc.c71
-rw-r--r--util/oslib-posix.c99
-rw-r--r--util/oslib-win32.c9
-rw-r--r--util/qemu-config.c8
-rw-r--r--util/qemu-coroutine-io.c (renamed from qemu-coroutine-io.c)2
-rw-r--r--util/qemu-coroutine-lock.c (renamed from qemu-coroutine-lock.c)4
-rw-r--r--util/qemu-coroutine-sleep.c (renamed from qemu-coroutine-sleep.c)2
-rw-r--r--util/qemu-coroutine.c (renamed from qemu-coroutine.c)4
-rw-r--r--util/qemu-sockets.c158
-rw-r--r--vl.c33
142 files changed, 7814 insertions, 903 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 01fb6e2..3144113 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1193,6 +1193,19 @@ F: crypto/
F: include/crypto/
F: tests/test-crypto-*
+Coroutines
+M: Stefan Hajnoczi <stefanha@redhat.com>
+M: Kevin Wolf <kwolf@redhat.com>
+F: util/*coroutine*
+F: include/qemu/coroutine*
+F: tests/test-coroutine.c
+
+Buffers
+M: Daniel P. Berrange <berrange@redhat.com>
+S: Odd fixes
+F: util/buffer.c
+F: include/qemu/buffer.h
+
Usermode Emulation
------------------
Overall
diff --git a/Makefile b/Makefile
index e370876..cbf252d 100644
--- a/Makefile
+++ b/Makefile
@@ -298,18 +298,15 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
-# we require QGA_VSS_PROVIDER files to be built alongside qemu-ga
-# executable since they are shipped together, but we don't want to actually
-# link against them
-qemu-ga$(EXESUF): $(qga-obj-y) libqemuutil.a libqemustub.a $(QGA_VSS_PROVIDER)
- $(call LINK, $(filter-out $(QGA_VSS_PROVIDER), $^))
+qemu-ga$(EXESUF): $(qga-obj-y) libqemuutil.a libqemustub.a
+ $(call LINK, $^)
ifdef QEMU_GA_MSI_ENABLED
QEMU_GA_MSI=qemu-ga-$(ARCH).msi
msi: $(QEMU_GA_MSI)
-$(QEMU_GA_MSI): qemu-ga.exe
+$(QEMU_GA_MSI): qemu-ga.exe $(QGA_VSS_PROVIDER)
$(QEMU_GA_MSI): config-host.mak
@@ -321,6 +318,11 @@ msi:
@echo "MSI build not configured or dependency resolution failed (reconfigure with --enable-guest-agent-msi option)"
endif
+ifneq ($(EXESUF),)
+.PHONY: qemu-ga
+qemu-ga: qemu-ga$(EXESUF) $(QGA_VSS_PROVIDER) $(QEMU_GA_MSI)
+endif
+
clean:
# avoid old build problems by removing potentially incorrect old files
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
diff --git a/Makefile.objs b/Makefile.objs
index bc43e5c..ecfe03c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -15,10 +15,6 @@ block-obj-$(CONFIG_WIN32) += aio-win32.o
block-obj-y += block/
block-obj-y += qemu-io-cmds.o
-block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
-block-obj-y += qemu-coroutine-sleep.o
-block-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o
-
block-obj-m = block/
#######################################################################
diff --git a/block.c b/block.c
index 09f2a75..6771c3a 100644
--- a/block.c
+++ b/block.c
@@ -33,7 +33,7 @@
#include "sysemu/block-backend.h"
#include "sysemu/sysemu.h"
#include "qemu/notify.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "block/qapi.h"
#include "qmp-commands.h"
#include "qemu/timer.h"
diff --git a/block/qcow2.h b/block/qcow2.h
index 3512263..b8c500b 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -26,7 +26,7 @@
#define BLOCK_QCOW2_H
#include "crypto/cipher.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
//#define DEBUG_ALLOC
//#define DEBUG_ALLOC2
diff --git a/block/vdi.c b/block/vdi.c
index 17626d4..17f435f 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -53,7 +53,7 @@
#include "block/block_int.h"
#include "qemu/module.h"
#include "migration/migration.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#if defined(CONFIG_UUID)
#include <uuid/uuid.h>
diff --git a/block/write-threshold.c b/block/write-threshold.c
index a53c1f5..0fe3891 100644
--- a/block/write-threshold.c
+++ b/block/write-threshold.c
@@ -11,7 +11,7 @@
*/
#include "block/block_int.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "block/write-threshold.h"
#include "qemu/notify.h"
#include "qapi-event.h"
diff --git a/blockjob.c b/blockjob.c
index d87869c..1da5491 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -31,7 +31,7 @@
#include "block/block_int.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qjson.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "qmp-commands.h"
#include "qemu/timer.h"
#include "qapi-event.h"
diff --git a/configure b/configure
index 913ae4a..211bc6e 100755
--- a/configure
+++ b/configure
@@ -3491,6 +3491,22 @@ if compile_prog "" "" ; then
eventfd=yes
fi
+# check if memfd is supported
+memfd=no
+cat > $TMPC << EOF
+#include <sys/memfd.h>
+
+int main(void)
+{
+ return memfd_create("foo", MFD_ALLOW_SEALING);
+}
+EOF
+if compile_prog "" "" ; then
+ memfd=yes
+fi
+
+
+
# check for fallocate
fallocate=no
cat > $TMPC << EOF
@@ -4437,7 +4453,7 @@ fi
if [ "$guest_agent" != "no" ]; then
if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then
- tools="qemu-ga\$(EXESUF) $tools"
+ tools="qemu-ga $tools"
guest_agent=yes
elif [ "$guest_agent" != yes ]; then
guest_agent=no
@@ -4885,6 +4901,9 @@ fi
if test "$eventfd" = "yes" ; then
echo "CONFIG_EVENTFD=y" >> $config_host_mak
fi
+if test "$memfd" = "yes" ; then
+ echo "CONFIG_MEMFD=y" >> $config_host_mak
+fi
if test "$fallocate" = "yes" ; then
echo "CONFIG_FALLOCATE=y" >> $config_host_mak
fi
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index e77cb1a..bb71b23 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -3,6 +3,7 @@
include pci.mak
include sound.mak
include usb.mak
+CONFIG_VIRTIO_VGA=y
CONFIG_ISA_MMIO=y
CONFIG_ESCC=y
CONFIG_M48T59=y
diff --git a/disas.c b/disas.c
index 45878fa..4e11944 100644
--- a/disas.c
+++ b/disas.c
@@ -214,11 +214,6 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
s.info.mach = bfd_mach_i386_i386;
}
s.info.print_insn = print_insn_i386;
-#elif defined(TARGET_SPARC)
- s.info.print_insn = print_insn_sparc;
-#ifdef TARGET_SPARC64
- s.info.mach = bfd_mach_sparc_v9b;
-#endif
#elif defined(TARGET_PPC)
if ((flags >> 16) & 1) {
s.info.endian = BFD_ENDIAN_LITTLE;
@@ -235,29 +230,6 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
}
s.info.disassembler_options = (char *)"any";
s.info.print_insn = print_insn_ppc;
-#elif defined(TARGET_M68K)
- s.info.print_insn = print_insn_m68k;
-#elif defined(TARGET_MIPS)
-#ifdef TARGET_WORDS_BIGENDIAN
- s.info.print_insn = print_insn_big_mips;
-#else
- s.info.print_insn = print_insn_little_mips;
-#endif
-#elif defined(TARGET_SH4)
- s.info.mach = bfd_mach_sh4;
- s.info.print_insn = print_insn_sh;
-#elif defined(TARGET_ALPHA)
- s.info.mach = bfd_mach_alpha_ev6;
- s.info.print_insn = print_insn_alpha;
-#elif defined(TARGET_S390X)
- s.info.mach = bfd_mach_s390_64;
- s.info.print_insn = print_insn_s390;
-#elif defined(TARGET_MOXIE)
- s.info.mach = bfd_arch_moxie;
- s.info.print_insn = print_insn_moxie;
-#elif defined(TARGET_LM32)
- s.info.mach = bfd_mach_lm32;
- s.info.print_insn = print_insn_lm32;
#endif
if (s.info.print_insn == NULL) {
s.info.print_insn = print_insn_od_target;
@@ -429,13 +401,6 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
s.info.mach = bfd_mach_i386_i386;
}
s.info.print_insn = print_insn_i386;
-#elif defined(TARGET_ALPHA)
- s.info.print_insn = print_insn_alpha;
-#elif defined(TARGET_SPARC)
- s.info.print_insn = print_insn_sparc;
-#ifdef TARGET_SPARC64
- s.info.mach = bfd_mach_sparc_v9b;
-#endif
#elif defined(TARGET_PPC)
if (flags & 0xFFFF) {
/* If we have a precise definition of the instruction set, use it. */
@@ -451,26 +416,6 @@ void monitor_disas(Monitor *mon, CPUState *cpu,
s.info.endian = BFD_ENDIAN_LITTLE;
}
s.info.print_insn = print_insn_ppc;
-#elif defined(TARGET_M68K)
- s.info.print_insn = print_insn_m68k;
-#elif defined(TARGET_MIPS)
-#ifdef TARGET_WORDS_BIGENDIAN
- s.info.print_insn = print_insn_big_mips;
-#else
- s.info.print_insn = print_insn_little_mips;
-#endif
-#elif defined(TARGET_SH4)
- s.info.mach = bfd_mach_sh4;
- s.info.print_insn = print_insn_sh;
-#elif defined(TARGET_S390X)
- s.info.mach = bfd_mach_s390_64;
- s.info.print_insn = print_insn_s390;
-#elif defined(TARGET_MOXIE)
- s.info.mach = bfd_arch_moxie;
- s.info.print_insn = print_insn_moxie;
-#elif defined(TARGET_LM32)
- s.info.mach = bfd_mach_lm32;
- s.info.print_insn = print_insn_lm32;
#endif
if (!s.info.print_insn) {
monitor_printf(mon, "0x" TARGET_FMT_lx
diff --git a/docs/specs/fw_cfg.txt b/docs/specs/fw_cfg.txt
index 74351dd..b8c794f 100644
--- a/docs/specs/fw_cfg.txt
+++ b/docs/specs/fw_cfg.txt
@@ -76,6 +76,13 @@ increasing address order, similar to memcpy().
Selector Register IOport: 0x510
Data Register IOport: 0x511
+DMA Address IOport: 0x514
+
+=== ARM Register Locations ===
+
+Selector Register address: Base + 8 (2 bytes)
+Data Register address: Base + 0 (8 bytes)
+DMA Address address: Base + 16 (8 bytes)
== Firmware Configuration Items ==
@@ -86,11 +93,15 @@ by selecting the "signature" item using key 0x0000 (FW_CFG_SIGNATURE),
and reading four bytes from the data register. If the fw_cfg device is
present, the four bytes read will contain the characters "QEMU".
-=== Revision (Key 0x0001, FW_CFG_ID) ===
+If the DMA interface is available, then reading the DMA Address
+Register returns 0x51454d5520434647 ("QEMU CFG" in big-endian format).
+
+=== Revision / feature bitmap (Key 0x0001, FW_CFG_ID) ===
-A 32-bit little-endian unsigned int, this item is used as an interface
-revision number, and is currently set to 1 by QEMU when fw_cfg is
-initialized.
+A 32-bit little-endian unsigned int, this item is used to check for enabled
+features.
+ - Bit 0: traditional interface. Always set.
+ - Bit 1: DMA interface.
=== File Directory (Key 0x0019, FW_CFG_FILE_DIR) ===
@@ -132,6 +143,55 @@ Selector Reg. Range Usage
In practice, the number of allowed firmware configuration items is given
by the value of FW_CFG_MAX_ENTRY (see fw_cfg.h).
+= Guest-side DMA Interface =
+
+If bit 1 of the feature bitmap is set, the DMA interface is present. This does
+not replace the existing fw_cfg interface, it is an add-on. This interface
+can be used through the 64-bit wide address register.
+
+The address register is in big-endian format. The value for the register is 0
+at startup and after an operation. A write to the least significant half (at
+offset 4) triggers an operation. This means that operations with 32-bit
+addresses can be triggered with just one write, whereas operations with
+64-bit addresses can be triggered with one 64-bit write or two 32-bit writes,
+starting with the most significant half (at offset 0).
+
+In this register, the physical address of a FWCfgDmaAccess structure in RAM
+should be written. This is the format of the FWCfgDmaAccess structure:
+
+typedef struct FWCfgDmaAccess {
+ uint32_t control;
+ uint32_t length;
+ uint64_t address;
+} FWCfgDmaAccess;
+
+The fields of the structure are in big endian mode, and the field at the lowest
+address is the "control" field.
+
+The "control" field has the following bits:
+ - Bit 0: Error
+ - Bit 1: Read
+ - Bit 2: Skip
+ - Bit 3: Select. The upper 16 bits are the selected index.
+
+When an operation is triggered, if the "control" field has bit 3 set, the
+upper 16 bits are interpreted as an index of a firmware configuration item.
+This has the same effect as writing the selector register.
+
+If the "control" field has bit 1 set, a read operation will be performed.
+"length" bytes for the current selector and offset will be copied into the
+physical RAM address specified by the "address" field.
+
+If the "control" field has bit 2 set (and not bit 1), a skip operation will be
+performed. The offset for the current selector will be advanced "length" bytes.
+
+To check the result, read the "control" field:
+ error bit set -> something went wrong.
+ all bits cleared -> transfer finished successfully.
+ otherwise -> transfer still in progress (doesn't happen
+ today due to implementation not being async,
+ but may in the future).
+
= Host-side API =
The following functions are available to the QEMU programmer for adding
@@ -159,6 +219,17 @@ will convert a 16-, 32-, or 64-bit integer to little-endian, then add
a dynamically allocated copy of the appropriately sized item to fw_cfg
under the given selector key value.
+== fw_cfg_modify_iXX() ==
+
+Modify the value of an XX-bit item (where XX may be 16, 32, or 64).
+Similarly to the corresponding fw_cfg_add_iXX() function set, convert
+a 16-, 32-, or 64-bit integer to little endian, create a dynamically
+allocated copy of the required size, and replace the existing item at
+the given selector key value with the newly allocated one. The previous
+item, assumed to have been allocated during an earlier call to
+fw_cfg_add_iXX() or fw_cfg_modify_iXX() (of the same width XX), is freed
+before the function returns.
+
== fw_cfg_add_file() ==
Given a filename (i.e., fw_cfg item name), starting pointer, and size,
@@ -216,6 +287,21 @@ the following syntax:
where <item_name> is the fw_cfg item name, and <path> is the location
on the host file system of a file containing the data to be inserted.
+Small enough items may be provided directly as strings on the command
+line, using the syntax:
+
+ -fw_cfg [name=]<item_name>,string=<string>
+
+The terminating NUL character of the content <string> will NOT be
+included as part of the fw_cfg item data, which is consistent with
+the absence of a NUL terminator for items inserted via the file option.
+
+Both <item_name> and, if applicable, the content <string> are passed
+through by QEMU without any interpretation, expansion, or further
+processing. Any such processing (potentially performed e.g., by the shell)
+is outside of QEMU's responsibility; as such, using plain ASCII characters
+is recommended.
+
NOTE: Users *SHOULD* choose item names beginning with the prefix "opt/"
when using the "-fw_cfg" command line option, to avoid conflicting with
item names used internally by QEMU. For instance:
diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
index 4eadad1..e0d71e2 100644
--- a/docs/specs/vhost-user.txt
+++ b/docs/specs/vhost-user.txt
@@ -115,11 +115,13 @@ the ones that do:
* VHOST_GET_FEATURES
* VHOST_GET_PROTOCOL_FEATURES
* VHOST_GET_VRING_BASE
+ * VHOST_SET_LOG_BASE (if VHOST_USER_PROTOCOL_F_LOG_SHMFD)
There are several messages that the master sends with file descriptors passed
in the ancillary data:
* VHOST_SET_MEM_TABLE
+ * VHOST_SET_LOG_BASE (if VHOST_USER_PROTOCOL_F_LOG_SHMFD)
* VHOST_SET_LOG_FD
* VHOST_SET_VRING_KICK
* VHOST_SET_VRING_CALL
@@ -140,8 +142,7 @@ Multiple queue support
Multiple queue is treated as a protocol extension, hence the slave has to
implement protocol features first. The multiple queues feature is supported
-only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set:
-#define VHOST_USER_PROTOCOL_F_MQ 0
+only when the protocol feature VHOST_USER_PROTOCOL_F_MQ (bit 0) is set.
The max number of queues the slave supports can be queried with message
VHOST_USER_GET_PROTOCOL_FEATURES. Master should stop when the number of
@@ -152,6 +153,49 @@ queue in the sent message to identify a specified queue. One queue pair
is enabled initially. More queues are enabled dynamically, by sending
message VHOST_USER_SET_VRING_ENABLE.
+Migration
+---------
+
+During live migration, the master may need to track the modifications
+the slave makes to the memory mapped regions. The client should mark
+the dirty pages in a log. Once it complies to this logging, it may
+declare the VHOST_F_LOG_ALL vhost feature.
+
+All the modifications to memory pointed by vring "descriptor" should
+be marked. Modifications to "used" vring should be marked if
+VHOST_VRING_F_LOG is part of ring's features.
+
+Dirty pages are of size:
+#define VHOST_LOG_PAGE 0x1000
+
+The log memory fd is provided in the ancillary data of
+VHOST_USER_SET_LOG_BASE message when the slave has
+VHOST_USER_PROTOCOL_F_LOG_SHMFD protocol feature.
+
+The size of the log may be computed by using all the known guest
+addresses. The log covers from address 0 to the maximum of guest
+regions. In pseudo-code, to mark page at "addr" as dirty:
+
+page = addr / VHOST_LOG_PAGE
+log[page / 8] |= 1 << page % 8
+
+Use atomic operations, as the log may be concurrently manipulated.
+
+VHOST_USER_SET_LOG_FD is an optional message with an eventfd in
+ancillary data, it may be used to inform the master that the log has
+been modified.
+
+Once the source has finished migration, VHOST_USER_RESET_OWNER message
+will be sent by the source. No further update must be done before the
+destination takes over with new regions & rings.
+
+Protocol features
+-----------------
+
+#define VHOST_USER_PROTOCOL_F_MQ 0
+#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
+#define VHOST_USER_PROTOCOL_F_RARP 2
+
Message types
-------------
@@ -236,6 +280,7 @@ Message types
Id: 6
Equivalent ioctl: VHOST_SET_LOG_BASE
Master payload: u64
+ Slave payload: N/A
Sets the logging base address.
@@ -337,3 +382,17 @@ Message types
Master payload: vring state description
Signal slave to enable or disable corresponding vring.
+
+ * VHOST_USER_SEND_RARP
+
+ Id: 19
+ Equivalent ioctl: N/A
+ Master payload: u64
+
+ Ask vhost user backend to broadcast a fake RARP to notify the migration
+ is terminated for guest that does not support GUEST_ANNOUNCE.
+ Only legal if feature bit VHOST_USER_F_PROTOCOL_FEATURES is present in
+ VHOST_USER_GET_FEATURES and protocol feature bit VHOST_USER_PROTOCOL_F_RARP
+ is present in VHOST_USER_GET_PROTOCOL_FEATURES.
+ The first 6 bytes of the payload contain the mac address of the guest to
+ allow the vhost user backend to construct and broadcast the fake RARP.
diff --git a/docs/virtio-migration.txt b/docs/virtio-migration.txt
new file mode 100644
index 0000000..cf66458
--- /dev/null
+++ b/docs/virtio-migration.txt
@@ -0,0 +1,106 @@
+Virtio devices and migration
+============================
+
+Copyright 2015 IBM Corp.
+
+This work is licensed under the terms of the GNU GPL, version 2 or later. See
+the COPYING file in the top-level directory.
+
+Saving and restoring the state of virtio devices is a bit of a twisty maze,
+for several reasons:
+- state is distributed between several parts:
+ - virtio core, for common fields like features, number of queues, ...
+ - virtio transport (pci, ccw, ...), for the different proxy devices and
+ transport specific state (msix vectors, indicators, ...)
+ - virtio device (net, blk, ...), for the different device types and their
+ state (mac address, request queue, ...)
+- most fields are saved via the stream interface; subsequently, subsections
+ have been added to make cross-version migration possible
+
+This file attempts to document the current procedure and point out some
+caveats.
+
+
+Save state procedure
+====================
+
+virtio core virtio transport virtio device
+----------- ---------------- -------------
+
+ save() function registered
+ via register_savevm()
+virtio_save() <----------
+ ------> save_config()
+ - save proxy device
+ - save transport-specific
+ device fields
+- save common device
+ fields
+- save common virtqueue
+ fields
+ ------> save_queue()
+ - save transport-specific
+ virtqueue fields
+ ------> save_device()
+ - save device-specific
+ fields
+- save subsections
+ - device endianness,
+ if changed from
+ default endianness
+ - 64 bit features, if
+ any high feature bit
+ is set
+ - virtio-1 virtqueue
+ fields, if VERSION_1
+ is set
+
+
+Load state procedure
+====================
+
+virtio core virtio transport virtio device
+----------- ---------------- -------------
+
+ load() function registered
+ via register_savevm()
+virtio_load() <----------
+ ------> load_config()
+ - load proxy device
+ - load transport-specific
+ device fields
+- load common device
+ fields
+- load common virtqueue
+ fields
+ ------> load_queue()
+ - load transport-specific
+ virtqueue fields
+- notify guest
+ ------> load_device()
+ - load device-specific
+ fields
+- load subsections
+ - device endianness
+ - 64 bit features
+ - virtio-1 virtqueue
+ fields
+- sanitize endianness
+- sanitize features
+- virtqueue index sanity
+ check
+ - feature-dependent setup
+
+
+Implications of this setup
+==========================
+
+Devices need to be careful in their state processing during load: The
+load_device() procedure is invoked by the core before subsections have
+been loaded. Any code that depends on information transmitted in subsections
+therefore has to be invoked in the device's load() function _after_
+virtio_load() returned (like e.g. code depending on features).
+
+Any extension of the state being migrated should be done in subsections
+added to the core for compatibility reasons. If transport or device specific
+state is added, core needs to invoke a callback from the new subsection.
diff --git a/exec.c b/exec.c
index aad94a0..8af2570 100644
--- a/exec.c
+++ b/exec.c
@@ -55,6 +55,9 @@
#include "exec/ram_addr.h"
#include "qemu/range.h"
+#ifndef _WIN32
+#include "qemu/mmap-alloc.h"
+#endif
//#define DEBUG_SUBPAGE
@@ -84,9 +87,9 @@ static MemoryRegion io_mem_unassigned;
*/
#define RAM_RESIZEABLE (1 << 2)
-/* An extra page is mapped on top of this RAM.
+/* RAM is backed by an mmapped file.
*/
-#define RAM_EXTRA (1 << 3)
+#define RAM_FILE (1 << 3)
#endif
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
@@ -1205,13 +1208,10 @@ static void *file_ram_alloc(RAMBlock *block,
char *filename;
char *sanitized_name;
char *c;
- void *ptr;
- void *area = NULL;
+ void *area;
int fd;
uint64_t hpagesize;
- uint64_t total;
Error *local_err = NULL;
- size_t offset;
hpagesize = gethugepagesize(path, &local_err);
if (local_err) {
@@ -1255,7 +1255,6 @@ static void *file_ram_alloc(RAMBlock *block,
g_free(filename);
memory = ROUND_UP(memory, hpagesize);
- total = memory + hpagesize;
/*
* ftruncate is not supported by hugetlbfs in older
@@ -1267,40 +1266,14 @@ static void *file_ram_alloc(RAMBlock *block,
perror("ftruncate");
}
- ptr = mmap(0, total, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS,
- -1, 0);
- if (ptr == MAP_FAILED) {
- error_setg_errno(errp, errno,
- "unable to allocate memory range for hugepages");
- close(fd);
- goto error;
- }
-
- offset = QEMU_ALIGN_UP((uintptr_t)ptr, hpagesize) - (uintptr_t)ptr;
-
- area = mmap(ptr + offset, memory, PROT_READ | PROT_WRITE,
- (block->flags & RAM_SHARED ? MAP_SHARED : MAP_PRIVATE) |
- MAP_FIXED,
- fd, 0);
+ area = qemu_ram_mmap(fd, memory, hpagesize, block->flags & RAM_SHARED);
if (area == MAP_FAILED) {
error_setg_errno(errp, errno,
"unable to map backing store for hugepages");
- munmap(ptr, total);
close(fd);
goto error;
}
- if (offset > 0) {
- munmap(ptr, offset);
- }
- ptr += offset;
- total -= offset;
-
- if (total > memory + getpagesize()) {
- munmap(ptr + memory + getpagesize(),
- total - memory - getpagesize());
- }
-
if (mem_prealloc) {
os_mem_prealloc(fd, area, memory);
}
@@ -1618,7 +1591,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
new_block->used_length = size;
new_block->max_length = size;
new_block->flags = share ? RAM_SHARED : 0;
- new_block->flags |= RAM_EXTRA;
+ new_block->flags |= RAM_FILE;
new_block->host = file_ram_alloc(new_block, size,
mem_path, errp);
if (!new_block->host) {
@@ -1720,8 +1693,8 @@ static void reclaim_ramblock(RAMBlock *block)
xen_invalidate_map_cache_entry(block->host);
#ifndef _WIN32
} else if (block->fd >= 0) {
- if (block->flags & RAM_EXTRA) {
- munmap(block->host, block->max_length + getpagesize());
+ if (block->flags & RAM_FILE) {
+ qemu_ram_munmap(block->host, block->max_length);
} else {
munmap(block->host, block->max_length);
}
diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index 65ad329..ec9cc7f 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -14,7 +14,7 @@
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "virtio-9p-coth.h"
int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 2efebf3..7cb55ee 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -14,7 +14,7 @@
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "virtio-9p-coth.h"
int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode,
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 42ee614..e1953a9 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -14,7 +14,7 @@
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "virtio-9p-coth.h"
static ssize_t __readlink(V9fsState *s, V9fsPath *path, V9fsString *buf)
diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c
index 18ee08d..55c0d23 100644
--- a/hw/9pfs/coxattr.c
+++ b/hw/9pfs/coxattr.c
@@ -14,7 +14,7 @@
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "virtio-9p-coth.h"
int v9fs_co_llistxattr(V9fsPDU *pdu, V9fsPath *path, void *value, size_t size)
diff --git a/hw/9pfs/virtio-9p-coth.c b/hw/9pfs/virtio-9p-coth.c
index 8185c53..5057f8d 100644
--- a/hw/9pfs/virtio-9p-coth.c
+++ b/hw/9pfs/virtio-9p-coth.c
@@ -15,7 +15,7 @@
#include "fsdev/qemu-fsdev.h"
#include "qemu/thread.h"
#include "qemu/event_notifier.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "virtio-9p-coth.h"
/* v9fs glib thread pool */
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 4f51b25..0fbe49a 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -16,7 +16,7 @@
#define _QEMU_VIRTIO_9P_COTH_H
#include "qemu/thread.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "virtio-9p.h"
#include <glib.h>
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 2e7d488..d7a4dc1 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -13,7 +13,7 @@
#include "fsdev/file-op-9p.h"
#include "fsdev/virtio-9p-marshal.h"
#include "qemu/thread.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
enum {
P9_TLERROR = 6,
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 4e7160c..5d38c47 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -119,7 +119,7 @@ static const MemMapEntry a15memmap[] = {
[VIRT_GIC_REDIST] = { 0x080A0000, 0x00F60000 },
[VIRT_UART] = { 0x09000000, 0x00001000 },
[VIRT_RTC] = { 0x09010000, 0x00001000 },
- [VIRT_FW_CFG] = { 0x09020000, 0x0000000a },
+ [VIRT_FW_CFG] = { 0x09020000, 0x00000018 },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
@@ -677,13 +677,13 @@ static void create_flash(const VirtBoardInfo *vbi)
g_free(nodename);
}
-static void create_fw_cfg(const VirtBoardInfo *vbi)
+static void create_fw_cfg(const VirtBoardInfo *vbi, AddressSpace *as)
{
hwaddr base = vbi->memmap[VIRT_FW_CFG].base;
hwaddr size = vbi->memmap[VIRT_FW_CFG].size;
char *nodename;
- fw_cfg_init_mem_wide(base + 8, base, 8);
+ fw_cfg_init_mem_wide(base + 8, base, 8, base + 16, as);
nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
qemu_fdt_add_subnode(vbi->fdt, nodename);
@@ -1031,7 +1031,7 @@ static void machvirt_init(MachineState *machine)
*/
create_virtio_devices(vbi, pic);
- create_fw_cfg(vbi);
+ create_fw_cfg(vbi, &address_space_memory);
rom_set_fw(fw_cfg_find());
guest_info->smp_cpus = smp_cpus;
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 8e93509..9354037 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -488,10 +488,10 @@ static inline int vmsvga_fill_rect(struct vmsvga_state_s *s,
#endif
struct vmsvga_cursor_definition_s {
- int width;
- int height;
+ uint32_t width;
+ uint32_t height;
int id;
- int bpp;
+ uint32_t bpp;
int hot_x;
int hot_y;
uint32_t mask[1024];
@@ -658,7 +658,10 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
cursor.bpp = vmsvga_fifo_read(s);
args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
- if (SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
+ if (cursor.width > 256 ||
+ cursor.height > 256 ||
+ cursor.bpp > 32 ||
+ SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) {
goto badcmd;
}
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 08055a8..3fe27fa 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -22,6 +22,7 @@
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
#include "intel_iommu_internal.h"
+#include "hw/pci/pci.h"
/*#define DEBUG_INTEL_IOMMU*/
#ifdef DEBUG_INTEL_IOMMU
@@ -166,19 +167,17 @@ static gboolean vtd_hash_remove_by_page(gpointer key, gpointer value,
*/
static void vtd_reset_context_cache(IntelIOMMUState *s)
{
- VTDAddressSpace **pvtd_as;
VTDAddressSpace *vtd_as;
- uint32_t bus_it;
+ VTDBus *vtd_bus;
+ GHashTableIter bus_it;
uint32_t devfn_it;
+ g_hash_table_iter_init(&bus_it, s->vtd_as_by_busptr);
+
VTD_DPRINTF(CACHE, "global context_cache_gen=1");
- for (bus_it = 0; bus_it < VTD_PCI_BUS_MAX; ++bus_it) {
- pvtd_as = s->address_spaces[bus_it];
- if (!pvtd_as) {
- continue;
- }
+ while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_bus)) {
for (devfn_it = 0; devfn_it < VTD_PCI_DEVFN_MAX; ++devfn_it) {
- vtd_as = pvtd_as[devfn_it];
+ vtd_as = vtd_bus->dev_as[devfn_it];
if (!vtd_as) {
continue;
}
@@ -754,12 +753,13 @@ static inline bool vtd_is_interrupt_addr(hwaddr addr)
* @is_write: The access is a write operation
* @entry: IOMMUTLBEntry that contain the addr to be translated and result
*/
-static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, uint8_t bus_num,
+static void vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
uint8_t devfn, hwaddr addr, bool is_write,
IOMMUTLBEntry *entry)
{
IntelIOMMUState *s = vtd_as->iommu_state;
VTDContextEntry ce;
+ uint8_t bus_num = pci_bus_num(bus);
VTDContextCacheEntry *cc_entry = &vtd_as->context_cache_entry;
uint64_t slpte;
uint32_t level;
@@ -874,6 +874,29 @@ static void vtd_context_global_invalidate(IntelIOMMUState *s)
}
}
+
+/* Find the VTD address space currently associated with a given bus number,
+ */
+static VTDBus *vtd_find_as_from_bus_num(IntelIOMMUState *s, uint8_t bus_num)
+{
+ VTDBus *vtd_bus = s->vtd_as_by_bus_num[bus_num];
+ if (!vtd_bus) {
+ /* Iterate over the registered buses to find the one
+ * which currently hold this bus number, and update the bus_num lookup table:
+ */
+ GHashTableIter iter;
+
+ g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
+ while (g_hash_table_iter_next (&iter, NULL, (void**)&vtd_bus)) {
+ if (pci_bus_num(vtd_bus->bus) == bus_num) {
+ s->vtd_as_by_bus_num[bus_num] = vtd_bus;
+ return vtd_bus;
+ }
+ }
+ }
+ return vtd_bus;
+}
+
/* Do a context-cache device-selective invalidation.
* @func_mask: FM field after shifting
*/
@@ -882,7 +905,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
uint16_t func_mask)
{
uint16_t mask;
- VTDAddressSpace **pvtd_as;
+ VTDBus *vtd_bus;
VTDAddressSpace *vtd_as;
uint16_t devfn;
uint16_t devfn_it;
@@ -903,11 +926,11 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
}
VTD_DPRINTF(INV, "device-selective invalidation source 0x%"PRIx16
" mask %"PRIu16, source_id, mask);
- pvtd_as = s->address_spaces[VTD_SID_TO_BUS(source_id)];
- if (pvtd_as) {
+ vtd_bus = vtd_find_as_from_bus_num(s, VTD_SID_TO_BUS(source_id));
+ if (vtd_bus) {
devfn = VTD_SID_TO_DEVFN(source_id);
for (devfn_it = 0; devfn_it < VTD_PCI_DEVFN_MAX; ++devfn_it) {
- vtd_as = pvtd_as[devfn_it];
+ vtd_as = vtd_bus->dev_as[devfn_it];
if (vtd_as && ((devfn_it & mask) == (devfn & mask))) {
VTD_DPRINTF(INV, "invalidate context-cahce of devfn 0x%"PRIx16,
devfn_it);
@@ -1805,11 +1828,11 @@ static IOMMUTLBEntry vtd_iommu_translate(MemoryRegion *iommu, hwaddr addr,
return ret;
}
- vtd_do_iommu_translate(vtd_as, vtd_as->bus_num, vtd_as->devfn, addr,
+ vtd_do_iommu_translate(vtd_as, vtd_as->bus, vtd_as->devfn, addr,
is_write, &ret);
VTD_DPRINTF(MMU,
"bus %"PRIu8 " slot %"PRIu8 " func %"PRIu8 " devfn %"PRIu8
- " gpa 0x%"PRIx64 " hpa 0x%"PRIx64, vtd_as->bus_num,
+ " gpa 0x%"PRIx64 " hpa 0x%"PRIx64, pci_bus_num(vtd_as->bus),
VTD_PCI_SLOT(vtd_as->devfn), VTD_PCI_FUNC(vtd_as->devfn),
vtd_as->devfn, addr, ret.translated_addr);
return ret;
@@ -1839,6 +1862,38 @@ static Property vtd_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+
+VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
+{
+ uintptr_t key = (uintptr_t)bus;
+ VTDBus *vtd_bus = g_hash_table_lookup(s->vtd_as_by_busptr, &key);
+ VTDAddressSpace *vtd_dev_as;
+
+ if (!vtd_bus) {
+ /* No corresponding free() */
+ vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * VTD_PCI_DEVFN_MAX);
+ vtd_bus->bus = bus;
+ key = (uintptr_t)bus;
+ g_hash_table_insert(s->vtd_as_by_busptr, &key, vtd_bus);
+ }
+
+ vtd_dev_as = vtd_bus->dev_as[devfn];
+
+ if (!vtd_dev_as) {
+ vtd_bus->dev_as[devfn] = vtd_dev_as = g_malloc0(sizeof(VTDAddressSpace));
+
+ vtd_dev_as->bus = bus;
+ vtd_dev_as->devfn = (uint8_t)devfn;
+ vtd_dev_as->iommu_state = s;
+ vtd_dev_as->context_cache_entry.context_cache_gen = 0;
+ memory_region_init_iommu(&vtd_dev_as->iommu, OBJECT(s),
+ &s->iommu_ops, "intel_iommu", UINT64_MAX);
+ address_space_init(&vtd_dev_as->as,
+ &vtd_dev_as->iommu, "intel_iommu");
+ }
+ return vtd_dev_as;
+}
+
/* Do the initialization. It will also be called when reset, so pay
* attention when adding new initialization stuff.
*/
@@ -1931,13 +1986,15 @@ static void vtd_realize(DeviceState *dev, Error **errp)
IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);
VTD_DPRINTF(GENERAL, "");
- memset(s->address_spaces, 0, sizeof(s->address_spaces));
+ memset(s->vtd_as_by_bus_num, 0, sizeof(s->vtd_as_by_bus_num));
memory_region_init_io(&s->csrmem, OBJECT(s), &vtd_mem_ops, s,
"intel_iommu", DMAR_REG_SIZE);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->csrmem);
/* No corresponding destroy */
s->iotlb = g_hash_table_new_full(vtd_uint64_hash, vtd_uint64_equal,
g_free, g_free);
+ s->vtd_as_by_busptr = g_hash_table_new_full(vtd_uint64_hash, vtd_uint64_equal,
+ g_free, g_free);
vtd_init(s);
}
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 682867a..3d958ba 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -752,14 +752,15 @@ static void pc_build_smbios(FWCfgState *fw_cfg)
}
}
-static FWCfgState *bochs_bios_init(void)
+static FWCfgState *bochs_bios_init(AddressSpace *as)
{
FWCfgState *fw_cfg;
uint64_t *numa_fw_cfg;
int i, j;
unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
- fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT);
+ fw_cfg = fw_cfg_init_io_dma(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 4, as);
+
/* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
*
* SeaBIOS needs FW_CFG_MAX_CPUS for CPU hotplug, but the CPU hotplug
@@ -1077,11 +1078,10 @@ out:
return cpu;
}
-static const char *current_cpu_model;
-
void pc_hot_add_cpu(const int64_t id, Error **errp)
{
X86CPU *cpu;
+ MachineState *machine = MACHINE(qdev_get_machine());
int64_t apic_id = x86_cpu_apic_id_from_index(id);
Error *local_err = NULL;
@@ -1109,7 +1109,7 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
return;
}
- cpu = pc_new_cpu(current_cpu_model, apic_id, &local_err);
+ cpu = pc_new_cpu(machine->cpu_model, apic_id, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
@@ -1117,22 +1117,22 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
object_unref(OBJECT(cpu));
}
-void pc_cpus_init(const char *cpu_model)
+void pc_cpus_init(PCMachineState *pcms)
{
int i;
X86CPU *cpu = NULL;
+ MachineState *machine = MACHINE(pcms);
Error *error = NULL;
unsigned long apic_id_limit;
/* init CPUs */
- if (cpu_model == NULL) {
+ if (machine->cpu_model == NULL) {
#ifdef TARGET_X86_64
- cpu_model = "qemu64";
+ machine->cpu_model = "qemu64";
#else
- cpu_model = "qemu32";
+ machine->cpu_model = "qemu32";
#endif
}
- current_cpu_model = cpu_model;
apic_id_limit = pc_apic_id_limit(max_cpus);
if (apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) {
@@ -1142,7 +1142,7 @@ void pc_cpus_init(const char *cpu_model)
}
for (i = 0; i < smp_cpus; i++) {
- cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i),
+ cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i),
&error);
if (error) {
error_report_err(error);
@@ -1393,7 +1393,8 @@ FWCfgState *pc_memory_init(PCMachineState *pcms,
option_rom_mr,
1);
- fw_cfg = bochs_bios_init();
+ fw_cfg = bochs_bios_init(&address_space_memory);
+
rom_set_fw(fw_cfg);
if (guest_info->has_reserved_memory && pcms->hotplug_memory.base) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a91cc3d..9d4425a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -139,7 +139,7 @@ static void pc_init1(MachineState *machine,
exit(1);
}
- pc_cpus_init(machine->cpu_model);
+ pc_cpus_init(pcms);
if (kvm_enabled() && kvmclock_enabled) {
kvmclock_create();
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 19e6670..3744abd 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -128,7 +128,7 @@ static void pc_q35_init(MachineState *machine)
exit(1);
}
- pc_cpus_init(machine->cpu_model);
+ pc_cpus_init(pcms);
pc_acpi_init("q35-acpi-dsdt.aml");
kvmclock_create();
diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c
index 7b25d27..1f5a40d 100644
--- a/hw/input/virtio-input.c
+++ b/hw/input/virtio-input.c
@@ -20,6 +20,10 @@ void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
unsigned have, need;
int i, len;
+ if (!vinput->active) {
+ return;
+ }
+
/* queue up events ... */
if (vinput->qindex == vinput->qsize) {
vinput->qsize++;
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 360699f..1ffc803 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -394,7 +394,7 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
/* SMI_EN = PMBASE + 30. SMI control and enable register */
if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
- cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
+ cpu_interrupt(current_cpu, CPU_INTERRUPT_SMI);
}
}
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 506fe0d..2bae994 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -25,6 +25,7 @@
#include "sysemu/numa.h"
#include "sysemu/kvm.h"
#include "trace.h"
+#include "hw/virtio/vhost.h"
typedef struct pc_dimms_capacity {
uint64_t size;
@@ -96,6 +97,12 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
goto out;
}
+ if (!vhost_has_free_slot()) {
+ error_setg(&local_err, "a used vhost backend has no free"
+ " memory slots left");
+ goto out;
+ }
+
memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);
vmstate_register_ram(mr, dev);
numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 2bce891..d91b7b1 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -85,6 +85,8 @@ static const int user_feature_bits[] = {
VIRTIO_NET_F_CTRL_MAC_ADDR,
VIRTIO_NET_F_CTRL_GUEST_OFFLOADS,
+ VIRTIO_NET_F_GUEST_ANNOUNCE,
+
VIRTIO_NET_F_MQ,
VHOST_INVALID_FEATURE_BIT
@@ -252,8 +254,7 @@ static int vhost_net_start_one(struct vhost_net *net,
file.fd = net->backend;
for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
const VhostOps *vhost_ops = net->dev.vhost_ops;
- r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND,
- &file);
+ r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
if (r < 0) {
r = -errno;
goto fail;
@@ -266,8 +267,7 @@ fail:
if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
while (file.index-- > 0) {
const VhostOps *vhost_ops = net->dev.vhost_ops;
- int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND,
- &file);
+ int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
assert(r >= 0);
}
}
@@ -289,15 +289,13 @@ static void vhost_net_stop_one(struct vhost_net *net,
if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
const VhostOps *vhost_ops = net->dev.vhost_ops;
- int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND,
- &file);
+ int r = vhost_ops->vhost_net_set_backend(&net->dev, &file);
assert(r >= 0);
}
} else if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER) {
for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
const VhostOps *vhost_ops = net->dev.vhost_ops;
- int r = vhost_ops->vhost_call(&net->dev, VHOST_RESET_DEVICE,
- NULL);
+ int r = vhost_ops->vhost_reset_device(&net->dev);
assert(r >= 0);
}
}
@@ -390,6 +388,18 @@ void vhost_net_cleanup(struct vhost_net *net)
g_free(net);
}
+int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
+{
+ const VhostOps *vhost_ops = net->dev.vhost_ops;
+ int r = -1;
+
+ if (vhost_ops->vhost_migration_done) {
+ r = vhost_ops->vhost_migration_done(&net->dev, mac_addr);
+ }
+
+ return r;
+}
+
bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
{
return vhost_virtqueue_pending(&net->dev, idx);
@@ -428,8 +438,8 @@ int vhost_set_vring_enable(NetClientState *nc, int enable)
VHostNetState *net = get_vhost_net(nc);
const VhostOps *vhost_ops = net->dev.vhost_ops;
- if (vhost_ops->vhost_backend_set_vring_enable) {
- return vhost_ops->vhost_backend_set_vring_enable(&net->dev, enable);
+ if (vhost_ops->vhost_set_vring_enable) {
+ return vhost_ops->vhost_set_vring_enable(&net->dev, enable);
}
return 0;
@@ -481,6 +491,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
{
}
+int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
+{
+ return -1;
+}
+
VHostNetState *get_vhost_net(NetClientState *nc)
{
return 0;
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 658f8c4..73b0a81 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -23,6 +23,7 @@
*/
#include "hw/hw.h"
#include "sysemu/sysemu.h"
+#include "sysemu/dma.h"
#include "hw/isa/isa.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/sysbus.h"
@@ -30,7 +31,7 @@
#include "qemu/error-report.h"
#include "qemu/config-file.h"
-#define FW_CFG_SIZE 2
+#define FW_CFG_CTL_SIZE 2
#define FW_CFG_NAME "fw_cfg"
#define FW_CFG_PATH "/machine/" FW_CFG_NAME
@@ -42,6 +43,18 @@
#define FW_CFG_IO(obj) OBJECT_CHECK(FWCfgIoState, (obj), TYPE_FW_CFG_IO)
#define FW_CFG_MEM(obj) OBJECT_CHECK(FWCfgMemState, (obj), TYPE_FW_CFG_MEM)
+/* FW_CFG_VERSION bits */
+#define FW_CFG_VERSION 0x01
+#define FW_CFG_VERSION_DMA 0x02
+
+/* FW_CFG_DMA_CONTROL bits */
+#define FW_CFG_DMA_CTL_ERROR 0x01
+#define FW_CFG_DMA_CTL_READ 0x02
+#define FW_CFG_DMA_CTL_SKIP 0x04
+#define FW_CFG_DMA_CTL_SELECT 0x08
+
+#define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* "QEMU CFG" */
+
typedef struct FWCfgEntry {
uint32_t len;
uint8_t *data;
@@ -59,6 +72,11 @@ struct FWCfgState {
uint16_t cur_entry;
uint32_t cur_offset;
Notifier machine_ready;
+
+ bool dma_enabled;
+ dma_addr_t dma_addr;
+ AddressSpace *dma_as;
+ MemoryRegion dma_iomem;
};
struct FWCfgIoState {
@@ -67,7 +85,7 @@ struct FWCfgIoState {
/*< public >*/
MemoryRegion comb_iomem;
- uint32_t iobase;
+ uint32_t iobase, dma_iobase;
};
struct FWCfgMemState {
@@ -292,6 +310,129 @@ static void fw_cfg_data_mem_write(void *opaque, hwaddr addr,
} while (i);
}
+static void fw_cfg_dma_transfer(FWCfgState *s)
+{
+ dma_addr_t len;
+ FWCfgDmaAccess dma;
+ int arch;
+ FWCfgEntry *e;
+ int read;
+ dma_addr_t dma_addr;
+
+ /* Reset the address before the next access */
+ dma_addr = s->dma_addr;
+ s->dma_addr = 0;
+
+ if (dma_memory_read(s->dma_as, dma_addr, &dma, sizeof(dma))) {
+ stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control),
+ FW_CFG_DMA_CTL_ERROR);
+ return;
+ }
+
+ dma.address = be64_to_cpu(dma.address);
+ dma.length = be32_to_cpu(dma.length);
+ dma.control = be32_to_cpu(dma.control);
+
+ if (dma.control & FW_CFG_DMA_CTL_SELECT) {
+ fw_cfg_select(s, dma.control >> 16);
+ }
+
+ arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);
+ e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];
+
+ if (dma.control & FW_CFG_DMA_CTL_READ) {
+ read = 1;
+ } else if (dma.control & FW_CFG_DMA_CTL_SKIP) {
+ read = 0;
+ } else {
+ dma.length = 0;
+ }
+
+ dma.control = 0;
+
+ while (dma.length > 0 && !(dma.control & FW_CFG_DMA_CTL_ERROR)) {
+ if (s->cur_entry == FW_CFG_INVALID || !e->data ||
+ s->cur_offset >= e->len) {
+ len = dma.length;
+
+ /* If the access is not a read access, it will be a skip access,
+ * tested before.
+ */
+ if (read) {
+ if (dma_memory_set(s->dma_as, dma.address, 0, len)) {
+ dma.control |= FW_CFG_DMA_CTL_ERROR;
+ }
+ }
+
+ } else {
+ if (dma.length <= (e->len - s->cur_offset)) {
+ len = dma.length;
+ } else {
+ len = (e->len - s->cur_offset);
+ }
+
+ if (e->read_callback) {
+ e->read_callback(e->callback_opaque, s->cur_offset);
+ }
+
+ /* If the access is not a read access, it will be a skip access,
+ * tested before.
+ */
+ if (read) {
+ if (dma_memory_write(s->dma_as, dma.address,
+ &e->data[s->cur_offset], len)) {
+ dma.control |= FW_CFG_DMA_CTL_ERROR;
+ }
+ }
+
+ s->cur_offset += len;
+ }
+
+ dma.address += len;
+ dma.length -= len;
+
+ }
+
+ stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control),
+ dma.control);
+
+ trace_fw_cfg_read(s, 0);
+}
+
+static uint64_t fw_cfg_dma_mem_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ /* Return a signature value (and handle various read sizes) */
+ return extract64(FW_CFG_DMA_SIGNATURE, (8 - addr - size) * 8, size * 8);
+}
+
+static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ FWCfgState *s = opaque;
+
+ if (size == 4) {
+ if (addr == 0) {
+ /* FWCfgDmaAccess high address */
+ s->dma_addr = value << 32;
+ } else if (addr == 4) {
+ /* FWCfgDmaAccess low address */
+ s->dma_addr |= value;
+ fw_cfg_dma_transfer(s);
+ }
+ } else if (size == 8 && addr == 0) {
+ s->dma_addr = value;
+ fw_cfg_dma_transfer(s);
+ }
+}
+
+static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
+ unsigned size, bool is_write)
+{
+ return !is_write || ((size == 4 && (addr == 0 || addr == 4)) ||
+ (size == 8 && addr == 0));
+}
+
static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
unsigned size, bool is_write)
{
@@ -359,6 +500,15 @@ static const MemoryRegionOps fw_cfg_comb_mem_ops = {
.valid.accepts = fw_cfg_comb_valid,
};
+static const MemoryRegionOps fw_cfg_dma_mem_ops = {
+ .read = fw_cfg_dma_mem_read,
+ .write = fw_cfg_dma_mem_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid.accepts = fw_cfg_dma_mem_valid,
+ .valid.max_access_size = 8,
+ .impl.max_access_size = 8,
+};
+
static void fw_cfg_reset(DeviceState *d)
{
FWCfgState *s = FW_CFG(d);
@@ -399,6 +549,22 @@ static bool is_version_1(void *opaque, int version_id)
return version_id == 1;
}
+static bool fw_cfg_dma_enabled(void *opaque)
+{
+ FWCfgState *s = opaque;
+
+ return s->dma_enabled;
+}
+
+static const VMStateDescription vmstate_fw_cfg_dma = {
+ .name = "fw_cfg/dma",
+ .needed = fw_cfg_dma_enabled,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(dma_addr, FWCfgState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
static const VMStateDescription vmstate_fw_cfg = {
.name = "fw_cfg",
.version_id = 2,
@@ -408,6 +574,10 @@ static const VMStateDescription vmstate_fw_cfg = {
VMSTATE_UINT16_HACK(cur_offset, FWCfgState, is_version_1),
VMSTATE_UINT32_V(cur_offset, FWCfgState, 2),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription*[]) {
+ &vmstate_fw_cfg_dma,
+ NULL,
}
};
@@ -593,7 +763,6 @@ static void fw_cfg_init1(DeviceState *dev)
qdev_init_nofail(dev);
fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
- fw_cfg_add_i32(s, FW_CFG_ID, 1);
fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
@@ -605,25 +774,53 @@ static void fw_cfg_init1(DeviceState *dev)
qemu_add_machine_init_done_notifier(&s->machine_ready);
}
-FWCfgState *fw_cfg_init_io(uint32_t iobase)
+FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
+ AddressSpace *dma_as)
{
DeviceState *dev;
+ FWCfgState *s;
+ uint32_t version = FW_CFG_VERSION;
+ bool dma_enabled = dma_iobase && dma_as;
dev = qdev_create(NULL, TYPE_FW_CFG_IO);
qdev_prop_set_uint32(dev, "iobase", iobase);
+ qdev_prop_set_uint32(dev, "dma_iobase", dma_iobase);
+ qdev_prop_set_bit(dev, "dma_enabled", dma_enabled);
+
fw_cfg_init1(dev);
+ s = FW_CFG(dev);
+
+ if (dma_enabled) {
+ /* 64 bits for the address field */
+ s->dma_as = dma_as;
+ s->dma_addr = 0;
+
+ version |= FW_CFG_VERSION_DMA;
+ }
- return FW_CFG(dev);
+ fw_cfg_add_i32(s, FW_CFG_ID, version);
+
+ return s;
+}
+
+FWCfgState *fw_cfg_init_io(uint32_t iobase)
+{
+ return fw_cfg_init_io_dma(iobase, 0, NULL);
}
-FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr, hwaddr data_addr,
- uint32_t data_width)
+FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
+ hwaddr data_addr, uint32_t data_width,
+ hwaddr dma_addr, AddressSpace *dma_as)
{
DeviceState *dev;
SysBusDevice *sbd;
+ FWCfgState *s;
+ uint32_t version = FW_CFG_VERSION;
+ bool dma_enabled = dma_addr && dma_as;
dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
qdev_prop_set_uint32(dev, "data_width", data_width);
+ qdev_prop_set_bit(dev, "dma_enabled", dma_enabled);
fw_cfg_init1(dev);
@@ -631,13 +828,25 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr, hwaddr data_addr,
sysbus_mmio_map(sbd, 0, ctl_addr);
sysbus_mmio_map(sbd, 1, data_addr);
- return FW_CFG(dev);
+ s = FW_CFG(dev);
+
+ if (dma_enabled) {
+ s->dma_as = dma_as;
+ s->dma_addr = 0;
+ sysbus_mmio_map(sbd, 2, dma_addr);
+ version |= FW_CFG_VERSION_DMA;
+ }
+
+ fw_cfg_add_i32(s, FW_CFG_ID, version);
+
+ return s;
}
FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr)
{
return fw_cfg_init_mem_wide(ctl_addr, data_addr,
- fw_cfg_data_mem_ops.valid.max_access_size);
+ fw_cfg_data_mem_ops.valid.max_access_size,
+ 0, NULL);
}
@@ -664,6 +873,9 @@ static const TypeInfo fw_cfg_info = {
static Property fw_cfg_io_properties[] = {
DEFINE_PROP_UINT32("iobase", FWCfgIoState, iobase, -1),
+ DEFINE_PROP_UINT32("dma_iobase", FWCfgIoState, dma_iobase, -1),
+ DEFINE_PROP_BOOL("dma_enabled", FWCfgIoState, parent_obj.dma_enabled,
+ false),
DEFINE_PROP_END_OF_LIST(),
};
@@ -673,8 +885,15 @@ static void fw_cfg_io_realize(DeviceState *dev, Error **errp)
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
memory_region_init_io(&s->comb_iomem, OBJECT(s), &fw_cfg_comb_mem_ops,
- FW_CFG(s), "fwcfg", FW_CFG_SIZE);
+ FW_CFG(s), "fwcfg", FW_CFG_CTL_SIZE);
sysbus_add_io(sbd, s->iobase, &s->comb_iomem);
+
+ if (FW_CFG(s)->dma_enabled) {
+ memory_region_init_io(&FW_CFG(s)->dma_iomem, OBJECT(s),
+ &fw_cfg_dma_mem_ops, FW_CFG(s), "fwcfg.dma",
+ sizeof(dma_addr_t));
+ sysbus_add_io(sbd, s->dma_iobase, &FW_CFG(s)->dma_iomem);
+ }
}
static void fw_cfg_io_class_init(ObjectClass *klass, void *data)
@@ -695,6 +914,8 @@ static const TypeInfo fw_cfg_io_info = {
static Property fw_cfg_mem_properties[] = {
DEFINE_PROP_UINT32("data_width", FWCfgMemState, data_width, -1),
+ DEFINE_PROP_BOOL("dma_enabled", FWCfgMemState, parent_obj.dma_enabled,
+ false),
DEFINE_PROP_END_OF_LIST(),
};
@@ -705,7 +926,7 @@ static void fw_cfg_mem_realize(DeviceState *dev, Error **errp)
const MemoryRegionOps *data_ops = &fw_cfg_data_mem_ops;
memory_region_init_io(&s->ctl_iomem, OBJECT(s), &fw_cfg_ctl_mem_ops,
- FW_CFG(s), "fwcfg.ctl", FW_CFG_SIZE);
+ FW_CFG(s), "fwcfg.ctl", FW_CFG_CTL_SIZE);
sysbus_init_mmio(sbd, &s->ctl_iomem);
if (s->data_width > data_ops->valid.max_access_size) {
@@ -723,6 +944,13 @@ static void fw_cfg_mem_realize(DeviceState *dev, Error **errp)
memory_region_init_io(&s->data_iomem, OBJECT(s), data_ops, FW_CFG(s),
"fwcfg.data", data_ops->valid.max_access_size);
sysbus_init_mmio(sbd, &s->data_iomem);
+
+ if (FW_CFG(s)->dma_enabled) {
+ memory_region_init_io(&FW_CFG(s)->dma_iomem, OBJECT(s),
+ &fw_cfg_dma_mem_ops, FW_CFG(s), "fwcfg.dma",
+ sizeof(dma_addr_t));
+ sysbus_init_mmio(sbd, &FW_CFG(s)->dma_iomem);
+ }
}
static void fw_cfg_mem_class_init(ObjectClass *klass, void *data)
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 1fb71c8..7b2fbf9 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -764,6 +764,7 @@ static int host_pci_config_read(int pos, int len, uint32_t val)
/* Access real host bridge. */
int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
0, 0, 0, 0, "config");
+ int ret = 0;
if (rc >= size || rc < 0) {
return -ENODEV;
@@ -775,16 +776,18 @@ static int host_pci_config_read(int pos, int len, uint32_t val)
}
if (lseek(config_fd, pos, SEEK_SET) != pos) {
- return -errno;
+ ret = -errno;
+ goto out;
}
do {
rc = read(config_fd, (uint8_t *)&val, len);
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
if (rc != len) {
- return -errno;
+ ret = -errno;
}
-
- return 0;
+out:
+ close(config_fd);
+ return ret;
}
static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index bd74094..c81507d 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -426,31 +426,12 @@ static void mch_reset(DeviceState *qdev)
static AddressSpace *q35_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
{
IntelIOMMUState *s = opaque;
- VTDAddressSpace **pvtd_as;
- int bus_num = pci_bus_num(bus);
+ VTDAddressSpace *vtd_as;
- assert(0 <= bus_num && bus_num <= VTD_PCI_BUS_MAX);
assert(0 <= devfn && devfn <= VTD_PCI_DEVFN_MAX);
- pvtd_as = s->address_spaces[bus_num];
- if (!pvtd_as) {
- /* No corresponding free() */
- pvtd_as = g_malloc0(sizeof(VTDAddressSpace *) * VTD_PCI_DEVFN_MAX);
- s->address_spaces[bus_num] = pvtd_as;
- }
- if (!pvtd_as[devfn]) {
- pvtd_as[devfn] = g_malloc0(sizeof(VTDAddressSpace));
-
- pvtd_as[devfn]->bus_num = (uint8_t)bus_num;
- pvtd_as[devfn]->devfn = (uint8_t)devfn;
- pvtd_as[devfn]->iommu_state = s;
- pvtd_as[devfn]->context_cache_entry.context_cache_gen = 0;
- memory_region_init_iommu(&pvtd_as[devfn]->iommu, OBJECT(s),
- &s->iommu_ops, "intel_iommu", UINT64_MAX);
- address_space_init(&pvtd_as[devfn]->as,
- &pvtd_as[devfn]->iommu, "intel_iommu");
- }
- return &pvtd_as[devfn]->as;
+ vtd_as = vtd_find_add_as(s, bus, devfn);
+ return &vtd_as->as;
}
static void mch_init_dmar(MCHPCIState *mch)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d1b0e53..3852ad1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1169,6 +1169,7 @@ static int spapr_vga_init(PCIBus *pci_bus)
case VGA_DEVICE:
return true;
case VGA_STD:
+ case VGA_VIRTIO:
return pci_vga_init(pci_bus) != NULL;
default:
fprintf(stderr, "This vga model is not supported,"
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 31473e7..5f7f349 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -95,6 +95,11 @@ static const VMStateDescription vmstate_ipl = {
}
};
+static S390IPLState *get_ipl_device(void)
+{
+ return S390_IPL(object_resolve_path_type("", TYPE_S390_IPL, NULL));
+}
+
static uint64_t bios_translate_addr(void *opaque, uint64_t srcaddr)
{
uint64_t dstaddr = *(uint64_t *) opaque;
@@ -218,7 +223,7 @@ static Property s390_ipl_properties[] = {
* - -1 if no valid boot device was found
* - ccw id of the boot device otherwise
*/
-static uint64_t s390_update_iplstate(CPUS390XState *env, S390IPLState *ipl)
+static uint64_t s390_update_iplstate(S390IPLState *ipl)
{
DeviceState *dev_st;
@@ -251,25 +256,19 @@ out:
return (uint32_t) (ipl->cssid << 24 | ipl->ssid << 16 | ipl->devno);
}
-int s390_ipl_update_diag308(IplParameterBlock *iplb)
+void s390_ipl_update_diag308(IplParameterBlock *iplb)
{
- S390IPLState *ipl;
+ S390IPLState *ipl = get_ipl_device();
- ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL));
- if (ipl) {
- ipl->iplb = *iplb;
- ipl->iplb_valid = true;
- return 0;
- }
- return -1;
+ ipl->iplb = *iplb;
+ ipl->iplb_valid = true;
}
IplParameterBlock *s390_ipl_get_iplb(void)
{
- S390IPLState *ipl;
+ S390IPLState *ipl = get_ipl_device();
- ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL));
- if (!ipl || !ipl->iplb_valid) {
+ if (!ipl->iplb_valid) {
return NULL;
}
return &ipl->iplb;
@@ -277,33 +276,33 @@ IplParameterBlock *s390_ipl_get_iplb(void)
void s390_reipl_request(void)
{
- S390IPLState *ipl;
+ S390IPLState *ipl = get_ipl_device();
- ipl = S390_IPL(object_resolve_path(TYPE_S390_IPL, NULL));
ipl->reipl_requested = true;
qemu_system_reset_request();
}
+void s390_ipl_prepare_cpu(S390CPU *cpu)
+{
+ S390IPLState *ipl = get_ipl_device();
+
+ cpu->env.psw.addr = ipl->start_addr;
+ cpu->env.psw.mask = IPL_PSW_MASK;
+
+ if (!ipl->kernel || ipl->iplb_valid) {
+ cpu->env.psw.addr = ipl->bios_start_addr;
+ cpu->env.regs[7] = s390_update_iplstate(ipl);
+ }
+}
+
static void s390_ipl_reset(DeviceState *dev)
{
S390IPLState *ipl = S390_IPL(dev);
- S390CPU *cpu = S390_CPU(qemu_get_cpu(0));
- CPUS390XState *env = &cpu->env;
-
- env->psw.addr = ipl->start_addr;
- env->psw.mask = IPL_PSW_MASK;
if (!ipl->reipl_requested) {
ipl->iplb_valid = false;
}
ipl->reipl_requested = false;
-
- if (!ipl->kernel || ipl->iplb_valid) {
- env->psw.addr = ipl->bios_start_addr;
- env->regs[7] = s390_update_iplstate(env, ipl);
- }
-
- s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
}
static void s390_ipl_class_init(ObjectClass *klass, void *data)
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index 70497bc..7f2b403 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -12,13 +12,16 @@
#ifndef HW_S390_IPL_H
#define HW_S390_IPL_H
+#include "cpu.h"
+
typedef struct IplParameterBlock {
uint8_t reserved1[110];
uint16_t devno;
uint8_t reserved2[88];
} IplParameterBlock;
-int s390_ipl_update_diag308(IplParameterBlock *iplb);
+void s390_ipl_update_diag308(IplParameterBlock *iplb);
+void s390_ipl_prepare_cpu(S390CPU *cpu);
IplParameterBlock *s390_ipl_get_iplb(void);
void s390_reipl_request(void);
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 6195f13..faba773 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -35,26 +35,23 @@ typedef struct S390CcwMachineState {
bool dea_key_wrap;
} S390CcwMachineState;
+static const char *const reset_dev_types[] = {
+ "virtual-css-bridge",
+ "s390-sclp-event-facility",
+ "s390-flic",
+ "diag288",
+};
+
void subsystem_reset(void)
{
- DeviceState *css, *sclp, *flic, *diag288;
+ DeviceState *dev;
+ int i;
- css = DEVICE(object_resolve_path_type("", "virtual-css-bridge", NULL));
- if (css) {
- qdev_reset_all(css);
- }
- sclp = DEVICE(object_resolve_path_type("",
- "s390-sclp-event-facility", NULL));
- if (sclp) {
- qdev_reset_all(sclp);
- }
- flic = DEVICE(object_resolve_path_type("", "s390-flic", NULL));
- if (flic) {
- qdev_reset_all(flic);
- }
- diag288 = DEVICE(object_resolve_path_type("", "diag288", NULL));
- if (diag288) {
- qdev_reset_all(diag288);
+ for (i = 0; i < ARRAY_SIZE(reset_dev_types); i++) {
+ dev = DEVICE(object_resolve_path_type("", reset_dev_types[i], NULL));
+ if (dev) {
+ qdev_reset_all(dev);
+ }
}
}
@@ -164,6 +161,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
NMIClass *nc = NMI_CLASS(oc);
mc->init = ccw_init;
+ mc->reset = s390_machine_reset;
mc->block_default_type = IF_VIRTIO;
mc->no_cdrom = 1;
mc->no_floppy = 1;
@@ -262,6 +260,18 @@ static const TypeInfo ccw_machine_info = {
.driver = "virtio-rng-ccw",\
.property = "max_revision",\
.value = "0",\
+ },{\
+ .driver = "virtio-net-ccw",\
+ .property = "max_revision",\
+ .value = "0",\
+ },{\
+ .driver = "virtio-scsi-ccw",\
+ .property = "max_revision",\
+ .value = "0",\
+ },{\
+ .driver = "vhost-scsi-ccw",\
+ .property = "max_revision",\
+ .value = "0",\
},
static void ccw_machine_2_4_class_init(ObjectClass *oc, void *data)
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index bc013eb..cbde977 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -40,6 +40,7 @@
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/s390-virtio.h"
#include "hw/s390x/storage-keys.h"
+#include "hw/s390x/ipl.h"
#include "cpu.h"
//#define DEBUG_S390
@@ -314,6 +315,19 @@ void s390_nmi(NMIState *n, int cpu_index, Error **errp)
}
}
+void s390_machine_reset(void)
+{
+ S390CPU *ipl_cpu = S390_CPU(qemu_get_cpu(0));
+
+ qemu_devices_reset();
+ s390_cmma_reset();
+ s390_crypto_reset();
+
+ /* all cpus are stopped - configure and start the ipl cpu only */
+ s390_ipl_prepare_cpu(ipl_cpu);
+ s390_cpu_set_state(CPU_STATE_OPERATING, ipl_cpu);
+}
+
static void s390_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -322,6 +336,7 @@ static void s390_machine_class_init(ObjectClass *oc, void *data)
mc->alias = "s390";
mc->desc = "VirtIO based S390 machine";
mc->init = s390_init;
+ mc->reset = s390_machine_reset;
mc->block_default_type = IF_VIRTIO;
mc->max_cpus = 255;
mc->no_serial = 1;
diff --git a/hw/s390x/s390-virtio.h b/hw/s390x/s390-virtio.h
index f389aa1..eebce8e 100644
--- a/hw/s390x/s390-virtio.h
+++ b/hw/s390x/s390-virtio.h
@@ -27,5 +27,6 @@ void s390_init_ipl_dev(const char *kernel_filename,
bool enforce_bios);
void s390_create_virtio_net(BusState *bus, const char *name);
void s390_nmi(NMIState *n, int cpu_index, Error **errp);
+void s390_machine_reset(void);
void s390_memory_init(ram_addr_t mem_size);
#endif
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index fb7983d..00cdac6 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -46,7 +46,7 @@ static int vhost_scsi_set_endpoint(VHostSCSI *s)
memset(&backend, 0, sizeof(backend));
pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
- ret = vhost_ops->vhost_call(&s->dev, VHOST_SCSI_SET_ENDPOINT, &backend);
+ ret = vhost_ops->vhost_scsi_set_endpoint(&s->dev, &backend);
if (ret < 0) {
return -errno;
}
@@ -61,7 +61,7 @@ static void vhost_scsi_clear_endpoint(VHostSCSI *s)
memset(&backend, 0, sizeof(backend));
pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
- vhost_ops->vhost_call(&s->dev, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
+ vhost_ops->vhost_scsi_clear_endpoint(&s->dev, &backend);
}
static int vhost_scsi_start(VHostSCSI *s)
@@ -77,8 +77,7 @@ static int vhost_scsi_start(VHostSCSI *s)
return -ENOSYS;
}
- ret = vhost_ops->vhost_call(&s->dev,
- VHOST_SCSI_GET_ABI_VERSION, &abi_version);
+ ret = vhost_ops->vhost_scsi_get_abi_version(&s->dev, &abi_version);
if (ret < 0) {
return -errno;
}
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 5f39e1e..ee6b43a 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -655,9 +655,12 @@ void hmp_info_usb(Monitor *mon, const QDict *qdict)
dev = port->dev;
if (!dev)
continue;
- monitor_printf(mon, " Device %d.%d, Port %s, Speed %s Mb/s, Product %s\n",
- bus->busnr, dev->addr, port->path, usb_speed(dev->speed),
- dev->product_desc);
+ monitor_printf(mon, " Device %d.%d, Port %s, Speed %s Mb/s, "
+ "Product %s%s%s\n",
+ bus->busnr, dev->addr, port->path,
+ usb_speed(dev->speed), dev->product_desc,
+ dev->qdev.id ? ", ID: " : "",
+ dev->qdev.id ?: "");
}
}
}
diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index f092bb8..02fb110 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -664,7 +664,7 @@ static const VMStateDescription vmstate_usb_audio = {
static Property usb_audio_properties[] = {
DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0),
DEFINE_PROP_UINT32("buffer", USBAudioState, buffer,
- 8 * USBAUDIO_PACKET_SIZE),
+ 32 * USBAUDIO_PACKET_SIZE),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 5e492fd..7695a97 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -451,6 +451,7 @@ static void usb_host_req_complete_iso(struct libusb_transfer *transfer)
}
if (xfer->ring->ep->pid == USB_TOKEN_IN) {
QTAILQ_INSERT_TAIL(&xfer->ring->copy, xfer, next);
+ usb_wakeup(xfer->ring->ep, 0);
} else {
QTAILQ_INSERT_TAIL(&xfer->ring->unused, xfer, next);
}
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 72d1392..1d5f684 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -11,6 +11,7 @@
#include "hw/virtio/vhost.h"
#include "hw/virtio/vhost-backend.h"
#include "qemu/error-report.h"
+#include "linux/vhost.h"
#include <sys/ioctl.h>
@@ -42,6 +43,122 @@ static int vhost_kernel_cleanup(struct vhost_dev *dev)
return close(fd);
}
+static int vhost_kernel_memslots_limit(struct vhost_dev *dev)
+{
+ int limit = 64;
+ char *s;
+
+ if (g_file_get_contents("/sys/module/vhost/parameters/max_mem_regions",
+ &s, NULL, NULL)) {
+ uint64_t val = g_ascii_strtoull(s, NULL, 10);
+ if (!((val == G_MAXUINT64 || !val) && errno)) {
+ return val;
+ }
+ error_report("ignoring invalid max_mem_regions value in vhost module:"
+ " %s", s);
+ }
+ return limit;
+}
+
+static int vhost_kernel_net_set_backend(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
+{
+ return vhost_kernel_call(dev, VHOST_NET_SET_BACKEND, file);
+}
+
+static int vhost_kernel_scsi_set_endpoint(struct vhost_dev *dev,
+ struct vhost_scsi_target *target)
+{
+ return vhost_kernel_call(dev, VHOST_SCSI_SET_ENDPOINT, target);
+}
+
+static int vhost_kernel_scsi_clear_endpoint(struct vhost_dev *dev,
+ struct vhost_scsi_target *target)
+{
+ return vhost_kernel_call(dev, VHOST_SCSI_CLEAR_ENDPOINT, target);
+}
+
+static int vhost_kernel_scsi_get_abi_version(struct vhost_dev *dev, int *version)
+{
+ return vhost_kernel_call(dev, VHOST_SCSI_GET_ABI_VERSION, version);
+}
+
+static int vhost_kernel_set_log_base(struct vhost_dev *dev, uint64_t base,
+ struct vhost_log *log)
+{
+ return vhost_kernel_call(dev, VHOST_SET_LOG_BASE, &base);
+}
+
+static int vhost_kernel_set_mem_table(struct vhost_dev *dev,
+ struct vhost_memory *mem)
+{
+ return vhost_kernel_call(dev, VHOST_SET_MEM_TABLE, mem);
+}
+
+static int vhost_kernel_set_vring_addr(struct vhost_dev *dev,
+ struct vhost_vring_addr *addr)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_ADDR, addr);
+}
+
+static int vhost_kernel_set_vring_endian(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_ENDIAN, ring);
+}
+
+static int vhost_kernel_set_vring_num(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_NUM, ring);
+}
+
+static int vhost_kernel_set_vring_base(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_BASE, ring);
+}
+
+static int vhost_kernel_get_vring_base(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_kernel_call(dev, VHOST_GET_VRING_BASE, ring);
+}
+
+static int vhost_kernel_set_vring_kick(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_KICK, file);
+}
+
+static int vhost_kernel_set_vring_call(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
+{
+ return vhost_kernel_call(dev, VHOST_SET_VRING_CALL, file);
+}
+
+static int vhost_kernel_set_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ return vhost_kernel_call(dev, VHOST_SET_FEATURES, &features);
+}
+
+static int vhost_kernel_get_features(struct vhost_dev *dev,
+ uint64_t *features)
+{
+ return vhost_kernel_call(dev, VHOST_GET_FEATURES, features);
+}
+
+static int vhost_kernel_set_owner(struct vhost_dev *dev)
+{
+ return vhost_kernel_call(dev, VHOST_SET_OWNER, NULL);
+}
+
+static int vhost_kernel_reset_device(struct vhost_dev *dev)
+{
+ return vhost_kernel_call(dev, VHOST_RESET_DEVICE, NULL);
+}
+
static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
{
assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs);
@@ -51,10 +168,27 @@ static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
static const VhostOps kernel_ops = {
.backend_type = VHOST_BACKEND_TYPE_KERNEL,
- .vhost_call = vhost_kernel_call,
.vhost_backend_init = vhost_kernel_init,
.vhost_backend_cleanup = vhost_kernel_cleanup,
- .vhost_backend_get_vq_index = vhost_kernel_get_vq_index,
+ .vhost_backend_memslots_limit = vhost_kernel_memslots_limit,
+ .vhost_net_set_backend = vhost_kernel_net_set_backend,
+ .vhost_scsi_set_endpoint = vhost_kernel_scsi_set_endpoint,
+ .vhost_scsi_clear_endpoint = vhost_kernel_scsi_clear_endpoint,
+ .vhost_scsi_get_abi_version = vhost_kernel_scsi_get_abi_version,
+ .vhost_set_log_base = vhost_kernel_set_log_base,
+ .vhost_set_mem_table = vhost_kernel_set_mem_table,
+ .vhost_set_vring_addr = vhost_kernel_set_vring_addr,
+ .vhost_set_vring_endian = vhost_kernel_set_vring_endian,
+ .vhost_set_vring_num = vhost_kernel_set_vring_num,
+ .vhost_set_vring_base = vhost_kernel_set_vring_base,
+ .vhost_get_vring_base = vhost_kernel_get_vring_base,
+ .vhost_set_vring_kick = vhost_kernel_set_vring_kick,
+ .vhost_set_vring_call = vhost_kernel_set_vring_call,
+ .vhost_set_features = vhost_kernel_set_features,
+ .vhost_get_features = vhost_kernel_get_features,
+ .vhost_set_owner = vhost_kernel_set_owner,
+ .vhost_reset_device = vhost_kernel_reset_device,
+ .vhost_get_vq_index = vhost_kernel_get_vq_index,
};
int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index b11c0d2..78442ba 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -10,11 +10,13 @@
#include "hw/virtio/vhost.h"
#include "hw/virtio/vhost-backend.h"
+#include "hw/virtio/virtio-net.h"
#include "sysemu/char.h"
#include "sysemu/kvm.h"
#include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "exec/ram_addr.h"
+#include "migration/migration.h"
#include <fcntl.h>
#include <unistd.h>
@@ -25,9 +27,16 @@
#define VHOST_MEMORY_MAX_NREGIONS 8
#define VHOST_USER_F_PROTOCOL_FEATURES 30
-#define VHOST_USER_PROTOCOL_FEATURE_MASK 0x1ULL
-#define VHOST_USER_PROTOCOL_F_MQ 0
+enum VhostUserProtocolFeature {
+ VHOST_USER_PROTOCOL_F_MQ = 0,
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
+ VHOST_USER_PROTOCOL_F_RARP = 2,
+
+ VHOST_USER_PROTOCOL_F_MAX
+};
+
+#define VHOST_USER_PROTOCOL_FEATURE_MASK ((1 << VHOST_USER_PROTOCOL_F_MAX) - 1)
typedef enum VhostUserRequest {
VHOST_USER_NONE = 0,
@@ -49,6 +58,7 @@ typedef enum VhostUserRequest {
VHOST_USER_SET_PROTOCOL_FEATURES = 16,
VHOST_USER_GET_QUEUE_NUM = 17,
VHOST_USER_SET_VRING_ENABLE = 18,
+ VHOST_USER_SEND_RARP = 19,
VHOST_USER_MAX
} VhostUserRequest;
@@ -97,37 +107,6 @@ static bool ioeventfd_enabled(void)
return kvm_enabled() && kvm_eventfds_enabled();
}
-static unsigned long int ioctl_to_vhost_user_request[VHOST_USER_MAX] = {
- -1, /* VHOST_USER_NONE */
- VHOST_GET_FEATURES, /* VHOST_USER_GET_FEATURES */
- VHOST_SET_FEATURES, /* VHOST_USER_SET_FEATURES */
- VHOST_SET_OWNER, /* VHOST_USER_SET_OWNER */
- VHOST_RESET_DEVICE, /* VHOST_USER_RESET_DEVICE */
- VHOST_SET_MEM_TABLE, /* VHOST_USER_SET_MEM_TABLE */
- VHOST_SET_LOG_BASE, /* VHOST_USER_SET_LOG_BASE */
- VHOST_SET_LOG_FD, /* VHOST_USER_SET_LOG_FD */
- VHOST_SET_VRING_NUM, /* VHOST_USER_SET_VRING_NUM */
- VHOST_SET_VRING_ADDR, /* VHOST_USER_SET_VRING_ADDR */
- VHOST_SET_VRING_BASE, /* VHOST_USER_SET_VRING_BASE */
- VHOST_GET_VRING_BASE, /* VHOST_USER_GET_VRING_BASE */
- VHOST_SET_VRING_KICK, /* VHOST_USER_SET_VRING_KICK */
- VHOST_SET_VRING_CALL, /* VHOST_USER_SET_VRING_CALL */
- VHOST_SET_VRING_ERR /* VHOST_USER_SET_VRING_ERR */
-};
-
-static VhostUserRequest vhost_user_request_translate(unsigned long int request)
-{
- VhostUserRequest idx;
-
- for (idx = 0; idx < VHOST_USER_MAX; idx++) {
- if (ioctl_to_vhost_user_request[idx] == request) {
- break;
- }
- }
-
- return (idx == VHOST_USER_MAX) ? VHOST_USER_NONE : idx;
-}
-
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
{
CharDriverState *chr = dev->opaque;
@@ -174,12 +153,35 @@ fail:
return -1;
}
+static bool vhost_user_one_time_request(VhostUserRequest request)
+{
+ switch (request) {
+ case VHOST_USER_SET_OWNER:
+ case VHOST_USER_RESET_DEVICE:
+ case VHOST_USER_SET_MEM_TABLE:
+ case VHOST_USER_GET_QUEUE_NUM:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* most non-init callers ignore the error */
static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
int *fds, int fd_num)
{
CharDriverState *chr = dev->opaque;
int size = VHOST_USER_HDR_SIZE + msg->size;
+ /*
+ * For non-vring specific requests, like VHOST_USER_SET_MEM_TABLE,
+ * we just need send it once in the first time. For later such
+ * request, we just ignore it.
+ */
+ if (vhost_user_one_time_request(msg->request) && dev->vq_index != 0) {
+ return 0;
+ }
+
if (fd_num) {
qemu_chr_fe_set_msgfds(chr, fds, fd_num);
}
@@ -188,195 +190,321 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
0 : -1;
}
-static bool vhost_user_one_time_request(VhostUserRequest request)
+static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
+ struct vhost_log *log)
{
- switch (request) {
- case VHOST_USER_SET_OWNER:
- case VHOST_USER_RESET_DEVICE:
- case VHOST_USER_SET_MEM_TABLE:
- case VHOST_USER_GET_QUEUE_NUM:
- return true;
- default:
- return false;
+ int fds[VHOST_MEMORY_MAX_NREGIONS];
+ size_t fd_num = 0;
+ bool shmfd = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD);
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_LOG_BASE,
+ .flags = VHOST_USER_VERSION,
+ .u64 = base,
+ .size = sizeof(m.u64),
+ };
+
+ if (shmfd && log->fd != -1) {
+ fds[fd_num++] = log->fd;
}
+
+ vhost_user_write(dev, &msg, fds, fd_num);
+
+ if (shmfd) {
+ msg.size = 0;
+ if (vhost_user_read(dev, &msg) < 0) {
+ return 0;
+ }
+
+ if (msg.request != VHOST_USER_SET_LOG_BASE) {
+ error_report("Received unexpected msg type. "
+ "Expected %d received %d",
+ VHOST_USER_SET_LOG_BASE, msg.request);
+ return -1;
+ }
+ }
+
+ return 0;
}
-static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
- void *arg)
+static int vhost_user_set_mem_table(struct vhost_dev *dev,
+ struct vhost_memory *mem)
{
- VhostUserMsg msg;
- VhostUserRequest msg_request;
- struct vhost_vring_file *file = 0;
- int need_reply = 0;
int fds[VHOST_MEMORY_MAX_NREGIONS];
int i, fd;
size_t fd_num = 0;
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_MEM_TABLE,
+ .flags = VHOST_USER_VERSION,
+ };
- assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
-
- /* only translate vhost ioctl requests */
- if (request > VHOST_USER_MAX) {
- msg_request = vhost_user_request_translate(request);
- } else {
- msg_request = request;
+ for (i = 0; i < dev->mem->nregions; ++i) {
+ struct vhost_memory_region *reg = dev->mem->regions + i;
+ ram_addr_t ram_addr;
+
+ assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
+ qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr,
+ &ram_addr);
+ fd = qemu_get_ram_fd(ram_addr);
+ if (fd > 0) {
+ msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
+ msg.memory.regions[fd_num].memory_size = reg->memory_size;
+ msg.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
+ msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
+ (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr);
+ assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
+ fds[fd_num++] = fd;
+ }
}
- /*
- * For non-vring specific requests, like VHOST_USER_SET_MEM_TABLE,
- * we just need send it once in the first time. For later such
- * request, we just ignore it.
- */
- if (vhost_user_one_time_request(msg_request) && dev->vq_index != 0) {
- return 0;
+ msg.memory.nregions = fd_num;
+
+ if (!fd_num) {
+ error_report("Failed initializing vhost-user memory map, "
+ "consider using -object memory-backend-file share=on");
+ return -1;
}
- msg.request = msg_request;
- msg.flags = VHOST_USER_VERSION;
- msg.size = 0;
+ msg.size = sizeof(m.memory.nregions);
+ msg.size += sizeof(m.memory.padding);
+ msg.size += fd_num * sizeof(VhostUserMemoryRegion);
- switch (msg_request) {
- case VHOST_USER_GET_FEATURES:
- case VHOST_USER_GET_PROTOCOL_FEATURES:
- case VHOST_USER_GET_QUEUE_NUM:
- need_reply = 1;
- break;
+ vhost_user_write(dev, &msg, fds, fd_num);
- case VHOST_USER_SET_FEATURES:
- case VHOST_USER_SET_LOG_BASE:
- case VHOST_USER_SET_PROTOCOL_FEATURES:
- msg.u64 = *((__u64 *) arg);
- msg.size = sizeof(m.u64);
- break;
+ return 0;
+}
- case VHOST_USER_SET_OWNER:
- case VHOST_USER_RESET_DEVICE:
- break;
+static int vhost_user_set_vring_addr(struct vhost_dev *dev,
+ struct vhost_vring_addr *addr)
+{
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_VRING_ADDR,
+ .flags = VHOST_USER_VERSION,
+ .addr = *addr,
+ .size = sizeof(*addr),
+ };
- case VHOST_USER_SET_MEM_TABLE:
- for (i = 0; i < dev->mem->nregions; ++i) {
- struct vhost_memory_region *reg = dev->mem->regions + i;
- ram_addr_t ram_addr;
-
- assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
- qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr, &ram_addr);
- fd = qemu_get_ram_fd(ram_addr);
- if (fd > 0) {
- msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
- msg.memory.regions[fd_num].memory_size = reg->memory_size;
- msg.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
- msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
- (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr);
- assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
- fds[fd_num++] = fd;
- }
- }
+ vhost_user_write(dev, &msg, NULL, 0);
- msg.memory.nregions = fd_num;
+ return 0;
+}
- if (!fd_num) {
- error_report("Failed initializing vhost-user memory map, "
- "consider using -object memory-backend-file share=on");
- return -1;
- }
+static int vhost_user_set_vring_endian(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ error_report("vhost-user trying to send unhandled ioctl");
+ return -1;
+}
- msg.size = sizeof(m.memory.nregions);
- msg.size += sizeof(m.memory.padding);
- msg.size += fd_num * sizeof(VhostUserMemoryRegion);
-
- break;
-
- case VHOST_USER_SET_LOG_FD:
- fds[fd_num++] = *((int *) arg);
- break;
-
- case VHOST_USER_SET_VRING_NUM:
- case VHOST_USER_SET_VRING_BASE:
- case VHOST_USER_SET_VRING_ENABLE:
- memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
- msg.size = sizeof(m.state);
- break;
-
- case VHOST_USER_GET_VRING_BASE:
- memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
- msg.size = sizeof(m.state);
- need_reply = 1;
- break;
-
- case VHOST_USER_SET_VRING_ADDR:
- memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr));
- msg.size = sizeof(m.addr);
- break;
-
- case VHOST_USER_SET_VRING_KICK:
- case VHOST_USER_SET_VRING_CALL:
- case VHOST_USER_SET_VRING_ERR:
- file = arg;
- msg.u64 = file->index & VHOST_USER_VRING_IDX_MASK;
- msg.size = sizeof(m.u64);
- if (ioeventfd_enabled() && file->fd > 0) {
- fds[fd_num++] = file->fd;
- } else {
- msg.u64 |= VHOST_USER_VRING_NOFD_MASK;
- }
- break;
- default:
- error_report("vhost-user trying to send unhandled ioctl");
+static int vhost_set_vring(struct vhost_dev *dev,
+ unsigned long int request,
+ struct vhost_vring_state *ring)
+{
+ VhostUserMsg msg = {
+ .request = request,
+ .flags = VHOST_USER_VERSION,
+ .state = *ring,
+ .size = sizeof(*ring),
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ return 0;
+}
+
+static int vhost_user_set_vring_num(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring);
+}
+
+static int vhost_user_set_vring_base(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring);
+}
+
+static int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
+{
+ struct vhost_vring_state state = {
+ .index = dev->vq_index,
+ .num = enable,
+ };
+
+ if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ))) {
return -1;
- break;
}
- if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
+ return vhost_set_vring(dev, VHOST_USER_SET_VRING_ENABLE, &state);
+}
+
+
+static int vhost_user_get_vring_base(struct vhost_dev *dev,
+ struct vhost_vring_state *ring)
+{
+ VhostUserMsg msg = {
+ .request = VHOST_USER_GET_VRING_BASE,
+ .flags = VHOST_USER_VERSION,
+ .state = *ring,
+ .size = sizeof(*ring),
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ if (vhost_user_read(dev, &msg) < 0) {
return 0;
}
- if (need_reply) {
- if (vhost_user_read(dev, &msg) < 0) {
- return 0;
- }
+ if (msg.request != VHOST_USER_GET_VRING_BASE) {
+ error_report("Received unexpected msg type. Expected %d received %d",
+ VHOST_USER_GET_VRING_BASE, msg.request);
+ return -1;
+ }
- if (msg_request != msg.request) {
- error_report("Received unexpected msg type."
- " Expected %d received %d", msg_request, msg.request);
- return -1;
- }
+ if (msg.size != sizeof(m.state)) {
+ error_report("Received bad msg size.");
+ return -1;
+ }
- switch (msg_request) {
- case VHOST_USER_GET_FEATURES:
- case VHOST_USER_GET_PROTOCOL_FEATURES:
- case VHOST_USER_GET_QUEUE_NUM:
- if (msg.size != sizeof(m.u64)) {
- error_report("Received bad msg size.");
- return -1;
- }
- *((__u64 *) arg) = msg.u64;
- break;
- case VHOST_USER_GET_VRING_BASE:
- if (msg.size != sizeof(m.state)) {
- error_report("Received bad msg size.");
- return -1;
- }
- memcpy(arg, &msg.state, sizeof(struct vhost_vring_state));
- break;
- default:
- error_report("Received unexpected msg type.");
- return -1;
- break;
- }
+ *ring = msg.state;
+
+ return 0;
+}
+
+static int vhost_set_vring_file(struct vhost_dev *dev,
+ VhostUserRequest request,
+ struct vhost_vring_file *file)
+{
+ int fds[VHOST_MEMORY_MAX_NREGIONS];
+ size_t fd_num = 0;
+ VhostUserMsg msg = {
+ .request = request,
+ .flags = VHOST_USER_VERSION,
+ .u64 = file->index & VHOST_USER_VRING_IDX_MASK,
+ .size = sizeof(m.u64),
+ };
+
+ if (ioeventfd_enabled() && file->fd > 0) {
+ fds[fd_num++] = file->fd;
+ } else {
+ msg.u64 |= VHOST_USER_VRING_NOFD_MASK;
+ }
+
+ vhost_user_write(dev, &msg, fds, fd_num);
+
+ return 0;
+}
+
+static int vhost_user_set_vring_kick(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
+{
+ return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_KICK, file);
+}
+
+static int vhost_user_set_vring_call(struct vhost_dev *dev,
+ struct vhost_vring_file *file)
+{
+ return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
+}
+
+static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64)
+{
+ VhostUserMsg msg = {
+ .request = request,
+ .flags = VHOST_USER_VERSION,
+ .u64 = u64,
+ .size = sizeof(m.u64),
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ return 0;
+}
+
+static int vhost_user_set_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ return vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES, features);
+}
+
+static int vhost_user_set_protocol_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ return vhost_user_set_u64(dev, VHOST_USER_SET_PROTOCOL_FEATURES, features);
+}
+
+static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
+{
+ VhostUserMsg msg = {
+ .request = request,
+ .flags = VHOST_USER_VERSION,
+ };
+
+ if (vhost_user_one_time_request(request) && dev->vq_index != 0) {
+ return 0;
+ }
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ if (vhost_user_read(dev, &msg) < 0) {
+ return 0;
+ }
+
+ if (msg.request != request) {
+ error_report("Received unexpected msg type. Expected %d received %d",
+ request, msg.request);
+ return -1;
}
+ if (msg.size != sizeof(m.u64)) {
+ error_report("Received bad msg size.");
+ return -1;
+ }
+
+ *u64 = msg.u64;
+
+ return 0;
+}
+
+static int vhost_user_get_features(struct vhost_dev *dev, uint64_t *features)
+{
+ return vhost_user_get_u64(dev, VHOST_USER_GET_FEATURES, features);
+}
+
+static int vhost_user_set_owner(struct vhost_dev *dev)
+{
+ VhostUserMsg msg = {
+ .request = VHOST_USER_SET_OWNER,
+ .flags = VHOST_USER_VERSION,
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
+ return 0;
+}
+
+static int vhost_user_reset_device(struct vhost_dev *dev)
+{
+ VhostUserMsg msg = {
+ .request = VHOST_USER_RESET_DEVICE,
+ .flags = VHOST_USER_VERSION,
+ };
+
+ vhost_user_write(dev, &msg, NULL, 0);
+
return 0;
}
static int vhost_user_init(struct vhost_dev *dev, void *opaque)
{
- unsigned long long features;
+ uint64_t features;
int err;
assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
dev->opaque = opaque;
- err = vhost_user_call(dev, VHOST_USER_GET_FEATURES, &features);
+ err = vhost_user_get_features(dev, &features);
if (err < 0) {
return err;
}
@@ -384,44 +512,37 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque)
if (virtio_has_feature(features, VHOST_USER_F_PROTOCOL_FEATURES)) {
dev->backend_features |= 1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
- err = vhost_user_call(dev, VHOST_USER_GET_PROTOCOL_FEATURES, &features);
+ err = vhost_user_get_u64(dev, VHOST_USER_GET_PROTOCOL_FEATURES,
+ &features);
if (err < 0) {
return err;
}
dev->protocol_features = features & VHOST_USER_PROTOCOL_FEATURE_MASK;
- err = vhost_user_call(dev, VHOST_USER_SET_PROTOCOL_FEATURES,
- &dev->protocol_features);
+ err = vhost_user_set_protocol_features(dev, dev->protocol_features);
if (err < 0) {
return err;
}
/* query the max queues we support if backend supports Multiple Queue */
if (dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ)) {
- err = vhost_user_call(dev, VHOST_USER_GET_QUEUE_NUM, &dev->max_queues);
+ err = vhost_user_get_u64(dev, VHOST_USER_GET_QUEUE_NUM,
+ &dev->max_queues);
if (err < 0) {
return err;
}
}
}
- return 0;
-}
-
-static int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable)
-{
- struct vhost_vring_state state = {
- .index = dev->vq_index,
- .num = enable,
- };
-
- assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
-
- if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_MQ))) {
- return -1;
+ if (dev->migration_blocker == NULL &&
+ !virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD)) {
+ error_setg(&dev->migration_blocker,
+ "Migration disabled: vhost-user backend lacks "
+ "VHOST_USER_PROTOCOL_F_LOG_SHMFD feature.");
}
- return vhost_user_call(dev, VHOST_USER_SET_VRING_ENABLE, &state);
+ return 0;
}
static int vhost_user_cleanup(struct vhost_dev *dev)
@@ -440,11 +561,65 @@ static int vhost_user_get_vq_index(struct vhost_dev *dev, int idx)
return idx;
}
+static int vhost_user_memslots_limit(struct vhost_dev *dev)
+{
+ return VHOST_MEMORY_MAX_NREGIONS;
+}
+
+static bool vhost_user_requires_shm_log(struct vhost_dev *dev)
+{
+ assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
+
+ return virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD);
+}
+
+static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
+{
+ VhostUserMsg msg = { 0 };
+ int err;
+
+ assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
+
+ /* If guest supports GUEST_ANNOUNCE do nothing */
+ if (virtio_has_feature(dev->acked_features, VIRTIO_NET_F_GUEST_ANNOUNCE)) {
+ return 0;
+ }
+
+ /* if backend supports VHOST_USER_PROTOCOL_F_RARP ask it to send the RARP */
+ if (virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_RARP)) {
+ msg.request = VHOST_USER_SEND_RARP;
+ msg.flags = VHOST_USER_VERSION;
+ memcpy((char *)&msg.u64, mac_addr, 6);
+ msg.size = sizeof(m.u64);
+
+ err = vhost_user_write(dev, &msg, NULL, 0);
+ return err;
+ }
+ return -1;
+}
+
const VhostOps user_ops = {
.backend_type = VHOST_BACKEND_TYPE_USER,
- .vhost_call = vhost_user_call,
.vhost_backend_init = vhost_user_init,
.vhost_backend_cleanup = vhost_user_cleanup,
- .vhost_backend_get_vq_index = vhost_user_get_vq_index,
- .vhost_backend_set_vring_enable = vhost_user_set_vring_enable,
+ .vhost_backend_memslots_limit = vhost_user_memslots_limit,
+ .vhost_set_log_base = vhost_user_set_log_base,
+ .vhost_set_mem_table = vhost_user_set_mem_table,
+ .vhost_set_vring_addr = vhost_user_set_vring_addr,
+ .vhost_set_vring_endian = vhost_user_set_vring_endian,
+ .vhost_set_vring_num = vhost_user_set_vring_num,
+ .vhost_set_vring_base = vhost_user_set_vring_base,
+ .vhost_get_vring_base = vhost_user_get_vring_base,
+ .vhost_set_vring_kick = vhost_user_set_vring_kick,
+ .vhost_set_vring_call = vhost_user_set_vring_call,
+ .vhost_set_features = vhost_user_set_features,
+ .vhost_get_features = vhost_user_get_features,
+ .vhost_set_owner = vhost_user_set_owner,
+ .vhost_reset_device = vhost_user_reset_device,
+ .vhost_get_vq_index = vhost_user_get_vq_index,
+ .vhost_set_vring_enable = vhost_user_set_vring_enable,
+ .vhost_requires_shm_log = vhost_user_requires_shm_log,
+ .vhost_migration_done = vhost_user_migration_done,
};
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index c0ed5b2..de29968 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -18,6 +18,7 @@
#include "qemu/atomic.h"
#include "qemu/range.h"
#include "qemu/error-report.h"
+#include "qemu/memfd.h"
#include <linux/vhost.h>
#include "exec/address-spaces.h"
#include "hw/virtio/virtio-bus.h"
@@ -25,6 +26,23 @@
#include "migration/migration.h"
static struct vhost_log *vhost_log;
+static struct vhost_log *vhost_log_shm;
+
+static unsigned int used_memslots;
+static QLIST_HEAD(, vhost_dev) vhost_devices =
+ QLIST_HEAD_INITIALIZER(vhost_devices);
+
+bool vhost_has_free_slot(void)
+{
+ unsigned int slots_limit = ~0U;
+ struct vhost_dev *hdev;
+
+ QLIST_FOREACH(hdev, &vhost_devices, entry) {
+ unsigned int r = hdev->vhost_ops->vhost_backend_memslots_limit(hdev);
+ slots_limit = MIN(slots_limit, r);
+ }
+ return slots_limit > used_memslots;
+}
static void vhost_dev_sync_region(struct vhost_dev *dev,
MemoryRegionSection *section,
@@ -286,25 +304,46 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev)
}
return log_size;
}
-static struct vhost_log *vhost_log_alloc(uint64_t size)
+
+static struct vhost_log *vhost_log_alloc(uint64_t size, bool share)
{
- struct vhost_log *log = g_malloc0(sizeof *log + size * sizeof(*(log->log)));
+ struct vhost_log *log;
+ uint64_t logsize = size * sizeof(*(log->log));
+ int fd = -1;
+
+ log = g_new0(struct vhost_log, 1);
+ if (share) {
+ log->log = qemu_memfd_alloc("vhost-log", logsize,
+ F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
+ &fd);
+ memset(log->log, 0, logsize);
+ } else {
+ log->log = g_malloc0(logsize);
+ }
log->size = size;
log->refcnt = 1;
+ log->fd = fd;
return log;
}
-static struct vhost_log *vhost_log_get(uint64_t size)
+static struct vhost_log *vhost_log_get(uint64_t size, bool share)
{
- if (!vhost_log || vhost_log->size != size) {
- vhost_log = vhost_log_alloc(size);
+ struct vhost_log *log = share ? vhost_log_shm : vhost_log;
+
+ if (!log || log->size != size) {
+ log = vhost_log_alloc(size, share);
+ if (share) {
+ vhost_log_shm = log;
+ } else {
+ vhost_log = log;
+ }
} else {
- ++vhost_log->refcnt;
+ ++log->refcnt;
}
- return vhost_log;
+ return log;
}
static void vhost_log_put(struct vhost_dev *dev, bool sync)
@@ -321,20 +360,35 @@ static void vhost_log_put(struct vhost_dev *dev, bool sync)
if (dev->log_size && sync) {
vhost_log_sync_range(dev, 0, dev->log_size * VHOST_LOG_CHUNK - 1);
}
+
if (vhost_log == log) {
+ g_free(log->log);
vhost_log = NULL;
+ } else if (vhost_log_shm == log) {
+ qemu_memfd_free(log->log, log->size * sizeof(*(log->log)),
+ log->fd);
+ vhost_log_shm = NULL;
}
+
g_free(log);
}
}
-static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
+static bool vhost_dev_log_is_shared(struct vhost_dev *dev)
{
- struct vhost_log *log = vhost_log_get(size);
+ return dev->vhost_ops->vhost_requires_shm_log &&
+ dev->vhost_ops->vhost_requires_shm_log(dev);
+}
+
+static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size)
+{
+ struct vhost_log *log = vhost_log_get(size, vhost_dev_log_is_shared(dev));
uint64_t log_base = (uintptr_t)log->log;
int r;
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_LOG_BASE, &log_base);
+ /* inform backend of log switching, this must be done before
+ releasing the current log, to ensure no logging is lost */
+ r = dev->vhost_ops->vhost_set_log_base(dev, log_base, log);
assert(r >= 0);
vhost_log_put(dev, true);
dev->log = log;
@@ -457,6 +511,7 @@ static void vhost_set_memory(MemoryListener *listener,
dev->mem_changed_start_addr = MIN(dev->mem_changed_start_addr, start_addr);
dev->mem_changed_end_addr = MAX(dev->mem_changed_end_addr, start_addr + size - 1);
dev->memory_changed = true;
+ used_memslots = dev->mem->nregions;
}
static bool vhost_section(MemoryRegionSection *section)
@@ -500,7 +555,7 @@ static void vhost_commit(MemoryListener *listener)
}
if (!dev->log_enabled) {
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem);
+ r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem);
assert(r >= 0);
dev->memory_changed = false;
return;
@@ -513,7 +568,7 @@ static void vhost_commit(MemoryListener *listener)
if (dev->log_size < log_size) {
vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER);
}
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_MEM_TABLE, dev->mem);
+ r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem);
assert(r >= 0);
/* To log less, can only decrease log size after table update. */
if (dev->log_size > log_size + VHOST_LOG_BUFFER) {
@@ -581,7 +636,7 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
.log_guest_addr = vq->used_phys,
.flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0,
};
- int r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ADDR, &addr);
+ int r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr);
if (r < 0) {
return -errno;
}
@@ -595,19 +650,20 @@ static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log)
if (enable_log) {
features |= 0x1ULL << VHOST_F_LOG_ALL;
}
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_FEATURES, &features);
+ r = dev->vhost_ops->vhost_set_features(dev, features);
return r < 0 ? -errno : 0;
}
static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log)
{
- int r, t, i;
+ int r, t, i, idx;
r = vhost_dev_set_features(dev, enable_log);
if (r < 0) {
goto err_features;
}
for (i = 0; i < dev->nvqs; ++i) {
- r = vhost_virtqueue_set_addr(dev, dev->vqs + i, i,
+ idx = dev->vhost_ops->vhost_get_vq_index(dev, dev->vq_index + i);
+ r = vhost_virtqueue_set_addr(dev, dev->vqs + i, idx,
enable_log);
if (r < 0) {
goto err_vq;
@@ -616,7 +672,8 @@ static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log)
return 0;
err_vq:
for (; i >= 0; --i) {
- t = vhost_virtqueue_set_addr(dev, dev->vqs + i, i,
+ idx = dev->vhost_ops->vhost_get_vq_index(dev, dev->vq_index + i);
+ t = vhost_virtqueue_set_addr(dev, dev->vqs + i, idx,
dev->log_enabled);
assert(t >= 0);
}
@@ -700,7 +757,7 @@ static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,
.num = is_big_endian
};
- if (!dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_ENDIAN, &s)) {
+ if (!dev->vhost_ops->vhost_set_vring_endian(dev, &s)) {
return 0;
}
@@ -719,7 +776,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
{
hwaddr s, l, a;
int r;
- int vhost_vq_index = dev->vhost_ops->vhost_backend_get_vq_index(dev, idx);
+ int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx);
struct vhost_vring_file file = {
.index = vhost_vq_index
};
@@ -730,13 +787,13 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
vq->num = state.num = virtio_queue_get_num(vdev, idx);
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_NUM, &state);
+ r = dev->vhost_ops->vhost_set_vring_num(dev, &state);
if (r) {
return -errno;
}
state.num = virtio_queue_get_last_avail_idx(vdev, idx);
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_BASE, &state);
+ r = dev->vhost_ops->vhost_set_vring_base(dev, &state);
if (r) {
return -errno;
}
@@ -788,7 +845,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
}
file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_KICK, &file);
+ r = dev->vhost_ops->vhost_set_vring_kick(dev, &file);
if (r) {
r = -errno;
goto fail_kick;
@@ -821,13 +878,13 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
struct vhost_virtqueue *vq,
unsigned idx)
{
- int vhost_vq_index = dev->vhost_ops->vhost_backend_get_vq_index(dev, idx);
+ int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx);
struct vhost_vring_state state = {
.index = vhost_vq_index,
};
int r;
- r = dev->vhost_ops->vhost_call(dev, VHOST_GET_VRING_BASE, &state);
+ r = dev->vhost_ops->vhost_get_vring_base(dev, &state);
if (r < 0) {
fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r);
fflush(stderr);
@@ -874,7 +931,7 @@ static void vhost_eventfd_del(MemoryListener *listener,
static int vhost_virtqueue_init(struct vhost_dev *dev,
struct vhost_virtqueue *vq, int n)
{
- int vhost_vq_index = dev->vhost_ops->vhost_backend_get_vq_index(dev, n);
+ int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, n);
struct vhost_vring_file file = {
.index = vhost_vq_index,
};
@@ -884,7 +941,7 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
}
file.fd = event_notifier_get_fd(&vq->masked_notifier);
- r = dev->vhost_ops->vhost_call(dev, VHOST_SET_VRING_CALL, &file);
+ r = dev->vhost_ops->vhost_set_vring_call(dev, &file);
if (r) {
r = -errno;
goto fail_call;
@@ -906,6 +963,8 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
uint64_t features;
int i, r;
+ hdev->migration_blocker = NULL;
+
if (vhost_set_backend_type(hdev, backend_type) < 0) {
close((uintptr_t)opaque);
return -1;
@@ -916,12 +975,20 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
return -errno;
}
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_OWNER, NULL);
+ if (used_memslots > hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) {
+ fprintf(stderr, "vhost backend memory slots limit is less"
+ " than current number of present memory slots\n");
+ close((uintptr_t)opaque);
+ return -1;
+ }
+ QLIST_INSERT_HEAD(&vhost_devices, hdev, entry);
+
+ r = hdev->vhost_ops->vhost_set_owner(hdev);
if (r < 0) {
goto fail;
}
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_GET_FEATURES, &features);
+ r = hdev->vhost_ops->vhost_get_features(hdev, &features);
if (r < 0) {
goto fail;
}
@@ -949,12 +1016,21 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
.eventfd_del = vhost_eventfd_del,
.priority = 10
};
- hdev->migration_blocker = NULL;
- if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
- error_setg(&hdev->migration_blocker,
- "Migration disabled: vhost lacks VHOST_F_LOG_ALL feature.");
+
+ if (hdev->migration_blocker == NULL) {
+ if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
+ error_setg(&hdev->migration_blocker,
+ "Migration disabled: vhost lacks VHOST_F_LOG_ALL feature.");
+ } else if (!qemu_memfd_check()) {
+ error_setg(&hdev->migration_blocker,
+ "Migration disabled: failed to allocate shared memory");
+ }
+ }
+
+ if (hdev->migration_blocker != NULL) {
migrate_add_blocker(hdev->migration_blocker);
}
+
hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions));
hdev->n_mem_sections = 0;
hdev->mem_sections = NULL;
@@ -972,6 +1048,7 @@ fail_vq:
fail:
r = -errno;
hdev->vhost_ops->vhost_backend_cleanup(hdev);
+ QLIST_REMOVE(hdev, entry);
return r;
}
@@ -989,6 +1066,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
g_free(hdev->mem);
g_free(hdev->mem_sections);
hdev->vhost_ops->vhost_backend_cleanup(hdev);
+ QLIST_REMOVE(hdev, entry);
}
/* Stop processing guest IO notifications in qemu.
@@ -1074,8 +1152,8 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
file.fd = event_notifier_get_fd(virtio_queue_get_guest_notifier(vvq));
}
- file.index = hdev->vhost_ops->vhost_backend_get_vq_index(hdev, n);
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_VRING_CALL, &file);
+ file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n);
+ r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file);
assert(r >= 0);
}
@@ -1117,7 +1195,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
if (r < 0) {
goto fail_features;
}
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_MEM_TABLE, hdev->mem);
+ r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem);
if (r < 0) {
r = -errno;
goto fail_mem;
@@ -1136,10 +1214,12 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
uint64_t log_base;
hdev->log_size = vhost_get_log_size(hdev);
- hdev->log = vhost_log_get(hdev->log_size);
+ hdev->log = vhost_log_get(hdev->log_size,
+ vhost_dev_log_is_shared(hdev));
log_base = (uintptr_t)hdev->log->log;
- r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_LOG_BASE,
- hdev->log_size ? &log_base : NULL);
+ r = hdev->vhost_ops->vhost_set_log_base(hdev,
+ hdev->log_size ? log_base : 0,
+ hdev->log);
if (r < 0) {
r = -errno;
goto fail_log;
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index 72350f1..c1bc5ae 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -149,6 +149,28 @@ static void lx60_net_init(MemoryRegion *address_space,
memory_region_add_subregion(address_space, buffers, ram);
}
+static pflash_t *xtfpga_flash_init(MemoryRegion *address_space,
+ const LxBoardDesc *board,
+ DriveInfo *dinfo, int be)
+{
+ SysBusDevice *s;
+ DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
+
+ qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo),
+ &error_abort);
+ qdev_prop_set_uint32(dev, "num-blocks",
+ board->flash_size / board->flash_sector_size);
+ qdev_prop_set_uint64(dev, "sector-length", board->flash_sector_size);
+ qdev_prop_set_uint8(dev, "width", 4);
+ qdev_prop_set_bit(dev, "big-endian", be);
+ qdev_prop_set_string(dev, "name", "lx60.io.flash");
+ qdev_init_nofail(dev);
+ s = SYS_BUS_DEVICE(dev);
+ memory_region_add_subregion(address_space, board->flash_base,
+ sysbus_mmio_get_region(s, 0));
+ return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
+}
+
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
{
XtensaCPU *cpu = opaque;
@@ -247,16 +269,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
dinfo = drive_get(IF_PFLASH, 0, 0);
if (dinfo) {
- flash = pflash_cfi01_register(board->flash_base,
- NULL, "lx60.io.flash", board->flash_size,
- blk_by_legacy_dinfo(dinfo),
- board->flash_sector_size,
- board->flash_size / board->flash_sector_size,
- 4, 0x0000, 0x0000, 0x0000, 0x0000, be);
- if (flash == NULL) {
- error_report("unable to mount pflash");
- exit(EXIT_FAILURE);
- }
+ flash = xtfpga_flash_init(system_io, board, dinfo, be);
}
/* Use presence of kernel file name as 'boot from SRAM' switch. */
@@ -386,7 +399,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
static void xtensa_lx60_init(MachineState *machine)
{
static const LxBoardDesc lx60_board = {
- .flash_base = 0xf8000000,
+ .flash_base = 0x08000000,
.flash_size = 0x00400000,
.flash_sector_size = 0x10000,
.sram_size = 0x20000,
@@ -397,7 +410,7 @@ static void xtensa_lx60_init(MachineState *machine)
static void xtensa_lx200_init(MachineState *machine)
{
static const LxBoardDesc lx200_board = {
- .flash_base = 0xf8000000,
+ .flash_base = 0x08000000,
.flash_size = 0x01000000,
.flash_sector_size = 0x20000,
.sram_size = 0x2000000,
@@ -408,7 +421,7 @@ static void xtensa_lx200_init(MachineState *machine)
static void xtensa_ml605_init(MachineState *machine)
{
static const LxBoardDesc ml605_board = {
- .flash_base = 0xf8000000,
+ .flash_base = 0x08000000,
.flash_size = 0x01000000,
.flash_sector_size = 0x20000,
.sram_size = 0x2000000,
@@ -419,7 +432,7 @@ static void xtensa_ml605_init(MachineState *machine)
static void xtensa_kc705_init(MachineState *machine)
{
static const LxBoardDesc kc705_board = {
- .flash_base = 0xf0000000,
+ .flash_base = 0x00000000,
.flash_size = 0x08000000,
.flash_boot_base = 0x06000000,
.flash_sector_size = 0x20000,
diff --git a/include/block/block.h b/include/block/block.h
index 6d70eb4..84f05ad 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -4,7 +4,7 @@
#include "block/aio.h"
#include "qemu-common.h"
#include "qemu/option.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "block/accounting.h"
#include "qapi/qmp/qobject.h"
#include "qapi-types.h"
diff --git a/include/block/block_int.h b/include/block/block_int.h
index c0e6513..a480f94 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -28,7 +28,7 @@
#include "block/block.h"
#include "qemu/option.h"
#include "qemu/queue.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "qemu/timer.h"
#include "qapi-types.h"
#include "qemu/hbitmap.h"
diff --git a/include/glib-compat.h b/include/glib-compat.h
index 318e000..fb25f43 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -165,4 +165,65 @@ static inline GThread *g_thread_new(const char *name,
#define CompatGCond GCond
#endif /* glib 2.31 */
+#ifndef g_assert_true
+#define g_assert_true(expr) \
+ do { \
+ if (G_LIKELY(expr)) { \
+ } else { \
+ g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ "'" #expr "' should be TRUE"); \
+ } \
+ } while (0)
+#endif
+
+#ifndef g_assert_false
+#define g_assert_false(expr) \
+ do { \
+ if (G_LIKELY(!(expr))) { \
+ } else { \
+ g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ "'" #expr "' should be FALSE"); \
+ } \
+ } while (0)
+#endif
+
+#ifndef g_assert_null
+#define g_assert_null(expr) \
+ do { \
+ if (G_LIKELY((expr) == NULL)) { \
+ } else { \
+ g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ "'" #expr "' should be NULL"); \
+ } \
+ } while (0)
+#endif
+
+#ifndef g_assert_nonnull
+#define g_assert_nonnull(expr) \
+ do { \
+ if (G_LIKELY((expr) != NULL)) { \
+ } else { \
+ g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ "'" #expr "' should not be NULL"); \
+ } \
+ } while (0)
+#endif
+
+#ifndef g_assert_cmpmem
+#define g_assert_cmpmem(m1, l1, m2, l2) \
+ do { \
+ gconstpointer __m1 = m1, __m2 = m2; \
+ int __l1 = l1, __l2 = l2; \
+ if (__l1 != __l2) { \
+ g_assertion_message_cmpnum( \
+ G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ #l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", __l1, "==", \
+ __l2, 'i'); \
+ } else if (memcmp(__m1, __m2, __l1) != 0) { \
+ g_assertion_message(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+ "assertion failed (" #m1 " == " #m2 ")"); \
+ } \
+ } while (0)
+#endif
+
#endif
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index e321ee4..5dbadb7 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -49,6 +49,7 @@ typedef struct VTDContextCacheEntry VTDContextCacheEntry;
typedef struct IntelIOMMUState IntelIOMMUState;
typedef struct VTDAddressSpace VTDAddressSpace;
typedef struct VTDIOTLBEntry VTDIOTLBEntry;
+typedef struct VTDBus VTDBus;
/* Context-Entry */
struct VTDContextEntry {
@@ -65,7 +66,7 @@ struct VTDContextCacheEntry {
};
struct VTDAddressSpace {
- uint8_t bus_num;
+ PCIBus *bus;
uint8_t devfn;
AddressSpace as;
MemoryRegion iommu;
@@ -73,6 +74,11 @@ struct VTDAddressSpace {
VTDContextCacheEntry context_cache_entry;
};
+struct VTDBus {
+ PCIBus* bus; /* A reference to the bus to provide translation for */
+ VTDAddressSpace *dev_as[0]; /* A table of VTDAddressSpace objects indexed by devfn */
+};
+
struct VTDIOTLBEntry {
uint64_t gfn;
uint16_t domain_id;
@@ -114,7 +120,13 @@ struct IntelIOMMUState {
GHashTable *iotlb; /* IOTLB */
MemoryRegionIOMMUOps iommu_ops;
- VTDAddressSpace **address_spaces[VTD_PCI_BUS_MAX];
+ GHashTable *vtd_as_by_busptr; /* VTDBus objects indexed by PCIBus* reference */
+ VTDBus *vtd_as_by_bus_num[VTD_PCI_BUS_MAX]; /* VTDBus objects indexed by bus number */
};
+/* Find the VTD Address space associated with the given bus pointer,
+ * create a new one if none exists
+ */
+VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn);
+
#endif
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 0503485..c5961d7 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -168,7 +168,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms);
void pc_register_ferr_irq(qemu_irq irq);
void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
-void pc_cpus_init(const char *cpu_model);
+void pc_cpus_init(PCMachineState *pcms);
void pc_hot_add_cpu(const int64_t id, Error **errp);
void pc_acpi_init(const char *default_dsdt);
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index e60d3ca..ee0cd8a 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -61,6 +61,15 @@ typedef struct FWCfgFiles {
FWCfgFile f[];
} FWCfgFiles;
+/* Control as first field allows for different structures selected by this
+ * field, which might be useful in the future
+ */
+typedef struct FWCfgDmaAccess {
+ uint32_t control;
+ uint32_t length;
+ uint64_t address;
+} QEMU_PACKED FWCfgDmaAccess;
+
typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
typedef void (*FWCfgReadCallback)(void *opaque, uint32_t offset);
@@ -77,10 +86,13 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
void *data, size_t len);
void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
size_t len);
+FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
+ AddressSpace *dma_as);
FWCfgState *fw_cfg_init_io(uint32_t iobase);
FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr);
-FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr, hwaddr data_addr,
- uint32_t data_width);
+FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
+ hwaddr data_addr, uint32_t data_width,
+ hwaddr dma_addr, AddressSpace *dma_as);
FWCfgState *fw_cfg_find(void);
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 3a0f6e2..c59cc81 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -11,6 +11,8 @@
#ifndef VHOST_BACKEND_H_
#define VHOST_BACKEND_H_
+#include <stdbool.h>
+
typedef enum VhostBackendType {
VHOST_BACKEND_TYPE_NONE = 0,
VHOST_BACKEND_TYPE_KERNEL = 1,
@@ -19,21 +21,82 @@ typedef enum VhostBackendType {
} VhostBackendType;
struct vhost_dev;
+struct vhost_log;
+struct vhost_memory;
+struct vhost_vring_file;
+struct vhost_vring_state;
+struct vhost_vring_addr;
+struct vhost_scsi_target;
-typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int request,
- void *arg);
typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
-typedef int (*vhost_backend_get_vq_index)(struct vhost_dev *dev, int idx);
-typedef int (*vhost_backend_set_vring_enable)(struct vhost_dev *dev, int enable);
+typedef int (*vhost_backend_memslots_limit)(struct vhost_dev *dev);
+
+typedef int (*vhost_net_set_backend_op)(struct vhost_dev *dev,
+ struct vhost_vring_file *file);
+typedef int (*vhost_scsi_set_endpoint_op)(struct vhost_dev *dev,
+ struct vhost_scsi_target *target);
+typedef int (*vhost_scsi_clear_endpoint_op)(struct vhost_dev *dev,
+ struct vhost_scsi_target *target);
+typedef int (*vhost_scsi_get_abi_version_op)(struct vhost_dev *dev,
+ int *version);
+typedef int (*vhost_set_log_base_op)(struct vhost_dev *dev, uint64_t base,
+ struct vhost_log *log);
+typedef int (*vhost_set_mem_table_op)(struct vhost_dev *dev,
+ struct vhost_memory *mem);
+typedef int (*vhost_set_vring_addr_op)(struct vhost_dev *dev,
+ struct vhost_vring_addr *addr);
+typedef int (*vhost_set_vring_endian_op)(struct vhost_dev *dev,
+ struct vhost_vring_state *ring);
+typedef int (*vhost_set_vring_num_op)(struct vhost_dev *dev,
+ struct vhost_vring_state *ring);
+typedef int (*vhost_set_vring_base_op)(struct vhost_dev *dev,
+ struct vhost_vring_state *ring);
+typedef int (*vhost_get_vring_base_op)(struct vhost_dev *dev,
+ struct vhost_vring_state *ring);
+typedef int (*vhost_set_vring_kick_op)(struct vhost_dev *dev,
+ struct vhost_vring_file *file);
+typedef int (*vhost_set_vring_call_op)(struct vhost_dev *dev,
+ struct vhost_vring_file *file);
+typedef int (*vhost_set_features_op)(struct vhost_dev *dev,
+ uint64_t features);
+typedef int (*vhost_get_features_op)(struct vhost_dev *dev,
+ uint64_t *features);
+typedef int (*vhost_set_owner_op)(struct vhost_dev *dev);
+typedef int (*vhost_reset_device_op)(struct vhost_dev *dev);
+typedef int (*vhost_get_vq_index_op)(struct vhost_dev *dev, int idx);
+typedef int (*vhost_set_vring_enable_op)(struct vhost_dev *dev,
+ int enable);
+typedef bool (*vhost_requires_shm_log_op)(struct vhost_dev *dev);
+typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
+ char *mac_addr);
typedef struct VhostOps {
VhostBackendType backend_type;
- vhost_call vhost_call;
vhost_backend_init vhost_backend_init;
vhost_backend_cleanup vhost_backend_cleanup;
- vhost_backend_get_vq_index vhost_backend_get_vq_index;
- vhost_backend_set_vring_enable vhost_backend_set_vring_enable;
+ vhost_backend_memslots_limit vhost_backend_memslots_limit;
+ vhost_net_set_backend_op vhost_net_set_backend;
+ vhost_scsi_set_endpoint_op vhost_scsi_set_endpoint;
+ vhost_scsi_clear_endpoint_op vhost_scsi_clear_endpoint;
+ vhost_scsi_get_abi_version_op vhost_scsi_get_abi_version;
+ vhost_set_log_base_op vhost_set_log_base;
+ vhost_set_mem_table_op vhost_set_mem_table;
+ vhost_set_vring_addr_op vhost_set_vring_addr;
+ vhost_set_vring_endian_op vhost_set_vring_endian;
+ vhost_set_vring_num_op vhost_set_vring_num;
+ vhost_set_vring_base_op vhost_set_vring_base;
+ vhost_get_vring_base_op vhost_get_vring_base;
+ vhost_set_vring_kick_op vhost_set_vring_kick;
+ vhost_set_vring_call_op vhost_set_vring_call;
+ vhost_set_features_op vhost_set_features;
+ vhost_get_features_op vhost_get_features;
+ vhost_set_owner_op vhost_set_owner;
+ vhost_reset_device_op vhost_reset_device;
+ vhost_get_vq_index_op vhost_get_vq_index;
+ vhost_set_vring_enable_op vhost_set_vring_enable;
+ vhost_requires_shm_log_op vhost_requires_shm_log;
+ vhost_migration_done_op vhost_migration_done;
} VhostOps;
extern const VhostOps user_ops;
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index c3758f3..7437fd4 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -31,7 +31,8 @@ typedef unsigned long vhost_log_chunk_t;
struct vhost_log {
unsigned long long size;
int refcnt;
- vhost_log_chunk_t log[0];
+ int fd;
+ vhost_log_chunk_t *log;
};
struct vhost_memory;
@@ -44,14 +45,14 @@ struct vhost_dev {
int nvqs;
/* the first virtqueue which would be used by this vhost dev */
int vq_index;
- unsigned long long features;
- unsigned long long acked_features;
- unsigned long long backend_features;
- unsigned long long protocol_features;
- unsigned long long max_queues;
+ uint64_t features;
+ uint64_t acked_features;
+ uint64_t backend_features;
+ uint64_t protocol_features;
+ uint64_t max_queues;
bool started;
bool log_enabled;
- unsigned long long log_size;
+ uint64_t log_size;
Error *migration_blocker;
bool memory_changed;
hwaddr mem_changed_start_addr;
@@ -59,6 +60,7 @@ struct vhost_dev {
const VhostOps *vhost_ops;
void *opaque;
struct vhost_log *log;
+ QLIST_ENTRY(vhost_dev) entry;
};
int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
@@ -83,4 +85,5 @@ uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
uint64_t features);
void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
uint64_t features);
+bool vhost_has_free_slot(void);
#endif
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 0188c4d..3389b41 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -27,6 +27,7 @@ void vhost_net_ack_features(VHostNetState *net, uint64_t features);
bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
int idx, bool mask);
+int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
VHostNetState *get_vhost_net(NetClientState *nc);
int vhost_set_vring_enable(NetClientState * nc, int enable);
diff --git a/include/qemu/buffer.h b/include/qemu/buffer.h
new file mode 100644
index 0000000..b380cec
--- /dev/null
+++ b/include/qemu/buffer.h
@@ -0,0 +1,118 @@
+/*
+ * QEMU generic buffers
+ *
+ * Copyright (c) 2015 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef QEMU_BUFFER_H__
+#define QEMU_BUFFER_H__
+
+#include "qemu-common.h"
+
+typedef struct Buffer Buffer;
+
+/**
+ * Buffer:
+ *
+ * The Buffer object provides a simple dynamically resizing
+ * array, with separate tracking of capacity and usage. This
+ * is typically useful when buffering I/O or processing data.
+ */
+
+struct Buffer {
+ size_t capacity;
+ size_t offset;
+ uint8_t *buffer;
+};
+
+/**
+ * buffer_reserve:
+ * @buffer: the buffer object
+ * @len: the minimum required free space
+ *
+ * Ensure that the buffer has space allocated for at least
+ * @len bytes. If the current buffer is too small, it will
+ * be reallocated, possibly to a larger size than requested.
+ */
+void buffer_reserve(Buffer *buffer, size_t len);
+
+/**
+ * buffer_reset:
+ * @buffer: the buffer object
+ *
+ * Reset the length of the stored data to zero, but do
+ * not free / reallocate the memory buffer
+ */
+void buffer_reset(Buffer *buffer);
+
+/**
+ * buffer_free:
+ * @buffer: the buffer object
+ *
+ * Reset the length of the stored data to zero and also
+ * free the internal memory buffer
+ */
+void buffer_free(Buffer *buffer);
+
+/**
+ * buffer_append:
+ * @buffer: the buffer object
+ * @data: the data block to append
+ * @len: the length of @data in bytes
+ *
+ * Append the contents of @data to the end of the buffer.
+ * The caller must ensure that the buffer has sufficient
+ * free space for @len bytes, typically by calling the
+ * buffer_reserve() method prior to appending.
+ */
+void buffer_append(Buffer *buffer, const void *data, size_t len);
+
+/**
+ * buffer_advance:
+ * @buffer: the buffer object
+ * @len: the number of bytes to skip
+ *
+ * Remove @len bytes of data from the head of the buffer.
+ * The internal buffer will not be reallocated, so will
+ * have at least @len bytes of free space after this
+ * call completes
+ */
+void buffer_advance(Buffer *buffer, size_t len);
+
+/**
+ * buffer_end:
+ * @buffer: the buffer object
+ *
+ * Get a pointer to the tail end of the internal buffer
+ * The returned pointer is only valid until the next
+ * call to buffer_reserve().
+ *
+ * Returns: the tail of the buffer
+ */
+uint8_t *buffer_end(Buffer *buffer);
+
+/**
+ * buffer_empty:
+ * @buffer: the buffer object
+ *
+ * Determine if the buffer contains any current data
+ *
+ * Returns: true if the buffer holds data, false otherwise
+ */
+gboolean buffer_empty(Buffer *buffer);
+
+#endif /* QEMU_BUFFER_H__ */
diff --git a/include/block/coroutine.h b/include/qemu/coroutine.h
index 20c027a..20c027a 100644
--- a/include/block/coroutine.h
+++ b/include/qemu/coroutine.h
diff --git a/include/block/coroutine_int.h b/include/qemu/coroutine_int.h
index 9aa1aae..42d6838 100644
--- a/include/block/coroutine_int.h
+++ b/include/qemu/coroutine_int.h
@@ -26,7 +26,7 @@
#define QEMU_COROUTINE_INT_H
#include "qemu/queue.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
typedef enum {
COROUTINE_YIELD = 1,
diff --git a/include/qemu/memfd.h b/include/qemu/memfd.h
new file mode 100644
index 0000000..53858ed
--- /dev/null
+++ b/include/qemu/memfd.h
@@ -0,0 +1,26 @@
+#ifndef QEMU_MEMFD_H
+#define QEMU_MEMFD_H
+
+#include "config-host.h"
+#include <stdbool.h>
+
+#ifndef F_LINUX_SPECIFIC_BASE
+#define F_LINUX_SPECIFIC_BASE 1024
+#endif
+
+#ifndef F_ADD_SEALS
+#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
+#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
+
+#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
+#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */
+#define F_SEAL_GROW 0x0004 /* prevent file from growing */
+#define F_SEAL_WRITE 0x0008 /* prevent writes */
+#endif
+
+void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
+ int *fd);
+void qemu_memfd_free(void *ptr, size_t size, int fd);
+bool qemu_memfd_check(void);
+
+#endif /* QEMU_MEMFD_H */
diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
new file mode 100644
index 0000000..56388e6
--- /dev/null
+++ b/include/qemu/mmap-alloc.h
@@ -0,0 +1,10 @@
+#ifndef QEMU_MMAP_ALLOC
+#define QEMU_MMAP_ALLOC
+
+#include "qemu-common.h"
+
+void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared);
+
+void qemu_ram_munmap(void *ptr, size_t size);
+
+#endif
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index ef21efb..b568424 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -69,6 +69,8 @@
#include "sysemu/os-posix.h"
#endif
+#include "qapi/error.h"
+
#if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10
/* [u]int_fast*_t not in <sys/int_types.h> */
typedef unsigned char uint_fast8_t;
@@ -286,4 +288,18 @@ void os_mem_prealloc(int fd, char *area, size_t sz);
int qemu_read_password(char *buf, int buf_size);
+/**
+ * qemu_fork:
+ *
+ * A version of fork that avoids signal handler race
+ * conditions that can lead to child process getting
+ * signals that are otherwise only expected by the
+ * parent. It also resets all signal handlers to the
+ * default settings.
+ *
+ * Returns 0 to child process, pid number to parent
+ * or -1 on failure.
+ */
+pid_t qemu_fork(Error **errp);
+
#endif
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index c174b5c..5a183c5 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -88,4 +88,38 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp);
int parse_host_port(struct sockaddr_in *saddr, const char *str);
int socket_init(void);
+/**
+ * socket_local_address:
+ * @fd: the socket file handle
+ * @errp: pointer to uninitialized error object
+ *
+ * Get the string representation of the local socket
+ * address. A pointer to the allocated address information
+ * struct will be returned, which the caller is required to
+ * release with a call qapi_free_SocketAddress when no
+ * longer required.
+ *
+ * Returns: the socket address struct, or NULL on error
+ */
+SocketAddress *socket_local_address(int fd, Error **errp);
+
+/**
+ * socket_remote_address:
+ * @fd: the socket file handle
+ * @errp: pointer to uninitialized error object
+ *
+ * Get the string representation of the remote socket
+ * address. A pointer to the allocated address information
+ * struct will be returned, which the caller is required to
+ * release with a call qapi_free_SocketAddress when no
+ * longer required.
+ *
+ * Returns: the socket address struct, or NULL on error
+ */
+SocketAddress *socket_remote_address(int fd, Error **errp);
+
+
+void qapi_copy_SocketAddress(SocketAddress **p_dest,
+ SocketAddress *src);
+
#endif /* QEMU_SOCKET_H */
diff --git a/linux-headers/asm-arm/unistd.h b/linux-headers/asm-arm/unistd.h
new file mode 100644
index 0000000..0a1376c
--- /dev/null
+++ b/linux-headers/asm-arm/unistd.h
@@ -0,0 +1,448 @@
+/*
+ * arch/arm/include/asm/unistd.h
+ *
+ * Copyright (C) 2001-2005 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Please forward _all_ changes to this file to rmk@arm.linux.org.uk,
+ * no matter what the change is. Thanks!
+ */
+#ifndef __ASM_ARM_UNISTD_H
+#define __ASM_ARM_UNISTD_H
+
+#define __NR_OABI_SYSCALL_BASE 0x900000
+
+#if defined(__thumb__) || defined(__ARM_EABI__)
+#define __NR_SYSCALL_BASE 0
+#else
+#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
+#endif
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
+#define __NR_exit (__NR_SYSCALL_BASE+ 1)
+#define __NR_fork (__NR_SYSCALL_BASE+ 2)
+#define __NR_read (__NR_SYSCALL_BASE+ 3)
+#define __NR_write (__NR_SYSCALL_BASE+ 4)
+#define __NR_open (__NR_SYSCALL_BASE+ 5)
+#define __NR_close (__NR_SYSCALL_BASE+ 6)
+ /* 7 was sys_waitpid */
+#define __NR_creat (__NR_SYSCALL_BASE+ 8)
+#define __NR_link (__NR_SYSCALL_BASE+ 9)
+#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
+#define __NR_execve (__NR_SYSCALL_BASE+ 11)
+#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
+#define __NR_time (__NR_SYSCALL_BASE+ 13)
+#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
+#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
+#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
+ /* 17 was sys_break */
+ /* 18 was sys_stat */
+#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
+#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
+#define __NR_mount (__NR_SYSCALL_BASE+ 21)
+#define __NR_umount (__NR_SYSCALL_BASE+ 22)
+#define __NR_setuid (__NR_SYSCALL_BASE+ 23)
+#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
+#define __NR_stime (__NR_SYSCALL_BASE+ 25)
+#define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
+#define __NR_alarm (__NR_SYSCALL_BASE+ 27)
+ /* 28 was sys_fstat */
+#define __NR_pause (__NR_SYSCALL_BASE+ 29)
+#define __NR_utime (__NR_SYSCALL_BASE+ 30)
+ /* 31 was sys_stty */
+ /* 32 was sys_gtty */
+#define __NR_access (__NR_SYSCALL_BASE+ 33)
+#define __NR_nice (__NR_SYSCALL_BASE+ 34)
+ /* 35 was sys_ftime */
+#define __NR_sync (__NR_SYSCALL_BASE+ 36)
+#define __NR_kill (__NR_SYSCALL_BASE+ 37)
+#define __NR_rename (__NR_SYSCALL_BASE+ 38)
+#define __NR_mkdir (__NR_SYSCALL_BASE+ 39)
+#define __NR_rmdir (__NR_SYSCALL_BASE+ 40)
+#define __NR_dup (__NR_SYSCALL_BASE+ 41)
+#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
+#define __NR_times (__NR_SYSCALL_BASE+ 43)
+ /* 44 was sys_prof */
+#define __NR_brk (__NR_SYSCALL_BASE+ 45)
+#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
+#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
+ /* 48 was sys_signal */
+#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
+#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
+#define __NR_acct (__NR_SYSCALL_BASE+ 51)
+#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
+ /* 53 was sys_lock */
+#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
+#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
+ /* 56 was sys_mpx */
+#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
+ /* 58 was sys_ulimit */
+ /* 59 was sys_olduname */
+#define __NR_umask (__NR_SYSCALL_BASE+ 60)
+#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
+#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
+#define __NR_dup2 (__NR_SYSCALL_BASE+ 63)
+#define __NR_getppid (__NR_SYSCALL_BASE+ 64)
+#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
+#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
+#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
+ /* 68 was sys_sgetmask */
+ /* 69 was sys_ssetmask */
+#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
+#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
+#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
+#define __NR_sigpending (__NR_SYSCALL_BASE+ 73)
+#define __NR_sethostname (__NR_SYSCALL_BASE+ 74)
+#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75)
+#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */
+#define __NR_getrusage (__NR_SYSCALL_BASE+ 77)
+#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78)
+#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79)
+#define __NR_getgroups (__NR_SYSCALL_BASE+ 80)
+#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
+#define __NR_select (__NR_SYSCALL_BASE+ 82)
+#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
+ /* 84 was sys_lstat */
+#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
+#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
+#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
+#define __NR_reboot (__NR_SYSCALL_BASE+ 88)
+#define __NR_readdir (__NR_SYSCALL_BASE+ 89)
+#define __NR_mmap (__NR_SYSCALL_BASE+ 90)
+#define __NR_munmap (__NR_SYSCALL_BASE+ 91)
+#define __NR_truncate (__NR_SYSCALL_BASE+ 92)
+#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93)
+#define __NR_fchmod (__NR_SYSCALL_BASE+ 94)
+#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
+#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
+#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
+ /* 98 was sys_profil */
+#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
+#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
+ /* 101 was sys_ioperm */
+#define __NR_socketcall (__NR_SYSCALL_BASE+102)
+#define __NR_syslog (__NR_SYSCALL_BASE+103)
+#define __NR_setitimer (__NR_SYSCALL_BASE+104)
+#define __NR_getitimer (__NR_SYSCALL_BASE+105)
+#define __NR_stat (__NR_SYSCALL_BASE+106)
+#define __NR_lstat (__NR_SYSCALL_BASE+107)
+#define __NR_fstat (__NR_SYSCALL_BASE+108)
+ /* 109 was sys_uname */
+ /* 110 was sys_iopl */
+#define __NR_vhangup (__NR_SYSCALL_BASE+111)
+ /* 112 was sys_idle */
+#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
+#define __NR_wait4 (__NR_SYSCALL_BASE+114)
+#define __NR_swapoff (__NR_SYSCALL_BASE+115)
+#define __NR_sysinfo (__NR_SYSCALL_BASE+116)
+#define __NR_ipc (__NR_SYSCALL_BASE+117)
+#define __NR_fsync (__NR_SYSCALL_BASE+118)
+#define __NR_sigreturn (__NR_SYSCALL_BASE+119)
+#define __NR_clone (__NR_SYSCALL_BASE+120)
+#define __NR_setdomainname (__NR_SYSCALL_BASE+121)
+#define __NR_uname (__NR_SYSCALL_BASE+122)
+ /* 123 was sys_modify_ldt */
+#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
+#define __NR_mprotect (__NR_SYSCALL_BASE+125)
+#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
+ /* 127 was sys_create_module */
+#define __NR_init_module (__NR_SYSCALL_BASE+128)
+#define __NR_delete_module (__NR_SYSCALL_BASE+129)
+ /* 130 was sys_get_kernel_syms */
+#define __NR_quotactl (__NR_SYSCALL_BASE+131)
+#define __NR_getpgid (__NR_SYSCALL_BASE+132)
+#define __NR_fchdir (__NR_SYSCALL_BASE+133)
+#define __NR_bdflush (__NR_SYSCALL_BASE+134)
+#define __NR_sysfs (__NR_SYSCALL_BASE+135)
+#define __NR_personality (__NR_SYSCALL_BASE+136)
+ /* 137 was sys_afs_syscall */
+#define __NR_setfsuid (__NR_SYSCALL_BASE+138)
+#define __NR_setfsgid (__NR_SYSCALL_BASE+139)
+#define __NR__llseek (__NR_SYSCALL_BASE+140)
+#define __NR_getdents (__NR_SYSCALL_BASE+141)
+#define __NR__newselect (__NR_SYSCALL_BASE+142)
+#define __NR_flock (__NR_SYSCALL_BASE+143)
+#define __NR_msync (__NR_SYSCALL_BASE+144)
+#define __NR_readv (__NR_SYSCALL_BASE+145)
+#define __NR_writev (__NR_SYSCALL_BASE+146)
+#define __NR_getsid (__NR_SYSCALL_BASE+147)
+#define __NR_fdatasync (__NR_SYSCALL_BASE+148)
+#define __NR__sysctl (__NR_SYSCALL_BASE+149)
+#define __NR_mlock (__NR_SYSCALL_BASE+150)
+#define __NR_munlock (__NR_SYSCALL_BASE+151)
+#define __NR_mlockall (__NR_SYSCALL_BASE+152)
+#define __NR_munlockall (__NR_SYSCALL_BASE+153)
+#define __NR_sched_setparam (__NR_SYSCALL_BASE+154)
+#define __NR_sched_getparam (__NR_SYSCALL_BASE+155)
+#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156)
+#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157)
+#define __NR_sched_yield (__NR_SYSCALL_BASE+158)
+#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159)
+#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160)
+#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161)
+#define __NR_nanosleep (__NR_SYSCALL_BASE+162)
+#define __NR_mremap (__NR_SYSCALL_BASE+163)
+#define __NR_setresuid (__NR_SYSCALL_BASE+164)
+#define __NR_getresuid (__NR_SYSCALL_BASE+165)
+ /* 166 was sys_vm86 */
+ /* 167 was sys_query_module */
+#define __NR_poll (__NR_SYSCALL_BASE+168)
+#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
+#define __NR_setresgid (__NR_SYSCALL_BASE+170)
+#define __NR_getresgid (__NR_SYSCALL_BASE+171)
+#define __NR_prctl (__NR_SYSCALL_BASE+172)
+#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173)
+#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174)
+#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175)
+#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176)
+#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177)
+#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178)
+#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179)
+#define __NR_pread64 (__NR_SYSCALL_BASE+180)
+#define __NR_pwrite64 (__NR_SYSCALL_BASE+181)
+#define __NR_chown (__NR_SYSCALL_BASE+182)
+#define __NR_getcwd (__NR_SYSCALL_BASE+183)
+#define __NR_capget (__NR_SYSCALL_BASE+184)
+#define __NR_capset (__NR_SYSCALL_BASE+185)
+#define __NR_sigaltstack (__NR_SYSCALL_BASE+186)
+#define __NR_sendfile (__NR_SYSCALL_BASE+187)
+ /* 188 reserved */
+ /* 189 reserved */
+#define __NR_vfork (__NR_SYSCALL_BASE+190)
+#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */
+#define __NR_mmap2 (__NR_SYSCALL_BASE+192)
+#define __NR_truncate64 (__NR_SYSCALL_BASE+193)
+#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194)
+#define __NR_stat64 (__NR_SYSCALL_BASE+195)
+#define __NR_lstat64 (__NR_SYSCALL_BASE+196)
+#define __NR_fstat64 (__NR_SYSCALL_BASE+197)
+#define __NR_lchown32 (__NR_SYSCALL_BASE+198)
+#define __NR_getuid32 (__NR_SYSCALL_BASE+199)
+#define __NR_getgid32 (__NR_SYSCALL_BASE+200)
+#define __NR_geteuid32 (__NR_SYSCALL_BASE+201)
+#define __NR_getegid32 (__NR_SYSCALL_BASE+202)
+#define __NR_setreuid32 (__NR_SYSCALL_BASE+203)
+#define __NR_setregid32 (__NR_SYSCALL_BASE+204)
+#define __NR_getgroups32 (__NR_SYSCALL_BASE+205)
+#define __NR_setgroups32 (__NR_SYSCALL_BASE+206)
+#define __NR_fchown32 (__NR_SYSCALL_BASE+207)
+#define __NR_setresuid32 (__NR_SYSCALL_BASE+208)
+#define __NR_getresuid32 (__NR_SYSCALL_BASE+209)
+#define __NR_setresgid32 (__NR_SYSCALL_BASE+210)
+#define __NR_getresgid32 (__NR_SYSCALL_BASE+211)
+#define __NR_chown32 (__NR_SYSCALL_BASE+212)
+#define __NR_setuid32 (__NR_SYSCALL_BASE+213)
+#define __NR_setgid32 (__NR_SYSCALL_BASE+214)
+#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215)
+#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216)
+#define __NR_getdents64 (__NR_SYSCALL_BASE+217)
+#define __NR_pivot_root (__NR_SYSCALL_BASE+218)
+#define __NR_mincore (__NR_SYSCALL_BASE+219)
+#define __NR_madvise (__NR_SYSCALL_BASE+220)
+#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
+ /* 222 for tux */
+ /* 223 is unused */
+#define __NR_gettid (__NR_SYSCALL_BASE+224)
+#define __NR_readahead (__NR_SYSCALL_BASE+225)
+#define __NR_setxattr (__NR_SYSCALL_BASE+226)
+#define __NR_lsetxattr (__NR_SYSCALL_BASE+227)
+#define __NR_fsetxattr (__NR_SYSCALL_BASE+228)
+#define __NR_getxattr (__NR_SYSCALL_BASE+229)
+#define __NR_lgetxattr (__NR_SYSCALL_BASE+230)
+#define __NR_fgetxattr (__NR_SYSCALL_BASE+231)
+#define __NR_listxattr (__NR_SYSCALL_BASE+232)
+#define __NR_llistxattr (__NR_SYSCALL_BASE+233)
+#define __NR_flistxattr (__NR_SYSCALL_BASE+234)
+#define __NR_removexattr (__NR_SYSCALL_BASE+235)
+#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
+#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
+#define __NR_tkill (__NR_SYSCALL_BASE+238)
+#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
+#define __NR_futex (__NR_SYSCALL_BASE+240)
+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
+#define __NR_io_setup (__NR_SYSCALL_BASE+243)
+#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
+#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
+#define __NR_io_submit (__NR_SYSCALL_BASE+246)
+#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
+#define __NR_exit_group (__NR_SYSCALL_BASE+248)
+#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
+#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
+#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
+#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
+#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
+ /* 254 for set_thread_area */
+ /* 255 for get_thread_area */
+#define __NR_set_tid_address (__NR_SYSCALL_BASE+256)
+#define __NR_timer_create (__NR_SYSCALL_BASE+257)
+#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
+#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
+#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
+#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
+#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
+#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
+#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
+#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
+#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
+#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
+#define __NR_tgkill (__NR_SYSCALL_BASE+268)
+#define __NR_utimes (__NR_SYSCALL_BASE+269)
+#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270)
+#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271)
+#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272)
+#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273)
+#define __NR_mq_open (__NR_SYSCALL_BASE+274)
+#define __NR_mq_unlink (__NR_SYSCALL_BASE+275)
+#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276)
+#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277)
+#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
+#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
+#define __NR_waitid (__NR_SYSCALL_BASE+280)
+#define __NR_socket (__NR_SYSCALL_BASE+281)
+#define __NR_bind (__NR_SYSCALL_BASE+282)
+#define __NR_connect (__NR_SYSCALL_BASE+283)
+#define __NR_listen (__NR_SYSCALL_BASE+284)
+#define __NR_accept (__NR_SYSCALL_BASE+285)
+#define __NR_getsockname (__NR_SYSCALL_BASE+286)
+#define __NR_getpeername (__NR_SYSCALL_BASE+287)
+#define __NR_socketpair (__NR_SYSCALL_BASE+288)
+#define __NR_send (__NR_SYSCALL_BASE+289)
+#define __NR_sendto (__NR_SYSCALL_BASE+290)
+#define __NR_recv (__NR_SYSCALL_BASE+291)
+#define __NR_recvfrom (__NR_SYSCALL_BASE+292)
+#define __NR_shutdown (__NR_SYSCALL_BASE+293)
+#define __NR_setsockopt (__NR_SYSCALL_BASE+294)
+#define __NR_getsockopt (__NR_SYSCALL_BASE+295)
+#define __NR_sendmsg (__NR_SYSCALL_BASE+296)
+#define __NR_recvmsg (__NR_SYSCALL_BASE+297)
+#define __NR_semop (__NR_SYSCALL_BASE+298)
+#define __NR_semget (__NR_SYSCALL_BASE+299)
+#define __NR_semctl (__NR_SYSCALL_BASE+300)
+#define __NR_msgsnd (__NR_SYSCALL_BASE+301)
+#define __NR_msgrcv (__NR_SYSCALL_BASE+302)
+#define __NR_msgget (__NR_SYSCALL_BASE+303)
+#define __NR_msgctl (__NR_SYSCALL_BASE+304)
+#define __NR_shmat (__NR_SYSCALL_BASE+305)
+#define __NR_shmdt (__NR_SYSCALL_BASE+306)
+#define __NR_shmget (__NR_SYSCALL_BASE+307)
+#define __NR_shmctl (__NR_SYSCALL_BASE+308)
+#define __NR_add_key (__NR_SYSCALL_BASE+309)
+#define __NR_request_key (__NR_SYSCALL_BASE+310)
+#define __NR_keyctl (__NR_SYSCALL_BASE+311)
+#define __NR_semtimedop (__NR_SYSCALL_BASE+312)
+#define __NR_vserver (__NR_SYSCALL_BASE+313)
+#define __NR_ioprio_set (__NR_SYSCALL_BASE+314)
+#define __NR_ioprio_get (__NR_SYSCALL_BASE+315)
+#define __NR_inotify_init (__NR_SYSCALL_BASE+316)
+#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317)
+#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318)
+#define __NR_mbind (__NR_SYSCALL_BASE+319)
+#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
+#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
+#define __NR_openat (__NR_SYSCALL_BASE+322)
+#define __NR_mkdirat (__NR_SYSCALL_BASE+323)
+#define __NR_mknodat (__NR_SYSCALL_BASE+324)
+#define __NR_fchownat (__NR_SYSCALL_BASE+325)
+#define __NR_futimesat (__NR_SYSCALL_BASE+326)
+#define __NR_fstatat64 (__NR_SYSCALL_BASE+327)
+#define __NR_unlinkat (__NR_SYSCALL_BASE+328)
+#define __NR_renameat (__NR_SYSCALL_BASE+329)
+#define __NR_linkat (__NR_SYSCALL_BASE+330)
+#define __NR_symlinkat (__NR_SYSCALL_BASE+331)
+#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
+#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
+#define __NR_faccessat (__NR_SYSCALL_BASE+334)
+#define __NR_pselect6 (__NR_SYSCALL_BASE+335)
+#define __NR_ppoll (__NR_SYSCALL_BASE+336)
+#define __NR_unshare (__NR_SYSCALL_BASE+337)
+#define __NR_set_robust_list (__NR_SYSCALL_BASE+338)
+#define __NR_get_robust_list (__NR_SYSCALL_BASE+339)
+#define __NR_splice (__NR_SYSCALL_BASE+340)
+#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341)
+#define __NR_sync_file_range2 __NR_arm_sync_file_range
+#define __NR_tee (__NR_SYSCALL_BASE+342)
+#define __NR_vmsplice (__NR_SYSCALL_BASE+343)
+#define __NR_move_pages (__NR_SYSCALL_BASE+344)
+#define __NR_getcpu (__NR_SYSCALL_BASE+345)
+#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346)
+#define __NR_kexec_load (__NR_SYSCALL_BASE+347)
+#define __NR_utimensat (__NR_SYSCALL_BASE+348)
+#define __NR_signalfd (__NR_SYSCALL_BASE+349)
+#define __NR_timerfd_create (__NR_SYSCALL_BASE+350)
+#define __NR_eventfd (__NR_SYSCALL_BASE+351)
+#define __NR_fallocate (__NR_SYSCALL_BASE+352)
+#define __NR_timerfd_settime (__NR_SYSCALL_BASE+353)
+#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+354)
+#define __NR_signalfd4 (__NR_SYSCALL_BASE+355)
+#define __NR_eventfd2 (__NR_SYSCALL_BASE+356)
+#define __NR_epoll_create1 (__NR_SYSCALL_BASE+357)
+#define __NR_dup3 (__NR_SYSCALL_BASE+358)
+#define __NR_pipe2 (__NR_SYSCALL_BASE+359)
+#define __NR_inotify_init1 (__NR_SYSCALL_BASE+360)
+#define __NR_preadv (__NR_SYSCALL_BASE+361)
+#define __NR_pwritev (__NR_SYSCALL_BASE+362)
+#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363)
+#define __NR_perf_event_open (__NR_SYSCALL_BASE+364)
+#define __NR_recvmmsg (__NR_SYSCALL_BASE+365)
+#define __NR_accept4 (__NR_SYSCALL_BASE+366)
+#define __NR_fanotify_init (__NR_SYSCALL_BASE+367)
+#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368)
+#define __NR_prlimit64 (__NR_SYSCALL_BASE+369)
+#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+370)
+#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371)
+#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372)
+#define __NR_syncfs (__NR_SYSCALL_BASE+373)
+#define __NR_sendmmsg (__NR_SYSCALL_BASE+374)
+#define __NR_setns (__NR_SYSCALL_BASE+375)
+#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
+#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
+#define __NR_kcmp (__NR_SYSCALL_BASE+378)
+#define __NR_finit_module (__NR_SYSCALL_BASE+379)
+#define __NR_sched_setattr (__NR_SYSCALL_BASE+380)
+#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)
+#define __NR_renameat2 (__NR_SYSCALL_BASE+382)
+#define __NR_seccomp (__NR_SYSCALL_BASE+383)
+#define __NR_getrandom (__NR_SYSCALL_BASE+384)
+#define __NR_memfd_create (__NR_SYSCALL_BASE+385)
+#define __NR_bpf (__NR_SYSCALL_BASE+386)
+#define __NR_execveat (__NR_SYSCALL_BASE+387)
+#define __NR_userfaultfd (__NR_SYSCALL_BASE+388)
+#define __NR_membarrier (__NR_SYSCALL_BASE+389)
+
+/*
+ * The following SWIs are ARM private.
+ */
+#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
+#define __ARM_NR_breakpoint (__ARM_NR_BASE+1)
+#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
+#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
+#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
+#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
+
+/*
+ * The following syscalls are obsolete and no longer available for EABI.
+ */
+#if defined(__ARM_EABI__)
+#undef __NR_time
+#undef __NR_umount
+#undef __NR_stime
+#undef __NR_alarm
+#undef __NR_utime
+#undef __NR_getrlimit
+#undef __NR_select
+#undef __NR_readdir
+#undef __NR_mmap
+#undef __NR_socketcall
+#undef __NR_syscall
+#undef __NR_ipc
+#endif
+
+#endif /* __ASM_ARM_UNISTD_H */
diff --git a/linux-headers/asm-arm64/unistd.h b/linux-headers/asm-arm64/unistd.h
new file mode 100644
index 0000000..1caadc2
--- /dev/null
+++ b/linux-headers/asm-arm64/unistd.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <asm-generic/unistd.h>
diff --git a/linux-headers/asm-mips/unistd.h b/linux-headers/asm-mips/unistd.h
new file mode 100644
index 0000000..2a20209
--- /dev/null
+++ b/linux-headers/asm-mips/unistd.h
@@ -0,0 +1,1063 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ *
+ * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
+ * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
+ */
+#ifndef _ASM_UNISTD_H
+#define _ASM_UNISTD_H
+
+#include <asm/sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+/*
+ * Linux o32 style syscalls are in the range from 4000 to 4999.
+ */
+#define __NR_Linux 4000
+#define __NR_syscall (__NR_Linux + 0)
+#define __NR_exit (__NR_Linux + 1)
+#define __NR_fork (__NR_Linux + 2)
+#define __NR_read (__NR_Linux + 3)
+#define __NR_write (__NR_Linux + 4)
+#define __NR_open (__NR_Linux + 5)
+#define __NR_close (__NR_Linux + 6)
+#define __NR_waitpid (__NR_Linux + 7)
+#define __NR_creat (__NR_Linux + 8)
+#define __NR_link (__NR_Linux + 9)
+#define __NR_unlink (__NR_Linux + 10)
+#define __NR_execve (__NR_Linux + 11)
+#define __NR_chdir (__NR_Linux + 12)
+#define __NR_time (__NR_Linux + 13)
+#define __NR_mknod (__NR_Linux + 14)
+#define __NR_chmod (__NR_Linux + 15)
+#define __NR_lchown (__NR_Linux + 16)
+#define __NR_break (__NR_Linux + 17)
+#define __NR_unused18 (__NR_Linux + 18)
+#define __NR_lseek (__NR_Linux + 19)
+#define __NR_getpid (__NR_Linux + 20)
+#define __NR_mount (__NR_Linux + 21)
+#define __NR_umount (__NR_Linux + 22)
+#define __NR_setuid (__NR_Linux + 23)
+#define __NR_getuid (__NR_Linux + 24)
+#define __NR_stime (__NR_Linux + 25)
+#define __NR_ptrace (__NR_Linux + 26)
+#define __NR_alarm (__NR_Linux + 27)
+#define __NR_unused28 (__NR_Linux + 28)
+#define __NR_pause (__NR_Linux + 29)
+#define __NR_utime (__NR_Linux + 30)
+#define __NR_stty (__NR_Linux + 31)
+#define __NR_gtty (__NR_Linux + 32)
+#define __NR_access (__NR_Linux + 33)
+#define __NR_nice (__NR_Linux + 34)
+#define __NR_ftime (__NR_Linux + 35)
+#define __NR_sync (__NR_Linux + 36)
+#define __NR_kill (__NR_Linux + 37)
+#define __NR_rename (__NR_Linux + 38)
+#define __NR_mkdir (__NR_Linux + 39)
+#define __NR_rmdir (__NR_Linux + 40)
+#define __NR_dup (__NR_Linux + 41)
+#define __NR_pipe (__NR_Linux + 42)
+#define __NR_times (__NR_Linux + 43)
+#define __NR_prof (__NR_Linux + 44)
+#define __NR_brk (__NR_Linux + 45)
+#define __NR_setgid (__NR_Linux + 46)
+#define __NR_getgid (__NR_Linux + 47)
+#define __NR_signal (__NR_Linux + 48)
+#define __NR_geteuid (__NR_Linux + 49)
+#define __NR_getegid (__NR_Linux + 50)
+#define __NR_acct (__NR_Linux + 51)
+#define __NR_umount2 (__NR_Linux + 52)
+#define __NR_lock (__NR_Linux + 53)
+#define __NR_ioctl (__NR_Linux + 54)
+#define __NR_fcntl (__NR_Linux + 55)
+#define __NR_mpx (__NR_Linux + 56)
+#define __NR_setpgid (__NR_Linux + 57)
+#define __NR_ulimit (__NR_Linux + 58)
+#define __NR_unused59 (__NR_Linux + 59)
+#define __NR_umask (__NR_Linux + 60)
+#define __NR_chroot (__NR_Linux + 61)
+#define __NR_ustat (__NR_Linux + 62)
+#define __NR_dup2 (__NR_Linux + 63)
+#define __NR_getppid (__NR_Linux + 64)
+#define __NR_getpgrp (__NR_Linux + 65)
+#define __NR_setsid (__NR_Linux + 66)
+#define __NR_sigaction (__NR_Linux + 67)
+#define __NR_sgetmask (__NR_Linux + 68)
+#define __NR_ssetmask (__NR_Linux + 69)
+#define __NR_setreuid (__NR_Linux + 70)
+#define __NR_setregid (__NR_Linux + 71)
+#define __NR_sigsuspend (__NR_Linux + 72)
+#define __NR_sigpending (__NR_Linux + 73)
+#define __NR_sethostname (__NR_Linux + 74)
+#define __NR_setrlimit (__NR_Linux + 75)
+#define __NR_getrlimit (__NR_Linux + 76)
+#define __NR_getrusage (__NR_Linux + 77)
+#define __NR_gettimeofday (__NR_Linux + 78)
+#define __NR_settimeofday (__NR_Linux + 79)
+#define __NR_getgroups (__NR_Linux + 80)
+#define __NR_setgroups (__NR_Linux + 81)
+#define __NR_reserved82 (__NR_Linux + 82)
+#define __NR_symlink (__NR_Linux + 83)
+#define __NR_unused84 (__NR_Linux + 84)
+#define __NR_readlink (__NR_Linux + 85)
+#define __NR_uselib (__NR_Linux + 86)
+#define __NR_swapon (__NR_Linux + 87)
+#define __NR_reboot (__NR_Linux + 88)
+#define __NR_readdir (__NR_Linux + 89)
+#define __NR_mmap (__NR_Linux + 90)
+#define __NR_munmap (__NR_Linux + 91)
+#define __NR_truncate (__NR_Linux + 92)
+#define __NR_ftruncate (__NR_Linux + 93)
+#define __NR_fchmod (__NR_Linux + 94)
+#define __NR_fchown (__NR_Linux + 95)
+#define __NR_getpriority (__NR_Linux + 96)
+#define __NR_setpriority (__NR_Linux + 97)
+#define __NR_profil (__NR_Linux + 98)
+#define __NR_statfs (__NR_Linux + 99)
+#define __NR_fstatfs (__NR_Linux + 100)
+#define __NR_ioperm (__NR_Linux + 101)
+#define __NR_socketcall (__NR_Linux + 102)
+#define __NR_syslog (__NR_Linux + 103)
+#define __NR_setitimer (__NR_Linux + 104)
+#define __NR_getitimer (__NR_Linux + 105)
+#define __NR_stat (__NR_Linux + 106)
+#define __NR_lstat (__NR_Linux + 107)
+#define __NR_fstat (__NR_Linux + 108)
+#define __NR_unused109 (__NR_Linux + 109)
+#define __NR_iopl (__NR_Linux + 110)
+#define __NR_vhangup (__NR_Linux + 111)
+#define __NR_idle (__NR_Linux + 112)
+#define __NR_vm86 (__NR_Linux + 113)
+#define __NR_wait4 (__NR_Linux + 114)
+#define __NR_swapoff (__NR_Linux + 115)
+#define __NR_sysinfo (__NR_Linux + 116)
+#define __NR_ipc (__NR_Linux + 117)
+#define __NR_fsync (__NR_Linux + 118)
+#define __NR_sigreturn (__NR_Linux + 119)
+#define __NR_clone (__NR_Linux + 120)
+#define __NR_setdomainname (__NR_Linux + 121)
+#define __NR_uname (__NR_Linux + 122)
+#define __NR_modify_ldt (__NR_Linux + 123)
+#define __NR_adjtimex (__NR_Linux + 124)
+#define __NR_mprotect (__NR_Linux + 125)
+#define __NR_sigprocmask (__NR_Linux + 126)
+#define __NR_create_module (__NR_Linux + 127)
+#define __NR_init_module (__NR_Linux + 128)
+#define __NR_delete_module (__NR_Linux + 129)
+#define __NR_get_kernel_syms (__NR_Linux + 130)
+#define __NR_quotactl (__NR_Linux + 131)
+#define __NR_getpgid (__NR_Linux + 132)
+#define __NR_fchdir (__NR_Linux + 133)
+#define __NR_bdflush (__NR_Linux + 134)
+#define __NR_sysfs (__NR_Linux + 135)
+#define __NR_personality (__NR_Linux + 136)
+#define __NR_afs_syscall (__NR_Linux + 137) /* Syscall for Andrew File System */
+#define __NR_setfsuid (__NR_Linux + 138)
+#define __NR_setfsgid (__NR_Linux + 139)
+#define __NR__llseek (__NR_Linux + 140)
+#define __NR_getdents (__NR_Linux + 141)
+#define __NR__newselect (__NR_Linux + 142)
+#define __NR_flock (__NR_Linux + 143)
+#define __NR_msync (__NR_Linux + 144)
+#define __NR_readv (__NR_Linux + 145)
+#define __NR_writev (__NR_Linux + 146)
+#define __NR_cacheflush (__NR_Linux + 147)
+#define __NR_cachectl (__NR_Linux + 148)
+#define __NR_sysmips (__NR_Linux + 149)
+#define __NR_unused150 (__NR_Linux + 150)
+#define __NR_getsid (__NR_Linux + 151)
+#define __NR_fdatasync (__NR_Linux + 152)
+#define __NR__sysctl (__NR_Linux + 153)
+#define __NR_mlock (__NR_Linux + 154)
+#define __NR_munlock (__NR_Linux + 155)
+#define __NR_mlockall (__NR_Linux + 156)
+#define __NR_munlockall (__NR_Linux + 157)
+#define __NR_sched_setparam (__NR_Linux + 158)
+#define __NR_sched_getparam (__NR_Linux + 159)
+#define __NR_sched_setscheduler (__NR_Linux + 160)
+#define __NR_sched_getscheduler (__NR_Linux + 161)
+#define __NR_sched_yield (__NR_Linux + 162)
+#define __NR_sched_get_priority_max (__NR_Linux + 163)
+#define __NR_sched_get_priority_min (__NR_Linux + 164)
+#define __NR_sched_rr_get_interval (__NR_Linux + 165)
+#define __NR_nanosleep (__NR_Linux + 166)
+#define __NR_mremap (__NR_Linux + 167)
+#define __NR_accept (__NR_Linux + 168)
+#define __NR_bind (__NR_Linux + 169)
+#define __NR_connect (__NR_Linux + 170)
+#define __NR_getpeername (__NR_Linux + 171)
+#define __NR_getsockname (__NR_Linux + 172)
+#define __NR_getsockopt (__NR_Linux + 173)
+#define __NR_listen (__NR_Linux + 174)
+#define __NR_recv (__NR_Linux + 175)
+#define __NR_recvfrom (__NR_Linux + 176)
+#define __NR_recvmsg (__NR_Linux + 177)
+#define __NR_send (__NR_Linux + 178)
+#define __NR_sendmsg (__NR_Linux + 179)
+#define __NR_sendto (__NR_Linux + 180)
+#define __NR_setsockopt (__NR_Linux + 181)
+#define __NR_shutdown (__NR_Linux + 182)
+#define __NR_socket (__NR_Linux + 183)
+#define __NR_socketpair (__NR_Linux + 184)
+#define __NR_setresuid (__NR_Linux + 185)
+#define __NR_getresuid (__NR_Linux + 186)
+#define __NR_query_module (__NR_Linux + 187)
+#define __NR_poll (__NR_Linux + 188)
+#define __NR_nfsservctl (__NR_Linux + 189)
+#define __NR_setresgid (__NR_Linux + 190)
+#define __NR_getresgid (__NR_Linux + 191)
+#define __NR_prctl (__NR_Linux + 192)
+#define __NR_rt_sigreturn (__NR_Linux + 193)
+#define __NR_rt_sigaction (__NR_Linux + 194)
+#define __NR_rt_sigprocmask (__NR_Linux + 195)
+#define __NR_rt_sigpending (__NR_Linux + 196)
+#define __NR_rt_sigtimedwait (__NR_Linux + 197)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 198)
+#define __NR_rt_sigsuspend (__NR_Linux + 199)
+#define __NR_pread64 (__NR_Linux + 200)
+#define __NR_pwrite64 (__NR_Linux + 201)
+#define __NR_chown (__NR_Linux + 202)
+#define __NR_getcwd (__NR_Linux + 203)
+#define __NR_capget (__NR_Linux + 204)
+#define __NR_capset (__NR_Linux + 205)
+#define __NR_sigaltstack (__NR_Linux + 206)
+#define __NR_sendfile (__NR_Linux + 207)
+#define __NR_getpmsg (__NR_Linux + 208)
+#define __NR_putpmsg (__NR_Linux + 209)
+#define __NR_mmap2 (__NR_Linux + 210)
+#define __NR_truncate64 (__NR_Linux + 211)
+#define __NR_ftruncate64 (__NR_Linux + 212)
+#define __NR_stat64 (__NR_Linux + 213)
+#define __NR_lstat64 (__NR_Linux + 214)
+#define __NR_fstat64 (__NR_Linux + 215)
+#define __NR_pivot_root (__NR_Linux + 216)
+#define __NR_mincore (__NR_Linux + 217)
+#define __NR_madvise (__NR_Linux + 218)
+#define __NR_getdents64 (__NR_Linux + 219)
+#define __NR_fcntl64 (__NR_Linux + 220)
+#define __NR_reserved221 (__NR_Linux + 221)
+#define __NR_gettid (__NR_Linux + 222)
+#define __NR_readahead (__NR_Linux + 223)
+#define __NR_setxattr (__NR_Linux + 224)
+#define __NR_lsetxattr (__NR_Linux + 225)
+#define __NR_fsetxattr (__NR_Linux + 226)
+#define __NR_getxattr (__NR_Linux + 227)
+#define __NR_lgetxattr (__NR_Linux + 228)
+#define __NR_fgetxattr (__NR_Linux + 229)
+#define __NR_listxattr (__NR_Linux + 230)
+#define __NR_llistxattr (__NR_Linux + 231)
+#define __NR_flistxattr (__NR_Linux + 232)
+#define __NR_removexattr (__NR_Linux + 233)
+#define __NR_lremovexattr (__NR_Linux + 234)
+#define __NR_fremovexattr (__NR_Linux + 235)
+#define __NR_tkill (__NR_Linux + 236)
+#define __NR_sendfile64 (__NR_Linux + 237)
+#define __NR_futex (__NR_Linux + 238)
+#define __NR_sched_setaffinity (__NR_Linux + 239)
+#define __NR_sched_getaffinity (__NR_Linux + 240)
+#define __NR_io_setup (__NR_Linux + 241)
+#define __NR_io_destroy (__NR_Linux + 242)
+#define __NR_io_getevents (__NR_Linux + 243)
+#define __NR_io_submit (__NR_Linux + 244)
+#define __NR_io_cancel (__NR_Linux + 245)
+#define __NR_exit_group (__NR_Linux + 246)
+#define __NR_lookup_dcookie (__NR_Linux + 247)
+#define __NR_epoll_create (__NR_Linux + 248)
+#define __NR_epoll_ctl (__NR_Linux + 249)
+#define __NR_epoll_wait (__NR_Linux + 250)
+#define __NR_remap_file_pages (__NR_Linux + 251)
+#define __NR_set_tid_address (__NR_Linux + 252)
+#define __NR_restart_syscall (__NR_Linux + 253)
+#define __NR_fadvise64 (__NR_Linux + 254)
+#define __NR_statfs64 (__NR_Linux + 255)
+#define __NR_fstatfs64 (__NR_Linux + 256)
+#define __NR_timer_create (__NR_Linux + 257)
+#define __NR_timer_settime (__NR_Linux + 258)
+#define __NR_timer_gettime (__NR_Linux + 259)
+#define __NR_timer_getoverrun (__NR_Linux + 260)
+#define __NR_timer_delete (__NR_Linux + 261)
+#define __NR_clock_settime (__NR_Linux + 262)
+#define __NR_clock_gettime (__NR_Linux + 263)
+#define __NR_clock_getres (__NR_Linux + 264)
+#define __NR_clock_nanosleep (__NR_Linux + 265)
+#define __NR_tgkill (__NR_Linux + 266)
+#define __NR_utimes (__NR_Linux + 267)
+#define __NR_mbind (__NR_Linux + 268)
+#define __NR_get_mempolicy (__NR_Linux + 269)
+#define __NR_set_mempolicy (__NR_Linux + 270)
+#define __NR_mq_open (__NR_Linux + 271)
+#define __NR_mq_unlink (__NR_Linux + 272)
+#define __NR_mq_timedsend (__NR_Linux + 273)
+#define __NR_mq_timedreceive (__NR_Linux + 274)
+#define __NR_mq_notify (__NR_Linux + 275)
+#define __NR_mq_getsetattr (__NR_Linux + 276)
+#define __NR_vserver (__NR_Linux + 277)
+#define __NR_waitid (__NR_Linux + 278)
+/* #define __NR_sys_setaltroot (__NR_Linux + 279) */
+#define __NR_add_key (__NR_Linux + 280)
+#define __NR_request_key (__NR_Linux + 281)
+#define __NR_keyctl (__NR_Linux + 282)
+#define __NR_set_thread_area (__NR_Linux + 283)
+#define __NR_inotify_init (__NR_Linux + 284)
+#define __NR_inotify_add_watch (__NR_Linux + 285)
+#define __NR_inotify_rm_watch (__NR_Linux + 286)
+#define __NR_migrate_pages (__NR_Linux + 287)
+#define __NR_openat (__NR_Linux + 288)
+#define __NR_mkdirat (__NR_Linux + 289)
+#define __NR_mknodat (__NR_Linux + 290)
+#define __NR_fchownat (__NR_Linux + 291)
+#define __NR_futimesat (__NR_Linux + 292)
+#define __NR_fstatat64 (__NR_Linux + 293)
+#define __NR_unlinkat (__NR_Linux + 294)
+#define __NR_renameat (__NR_Linux + 295)
+#define __NR_linkat (__NR_Linux + 296)
+#define __NR_symlinkat (__NR_Linux + 297)
+#define __NR_readlinkat (__NR_Linux + 298)
+#define __NR_fchmodat (__NR_Linux + 299)
+#define __NR_faccessat (__NR_Linux + 300)
+#define __NR_pselect6 (__NR_Linux + 301)
+#define __NR_ppoll (__NR_Linux + 302)
+#define __NR_unshare (__NR_Linux + 303)
+#define __NR_splice (__NR_Linux + 304)
+#define __NR_sync_file_range (__NR_Linux + 305)
+#define __NR_tee (__NR_Linux + 306)
+#define __NR_vmsplice (__NR_Linux + 307)
+#define __NR_move_pages (__NR_Linux + 308)
+#define __NR_set_robust_list (__NR_Linux + 309)
+#define __NR_get_robust_list (__NR_Linux + 310)
+#define __NR_kexec_load (__NR_Linux + 311)
+#define __NR_getcpu (__NR_Linux + 312)
+#define __NR_epoll_pwait (__NR_Linux + 313)
+#define __NR_ioprio_set (__NR_Linux + 314)
+#define __NR_ioprio_get (__NR_Linux + 315)
+#define __NR_utimensat (__NR_Linux + 316)
+#define __NR_signalfd (__NR_Linux + 317)
+#define __NR_timerfd (__NR_Linux + 318)
+#define __NR_eventfd (__NR_Linux + 319)
+#define __NR_fallocate (__NR_Linux + 320)
+#define __NR_timerfd_create (__NR_Linux + 321)
+#define __NR_timerfd_gettime (__NR_Linux + 322)
+#define __NR_timerfd_settime (__NR_Linux + 323)
+#define __NR_signalfd4 (__NR_Linux + 324)
+#define __NR_eventfd2 (__NR_Linux + 325)
+#define __NR_epoll_create1 (__NR_Linux + 326)
+#define __NR_dup3 (__NR_Linux + 327)
+#define __NR_pipe2 (__NR_Linux + 328)
+#define __NR_inotify_init1 (__NR_Linux + 329)
+#define __NR_preadv (__NR_Linux + 330)
+#define __NR_pwritev (__NR_Linux + 331)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 332)
+#define __NR_perf_event_open (__NR_Linux + 333)
+#define __NR_accept4 (__NR_Linux + 334)
+#define __NR_recvmmsg (__NR_Linux + 335)
+#define __NR_fanotify_init (__NR_Linux + 336)
+#define __NR_fanotify_mark (__NR_Linux + 337)
+#define __NR_prlimit64 (__NR_Linux + 338)
+#define __NR_name_to_handle_at (__NR_Linux + 339)
+#define __NR_open_by_handle_at (__NR_Linux + 340)
+#define __NR_clock_adjtime (__NR_Linux + 341)
+#define __NR_syncfs (__NR_Linux + 342)
+#define __NR_sendmmsg (__NR_Linux + 343)
+#define __NR_setns (__NR_Linux + 344)
+#define __NR_process_vm_readv (__NR_Linux + 345)
+#define __NR_process_vm_writev (__NR_Linux + 346)
+#define __NR_kcmp (__NR_Linux + 347)
+#define __NR_finit_module (__NR_Linux + 348)
+#define __NR_sched_setattr (__NR_Linux + 349)
+#define __NR_sched_getattr (__NR_Linux + 350)
+#define __NR_renameat2 (__NR_Linux + 351)
+#define __NR_seccomp (__NR_Linux + 352)
+#define __NR_getrandom (__NR_Linux + 353)
+#define __NR_memfd_create (__NR_Linux + 354)
+#define __NR_bpf (__NR_Linux + 355)
+#define __NR_execveat (__NR_Linux + 356)
+
+/*
+ * Offset of the last Linux o32 flavoured syscall
+ */
+#define __NR_Linux_syscalls 356
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#define __NR_O32_Linux 4000
+#define __NR_O32_Linux_syscalls 356
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+
+/*
+ * Linux 64-bit syscalls are in the range from 5000 to 5999.
+ */
+#define __NR_Linux 5000
+#define __NR_read (__NR_Linux + 0)
+#define __NR_write (__NR_Linux + 1)
+#define __NR_open (__NR_Linux + 2)
+#define __NR_close (__NR_Linux + 3)
+#define __NR_stat (__NR_Linux + 4)
+#define __NR_fstat (__NR_Linux + 5)
+#define __NR_lstat (__NR_Linux + 6)
+#define __NR_poll (__NR_Linux + 7)
+#define __NR_lseek (__NR_Linux + 8)
+#define __NR_mmap (__NR_Linux + 9)
+#define __NR_mprotect (__NR_Linux + 10)
+#define __NR_munmap (__NR_Linux + 11)
+#define __NR_brk (__NR_Linux + 12)
+#define __NR_rt_sigaction (__NR_Linux + 13)
+#define __NR_rt_sigprocmask (__NR_Linux + 14)
+#define __NR_ioctl (__NR_Linux + 15)
+#define __NR_pread64 (__NR_Linux + 16)
+#define __NR_pwrite64 (__NR_Linux + 17)
+#define __NR_readv (__NR_Linux + 18)
+#define __NR_writev (__NR_Linux + 19)
+#define __NR_access (__NR_Linux + 20)
+#define __NR_pipe (__NR_Linux + 21)
+#define __NR__newselect (__NR_Linux + 22)
+#define __NR_sched_yield (__NR_Linux + 23)
+#define __NR_mremap (__NR_Linux + 24)
+#define __NR_msync (__NR_Linux + 25)
+#define __NR_mincore (__NR_Linux + 26)
+#define __NR_madvise (__NR_Linux + 27)
+#define __NR_shmget (__NR_Linux + 28)
+#define __NR_shmat (__NR_Linux + 29)
+#define __NR_shmctl (__NR_Linux + 30)
+#define __NR_dup (__NR_Linux + 31)
+#define __NR_dup2 (__NR_Linux + 32)
+#define __NR_pause (__NR_Linux + 33)
+#define __NR_nanosleep (__NR_Linux + 34)
+#define __NR_getitimer (__NR_Linux + 35)
+#define __NR_setitimer (__NR_Linux + 36)
+#define __NR_alarm (__NR_Linux + 37)
+#define __NR_getpid (__NR_Linux + 38)
+#define __NR_sendfile (__NR_Linux + 39)
+#define __NR_socket (__NR_Linux + 40)
+#define __NR_connect (__NR_Linux + 41)
+#define __NR_accept (__NR_Linux + 42)
+#define __NR_sendto (__NR_Linux + 43)
+#define __NR_recvfrom (__NR_Linux + 44)
+#define __NR_sendmsg (__NR_Linux + 45)
+#define __NR_recvmsg (__NR_Linux + 46)
+#define __NR_shutdown (__NR_Linux + 47)
+#define __NR_bind (__NR_Linux + 48)
+#define __NR_listen (__NR_Linux + 49)
+#define __NR_getsockname (__NR_Linux + 50)
+#define __NR_getpeername (__NR_Linux + 51)
+#define __NR_socketpair (__NR_Linux + 52)
+#define __NR_setsockopt (__NR_Linux + 53)
+#define __NR_getsockopt (__NR_Linux + 54)
+#define __NR_clone (__NR_Linux + 55)
+#define __NR_fork (__NR_Linux + 56)
+#define __NR_execve (__NR_Linux + 57)
+#define __NR_exit (__NR_Linux + 58)
+#define __NR_wait4 (__NR_Linux + 59)
+#define __NR_kill (__NR_Linux + 60)
+#define __NR_uname (__NR_Linux + 61)
+#define __NR_semget (__NR_Linux + 62)
+#define __NR_semop (__NR_Linux + 63)
+#define __NR_semctl (__NR_Linux + 64)
+#define __NR_shmdt (__NR_Linux + 65)
+#define __NR_msgget (__NR_Linux + 66)
+#define __NR_msgsnd (__NR_Linux + 67)
+#define __NR_msgrcv (__NR_Linux + 68)
+#define __NR_msgctl (__NR_Linux + 69)
+#define __NR_fcntl (__NR_Linux + 70)
+#define __NR_flock (__NR_Linux + 71)
+#define __NR_fsync (__NR_Linux + 72)
+#define __NR_fdatasync (__NR_Linux + 73)
+#define __NR_truncate (__NR_Linux + 74)
+#define __NR_ftruncate (__NR_Linux + 75)
+#define __NR_getdents (__NR_Linux + 76)
+#define __NR_getcwd (__NR_Linux + 77)
+#define __NR_chdir (__NR_Linux + 78)
+#define __NR_fchdir (__NR_Linux + 79)
+#define __NR_rename (__NR_Linux + 80)
+#define __NR_mkdir (__NR_Linux + 81)
+#define __NR_rmdir (__NR_Linux + 82)
+#define __NR_creat (__NR_Linux + 83)
+#define __NR_link (__NR_Linux + 84)
+#define __NR_unlink (__NR_Linux + 85)
+#define __NR_symlink (__NR_Linux + 86)
+#define __NR_readlink (__NR_Linux + 87)
+#define __NR_chmod (__NR_Linux + 88)
+#define __NR_fchmod (__NR_Linux + 89)
+#define __NR_chown (__NR_Linux + 90)
+#define __NR_fchown (__NR_Linux + 91)
+#define __NR_lchown (__NR_Linux + 92)
+#define __NR_umask (__NR_Linux + 93)
+#define __NR_gettimeofday (__NR_Linux + 94)
+#define __NR_getrlimit (__NR_Linux + 95)
+#define __NR_getrusage (__NR_Linux + 96)
+#define __NR_sysinfo (__NR_Linux + 97)
+#define __NR_times (__NR_Linux + 98)
+#define __NR_ptrace (__NR_Linux + 99)
+#define __NR_getuid (__NR_Linux + 100)
+#define __NR_syslog (__NR_Linux + 101)
+#define __NR_getgid (__NR_Linux + 102)
+#define __NR_setuid (__NR_Linux + 103)
+#define __NR_setgid (__NR_Linux + 104)
+#define __NR_geteuid (__NR_Linux + 105)
+#define __NR_getegid (__NR_Linux + 106)
+#define __NR_setpgid (__NR_Linux + 107)
+#define __NR_getppid (__NR_Linux + 108)
+#define __NR_getpgrp (__NR_Linux + 109)
+#define __NR_setsid (__NR_Linux + 110)
+#define __NR_setreuid (__NR_Linux + 111)
+#define __NR_setregid (__NR_Linux + 112)
+#define __NR_getgroups (__NR_Linux + 113)
+#define __NR_setgroups (__NR_Linux + 114)
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_getresuid (__NR_Linux + 116)
+#define __NR_setresgid (__NR_Linux + 117)
+#define __NR_getresgid (__NR_Linux + 118)
+#define __NR_getpgid (__NR_Linux + 119)
+#define __NR_setfsuid (__NR_Linux + 120)
+#define __NR_setfsgid (__NR_Linux + 121)
+#define __NR_getsid (__NR_Linux + 122)
+#define __NR_capget (__NR_Linux + 123)
+#define __NR_capset (__NR_Linux + 124)
+#define __NR_rt_sigpending (__NR_Linux + 125)
+#define __NR_rt_sigtimedwait (__NR_Linux + 126)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
+#define __NR_rt_sigsuspend (__NR_Linux + 128)
+#define __NR_sigaltstack (__NR_Linux + 129)
+#define __NR_utime (__NR_Linux + 130)
+#define __NR_mknod (__NR_Linux + 131)
+#define __NR_personality (__NR_Linux + 132)
+#define __NR_ustat (__NR_Linux + 133)
+#define __NR_statfs (__NR_Linux + 134)
+#define __NR_fstatfs (__NR_Linux + 135)
+#define __NR_sysfs (__NR_Linux + 136)
+#define __NR_getpriority (__NR_Linux + 137)
+#define __NR_setpriority (__NR_Linux + 138)
+#define __NR_sched_setparam (__NR_Linux + 139)
+#define __NR_sched_getparam (__NR_Linux + 140)
+#define __NR_sched_setscheduler (__NR_Linux + 141)
+#define __NR_sched_getscheduler (__NR_Linux + 142)
+#define __NR_sched_get_priority_max (__NR_Linux + 143)
+#define __NR_sched_get_priority_min (__NR_Linux + 144)
+#define __NR_sched_rr_get_interval (__NR_Linux + 145)
+#define __NR_mlock (__NR_Linux + 146)
+#define __NR_munlock (__NR_Linux + 147)
+#define __NR_mlockall (__NR_Linux + 148)
+#define __NR_munlockall (__NR_Linux + 149)
+#define __NR_vhangup (__NR_Linux + 150)
+#define __NR_pivot_root (__NR_Linux + 151)
+#define __NR__sysctl (__NR_Linux + 152)
+#define __NR_prctl (__NR_Linux + 153)
+#define __NR_adjtimex (__NR_Linux + 154)
+#define __NR_setrlimit (__NR_Linux + 155)
+#define __NR_chroot (__NR_Linux + 156)
+#define __NR_sync (__NR_Linux + 157)
+#define __NR_acct (__NR_Linux + 158)
+#define __NR_settimeofday (__NR_Linux + 159)
+#define __NR_mount (__NR_Linux + 160)
+#define __NR_umount2 (__NR_Linux + 161)
+#define __NR_swapon (__NR_Linux + 162)
+#define __NR_swapoff (__NR_Linux + 163)
+#define __NR_reboot (__NR_Linux + 164)
+#define __NR_sethostname (__NR_Linux + 165)
+#define __NR_setdomainname (__NR_Linux + 166)
+#define __NR_create_module (__NR_Linux + 167)
+#define __NR_init_module (__NR_Linux + 168)
+#define __NR_delete_module (__NR_Linux + 169)
+#define __NR_get_kernel_syms (__NR_Linux + 170)
+#define __NR_query_module (__NR_Linux + 171)
+#define __NR_quotactl (__NR_Linux + 172)
+#define __NR_nfsservctl (__NR_Linux + 173)
+#define __NR_getpmsg (__NR_Linux + 174)
+#define __NR_putpmsg (__NR_Linux + 175)
+#define __NR_afs_syscall (__NR_Linux + 176)
+#define __NR_reserved177 (__NR_Linux + 177)
+#define __NR_gettid (__NR_Linux + 178)
+#define __NR_readahead (__NR_Linux + 179)
+#define __NR_setxattr (__NR_Linux + 180)
+#define __NR_lsetxattr (__NR_Linux + 181)
+#define __NR_fsetxattr (__NR_Linux + 182)
+#define __NR_getxattr (__NR_Linux + 183)
+#define __NR_lgetxattr (__NR_Linux + 184)
+#define __NR_fgetxattr (__NR_Linux + 185)
+#define __NR_listxattr (__NR_Linux + 186)
+#define __NR_llistxattr (__NR_Linux + 187)
+#define __NR_flistxattr (__NR_Linux + 188)
+#define __NR_removexattr (__NR_Linux + 189)
+#define __NR_lremovexattr (__NR_Linux + 190)
+#define __NR_fremovexattr (__NR_Linux + 191)
+#define __NR_tkill (__NR_Linux + 192)
+#define __NR_reserved193 (__NR_Linux + 193)
+#define __NR_futex (__NR_Linux + 194)
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#define __NR_cacheflush (__NR_Linux + 197)
+#define __NR_cachectl (__NR_Linux + 198)
+#define __NR_sysmips (__NR_Linux + 199)
+#define __NR_io_setup (__NR_Linux + 200)
+#define __NR_io_destroy (__NR_Linux + 201)
+#define __NR_io_getevents (__NR_Linux + 202)
+#define __NR_io_submit (__NR_Linux + 203)
+#define __NR_io_cancel (__NR_Linux + 204)
+#define __NR_exit_group (__NR_Linux + 205)
+#define __NR_lookup_dcookie (__NR_Linux + 206)
+#define __NR_epoll_create (__NR_Linux + 207)
+#define __NR_epoll_ctl (__NR_Linux + 208)
+#define __NR_epoll_wait (__NR_Linux + 209)
+#define __NR_remap_file_pages (__NR_Linux + 210)
+#define __NR_rt_sigreturn (__NR_Linux + 211)
+#define __NR_set_tid_address (__NR_Linux + 212)
+#define __NR_restart_syscall (__NR_Linux + 213)
+#define __NR_semtimedop (__NR_Linux + 214)
+#define __NR_fadvise64 (__NR_Linux + 215)
+#define __NR_timer_create (__NR_Linux + 216)
+#define __NR_timer_settime (__NR_Linux + 217)
+#define __NR_timer_gettime (__NR_Linux + 218)
+#define __NR_timer_getoverrun (__NR_Linux + 219)
+#define __NR_timer_delete (__NR_Linux + 220)
+#define __NR_clock_settime (__NR_Linux + 221)
+#define __NR_clock_gettime (__NR_Linux + 222)
+#define __NR_clock_getres (__NR_Linux + 223)
+#define __NR_clock_nanosleep (__NR_Linux + 224)
+#define __NR_tgkill (__NR_Linux + 225)
+#define __NR_utimes (__NR_Linux + 226)
+#define __NR_mbind (__NR_Linux + 227)
+#define __NR_get_mempolicy (__NR_Linux + 228)
+#define __NR_set_mempolicy (__NR_Linux + 229)
+#define __NR_mq_open (__NR_Linux + 230)
+#define __NR_mq_unlink (__NR_Linux + 231)
+#define __NR_mq_timedsend (__NR_Linux + 232)
+#define __NR_mq_timedreceive (__NR_Linux + 233)
+#define __NR_mq_notify (__NR_Linux + 234)
+#define __NR_mq_getsetattr (__NR_Linux + 235)
+#define __NR_vserver (__NR_Linux + 236)
+#define __NR_waitid (__NR_Linux + 237)
+/* #define __NR_sys_setaltroot (__NR_Linux + 238) */
+#define __NR_add_key (__NR_Linux + 239)
+#define __NR_request_key (__NR_Linux + 240)
+#define __NR_keyctl (__NR_Linux + 241)
+#define __NR_set_thread_area (__NR_Linux + 242)
+#define __NR_inotify_init (__NR_Linux + 243)
+#define __NR_inotify_add_watch (__NR_Linux + 244)
+#define __NR_inotify_rm_watch (__NR_Linux + 245)
+#define __NR_migrate_pages (__NR_Linux + 246)
+#define __NR_openat (__NR_Linux + 247)
+#define __NR_mkdirat (__NR_Linux + 248)
+#define __NR_mknodat (__NR_Linux + 249)
+#define __NR_fchownat (__NR_Linux + 250)
+#define __NR_futimesat (__NR_Linux + 251)
+#define __NR_newfstatat (__NR_Linux + 252)
+#define __NR_unlinkat (__NR_Linux + 253)
+#define __NR_renameat (__NR_Linux + 254)
+#define __NR_linkat (__NR_Linux + 255)
+#define __NR_symlinkat (__NR_Linux + 256)
+#define __NR_readlinkat (__NR_Linux + 257)
+#define __NR_fchmodat (__NR_Linux + 258)
+#define __NR_faccessat (__NR_Linux + 259)
+#define __NR_pselect6 (__NR_Linux + 260)
+#define __NR_ppoll (__NR_Linux + 261)
+#define __NR_unshare (__NR_Linux + 262)
+#define __NR_splice (__NR_Linux + 263)
+#define __NR_sync_file_range (__NR_Linux + 264)
+#define __NR_tee (__NR_Linux + 265)
+#define __NR_vmsplice (__NR_Linux + 266)
+#define __NR_move_pages (__NR_Linux + 267)
+#define __NR_set_robust_list (__NR_Linux + 268)
+#define __NR_get_robust_list (__NR_Linux + 269)
+#define __NR_kexec_load (__NR_Linux + 270)
+#define __NR_getcpu (__NR_Linux + 271)
+#define __NR_epoll_pwait (__NR_Linux + 272)
+#define __NR_ioprio_set (__NR_Linux + 273)
+#define __NR_ioprio_get (__NR_Linux + 274)
+#define __NR_utimensat (__NR_Linux + 275)
+#define __NR_signalfd (__NR_Linux + 276)
+#define __NR_timerfd (__NR_Linux + 277)
+#define __NR_eventfd (__NR_Linux + 278)
+#define __NR_fallocate (__NR_Linux + 279)
+#define __NR_timerfd_create (__NR_Linux + 280)
+#define __NR_timerfd_gettime (__NR_Linux + 281)
+#define __NR_timerfd_settime (__NR_Linux + 282)
+#define __NR_signalfd4 (__NR_Linux + 283)
+#define __NR_eventfd2 (__NR_Linux + 284)
+#define __NR_epoll_create1 (__NR_Linux + 285)
+#define __NR_dup3 (__NR_Linux + 286)
+#define __NR_pipe2 (__NR_Linux + 287)
+#define __NR_inotify_init1 (__NR_Linux + 288)
+#define __NR_preadv (__NR_Linux + 289)
+#define __NR_pwritev (__NR_Linux + 290)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 291)
+#define __NR_perf_event_open (__NR_Linux + 292)
+#define __NR_accept4 (__NR_Linux + 293)
+#define __NR_recvmmsg (__NR_Linux + 294)
+#define __NR_fanotify_init (__NR_Linux + 295)
+#define __NR_fanotify_mark (__NR_Linux + 296)
+#define __NR_prlimit64 (__NR_Linux + 297)
+#define __NR_name_to_handle_at (__NR_Linux + 298)
+#define __NR_open_by_handle_at (__NR_Linux + 299)
+#define __NR_clock_adjtime (__NR_Linux + 300)
+#define __NR_syncfs (__NR_Linux + 301)
+#define __NR_sendmmsg (__NR_Linux + 302)
+#define __NR_setns (__NR_Linux + 303)
+#define __NR_process_vm_readv (__NR_Linux + 304)
+#define __NR_process_vm_writev (__NR_Linux + 305)
+#define __NR_kcmp (__NR_Linux + 306)
+#define __NR_finit_module (__NR_Linux + 307)
+#define __NR_getdents64 (__NR_Linux + 308)
+#define __NR_sched_setattr (__NR_Linux + 309)
+#define __NR_sched_getattr (__NR_Linux + 310)
+#define __NR_renameat2 (__NR_Linux + 311)
+#define __NR_seccomp (__NR_Linux + 312)
+#define __NR_getrandom (__NR_Linux + 313)
+#define __NR_memfd_create (__NR_Linux + 314)
+#define __NR_bpf (__NR_Linux + 315)
+#define __NR_execveat (__NR_Linux + 316)
+
+/*
+ * Offset of the last Linux 64-bit flavoured syscall
+ */
+#define __NR_Linux_syscalls 316
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+
+#define __NR_64_Linux 5000
+#define __NR_64_Linux_syscalls 316
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+
+/*
+ * Linux N32 syscalls are in the range from 6000 to 6999.
+ */
+#define __NR_Linux 6000
+#define __NR_read (__NR_Linux + 0)
+#define __NR_write (__NR_Linux + 1)
+#define __NR_open (__NR_Linux + 2)
+#define __NR_close (__NR_Linux + 3)
+#define __NR_stat (__NR_Linux + 4)
+#define __NR_fstat (__NR_Linux + 5)
+#define __NR_lstat (__NR_Linux + 6)
+#define __NR_poll (__NR_Linux + 7)
+#define __NR_lseek (__NR_Linux + 8)
+#define __NR_mmap (__NR_Linux + 9)
+#define __NR_mprotect (__NR_Linux + 10)
+#define __NR_munmap (__NR_Linux + 11)
+#define __NR_brk (__NR_Linux + 12)
+#define __NR_rt_sigaction (__NR_Linux + 13)
+#define __NR_rt_sigprocmask (__NR_Linux + 14)
+#define __NR_ioctl (__NR_Linux + 15)
+#define __NR_pread64 (__NR_Linux + 16)
+#define __NR_pwrite64 (__NR_Linux + 17)
+#define __NR_readv (__NR_Linux + 18)
+#define __NR_writev (__NR_Linux + 19)
+#define __NR_access (__NR_Linux + 20)
+#define __NR_pipe (__NR_Linux + 21)
+#define __NR__newselect (__NR_Linux + 22)
+#define __NR_sched_yield (__NR_Linux + 23)
+#define __NR_mremap (__NR_Linux + 24)
+#define __NR_msync (__NR_Linux + 25)
+#define __NR_mincore (__NR_Linux + 26)
+#define __NR_madvise (__NR_Linux + 27)
+#define __NR_shmget (__NR_Linux + 28)
+#define __NR_shmat (__NR_Linux + 29)
+#define __NR_shmctl (__NR_Linux + 30)
+#define __NR_dup (__NR_Linux + 31)
+#define __NR_dup2 (__NR_Linux + 32)
+#define __NR_pause (__NR_Linux + 33)
+#define __NR_nanosleep (__NR_Linux + 34)
+#define __NR_getitimer (__NR_Linux + 35)
+#define __NR_setitimer (__NR_Linux + 36)
+#define __NR_alarm (__NR_Linux + 37)
+#define __NR_getpid (__NR_Linux + 38)
+#define __NR_sendfile (__NR_Linux + 39)
+#define __NR_socket (__NR_Linux + 40)
+#define __NR_connect (__NR_Linux + 41)
+#define __NR_accept (__NR_Linux + 42)
+#define __NR_sendto (__NR_Linux + 43)
+#define __NR_recvfrom (__NR_Linux + 44)
+#define __NR_sendmsg (__NR_Linux + 45)
+#define __NR_recvmsg (__NR_Linux + 46)
+#define __NR_shutdown (__NR_Linux + 47)
+#define __NR_bind (__NR_Linux + 48)
+#define __NR_listen (__NR_Linux + 49)
+#define __NR_getsockname (__NR_Linux + 50)
+#define __NR_getpeername (__NR_Linux + 51)
+#define __NR_socketpair (__NR_Linux + 52)
+#define __NR_setsockopt (__NR_Linux + 53)
+#define __NR_getsockopt (__NR_Linux + 54)
+#define __NR_clone (__NR_Linux + 55)
+#define __NR_fork (__NR_Linux + 56)
+#define __NR_execve (__NR_Linux + 57)
+#define __NR_exit (__NR_Linux + 58)
+#define __NR_wait4 (__NR_Linux + 59)
+#define __NR_kill (__NR_Linux + 60)
+#define __NR_uname (__NR_Linux + 61)
+#define __NR_semget (__NR_Linux + 62)
+#define __NR_semop (__NR_Linux + 63)
+#define __NR_semctl (__NR_Linux + 64)
+#define __NR_shmdt (__NR_Linux + 65)
+#define __NR_msgget (__NR_Linux + 66)
+#define __NR_msgsnd (__NR_Linux + 67)
+#define __NR_msgrcv (__NR_Linux + 68)
+#define __NR_msgctl (__NR_Linux + 69)
+#define __NR_fcntl (__NR_Linux + 70)
+#define __NR_flock (__NR_Linux + 71)
+#define __NR_fsync (__NR_Linux + 72)
+#define __NR_fdatasync (__NR_Linux + 73)
+#define __NR_truncate (__NR_Linux + 74)
+#define __NR_ftruncate (__NR_Linux + 75)
+#define __NR_getdents (__NR_Linux + 76)
+#define __NR_getcwd (__NR_Linux + 77)
+#define __NR_chdir (__NR_Linux + 78)
+#define __NR_fchdir (__NR_Linux + 79)
+#define __NR_rename (__NR_Linux + 80)
+#define __NR_mkdir (__NR_Linux + 81)
+#define __NR_rmdir (__NR_Linux + 82)
+#define __NR_creat (__NR_Linux + 83)
+#define __NR_link (__NR_Linux + 84)
+#define __NR_unlink (__NR_Linux + 85)
+#define __NR_symlink (__NR_Linux + 86)
+#define __NR_readlink (__NR_Linux + 87)
+#define __NR_chmod (__NR_Linux + 88)
+#define __NR_fchmod (__NR_Linux + 89)
+#define __NR_chown (__NR_Linux + 90)
+#define __NR_fchown (__NR_Linux + 91)
+#define __NR_lchown (__NR_Linux + 92)
+#define __NR_umask (__NR_Linux + 93)
+#define __NR_gettimeofday (__NR_Linux + 94)
+#define __NR_getrlimit (__NR_Linux + 95)
+#define __NR_getrusage (__NR_Linux + 96)
+#define __NR_sysinfo (__NR_Linux + 97)
+#define __NR_times (__NR_Linux + 98)
+#define __NR_ptrace (__NR_Linux + 99)
+#define __NR_getuid (__NR_Linux + 100)
+#define __NR_syslog (__NR_Linux + 101)
+#define __NR_getgid (__NR_Linux + 102)
+#define __NR_setuid (__NR_Linux + 103)
+#define __NR_setgid (__NR_Linux + 104)
+#define __NR_geteuid (__NR_Linux + 105)
+#define __NR_getegid (__NR_Linux + 106)
+#define __NR_setpgid (__NR_Linux + 107)
+#define __NR_getppid (__NR_Linux + 108)
+#define __NR_getpgrp (__NR_Linux + 109)
+#define __NR_setsid (__NR_Linux + 110)
+#define __NR_setreuid (__NR_Linux + 111)
+#define __NR_setregid (__NR_Linux + 112)
+#define __NR_getgroups (__NR_Linux + 113)
+#define __NR_setgroups (__NR_Linux + 114)
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_getresuid (__NR_Linux + 116)
+#define __NR_setresgid (__NR_Linux + 117)
+#define __NR_getresgid (__NR_Linux + 118)
+#define __NR_getpgid (__NR_Linux + 119)
+#define __NR_setfsuid (__NR_Linux + 120)
+#define __NR_setfsgid (__NR_Linux + 121)
+#define __NR_getsid (__NR_Linux + 122)
+#define __NR_capget (__NR_Linux + 123)
+#define __NR_capset (__NR_Linux + 124)
+#define __NR_rt_sigpending (__NR_Linux + 125)
+#define __NR_rt_sigtimedwait (__NR_Linux + 126)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
+#define __NR_rt_sigsuspend (__NR_Linux + 128)
+#define __NR_sigaltstack (__NR_Linux + 129)
+#define __NR_utime (__NR_Linux + 130)
+#define __NR_mknod (__NR_Linux + 131)
+#define __NR_personality (__NR_Linux + 132)
+#define __NR_ustat (__NR_Linux + 133)
+#define __NR_statfs (__NR_Linux + 134)
+#define __NR_fstatfs (__NR_Linux + 135)
+#define __NR_sysfs (__NR_Linux + 136)
+#define __NR_getpriority (__NR_Linux + 137)
+#define __NR_setpriority (__NR_Linux + 138)
+#define __NR_sched_setparam (__NR_Linux + 139)
+#define __NR_sched_getparam (__NR_Linux + 140)
+#define __NR_sched_setscheduler (__NR_Linux + 141)
+#define __NR_sched_getscheduler (__NR_Linux + 142)
+#define __NR_sched_get_priority_max (__NR_Linux + 143)
+#define __NR_sched_get_priority_min (__NR_Linux + 144)
+#define __NR_sched_rr_get_interval (__NR_Linux + 145)
+#define __NR_mlock (__NR_Linux + 146)
+#define __NR_munlock (__NR_Linux + 147)
+#define __NR_mlockall (__NR_Linux + 148)
+#define __NR_munlockall (__NR_Linux + 149)
+#define __NR_vhangup (__NR_Linux + 150)
+#define __NR_pivot_root (__NR_Linux + 151)
+#define __NR__sysctl (__NR_Linux + 152)
+#define __NR_prctl (__NR_Linux + 153)
+#define __NR_adjtimex (__NR_Linux + 154)
+#define __NR_setrlimit (__NR_Linux + 155)
+#define __NR_chroot (__NR_Linux + 156)
+#define __NR_sync (__NR_Linux + 157)
+#define __NR_acct (__NR_Linux + 158)
+#define __NR_settimeofday (__NR_Linux + 159)
+#define __NR_mount (__NR_Linux + 160)
+#define __NR_umount2 (__NR_Linux + 161)
+#define __NR_swapon (__NR_Linux + 162)
+#define __NR_swapoff (__NR_Linux + 163)
+#define __NR_reboot (__NR_Linux + 164)
+#define __NR_sethostname (__NR_Linux + 165)
+#define __NR_setdomainname (__NR_Linux + 166)
+#define __NR_create_module (__NR_Linux + 167)
+#define __NR_init_module (__NR_Linux + 168)
+#define __NR_delete_module (__NR_Linux + 169)
+#define __NR_get_kernel_syms (__NR_Linux + 170)
+#define __NR_query_module (__NR_Linux + 171)
+#define __NR_quotactl (__NR_Linux + 172)
+#define __NR_nfsservctl (__NR_Linux + 173)
+#define __NR_getpmsg (__NR_Linux + 174)
+#define __NR_putpmsg (__NR_Linux + 175)
+#define __NR_afs_syscall (__NR_Linux + 176)
+#define __NR_reserved177 (__NR_Linux + 177)
+#define __NR_gettid (__NR_Linux + 178)
+#define __NR_readahead (__NR_Linux + 179)
+#define __NR_setxattr (__NR_Linux + 180)
+#define __NR_lsetxattr (__NR_Linux + 181)
+#define __NR_fsetxattr (__NR_Linux + 182)
+#define __NR_getxattr (__NR_Linux + 183)
+#define __NR_lgetxattr (__NR_Linux + 184)
+#define __NR_fgetxattr (__NR_Linux + 185)
+#define __NR_listxattr (__NR_Linux + 186)
+#define __NR_llistxattr (__NR_Linux + 187)
+#define __NR_flistxattr (__NR_Linux + 188)
+#define __NR_removexattr (__NR_Linux + 189)
+#define __NR_lremovexattr (__NR_Linux + 190)
+#define __NR_fremovexattr (__NR_Linux + 191)
+#define __NR_tkill (__NR_Linux + 192)
+#define __NR_reserved193 (__NR_Linux + 193)
+#define __NR_futex (__NR_Linux + 194)
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#define __NR_cacheflush (__NR_Linux + 197)
+#define __NR_cachectl (__NR_Linux + 198)
+#define __NR_sysmips (__NR_Linux + 199)
+#define __NR_io_setup (__NR_Linux + 200)
+#define __NR_io_destroy (__NR_Linux + 201)
+#define __NR_io_getevents (__NR_Linux + 202)
+#define __NR_io_submit (__NR_Linux + 203)
+#define __NR_io_cancel (__NR_Linux + 204)
+#define __NR_exit_group (__NR_Linux + 205)
+#define __NR_lookup_dcookie (__NR_Linux + 206)
+#define __NR_epoll_create (__NR_Linux + 207)
+#define __NR_epoll_ctl (__NR_Linux + 208)
+#define __NR_epoll_wait (__NR_Linux + 209)
+#define __NR_remap_file_pages (__NR_Linux + 210)
+#define __NR_rt_sigreturn (__NR_Linux + 211)
+#define __NR_fcntl64 (__NR_Linux + 212)
+#define __NR_set_tid_address (__NR_Linux + 213)
+#define __NR_restart_syscall (__NR_Linux + 214)
+#define __NR_semtimedop (__NR_Linux + 215)
+#define __NR_fadvise64 (__NR_Linux + 216)
+#define __NR_statfs64 (__NR_Linux + 217)
+#define __NR_fstatfs64 (__NR_Linux + 218)
+#define __NR_sendfile64 (__NR_Linux + 219)
+#define __NR_timer_create (__NR_Linux + 220)
+#define __NR_timer_settime (__NR_Linux + 221)
+#define __NR_timer_gettime (__NR_Linux + 222)
+#define __NR_timer_getoverrun (__NR_Linux + 223)
+#define __NR_timer_delete (__NR_Linux + 224)
+#define __NR_clock_settime (__NR_Linux + 225)
+#define __NR_clock_gettime (__NR_Linux + 226)
+#define __NR_clock_getres (__NR_Linux + 227)
+#define __NR_clock_nanosleep (__NR_Linux + 228)
+#define __NR_tgkill (__NR_Linux + 229)
+#define __NR_utimes (__NR_Linux + 230)
+#define __NR_mbind (__NR_Linux + 231)
+#define __NR_get_mempolicy (__NR_Linux + 232)
+#define __NR_set_mempolicy (__NR_Linux + 233)
+#define __NR_mq_open (__NR_Linux + 234)
+#define __NR_mq_unlink (__NR_Linux + 235)
+#define __NR_mq_timedsend (__NR_Linux + 236)
+#define __NR_mq_timedreceive (__NR_Linux + 237)
+#define __NR_mq_notify (__NR_Linux + 238)
+#define __NR_mq_getsetattr (__NR_Linux + 239)
+#define __NR_vserver (__NR_Linux + 240)
+#define __NR_waitid (__NR_Linux + 241)
+/* #define __NR_sys_setaltroot (__NR_Linux + 242) */
+#define __NR_add_key (__NR_Linux + 243)
+#define __NR_request_key (__NR_Linux + 244)
+#define __NR_keyctl (__NR_Linux + 245)
+#define __NR_set_thread_area (__NR_Linux + 246)
+#define __NR_inotify_init (__NR_Linux + 247)
+#define __NR_inotify_add_watch (__NR_Linux + 248)
+#define __NR_inotify_rm_watch (__NR_Linux + 249)
+#define __NR_migrate_pages (__NR_Linux + 250)
+#define __NR_openat (__NR_Linux + 251)
+#define __NR_mkdirat (__NR_Linux + 252)
+#define __NR_mknodat (__NR_Linux + 253)
+#define __NR_fchownat (__NR_Linux + 254)
+#define __NR_futimesat (__NR_Linux + 255)
+#define __NR_newfstatat (__NR_Linux + 256)
+#define __NR_unlinkat (__NR_Linux + 257)
+#define __NR_renameat (__NR_Linux + 258)
+#define __NR_linkat (__NR_Linux + 259)
+#define __NR_symlinkat (__NR_Linux + 260)
+#define __NR_readlinkat (__NR_Linux + 261)
+#define __NR_fchmodat (__NR_Linux + 262)
+#define __NR_faccessat (__NR_Linux + 263)
+#define __NR_pselect6 (__NR_Linux + 264)
+#define __NR_ppoll (__NR_Linux + 265)
+#define __NR_unshare (__NR_Linux + 266)
+#define __NR_splice (__NR_Linux + 267)
+#define __NR_sync_file_range (__NR_Linux + 268)
+#define __NR_tee (__NR_Linux + 269)
+#define __NR_vmsplice (__NR_Linux + 270)
+#define __NR_move_pages (__NR_Linux + 271)
+#define __NR_set_robust_list (__NR_Linux + 272)
+#define __NR_get_robust_list (__NR_Linux + 273)
+#define __NR_kexec_load (__NR_Linux + 274)
+#define __NR_getcpu (__NR_Linux + 275)
+#define __NR_epoll_pwait (__NR_Linux + 276)
+#define __NR_ioprio_set (__NR_Linux + 277)
+#define __NR_ioprio_get (__NR_Linux + 278)
+#define __NR_utimensat (__NR_Linux + 279)
+#define __NR_signalfd (__NR_Linux + 280)
+#define __NR_timerfd (__NR_Linux + 281)
+#define __NR_eventfd (__NR_Linux + 282)
+#define __NR_fallocate (__NR_Linux + 283)
+#define __NR_timerfd_create (__NR_Linux + 284)
+#define __NR_timerfd_gettime (__NR_Linux + 285)
+#define __NR_timerfd_settime (__NR_Linux + 286)
+#define __NR_signalfd4 (__NR_Linux + 287)
+#define __NR_eventfd2 (__NR_Linux + 288)
+#define __NR_epoll_create1 (__NR_Linux + 289)
+#define __NR_dup3 (__NR_Linux + 290)
+#define __NR_pipe2 (__NR_Linux + 291)
+#define __NR_inotify_init1 (__NR_Linux + 292)
+#define __NR_preadv (__NR_Linux + 293)
+#define __NR_pwritev (__NR_Linux + 294)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 295)
+#define __NR_perf_event_open (__NR_Linux + 296)
+#define __NR_accept4 (__NR_Linux + 297)
+#define __NR_recvmmsg (__NR_Linux + 298)
+#define __NR_getdents64 (__NR_Linux + 299)
+#define __NR_fanotify_init (__NR_Linux + 300)
+#define __NR_fanotify_mark (__NR_Linux + 301)
+#define __NR_prlimit64 (__NR_Linux + 302)
+#define __NR_name_to_handle_at (__NR_Linux + 303)
+#define __NR_open_by_handle_at (__NR_Linux + 304)
+#define __NR_clock_adjtime (__NR_Linux + 305)
+#define __NR_syncfs (__NR_Linux + 306)
+#define __NR_sendmmsg (__NR_Linux + 307)
+#define __NR_setns (__NR_Linux + 308)
+#define __NR_process_vm_readv (__NR_Linux + 309)
+#define __NR_process_vm_writev (__NR_Linux + 310)
+#define __NR_kcmp (__NR_Linux + 311)
+#define __NR_finit_module (__NR_Linux + 312)
+#define __NR_sched_setattr (__NR_Linux + 313)
+#define __NR_sched_getattr (__NR_Linux + 314)
+#define __NR_renameat2 (__NR_Linux + 315)
+#define __NR_seccomp (__NR_Linux + 316)
+#define __NR_getrandom (__NR_Linux + 317)
+#define __NR_memfd_create (__NR_Linux + 318)
+#define __NR_bpf (__NR_Linux + 319)
+#define __NR_execveat (__NR_Linux + 320)
+
+/*
+ * Offset of the last N32 flavoured syscall
+ */
+#define __NR_Linux_syscalls 320
+
+#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
+
+#define __NR_N32_Linux 6000
+#define __NR_N32_Linux_syscalls 320
+
+#endif /* _ASM_UNISTD_H */
diff --git a/linux-headers/asm-powerpc/unistd.h b/linux-headers/asm-powerpc/unistd.h
new file mode 100644
index 0000000..28deee0
--- /dev/null
+++ b/linux-headers/asm-powerpc/unistd.h
@@ -0,0 +1,392 @@
+/*
+ * This file contains the system call numbers.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_POWERPC_UNISTD_H_
+#define _ASM_POWERPC_UNISTD_H_
+
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_vm86 113
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_modify_ldt 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_query_module 166
+#define __NR_poll 167
+#define __NR_nfsservctl 168
+#define __NR_setresgid 169
+#define __NR_getresgid 170
+#define __NR_prctl 171
+#define __NR_rt_sigreturn 172
+#define __NR_rt_sigaction 173
+#define __NR_rt_sigprocmask 174
+#define __NR_rt_sigpending 175
+#define __NR_rt_sigtimedwait 176
+#define __NR_rt_sigqueueinfo 177
+#define __NR_rt_sigsuspend 178
+#define __NR_pread64 179
+#define __NR_pwrite64 180
+#define __NR_chown 181
+#define __NR_getcwd 182
+#define __NR_capget 183
+#define __NR_capset 184
+#define __NR_sigaltstack 185
+#define __NR_sendfile 186
+#define __NR_getpmsg 187 /* some people actually want streams */
+#define __NR_putpmsg 188 /* some people actually want streams */
+#define __NR_vfork 189
+#define __NR_ugetrlimit 190 /* SuS compliant getrlimit */
+#define __NR_readahead 191
+#ifndef __powerpc64__ /* these are 32-bit only */
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#endif
+#define __NR_pciconfig_read 198
+#define __NR_pciconfig_write 199
+#define __NR_pciconfig_iobase 200
+#define __NR_multiplexer 201
+#define __NR_getdents64 202
+#define __NR_pivot_root 203
+#ifndef __powerpc64__
+#define __NR_fcntl64 204
+#endif
+#define __NR_madvise 205
+#define __NR_mincore 206
+#define __NR_gettid 207
+#define __NR_tkill 208
+#define __NR_setxattr 209
+#define __NR_lsetxattr 210
+#define __NR_fsetxattr 211
+#define __NR_getxattr 212
+#define __NR_lgetxattr 213
+#define __NR_fgetxattr 214
+#define __NR_listxattr 215
+#define __NR_llistxattr 216
+#define __NR_flistxattr 217
+#define __NR_removexattr 218
+#define __NR_lremovexattr 219
+#define __NR_fremovexattr 220
+#define __NR_futex 221
+#define __NR_sched_setaffinity 222
+#define __NR_sched_getaffinity 223
+/* 224 currently unused */
+#define __NR_tuxcall 225
+#ifndef __powerpc64__
+#define __NR_sendfile64 226
+#endif
+#define __NR_io_setup 227
+#define __NR_io_destroy 228
+#define __NR_io_getevents 229
+#define __NR_io_submit 230
+#define __NR_io_cancel 231
+#define __NR_set_tid_address 232
+#define __NR_fadvise64 233
+#define __NR_exit_group 234
+#define __NR_lookup_dcookie 235
+#define __NR_epoll_create 236
+#define __NR_epoll_ctl 237
+#define __NR_epoll_wait 238
+#define __NR_remap_file_pages 239
+#define __NR_timer_create 240
+#define __NR_timer_settime 241
+#define __NR_timer_gettime 242
+#define __NR_timer_getoverrun 243
+#define __NR_timer_delete 244
+#define __NR_clock_settime 245
+#define __NR_clock_gettime 246
+#define __NR_clock_getres 247
+#define __NR_clock_nanosleep 248
+#define __NR_swapcontext 249
+#define __NR_tgkill 250
+#define __NR_utimes 251
+#define __NR_statfs64 252
+#define __NR_fstatfs64 253
+#ifndef __powerpc64__
+#define __NR_fadvise64_64 254
+#endif
+#define __NR_rtas 255
+#define __NR_sys_debug_setcontext 256
+/* Number 257 is reserved for vserver */
+#define __NR_migrate_pages 258
+#define __NR_mbind 259
+#define __NR_get_mempolicy 260
+#define __NR_set_mempolicy 261
+#define __NR_mq_open 262
+#define __NR_mq_unlink 263
+#define __NR_mq_timedsend 264
+#define __NR_mq_timedreceive 265
+#define __NR_mq_notify 266
+#define __NR_mq_getsetattr 267
+#define __NR_kexec_load 268
+#define __NR_add_key 269
+#define __NR_request_key 270
+#define __NR_keyctl 271
+#define __NR_waitid 272
+#define __NR_ioprio_set 273
+#define __NR_ioprio_get 274
+#define __NR_inotify_init 275
+#define __NR_inotify_add_watch 276
+#define __NR_inotify_rm_watch 277
+#define __NR_spu_run 278
+#define __NR_spu_create 279
+#define __NR_pselect6 280
+#define __NR_ppoll 281
+#define __NR_unshare 282
+#define __NR_splice 283
+#define __NR_tee 284
+#define __NR_vmsplice 285
+#define __NR_openat 286
+#define __NR_mkdirat 287
+#define __NR_mknodat 288
+#define __NR_fchownat 289
+#define __NR_futimesat 290
+#ifdef __powerpc64__
+#define __NR_newfstatat 291
+#else
+#define __NR_fstatat64 291
+#endif
+#define __NR_unlinkat 292
+#define __NR_renameat 293
+#define __NR_linkat 294
+#define __NR_symlinkat 295
+#define __NR_readlinkat 296
+#define __NR_fchmodat 297
+#define __NR_faccessat 298
+#define __NR_get_robust_list 299
+#define __NR_set_robust_list 300
+#define __NR_move_pages 301
+#define __NR_getcpu 302
+#define __NR_epoll_pwait 303
+#define __NR_utimensat 304
+#define __NR_signalfd 305
+#define __NR_timerfd_create 306
+#define __NR_eventfd 307
+#define __NR_sync_file_range2 308
+#define __NR_fallocate 309
+#define __NR_subpage_prot 310
+#define __NR_timerfd_settime 311
+#define __NR_timerfd_gettime 312
+#define __NR_signalfd4 313
+#define __NR_eventfd2 314
+#define __NR_epoll_create1 315
+#define __NR_dup3 316
+#define __NR_pipe2 317
+#define __NR_inotify_init1 318
+#define __NR_perf_event_open 319
+#define __NR_preadv 320
+#define __NR_pwritev 321
+#define __NR_rt_tgsigqueueinfo 322
+#define __NR_fanotify_init 323
+#define __NR_fanotify_mark 324
+#define __NR_prlimit64 325
+#define __NR_socket 326
+#define __NR_bind 327
+#define __NR_connect 328
+#define __NR_listen 329
+#define __NR_accept 330
+#define __NR_getsockname 331
+#define __NR_getpeername 332
+#define __NR_socketpair 333
+#define __NR_send 334
+#define __NR_sendto 335
+#define __NR_recv 336
+#define __NR_recvfrom 337
+#define __NR_shutdown 338
+#define __NR_setsockopt 339
+#define __NR_getsockopt 340
+#define __NR_sendmsg 341
+#define __NR_recvmsg 342
+#define __NR_recvmmsg 343
+#define __NR_accept4 344
+#define __NR_name_to_handle_at 345
+#define __NR_open_by_handle_at 346
+#define __NR_clock_adjtime 347
+#define __NR_syncfs 348
+#define __NR_sendmmsg 349
+#define __NR_setns 350
+#define __NR_process_vm_readv 351
+#define __NR_process_vm_writev 352
+#define __NR_finit_module 353
+#define __NR_kcmp 354
+#define __NR_sched_setattr 355
+#define __NR_sched_getattr 356
+#define __NR_renameat2 357
+#define __NR_seccomp 358
+#define __NR_getrandom 359
+#define __NR_memfd_create 360
+#define __NR_bpf 361
+#define __NR_execveat 362
+#define __NR_switch_endian 363
+#define __NR_userfaultfd 364
+#define __NR_membarrier 365
+
+#endif /* _ASM_POWERPC_UNISTD_H_ */
diff --git a/linux-headers/asm-s390/unistd.h b/linux-headers/asm-s390/unistd.h
new file mode 100644
index 0000000..04b43b1
--- /dev/null
+++ b/linux-headers/asm-s390/unistd.h
@@ -0,0 +1,404 @@
+/*
+ * S390 version
+ *
+ * Derived from "include/asm-i386/unistd.h"
+ */
+
+#ifndef _ASM_S390_UNISTD_H_
+#define _ASM_S390_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_restart_syscall 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_brk 45
+#define __NR_signal 48
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_setpgid 57
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_symlink 83
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_lookup_dcookie 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_getdents 141
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188
+#define __NR_putpmsg 189
+#define __NR_vfork 190
+#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+#define __NR_getdents64 220
+#define __NR_readahead 222
+#define __NR_setxattr 224
+#define __NR_lsetxattr 225
+#define __NR_fsetxattr 226
+#define __NR_getxattr 227
+#define __NR_lgetxattr 228
+#define __NR_fgetxattr 229
+#define __NR_listxattr 230
+#define __NR_llistxattr 231
+#define __NR_flistxattr 232
+#define __NR_removexattr 233
+#define __NR_lremovexattr 234
+#define __NR_fremovexattr 235
+#define __NR_gettid 236
+#define __NR_tkill 237
+#define __NR_futex 238
+#define __NR_sched_setaffinity 239
+#define __NR_sched_getaffinity 240
+#define __NR_tgkill 241
+/* Number 242 is reserved for tux */
+#define __NR_io_setup 243
+#define __NR_io_destroy 244
+#define __NR_io_getevents 245
+#define __NR_io_submit 246
+#define __NR_io_cancel 247
+#define __NR_exit_group 248
+#define __NR_epoll_create 249
+#define __NR_epoll_ctl 250
+#define __NR_epoll_wait 251
+#define __NR_set_tid_address 252
+#define __NR_fadvise64 253
+#define __NR_timer_create 254
+#define __NR_timer_settime (__NR_timer_create+1)
+#define __NR_timer_gettime (__NR_timer_create+2)
+#define __NR_timer_getoverrun (__NR_timer_create+3)
+#define __NR_timer_delete (__NR_timer_create+4)
+#define __NR_clock_settime (__NR_timer_create+5)
+#define __NR_clock_gettime (__NR_timer_create+6)
+#define __NR_clock_getres (__NR_timer_create+7)
+#define __NR_clock_nanosleep (__NR_timer_create+8)
+/* Number 263 is reserved for vserver */
+#define __NR_statfs64 265
+#define __NR_fstatfs64 266
+#define __NR_remap_file_pages 267
+#define __NR_mbind 268
+#define __NR_get_mempolicy 269
+#define __NR_set_mempolicy 270
+#define __NR_mq_open 271
+#define __NR_mq_unlink 272
+#define __NR_mq_timedsend 273
+#define __NR_mq_timedreceive 274
+#define __NR_mq_notify 275
+#define __NR_mq_getsetattr 276
+#define __NR_kexec_load 277
+#define __NR_add_key 278
+#define __NR_request_key 279
+#define __NR_keyctl 280
+#define __NR_waitid 281
+#define __NR_ioprio_set 282
+#define __NR_ioprio_get 283
+#define __NR_inotify_init 284
+#define __NR_inotify_add_watch 285
+#define __NR_inotify_rm_watch 286
+#define __NR_migrate_pages 287
+#define __NR_openat 288
+#define __NR_mkdirat 289
+#define __NR_mknodat 290
+#define __NR_fchownat 291
+#define __NR_futimesat 292
+#define __NR_unlinkat 294
+#define __NR_renameat 295
+#define __NR_linkat 296
+#define __NR_symlinkat 297
+#define __NR_readlinkat 298
+#define __NR_fchmodat 299
+#define __NR_faccessat 300
+#define __NR_pselect6 301
+#define __NR_ppoll 302
+#define __NR_unshare 303
+#define __NR_set_robust_list 304
+#define __NR_get_robust_list 305
+#define __NR_splice 306
+#define __NR_sync_file_range 307
+#define __NR_tee 308
+#define __NR_vmsplice 309
+#define __NR_move_pages 310
+#define __NR_getcpu 311
+#define __NR_epoll_pwait 312
+#define __NR_utimes 313
+#define __NR_fallocate 314
+#define __NR_utimensat 315
+#define __NR_signalfd 316
+#define __NR_timerfd 317
+#define __NR_eventfd 318
+#define __NR_timerfd_create 319
+#define __NR_timerfd_settime 320
+#define __NR_timerfd_gettime 321
+#define __NR_signalfd4 322
+#define __NR_eventfd2 323
+#define __NR_inotify_init1 324
+#define __NR_pipe2 325
+#define __NR_dup3 326
+#define __NR_epoll_create1 327
+#define __NR_preadv 328
+#define __NR_pwritev 329
+#define __NR_rt_tgsigqueueinfo 330
+#define __NR_perf_event_open 331
+#define __NR_fanotify_init 332
+#define __NR_fanotify_mark 333
+#define __NR_prlimit64 334
+#define __NR_name_to_handle_at 335
+#define __NR_open_by_handle_at 336
+#define __NR_clock_adjtime 337
+#define __NR_syncfs 338
+#define __NR_setns 339
+#define __NR_process_vm_readv 340
+#define __NR_process_vm_writev 341
+#define __NR_s390_runtime_instr 342
+#define __NR_kcmp 343
+#define __NR_finit_module 344
+#define __NR_sched_setattr 345
+#define __NR_sched_getattr 346
+#define __NR_renameat2 347
+#define __NR_seccomp 348
+#define __NR_getrandom 349
+#define __NR_memfd_create 350
+#define __NR_bpf 351
+#define __NR_s390_pci_mmio_write 352
+#define __NR_s390_pci_mmio_read 353
+#define __NR_execveat 354
+#define __NR_userfaultfd 355
+#define __NR_membarrier 356
+#define __NR_recvmmsg 357
+#define __NR_sendmmsg 358
+#define __NR_socket 359
+#define __NR_socketpair 360
+#define __NR_bind 361
+#define __NR_connect 362
+#define __NR_listen 363
+#define __NR_accept4 364
+#define __NR_getsockopt 365
+#define __NR_setsockopt 366
+#define __NR_getsockname 367
+#define __NR_getpeername 368
+#define __NR_sendto 369
+#define __NR_sendmsg 370
+#define __NR_recvfrom 371
+#define __NR_recvmsg 372
+#define __NR_shutdown 373
+#define NR_syscalls 374
+
+/*
+ * There are some system calls that are not present on 64 bit, some
+ * have a different name although they do the same (e.g. __NR_chown32
+ * is __NR_chown on 64 bit).
+ */
+#ifndef __s390x__
+
+#define __NR_time 13
+#define __NR_lchown 16
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_getrlimit 76
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_fchown 95
+#define __NR_ioperm 101
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR__newselect 142
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_chown 182
+#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_lchown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_chown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_fcntl64 221
+#define __NR_sendfile64 223
+#define __NR_fadvise64_64 264
+#define __NR_fstatat64 293
+
+#else
+
+#define __NR_select 142
+#define __NR_getrlimit 191 /* SuS compliant getrlimit */
+#define __NR_lchown 198
+#define __NR_getuid 199
+#define __NR_getgid 200
+#define __NR_geteuid 201
+#define __NR_getegid 202
+#define __NR_setreuid 203
+#define __NR_setregid 204
+#define __NR_getgroups 205
+#define __NR_setgroups 206
+#define __NR_fchown 207
+#define __NR_setresuid 208
+#define __NR_getresuid 209
+#define __NR_setresgid 210
+#define __NR_getresgid 211
+#define __NR_chown 212
+#define __NR_setuid 213
+#define __NR_setgid 214
+#define __NR_setfsuid 215
+#define __NR_setfsgid 216
+#define __NR_newfstatat 293
+
+#endif
+
+#endif /* _ASM_S390_UNISTD_H_ */
diff --git a/linux-headers/asm-x86/unistd.h b/linux-headers/asm-x86/unistd.h
new file mode 100644
index 0000000..1f99b12
--- /dev/null
+++ b/linux-headers/asm-x86/unistd.h
@@ -0,0 +1,15 @@
+#ifndef _ASM_X86_UNISTD_H
+#define _ASM_X86_UNISTD_H
+
+/* x32 syscall flag bit */
+#define __X32_SYSCALL_BIT 0x40000000
+
+# ifdef __i386__
+# include <asm/unistd_32.h>
+# elif defined(__ILP32__)
+# include <asm/unistd_x32.h>
+# else
+# include <asm/unistd_64.h>
+# endif
+
+#endif /* _ASM_X86_UNISTD_H */
diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h
new file mode 100644
index 0000000..7570c80
--- /dev/null
+++ b/linux-headers/asm-x86/unistd_32.h
@@ -0,0 +1,377 @@
+#ifndef _ASM_X86_UNISTD_32_H
+#define _ASM_X86_UNISTD_32_H 1
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_vm86old 113
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_modify_ldt 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_vm86 166
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_chown 182
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188
+#define __NR_putpmsg 189
+#define __NR_vfork 190
+#define __NR_ugetrlimit 191
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_lchown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_chown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+#define __NR_getdents64 220
+#define __NR_fcntl64 221
+#define __NR_gettid 224
+#define __NR_readahead 225
+#define __NR_setxattr 226
+#define __NR_lsetxattr 227
+#define __NR_fsetxattr 228
+#define __NR_getxattr 229
+#define __NR_lgetxattr 230
+#define __NR_fgetxattr 231
+#define __NR_listxattr 232
+#define __NR_llistxattr 233
+#define __NR_flistxattr 234
+#define __NR_removexattr 235
+#define __NR_lremovexattr 236
+#define __NR_fremovexattr 237
+#define __NR_tkill 238
+#define __NR_sendfile64 239
+#define __NR_futex 240
+#define __NR_sched_setaffinity 241
+#define __NR_sched_getaffinity 242
+#define __NR_set_thread_area 243
+#define __NR_get_thread_area 244
+#define __NR_io_setup 245
+#define __NR_io_destroy 246
+#define __NR_io_getevents 247
+#define __NR_io_submit 248
+#define __NR_io_cancel 249
+#define __NR_fadvise64 250
+#define __NR_exit_group 252
+#define __NR_lookup_dcookie 253
+#define __NR_epoll_create 254
+#define __NR_epoll_ctl 255
+#define __NR_epoll_wait 256
+#define __NR_remap_file_pages 257
+#define __NR_set_tid_address 258
+#define __NR_timer_create 259
+#define __NR_timer_settime 260
+#define __NR_timer_gettime 261
+#define __NR_timer_getoverrun 262
+#define __NR_timer_delete 263
+#define __NR_clock_settime 264
+#define __NR_clock_gettime 265
+#define __NR_clock_getres 266
+#define __NR_clock_nanosleep 267
+#define __NR_statfs64 268
+#define __NR_fstatfs64 269
+#define __NR_tgkill 270
+#define __NR_utimes 271
+#define __NR_fadvise64_64 272
+#define __NR_vserver 273
+#define __NR_mbind 274
+#define __NR_get_mempolicy 275
+#define __NR_set_mempolicy 276
+#define __NR_mq_open 277
+#define __NR_mq_unlink 278
+#define __NR_mq_timedsend 279
+#define __NR_mq_timedreceive 280
+#define __NR_mq_notify 281
+#define __NR_mq_getsetattr 282
+#define __NR_kexec_load 283
+#define __NR_waitid 284
+#define __NR_add_key 286
+#define __NR_request_key 287
+#define __NR_keyctl 288
+#define __NR_ioprio_set 289
+#define __NR_ioprio_get 290
+#define __NR_inotify_init 291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch 293
+#define __NR_migrate_pages 294
+#define __NR_openat 295
+#define __NR_mkdirat 296
+#define __NR_mknodat 297
+#define __NR_fchownat 298
+#define __NR_futimesat 299
+#define __NR_fstatat64 300
+#define __NR_unlinkat 301
+#define __NR_renameat 302
+#define __NR_linkat 303
+#define __NR_symlinkat 304
+#define __NR_readlinkat 305
+#define __NR_fchmodat 306
+#define __NR_faccessat 307
+#define __NR_pselect6 308
+#define __NR_ppoll 309
+#define __NR_unshare 310
+#define __NR_set_robust_list 311
+#define __NR_get_robust_list 312
+#define __NR_splice 313
+#define __NR_sync_file_range 314
+#define __NR_tee 315
+#define __NR_vmsplice 316
+#define __NR_move_pages 317
+#define __NR_getcpu 318
+#define __NR_epoll_pwait 319
+#define __NR_utimensat 320
+#define __NR_signalfd 321
+#define __NR_timerfd_create 322
+#define __NR_eventfd 323
+#define __NR_fallocate 324
+#define __NR_timerfd_settime 325
+#define __NR_timerfd_gettime 326
+#define __NR_signalfd4 327
+#define __NR_eventfd2 328
+#define __NR_epoll_create1 329
+#define __NR_dup3 330
+#define __NR_pipe2 331
+#define __NR_inotify_init1 332
+#define __NR_preadv 333
+#define __NR_pwritev 334
+#define __NR_rt_tgsigqueueinfo 335
+#define __NR_perf_event_open 336
+#define __NR_recvmmsg 337
+#define __NR_fanotify_init 338
+#define __NR_fanotify_mark 339
+#define __NR_prlimit64 340
+#define __NR_name_to_handle_at 341
+#define __NR_open_by_handle_at 342
+#define __NR_clock_adjtime 343
+#define __NR_syncfs 344
+#define __NR_sendmmsg 345
+#define __NR_setns 346
+#define __NR_process_vm_readv 347
+#define __NR_process_vm_writev 348
+#define __NR_kcmp 349
+#define __NR_finit_module 350
+#define __NR_sched_setattr 351
+#define __NR_sched_getattr 352
+#define __NR_renameat2 353
+#define __NR_seccomp 354
+#define __NR_getrandom 355
+#define __NR_memfd_create 356
+#define __NR_bpf 357
+#define __NR_execveat 358
+#define __NR_socket 359
+#define __NR_socketpair 360
+#define __NR_bind 361
+#define __NR_connect 362
+#define __NR_listen 363
+#define __NR_accept4 364
+#define __NR_getsockopt 365
+#define __NR_setsockopt 366
+#define __NR_getsockname 367
+#define __NR_getpeername 368
+#define __NR_sendto 369
+#define __NR_sendmsg 370
+#define __NR_recvfrom 371
+#define __NR_recvmsg 372
+#define __NR_shutdown 373
+#define __NR_userfaultfd 374
+#define __NR_membarrier 375
+
+#endif /* _ASM_X86_UNISTD_32_H */
diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h
new file mode 100644
index 0000000..fdc7afb
--- /dev/null
+++ b/linux-headers/asm-x86/unistd_64.h
@@ -0,0 +1,330 @@
+#ifndef _ASM_X86_UNISTD_64_H
+#define _ASM_X86_UNISTD_64_H 1
+
+#define __NR_read 0
+#define __NR_write 1
+#define __NR_open 2
+#define __NR_close 3
+#define __NR_stat 4
+#define __NR_fstat 5
+#define __NR_lstat 6
+#define __NR_poll 7
+#define __NR_lseek 8
+#define __NR_mmap 9
+#define __NR_mprotect 10
+#define __NR_munmap 11
+#define __NR_brk 12
+#define __NR_rt_sigaction 13
+#define __NR_rt_sigprocmask 14
+#define __NR_rt_sigreturn 15
+#define __NR_ioctl 16
+#define __NR_pread64 17
+#define __NR_pwrite64 18
+#define __NR_readv 19
+#define __NR_writev 20
+#define __NR_access 21
+#define __NR_pipe 22
+#define __NR_select 23
+#define __NR_sched_yield 24
+#define __NR_mremap 25
+#define __NR_msync 26
+#define __NR_mincore 27
+#define __NR_madvise 28
+#define __NR_shmget 29
+#define __NR_shmat 30
+#define __NR_shmctl 31
+#define __NR_dup 32
+#define __NR_dup2 33
+#define __NR_pause 34
+#define __NR_nanosleep 35
+#define __NR_getitimer 36
+#define __NR_alarm 37
+#define __NR_setitimer 38
+#define __NR_getpid 39
+#define __NR_sendfile 40
+#define __NR_socket 41
+#define __NR_connect 42
+#define __NR_accept 43
+#define __NR_sendto 44
+#define __NR_recvfrom 45
+#define __NR_sendmsg 46
+#define __NR_recvmsg 47
+#define __NR_shutdown 48
+#define __NR_bind 49
+#define __NR_listen 50
+#define __NR_getsockname 51
+#define __NR_getpeername 52
+#define __NR_socketpair 53
+#define __NR_setsockopt 54
+#define __NR_getsockopt 55
+#define __NR_clone 56
+#define __NR_fork 57
+#define __NR_vfork 58
+#define __NR_execve 59
+#define __NR_exit 60
+#define __NR_wait4 61
+#define __NR_kill 62
+#define __NR_uname 63
+#define __NR_semget 64
+#define __NR_semop 65
+#define __NR_semctl 66
+#define __NR_shmdt 67
+#define __NR_msgget 68
+#define __NR_msgsnd 69
+#define __NR_msgrcv 70
+#define __NR_msgctl 71
+#define __NR_fcntl 72
+#define __NR_flock 73
+#define __NR_fsync 74
+#define __NR_fdatasync 75
+#define __NR_truncate 76
+#define __NR_ftruncate 77
+#define __NR_getdents 78
+#define __NR_getcwd 79
+#define __NR_chdir 80
+#define __NR_fchdir 81
+#define __NR_rename 82
+#define __NR_mkdir 83
+#define __NR_rmdir 84
+#define __NR_creat 85
+#define __NR_link 86
+#define __NR_unlink 87
+#define __NR_symlink 88
+#define __NR_readlink 89
+#define __NR_chmod 90
+#define __NR_fchmod 91
+#define __NR_chown 92
+#define __NR_fchown 93
+#define __NR_lchown 94
+#define __NR_umask 95
+#define __NR_gettimeofday 96
+#define __NR_getrlimit 97
+#define __NR_getrusage 98
+#define __NR_sysinfo 99
+#define __NR_times 100
+#define __NR_ptrace 101
+#define __NR_getuid 102
+#define __NR_syslog 103
+#define __NR_getgid 104
+#define __NR_setuid 105
+#define __NR_setgid 106
+#define __NR_geteuid 107
+#define __NR_getegid 108
+#define __NR_setpgid 109
+#define __NR_getppid 110
+#define __NR_getpgrp 111
+#define __NR_setsid 112
+#define __NR_setreuid 113
+#define __NR_setregid 114
+#define __NR_getgroups 115
+#define __NR_setgroups 116
+#define __NR_setresuid 117
+#define __NR_getresuid 118
+#define __NR_setresgid 119
+#define __NR_getresgid 120
+#define __NR_getpgid 121
+#define __NR_setfsuid 122
+#define __NR_setfsgid 123
+#define __NR_getsid 124
+#define __NR_capget 125
+#define __NR_capset 126
+#define __NR_rt_sigpending 127
+#define __NR_rt_sigtimedwait 128
+#define __NR_rt_sigqueueinfo 129
+#define __NR_rt_sigsuspend 130
+#define __NR_sigaltstack 131
+#define __NR_utime 132
+#define __NR_mknod 133
+#define __NR_uselib 134
+#define __NR_personality 135
+#define __NR_ustat 136
+#define __NR_statfs 137
+#define __NR_fstatfs 138
+#define __NR_sysfs 139
+#define __NR_getpriority 140
+#define __NR_setpriority 141
+#define __NR_sched_setparam 142
+#define __NR_sched_getparam 143
+#define __NR_sched_setscheduler 144
+#define __NR_sched_getscheduler 145
+#define __NR_sched_get_priority_max 146
+#define __NR_sched_get_priority_min 147
+#define __NR_sched_rr_get_interval 148
+#define __NR_mlock 149
+#define __NR_munlock 150
+#define __NR_mlockall 151
+#define __NR_munlockall 152
+#define __NR_vhangup 153
+#define __NR_modify_ldt 154
+#define __NR_pivot_root 155
+#define __NR__sysctl 156
+#define __NR_prctl 157
+#define __NR_arch_prctl 158
+#define __NR_adjtimex 159
+#define __NR_setrlimit 160
+#define __NR_chroot 161
+#define __NR_sync 162
+#define __NR_acct 163
+#define __NR_settimeofday 164
+#define __NR_mount 165
+#define __NR_umount2 166
+#define __NR_swapon 167
+#define __NR_swapoff 168
+#define __NR_reboot 169
+#define __NR_sethostname 170
+#define __NR_setdomainname 171
+#define __NR_iopl 172
+#define __NR_ioperm 173
+#define __NR_create_module 174
+#define __NR_init_module 175
+#define __NR_delete_module 176
+#define __NR_get_kernel_syms 177
+#define __NR_query_module 178
+#define __NR_quotactl 179
+#define __NR_nfsservctl 180
+#define __NR_getpmsg 181
+#define __NR_putpmsg 182
+#define __NR_afs_syscall 183
+#define __NR_tuxcall 184
+#define __NR_security 185
+#define __NR_gettid 186
+#define __NR_readahead 187
+#define __NR_setxattr 188
+#define __NR_lsetxattr 189
+#define __NR_fsetxattr 190
+#define __NR_getxattr 191
+#define __NR_lgetxattr 192
+#define __NR_fgetxattr 193
+#define __NR_listxattr 194
+#define __NR_llistxattr 195
+#define __NR_flistxattr 196
+#define __NR_removexattr 197
+#define __NR_lremovexattr 198
+#define __NR_fremovexattr 199
+#define __NR_tkill 200
+#define __NR_time 201
+#define __NR_futex 202
+#define __NR_sched_setaffinity 203
+#define __NR_sched_getaffinity 204
+#define __NR_set_thread_area 205
+#define __NR_io_setup 206
+#define __NR_io_destroy 207
+#define __NR_io_getevents 208
+#define __NR_io_submit 209
+#define __NR_io_cancel 210
+#define __NR_get_thread_area 211
+#define __NR_lookup_dcookie 212
+#define __NR_epoll_create 213
+#define __NR_epoll_ctl_old 214
+#define __NR_epoll_wait_old 215
+#define __NR_remap_file_pages 216
+#define __NR_getdents64 217
+#define __NR_set_tid_address 218
+#define __NR_restart_syscall 219
+#define __NR_semtimedop 220
+#define __NR_fadvise64 221
+#define __NR_timer_create 222
+#define __NR_timer_settime 223
+#define __NR_timer_gettime 224
+#define __NR_timer_getoverrun 225
+#define __NR_timer_delete 226
+#define __NR_clock_settime 227
+#define __NR_clock_gettime 228
+#define __NR_clock_getres 229
+#define __NR_clock_nanosleep 230
+#define __NR_exit_group 231
+#define __NR_epoll_wait 232
+#define __NR_epoll_ctl 233
+#define __NR_tgkill 234
+#define __NR_utimes 235
+#define __NR_vserver 236
+#define __NR_mbind 237
+#define __NR_set_mempolicy 238
+#define __NR_get_mempolicy 239
+#define __NR_mq_open 240
+#define __NR_mq_unlink 241
+#define __NR_mq_timedsend 242
+#define __NR_mq_timedreceive 243
+#define __NR_mq_notify 244
+#define __NR_mq_getsetattr 245
+#define __NR_kexec_load 246
+#define __NR_waitid 247
+#define __NR_add_key 248
+#define __NR_request_key 249
+#define __NR_keyctl 250
+#define __NR_ioprio_set 251
+#define __NR_ioprio_get 252
+#define __NR_inotify_init 253
+#define __NR_inotify_add_watch 254
+#define __NR_inotify_rm_watch 255
+#define __NR_migrate_pages 256
+#define __NR_openat 257
+#define __NR_mkdirat 258
+#define __NR_mknodat 259
+#define __NR_fchownat 260
+#define __NR_futimesat 261
+#define __NR_newfstatat 262
+#define __NR_unlinkat 263
+#define __NR_renameat 264
+#define __NR_linkat 265
+#define __NR_symlinkat 266
+#define __NR_readlinkat 267
+#define __NR_fchmodat 268
+#define __NR_faccessat 269
+#define __NR_pselect6 270
+#define __NR_ppoll 271
+#define __NR_unshare 272
+#define __NR_set_robust_list 273
+#define __NR_get_robust_list 274
+#define __NR_splice 275
+#define __NR_tee 276
+#define __NR_sync_file_range 277
+#define __NR_vmsplice 278
+#define __NR_move_pages 279
+#define __NR_utimensat 280
+#define __NR_epoll_pwait 281
+#define __NR_signalfd 282
+#define __NR_timerfd_create 283
+#define __NR_eventfd 284
+#define __NR_fallocate 285
+#define __NR_timerfd_settime 286
+#define __NR_timerfd_gettime 287
+#define __NR_accept4 288
+#define __NR_signalfd4 289
+#define __NR_eventfd2 290
+#define __NR_epoll_create1 291
+#define __NR_dup3 292
+#define __NR_pipe2 293
+#define __NR_inotify_init1 294
+#define __NR_preadv 295
+#define __NR_pwritev 296
+#define __NR_rt_tgsigqueueinfo 297
+#define __NR_perf_event_open 298
+#define __NR_recvmmsg 299
+#define __NR_fanotify_init 300
+#define __NR_fanotify_mark 301
+#define __NR_prlimit64 302
+#define __NR_name_to_handle_at 303
+#define __NR_open_by_handle_at 304
+#define __NR_clock_adjtime 305
+#define __NR_syncfs 306
+#define __NR_sendmmsg 307
+#define __NR_setns 308
+#define __NR_getcpu 309
+#define __NR_process_vm_readv 310
+#define __NR_process_vm_writev 311
+#define __NR_kcmp 312
+#define __NR_finit_module 313
+#define __NR_sched_setattr 314
+#define __NR_sched_getattr 315
+#define __NR_renameat2 316
+#define __NR_seccomp 317
+#define __NR_getrandom 318
+#define __NR_memfd_create 319
+#define __NR_kexec_file_load 320
+#define __NR_bpf 321
+#define __NR_execveat 322
+#define __NR_userfaultfd 323
+#define __NR_membarrier 324
+
+#endif /* _ASM_X86_UNISTD_64_H */
diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h
new file mode 100644
index 0000000..ac6d198
--- /dev/null
+++ b/linux-headers/asm-x86/unistd_x32.h
@@ -0,0 +1,319 @@
+#ifndef _ASM_X86_UNISTD_X32_H
+#define _ASM_X86_UNISTD_X32_H 1
+
+#define __NR_read (__X32_SYSCALL_BIT + 0)
+#define __NR_write (__X32_SYSCALL_BIT + 1)
+#define __NR_open (__X32_SYSCALL_BIT + 2)
+#define __NR_close (__X32_SYSCALL_BIT + 3)
+#define __NR_stat (__X32_SYSCALL_BIT + 4)
+#define __NR_fstat (__X32_SYSCALL_BIT + 5)
+#define __NR_lstat (__X32_SYSCALL_BIT + 6)
+#define __NR_poll (__X32_SYSCALL_BIT + 7)
+#define __NR_lseek (__X32_SYSCALL_BIT + 8)
+#define __NR_mmap (__X32_SYSCALL_BIT + 9)
+#define __NR_mprotect (__X32_SYSCALL_BIT + 10)
+#define __NR_munmap (__X32_SYSCALL_BIT + 11)
+#define __NR_brk (__X32_SYSCALL_BIT + 12)
+#define __NR_rt_sigprocmask (__X32_SYSCALL_BIT + 14)
+#define __NR_pread64 (__X32_SYSCALL_BIT + 17)
+#define __NR_pwrite64 (__X32_SYSCALL_BIT + 18)
+#define __NR_access (__X32_SYSCALL_BIT + 21)
+#define __NR_pipe (__X32_SYSCALL_BIT + 22)
+#define __NR_select (__X32_SYSCALL_BIT + 23)
+#define __NR_sched_yield (__X32_SYSCALL_BIT + 24)
+#define __NR_mremap (__X32_SYSCALL_BIT + 25)
+#define __NR_msync (__X32_SYSCALL_BIT + 26)
+#define __NR_mincore (__X32_SYSCALL_BIT + 27)
+#define __NR_madvise (__X32_SYSCALL_BIT + 28)
+#define __NR_shmget (__X32_SYSCALL_BIT + 29)
+#define __NR_shmat (__X32_SYSCALL_BIT + 30)
+#define __NR_shmctl (__X32_SYSCALL_BIT + 31)
+#define __NR_dup (__X32_SYSCALL_BIT + 32)
+#define __NR_dup2 (__X32_SYSCALL_BIT + 33)
+#define __NR_pause (__X32_SYSCALL_BIT + 34)
+#define __NR_nanosleep (__X32_SYSCALL_BIT + 35)
+#define __NR_getitimer (__X32_SYSCALL_BIT + 36)
+#define __NR_alarm (__X32_SYSCALL_BIT + 37)
+#define __NR_setitimer (__X32_SYSCALL_BIT + 38)
+#define __NR_getpid (__X32_SYSCALL_BIT + 39)
+#define __NR_sendfile (__X32_SYSCALL_BIT + 40)
+#define __NR_socket (__X32_SYSCALL_BIT + 41)
+#define __NR_connect (__X32_SYSCALL_BIT + 42)
+#define __NR_accept (__X32_SYSCALL_BIT + 43)
+#define __NR_sendto (__X32_SYSCALL_BIT + 44)
+#define __NR_shutdown (__X32_SYSCALL_BIT + 48)
+#define __NR_bind (__X32_SYSCALL_BIT + 49)
+#define __NR_listen (__X32_SYSCALL_BIT + 50)
+#define __NR_getsockname (__X32_SYSCALL_BIT + 51)
+#define __NR_getpeername (__X32_SYSCALL_BIT + 52)
+#define __NR_socketpair (__X32_SYSCALL_BIT + 53)
+#define __NR_clone (__X32_SYSCALL_BIT + 56)
+#define __NR_fork (__X32_SYSCALL_BIT + 57)
+#define __NR_vfork (__X32_SYSCALL_BIT + 58)
+#define __NR_exit (__X32_SYSCALL_BIT + 60)
+#define __NR_wait4 (__X32_SYSCALL_BIT + 61)
+#define __NR_kill (__X32_SYSCALL_BIT + 62)
+#define __NR_uname (__X32_SYSCALL_BIT + 63)
+#define __NR_semget (__X32_SYSCALL_BIT + 64)
+#define __NR_semop (__X32_SYSCALL_BIT + 65)
+#define __NR_semctl (__X32_SYSCALL_BIT + 66)
+#define __NR_shmdt (__X32_SYSCALL_BIT + 67)
+#define __NR_msgget (__X32_SYSCALL_BIT + 68)
+#define __NR_msgsnd (__X32_SYSCALL_BIT + 69)
+#define __NR_msgrcv (__X32_SYSCALL_BIT + 70)
+#define __NR_msgctl (__X32_SYSCALL_BIT + 71)
+#define __NR_fcntl (__X32_SYSCALL_BIT + 72)
+#define __NR_flock (__X32_SYSCALL_BIT + 73)
+#define __NR_fsync (__X32_SYSCALL_BIT + 74)
+#define __NR_fdatasync (__X32_SYSCALL_BIT + 75)
+#define __NR_truncate (__X32_SYSCALL_BIT + 76)
+#define __NR_ftruncate (__X32_SYSCALL_BIT + 77)
+#define __NR_getdents (__X32_SYSCALL_BIT + 78)
+#define __NR_getcwd (__X32_SYSCALL_BIT + 79)
+#define __NR_chdir (__X32_SYSCALL_BIT + 80)
+#define __NR_fchdir (__X32_SYSCALL_BIT + 81)
+#define __NR_rename (__X32_SYSCALL_BIT + 82)
+#define __NR_mkdir (__X32_SYSCALL_BIT + 83)
+#define __NR_rmdir (__X32_SYSCALL_BIT + 84)
+#define __NR_creat (__X32_SYSCALL_BIT + 85)
+#define __NR_link (__X32_SYSCALL_BIT + 86)
+#define __NR_unlink (__X32_SYSCALL_BIT + 87)
+#define __NR_symlink (__X32_SYSCALL_BIT + 88)
+#define __NR_readlink (__X32_SYSCALL_BIT + 89)
+#define __NR_chmod (__X32_SYSCALL_BIT + 90)
+#define __NR_fchmod (__X32_SYSCALL_BIT + 91)
+#define __NR_chown (__X32_SYSCALL_BIT + 92)
+#define __NR_fchown (__X32_SYSCALL_BIT + 93)
+#define __NR_lchown (__X32_SYSCALL_BIT + 94)
+#define __NR_umask (__X32_SYSCALL_BIT + 95)
+#define __NR_gettimeofday (__X32_SYSCALL_BIT + 96)
+#define __NR_getrlimit (__X32_SYSCALL_BIT + 97)
+#define __NR_getrusage (__X32_SYSCALL_BIT + 98)
+#define __NR_sysinfo (__X32_SYSCALL_BIT + 99)
+#define __NR_times (__X32_SYSCALL_BIT + 100)
+#define __NR_getuid (__X32_SYSCALL_BIT + 102)
+#define __NR_syslog (__X32_SYSCALL_BIT + 103)
+#define __NR_getgid (__X32_SYSCALL_BIT + 104)
+#define __NR_setuid (__X32_SYSCALL_BIT + 105)
+#define __NR_setgid (__X32_SYSCALL_BIT + 106)
+#define __NR_geteuid (__X32_SYSCALL_BIT + 107)
+#define __NR_getegid (__X32_SYSCALL_BIT + 108)
+#define __NR_setpgid (__X32_SYSCALL_BIT + 109)
+#define __NR_getppid (__X32_SYSCALL_BIT + 110)
+#define __NR_getpgrp (__X32_SYSCALL_BIT + 111)
+#define __NR_setsid (__X32_SYSCALL_BIT + 112)
+#define __NR_setreuid (__X32_SYSCALL_BIT + 113)
+#define __NR_setregid (__X32_SYSCALL_BIT + 114)
+#define __NR_getgroups (__X32_SYSCALL_BIT + 115)
+#define __NR_setgroups (__X32_SYSCALL_BIT + 116)
+#define __NR_setresuid (__X32_SYSCALL_BIT + 117)
+#define __NR_getresuid (__X32_SYSCALL_BIT + 118)
+#define __NR_setresgid (__X32_SYSCALL_BIT + 119)
+#define __NR_getresgid (__X32_SYSCALL_BIT + 120)
+#define __NR_getpgid (__X32_SYSCALL_BIT + 121)
+#define __NR_setfsuid (__X32_SYSCALL_BIT + 122)
+#define __NR_setfsgid (__X32_SYSCALL_BIT + 123)
+#define __NR_getsid (__X32_SYSCALL_BIT + 124)
+#define __NR_capget (__X32_SYSCALL_BIT + 125)
+#define __NR_capset (__X32_SYSCALL_BIT + 126)
+#define __NR_rt_sigsuspend (__X32_SYSCALL_BIT + 130)
+#define __NR_utime (__X32_SYSCALL_BIT + 132)
+#define __NR_mknod (__X32_SYSCALL_BIT + 133)
+#define __NR_personality (__X32_SYSCALL_BIT + 135)
+#define __NR_ustat (__X32_SYSCALL_BIT + 136)
+#define __NR_statfs (__X32_SYSCALL_BIT + 137)
+#define __NR_fstatfs (__X32_SYSCALL_BIT + 138)
+#define __NR_sysfs (__X32_SYSCALL_BIT + 139)
+#define __NR_getpriority (__X32_SYSCALL_BIT + 140)
+#define __NR_setpriority (__X32_SYSCALL_BIT + 141)
+#define __NR_sched_setparam (__X32_SYSCALL_BIT + 142)
+#define __NR_sched_getparam (__X32_SYSCALL_BIT + 143)
+#define __NR_sched_setscheduler (__X32_SYSCALL_BIT + 144)
+#define __NR_sched_getscheduler (__X32_SYSCALL_BIT + 145)
+#define __NR_sched_get_priority_max (__X32_SYSCALL_BIT + 146)
+#define __NR_sched_get_priority_min (__X32_SYSCALL_BIT + 147)
+#define __NR_sched_rr_get_interval (__X32_SYSCALL_BIT + 148)
+#define __NR_mlock (__X32_SYSCALL_BIT + 149)
+#define __NR_munlock (__X32_SYSCALL_BIT + 150)
+#define __NR_mlockall (__X32_SYSCALL_BIT + 151)
+#define __NR_munlockall (__X32_SYSCALL_BIT + 152)
+#define __NR_vhangup (__X32_SYSCALL_BIT + 153)
+#define __NR_modify_ldt (__X32_SYSCALL_BIT + 154)
+#define __NR_pivot_root (__X32_SYSCALL_BIT + 155)
+#define __NR_prctl (__X32_SYSCALL_BIT + 157)
+#define __NR_arch_prctl (__X32_SYSCALL_BIT + 158)
+#define __NR_adjtimex (__X32_SYSCALL_BIT + 159)
+#define __NR_setrlimit (__X32_SYSCALL_BIT + 160)
+#define __NR_chroot (__X32_SYSCALL_BIT + 161)
+#define __NR_sync (__X32_SYSCALL_BIT + 162)
+#define __NR_acct (__X32_SYSCALL_BIT + 163)
+#define __NR_settimeofday (__X32_SYSCALL_BIT + 164)
+#define __NR_mount (__X32_SYSCALL_BIT + 165)
+#define __NR_umount2 (__X32_SYSCALL_BIT + 166)
+#define __NR_swapon (__X32_SYSCALL_BIT + 167)
+#define __NR_swapoff (__X32_SYSCALL_BIT + 168)
+#define __NR_reboot (__X32_SYSCALL_BIT + 169)
+#define __NR_sethostname (__X32_SYSCALL_BIT + 170)
+#define __NR_setdomainname (__X32_SYSCALL_BIT + 171)
+#define __NR_iopl (__X32_SYSCALL_BIT + 172)
+#define __NR_ioperm (__X32_SYSCALL_BIT + 173)
+#define __NR_init_module (__X32_SYSCALL_BIT + 175)
+#define __NR_delete_module (__X32_SYSCALL_BIT + 176)
+#define __NR_quotactl (__X32_SYSCALL_BIT + 179)
+#define __NR_getpmsg (__X32_SYSCALL_BIT + 181)
+#define __NR_putpmsg (__X32_SYSCALL_BIT + 182)
+#define __NR_afs_syscall (__X32_SYSCALL_BIT + 183)
+#define __NR_tuxcall (__X32_SYSCALL_BIT + 184)
+#define __NR_security (__X32_SYSCALL_BIT + 185)
+#define __NR_gettid (__X32_SYSCALL_BIT + 186)
+#define __NR_readahead (__X32_SYSCALL_BIT + 187)
+#define __NR_setxattr (__X32_SYSCALL_BIT + 188)
+#define __NR_lsetxattr (__X32_SYSCALL_BIT + 189)
+#define __NR_fsetxattr (__X32_SYSCALL_BIT + 190)
+#define __NR_getxattr (__X32_SYSCALL_BIT + 191)
+#define __NR_lgetxattr (__X32_SYSCALL_BIT + 192)
+#define __NR_fgetxattr (__X32_SYSCALL_BIT + 193)
+#define __NR_listxattr (__X32_SYSCALL_BIT + 194)
+#define __NR_llistxattr (__X32_SYSCALL_BIT + 195)
+#define __NR_flistxattr (__X32_SYSCALL_BIT + 196)
+#define __NR_removexattr (__X32_SYSCALL_BIT + 197)
+#define __NR_lremovexattr (__X32_SYSCALL_BIT + 198)
+#define __NR_fremovexattr (__X32_SYSCALL_BIT + 199)
+#define __NR_tkill (__X32_SYSCALL_BIT + 200)
+#define __NR_time (__X32_SYSCALL_BIT + 201)
+#define __NR_futex (__X32_SYSCALL_BIT + 202)
+#define __NR_sched_setaffinity (__X32_SYSCALL_BIT + 203)
+#define __NR_sched_getaffinity (__X32_SYSCALL_BIT + 204)
+#define __NR_io_destroy (__X32_SYSCALL_BIT + 207)
+#define __NR_io_getevents (__X32_SYSCALL_BIT + 208)
+#define __NR_io_cancel (__X32_SYSCALL_BIT + 210)
+#define __NR_lookup_dcookie (__X32_SYSCALL_BIT + 212)
+#define __NR_epoll_create (__X32_SYSCALL_BIT + 213)
+#define __NR_remap_file_pages (__X32_SYSCALL_BIT + 216)
+#define __NR_getdents64 (__X32_SYSCALL_BIT + 217)
+#define __NR_set_tid_address (__X32_SYSCALL_BIT + 218)
+#define __NR_restart_syscall (__X32_SYSCALL_BIT + 219)
+#define __NR_semtimedop (__X32_SYSCALL_BIT + 220)
+#define __NR_fadvise64 (__X32_SYSCALL_BIT + 221)
+#define __NR_timer_settime (__X32_SYSCALL_BIT + 223)
+#define __NR_timer_gettime (__X32_SYSCALL_BIT + 224)
+#define __NR_timer_getoverrun (__X32_SYSCALL_BIT + 225)
+#define __NR_timer_delete (__X32_SYSCALL_BIT + 226)
+#define __NR_clock_settime (__X32_SYSCALL_BIT + 227)
+#define __NR_clock_gettime (__X32_SYSCALL_BIT + 228)
+#define __NR_clock_getres (__X32_SYSCALL_BIT + 229)
+#define __NR_clock_nanosleep (__X32_SYSCALL_BIT + 230)
+#define __NR_exit_group (__X32_SYSCALL_BIT + 231)
+#define __NR_epoll_wait (__X32_SYSCALL_BIT + 232)
+#define __NR_epoll_ctl (__X32_SYSCALL_BIT + 233)
+#define __NR_tgkill (__X32_SYSCALL_BIT + 234)
+#define __NR_utimes (__X32_SYSCALL_BIT + 235)
+#define __NR_mbind (__X32_SYSCALL_BIT + 237)
+#define __NR_set_mempolicy (__X32_SYSCALL_BIT + 238)
+#define __NR_get_mempolicy (__X32_SYSCALL_BIT + 239)
+#define __NR_mq_open (__X32_SYSCALL_BIT + 240)
+#define __NR_mq_unlink (__X32_SYSCALL_BIT + 241)
+#define __NR_mq_timedsend (__X32_SYSCALL_BIT + 242)
+#define __NR_mq_timedreceive (__X32_SYSCALL_BIT + 243)
+#define __NR_mq_getsetattr (__X32_SYSCALL_BIT + 245)
+#define __NR_add_key (__X32_SYSCALL_BIT + 248)
+#define __NR_request_key (__X32_SYSCALL_BIT + 249)
+#define __NR_keyctl (__X32_SYSCALL_BIT + 250)
+#define __NR_ioprio_set (__X32_SYSCALL_BIT + 251)
+#define __NR_ioprio_get (__X32_SYSCALL_BIT + 252)
+#define __NR_inotify_init (__X32_SYSCALL_BIT + 253)
+#define __NR_inotify_add_watch (__X32_SYSCALL_BIT + 254)
+#define __NR_inotify_rm_watch (__X32_SYSCALL_BIT + 255)
+#define __NR_migrate_pages (__X32_SYSCALL_BIT + 256)
+#define __NR_openat (__X32_SYSCALL_BIT + 257)
+#define __NR_mkdirat (__X32_SYSCALL_BIT + 258)
+#define __NR_mknodat (__X32_SYSCALL_BIT + 259)
+#define __NR_fchownat (__X32_SYSCALL_BIT + 260)
+#define __NR_futimesat (__X32_SYSCALL_BIT + 261)
+#define __NR_newfstatat (__X32_SYSCALL_BIT + 262)
+#define __NR_unlinkat (__X32_SYSCALL_BIT + 263)
+#define __NR_renameat (__X32_SYSCALL_BIT + 264)
+#define __NR_linkat (__X32_SYSCALL_BIT + 265)
+#define __NR_symlinkat (__X32_SYSCALL_BIT + 266)
+#define __NR_readlinkat (__X32_SYSCALL_BIT + 267)
+#define __NR_fchmodat (__X32_SYSCALL_BIT + 268)
+#define __NR_faccessat (__X32_SYSCALL_BIT + 269)
+#define __NR_pselect6 (__X32_SYSCALL_BIT + 270)
+#define __NR_ppoll (__X32_SYSCALL_BIT + 271)
+#define __NR_unshare (__X32_SYSCALL_BIT + 272)
+#define __NR_splice (__X32_SYSCALL_BIT + 275)
+#define __NR_tee (__X32_SYSCALL_BIT + 276)
+#define __NR_sync_file_range (__X32_SYSCALL_BIT + 277)
+#define __NR_utimensat (__X32_SYSCALL_BIT + 280)
+#define __NR_epoll_pwait (__X32_SYSCALL_BIT + 281)
+#define __NR_signalfd (__X32_SYSCALL_BIT + 282)
+#define __NR_timerfd_create (__X32_SYSCALL_BIT + 283)
+#define __NR_eventfd (__X32_SYSCALL_BIT + 284)
+#define __NR_fallocate (__X32_SYSCALL_BIT + 285)
+#define __NR_timerfd_settime (__X32_SYSCALL_BIT + 286)
+#define __NR_timerfd_gettime (__X32_SYSCALL_BIT + 287)
+#define __NR_accept4 (__X32_SYSCALL_BIT + 288)
+#define __NR_signalfd4 (__X32_SYSCALL_BIT + 289)
+#define __NR_eventfd2 (__X32_SYSCALL_BIT + 290)
+#define __NR_epoll_create1 (__X32_SYSCALL_BIT + 291)
+#define __NR_dup3 (__X32_SYSCALL_BIT + 292)
+#define __NR_pipe2 (__X32_SYSCALL_BIT + 293)
+#define __NR_inotify_init1 (__X32_SYSCALL_BIT + 294)
+#define __NR_perf_event_open (__X32_SYSCALL_BIT + 298)
+#define __NR_fanotify_init (__X32_SYSCALL_BIT + 300)
+#define __NR_fanotify_mark (__X32_SYSCALL_BIT + 301)
+#define __NR_prlimit64 (__X32_SYSCALL_BIT + 302)
+#define __NR_name_to_handle_at (__X32_SYSCALL_BIT + 303)
+#define __NR_open_by_handle_at (__X32_SYSCALL_BIT + 304)
+#define __NR_clock_adjtime (__X32_SYSCALL_BIT + 305)
+#define __NR_syncfs (__X32_SYSCALL_BIT + 306)
+#define __NR_setns (__X32_SYSCALL_BIT + 308)
+#define __NR_getcpu (__X32_SYSCALL_BIT + 309)
+#define __NR_kcmp (__X32_SYSCALL_BIT + 312)
+#define __NR_finit_module (__X32_SYSCALL_BIT + 313)
+#define __NR_sched_setattr (__X32_SYSCALL_BIT + 314)
+#define __NR_sched_getattr (__X32_SYSCALL_BIT + 315)
+#define __NR_renameat2 (__X32_SYSCALL_BIT + 316)
+#define __NR_seccomp (__X32_SYSCALL_BIT + 317)
+#define __NR_getrandom (__X32_SYSCALL_BIT + 318)
+#define __NR_memfd_create (__X32_SYSCALL_BIT + 319)
+#define __NR_kexec_file_load (__X32_SYSCALL_BIT + 320)
+#define __NR_bpf (__X32_SYSCALL_BIT + 321)
+#define __NR_userfaultfd (__X32_SYSCALL_BIT + 323)
+#define __NR_membarrier (__X32_SYSCALL_BIT + 324)
+#define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
+#define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
+#define __NR_ioctl (__X32_SYSCALL_BIT + 514)
+#define __NR_readv (__X32_SYSCALL_BIT + 515)
+#define __NR_writev (__X32_SYSCALL_BIT + 516)
+#define __NR_recvfrom (__X32_SYSCALL_BIT + 517)
+#define __NR_sendmsg (__X32_SYSCALL_BIT + 518)
+#define __NR_recvmsg (__X32_SYSCALL_BIT + 519)
+#define __NR_execve (__X32_SYSCALL_BIT + 520)
+#define __NR_ptrace (__X32_SYSCALL_BIT + 521)
+#define __NR_rt_sigpending (__X32_SYSCALL_BIT + 522)
+#define __NR_rt_sigtimedwait (__X32_SYSCALL_BIT + 523)
+#define __NR_rt_sigqueueinfo (__X32_SYSCALL_BIT + 524)
+#define __NR_sigaltstack (__X32_SYSCALL_BIT + 525)
+#define __NR_timer_create (__X32_SYSCALL_BIT + 526)
+#define __NR_mq_notify (__X32_SYSCALL_BIT + 527)
+#define __NR_kexec_load (__X32_SYSCALL_BIT + 528)
+#define __NR_waitid (__X32_SYSCALL_BIT + 529)
+#define __NR_set_robust_list (__X32_SYSCALL_BIT + 530)
+#define __NR_get_robust_list (__X32_SYSCALL_BIT + 531)
+#define __NR_vmsplice (__X32_SYSCALL_BIT + 532)
+#define __NR_move_pages (__X32_SYSCALL_BIT + 533)
+#define __NR_preadv (__X32_SYSCALL_BIT + 534)
+#define __NR_pwritev (__X32_SYSCALL_BIT + 535)
+#define __NR_rt_tgsigqueueinfo (__X32_SYSCALL_BIT + 536)
+#define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
+#define __NR_sendmmsg (__X32_SYSCALL_BIT + 538)
+#define __NR_process_vm_readv (__X32_SYSCALL_BIT + 539)
+#define __NR_process_vm_writev (__X32_SYSCALL_BIT + 540)
+#define __NR_setsockopt (__X32_SYSCALL_BIT + 541)
+#define __NR_getsockopt (__X32_SYSCALL_BIT + 542)
+#define __NR_io_setup (__X32_SYSCALL_BIT + 543)
+#define __NR_io_submit (__X32_SYSCALL_BIT + 544)
+#define __NR_execveat (__X32_SYSCALL_BIT + 545)
+
+#endif /* _ASM_X86_UNISTD_X32_H */
diff --git a/migration/qemu-file-buf.c b/migration/qemu-file-buf.c
index e3fd085..49516b8 100644
--- a/migration/qemu-file-buf.c
+++ b/migration/qemu-file-buf.c
@@ -29,7 +29,7 @@
#include "qemu/error-report.h"
#include "qemu/iov.h"
#include "qemu/sockets.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "migration/migration.h"
#include "migration/qemu-file.h"
#include "migration/qemu-file-internal.h"
diff --git a/migration/qemu-file-stdio.c b/migration/qemu-file-stdio.c
index 889ffb3..9bde9db 100644
--- a/migration/qemu-file-stdio.c
+++ b/migration/qemu-file-stdio.c
@@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#include "qemu-common.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "migration/qemu-file.h"
typedef struct QEMUFileStdio {
diff --git a/migration/qemu-file-unix.c b/migration/qemu-file-unix.c
index bf7a0e4..809bf07 100644
--- a/migration/qemu-file-unix.c
+++ b/migration/qemu-file-unix.c
@@ -24,7 +24,7 @@
#include "qemu-common.h"
#include "qemu/iov.h"
#include "qemu/sockets.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "migration/qemu-file.h"
#include "migration/qemu-file-internal.h"
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index 49addf6..df49023 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -26,7 +26,7 @@
#include "qemu/error-report.h"
#include "qemu/iov.h"
#include "qemu/sockets.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "migration/migration.h"
#include "migration/qemu-file.h"
#include "migration/qemu-file-internal.h"
diff --git a/migration/rdma.c b/migration/rdma.c
index 7a7176f..553fbd7 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -19,7 +19,7 @@
#include "qemu/main-loop.h"
#include "qemu/sockets.h"
#include "qemu/bitmap.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/nbd.c b/nbd.c
index 74859cb..fc34c44 100644
--- a/nbd.c
+++ b/nbd.c
@@ -19,7 +19,7 @@
#include "block/nbd.h"
#include "sysemu/block-backend.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include <errno.h>
#include <string.h>
diff --git a/net/net.c b/net/net.c
index 39af893..3c68f3f 100644
--- a/net/net.c
+++ b/net/net.c
@@ -524,20 +524,28 @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
int qemu_set_vnet_le(NetClientState *nc, bool is_le)
{
+#ifdef HOST_WORDS_BIGENDIAN
if (!nc || !nc->info->set_vnet_le) {
return -ENOSYS;
}
return nc->info->set_vnet_le(nc, is_le);
+#else
+ return 0;
+#endif
}
int qemu_set_vnet_be(NetClientState *nc, bool is_be)
{
+#ifdef HOST_WORDS_BIGENDIAN
+ return 0;
+#else
if (!nc || !nc->info->set_vnet_be) {
return -ENOSYS;
}
return nc->info->set_vnet_be(nc, is_be);
+#endif
}
int qemu_can_send_packet(NetClientState *sender)
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 8f354eb..17b5c2a 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -15,6 +15,7 @@
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qmp-commands.h"
+#include "trace.h"
typedef struct VhostUserState {
NetClientState nc;
@@ -102,6 +103,35 @@ err:
return -1;
}
+static ssize_t vhost_user_receive(NetClientState *nc, const uint8_t *buf,
+ size_t size)
+{
+ /* In case of RARP (message size is 60) notify backup to send a fake RARP.
+ This fake RARP will be sent by backend only for guest
+ without GUEST_ANNOUNCE capability.
+ */
+ if (size == 60) {
+ VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
+ int r;
+ static int display_rarp_failure = 1;
+ char mac_addr[6];
+
+ /* extract guest mac address from the RARP message */
+ memcpy(mac_addr, &buf[6], 6);
+
+ r = vhost_net_notify_migration_done(s->vhost_net, mac_addr);
+
+ if ((r != 0) && (display_rarp_failure)) {
+ fprintf(stderr,
+ "Vhost user backend fails to broadcast fake RARP\n");
+ fflush(stderr);
+ display_rarp_failure = 0;
+ }
+ }
+
+ return size;
+}
+
static void vhost_user_cleanup(NetClientState *nc)
{
VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc);
@@ -131,6 +161,7 @@ static bool vhost_user_has_ufo(NetClientState *nc)
static NetClientInfo net_vhost_user_info = {
.type = NET_CLIENT_OPTIONS_KIND_VHOST_USER,
.size = sizeof(VhostUserState),
+ .receive = vhost_user_receive,
.cleanup = vhost_user_cleanup,
.has_vnet_hdr = vhost_user_has_vnet_hdr,
.has_ufo = vhost_user_has_ufo,
@@ -148,18 +179,17 @@ static void net_vhost_user_event(void *opaque, int event)
NET_CLIENT_OPTIONS_KIND_NIC,
MAX_QUEUE_NUM);
s = DO_UPCAST(VhostUserState, nc, ncs[0]);
+ trace_vhost_user_event(s->chr->label, event);
switch (event) {
case CHR_EVENT_OPENED:
if (vhost_user_start(queues, ncs) < 0) {
exit(1);
}
qmp_set_link(name, true, &err);
- error_report("chardev \"%s\" went up", s->chr->label);
break;
case CHR_EVENT_CLOSED:
qmp_set_link(name, true, &err);
vhost_user_stop(queues, ncs);
- error_report("chardev \"%s\" went down", s->chr->label);
break;
}
@@ -182,8 +212,6 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
i, chr->label);
- /* We don't provide a receive callback */
- nc->receive_disabled = 1;
nc->queue_index = i;
s = DO_UPCAST(VhostUserState, nc, nc);
diff --git a/qapi-schema.json b/qapi-schema.json
index 702b7b5..f60be29 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2614,7 +2614,9 @@
#
# @host: host part of the address
#
-# @port: port part of the address, or lowest port if @to is present
+# @port: port part of the address, or lowest port if @to is present.
+# Kernel selects a free port if omitted for listener addresses.
+# #optional
#
# @to: highest port to try
#
@@ -2629,7 +2631,7 @@
{ 'struct': 'InetSocketAddress',
'data': {
'host': 'str',
- 'port': 'str',
+ '*port': 'str',
'*to': 'uint16',
'*ipv4': 'bool',
'*ipv6': 'bool' } }
diff --git a/qemu-char.c b/qemu-char.c
index 13371c4..908e712 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -92,31 +92,6 @@
/***********************************************************/
/* Socket address helpers */
-static void qapi_copy_SocketAddress(SocketAddress **p_dest,
- SocketAddress *src)
-{
- QmpOutputVisitor *qov;
- QmpInputVisitor *qiv;
- Visitor *ov, *iv;
- QObject *obj;
-
- *p_dest = NULL;
-
- qov = qmp_output_visitor_new();
- ov = qmp_output_get_visitor(qov);
- visit_type_SocketAddress(ov, &src, NULL, &error_abort);
- obj = qmp_output_get_qobject(qov);
- qmp_output_visitor_cleanup(qov);
- if (!obj) {
- return;
- }
-
- qiv = qmp_input_visitor_new(obj);
- iv = qmp_input_get_visitor(qiv);
- visit_type_SocketAddress(iv, p_dest, NULL, &error_abort);
- qmp_input_visitor_cleanup(qiv);
- qobject_decref(obj);
-}
static int SocketAddress_to_str(char *dest, int max_len,
const char *prefix, SocketAddress *addr,
diff --git a/qemu-options.hx b/qemu-options.hx
index 2485b94..edee5f4 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2724,13 +2724,18 @@ ETEXI
DEF("fw_cfg", HAS_ARG, QEMU_OPTION_fwcfg,
"-fw_cfg [name=]<name>,file=<file>\n"
- " add named fw_cfg entry from file\n",
+ " add named fw_cfg entry from file\n"
+ "-fw_cfg [name=]<name>,string=<str>\n"
+ " add named fw_cfg entry from string\n",
QEMU_ARCH_ALL)
STEXI
@item -fw_cfg [name=]@var{name},file=@var{file}
@findex -fw_cfg
Add named fw_cfg entry from file. @var{name} determines the name of
the entry in the fw_cfg file directory exposed to the guest.
+
+@item -fw_cfg [name=]@var{name},string=@var{str}
+Add named fw_cfg entry from string.
ETEXI
DEF("serial", HAS_ARG, QEMU_OPTION_serial, \
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index f9de0d3..80d034a 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -237,7 +237,8 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = {
{ SCMP_SYS(fadvise64), 240 },
{ SCMP_SYS(inotify_init1), 240 },
{ SCMP_SYS(inotify_add_watch), 240 },
- { SCMP_SYS(mbind), 240 }
+ { SCMP_SYS(mbind), 240 },
+ { SCMP_SYS(memfd_create), 240 }
};
int seccomp_start(void)
diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index 8aad4fe..50d9dd3 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -217,25 +217,24 @@ GIOStatus ga_channel_write_all(GAChannel *c, const gchar *buf, gsize size)
GIOStatus status = G_IO_STATUS_NORMAL;
while (size) {
+ g_debug("sending data, count: %d", (int)size);
status = g_io_channel_write_chars(c->client_channel, buf, size,
&written, &err);
- g_debug("sending data, count: %d", (int)size);
- if (err != NULL) {
+ if (status == G_IO_STATUS_NORMAL) {
+ size -= written;
+ buf += written;
+ } else if (status != G_IO_STATUS_AGAIN) {
g_warning("error writing to channel: %s", err->message);
- return G_IO_STATUS_ERROR;
- }
- if (status != G_IO_STATUS_NORMAL) {
- break;
+ return status;
}
- size -= written;
}
- if (status == G_IO_STATUS_NORMAL) {
+ do {
status = g_io_channel_flush(c->client_channel, &err);
- if (err != NULL) {
- g_warning("error flushing channel: %s", err->message);
- return G_IO_STATUS_ERROR;
- }
+ } while (status == G_IO_STATUS_AGAIN);
+
+ if (status != G_IO_STATUS_NORMAL) {
+ g_warning("error flushing channel: %s", err->message);
}
return status;
@@ -249,7 +248,7 @@ GIOStatus ga_channel_read(GAChannel *c, gchar *buf, gsize size, gsize *count)
GAChannel *ga_channel_new(GAChannelMethod method, const gchar *path,
GAChannelCallback cb, gpointer opaque)
{
- GAChannel *c = g_malloc0(sizeof(GAChannel));
+ GAChannel *c = g_new0(GAChannel, 1);
c->event_cb = cb;
c->user_data = opaque;
diff --git a/qga/channel-win32.c b/qga/channel-win32.c
index 04fa5e4..0452b9f 100644
--- a/qga/channel-win32.c
+++ b/qga/channel-win32.c
@@ -269,7 +269,7 @@ static GIOStatus ga_channel_write(GAChannel *c, const char *buf, size_t size,
GIOStatus ga_channel_write_all(GAChannel *c, const char *buf, size_t size)
{
GIOStatus status = G_IO_STATUS_NORMAL;
- size_t count;
+ size_t count = 0;
while (size) {
status = ga_channel_write(c, buf, size, &count);
@@ -322,7 +322,7 @@ static gboolean ga_channel_open(GAChannel *c, GAChannelMethod method,
GAChannel *ga_channel_new(GAChannelMethod method, const gchar *path,
GAChannelCallback cb, gpointer opaque)
{
- GAChannel *c = g_malloc0(sizeof(GAChannel));
+ GAChannel *c = g_new0(GAChannel, 1);
SECURITY_ATTRIBUTES sec_attrs;
if (!ga_channel_open(c, method, path)) {
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index b03c316..67a173a 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -223,7 +223,9 @@ typedef struct GuestFileHandle {
static struct {
QTAILQ_HEAD(, GuestFileHandle) filehandles;
-} guest_file_state;
+} guest_file_state = {
+ .filehandles = QTAILQ_HEAD_INITIALIZER(guest_file_state.filehandles),
+};
static int64_t guest_file_handle_add(FILE *fh, Error **errp)
{
@@ -235,7 +237,7 @@ static int64_t guest_file_handle_add(FILE *fh, Error **errp)
return -1;
}
- gfh = g_malloc0(sizeof(GuestFileHandle));
+ gfh = g_new0(GuestFileHandle, 1);
gfh->id = handle;
gfh->fh = fh;
QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
@@ -488,7 +490,7 @@ struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
slog("guest-file-read failed, handle: %" PRId64, handle);
} else {
buf[read_count] = 0;
- read_data = g_malloc0(sizeof(GuestFileRead));
+ read_data = g_new0(GuestFileRead, 1);
read_data->count = read_count;
read_data->eof = feof(fh);
if (read_count) {
@@ -533,7 +535,7 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
error_setg_errno(errp, errno, "failed to write to file");
slog("guest-file-write failed, handle: %" PRId64, handle);
} else {
- write_data = g_malloc0(sizeof(GuestFileWrite));
+ write_data = g_new0(GuestFileWrite, 1);
write_data->count = write_count;
write_data->eof = feof(fh);
}
@@ -586,11 +588,6 @@ void qmp_guest_file_flush(int64_t handle, Error **errp)
}
}
-static void guest_file_init(void)
-{
- QTAILQ_INIT(&guest_file_state.filehandles);
-}
-
/* linux-specific implementations. avoid this if at all possible. */
#if defined(__linux__)
@@ -678,7 +675,7 @@ static void build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp)
continue;
}
- mount = g_malloc0(sizeof(FsMount));
+ mount = g_new0(FsMount, 1);
mount->dirname = g_strdup(ment->mnt_dir);
mount->devtype = g_strdup(ment->mnt_type);
mount->devmajor = devmajor;
@@ -757,7 +754,7 @@ static void build_fs_mount_list(FsMountList *mounts, Error **errp)
}
}
- mount = g_malloc0(sizeof(FsMount));
+ mount = g_new0(FsMount, 1);
mount->dirname = g_strdup(line + dir_s);
mount->devtype = g_strdup(dash + type_s);
mount->devmajor = devmajor;
@@ -2213,8 +2210,14 @@ GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp)
dp = opendir("/sys/devices/system/memory/");
if (!dp) {
- error_setg_errno(errp, errno, "Can't open directory"
- "\"/sys/devices/system/memory/\"\n");
+ /* it's ok if this happens to be a system that doesn't expose
+ * memory blocks via sysfs, but otherwise we should report
+ * an error
+ */
+ if (errno != ENOENT) {
+ error_setg_errno(errp, errno, "Can't open directory"
+ "\"/sys/devices/system/memory/\"\n");
+ }
return NULL;
}
@@ -2486,5 +2489,4 @@ void ga_command_state_init(GAState *s, GACommandState *cs)
#if defined(CONFIG_FSFREEZE)
ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup);
#endif
- ga_command_state_add(cs, guest_file_init, NULL);
}
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 41bdd3f..d9de23b 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -55,7 +55,9 @@ typedef struct GuestFileHandle {
static struct {
QTAILQ_HEAD(, GuestFileHandle) filehandles;
-} guest_file_state;
+} guest_file_state = {
+ .filehandles = QTAILQ_HEAD_INITIALIZER(guest_file_state.filehandles),
+};
typedef struct OpenFlags {
@@ -106,7 +108,7 @@ static int64_t guest_file_handle_add(HANDLE fh, Error **errp)
if (handle < 0) {
return -1;
}
- gfh = g_malloc0(sizeof(GuestFileHandle));
+ gfh = g_new0(GuestFileHandle, 1);
gfh->id = handle;
gfh->fh = fh;
QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
@@ -298,7 +300,7 @@ GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
slog("guest-file-read failed, handle %" PRId64, handle);
} else {
buf[read_count] = 0;
- read_data = g_malloc0(sizeof(GuestFileRead));
+ read_data = g_new0(GuestFileRead, 1);
read_data->count = (size_t)read_count;
read_data->eof = read_count == 0;
@@ -342,7 +344,7 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
error_setg_win32(errp, GetLastError(), "failed to write to file");
slog("guest-file-write-failed, handle: %" PRId64, handle);
} else {
- write_data = g_malloc0(sizeof(GuestFileWrite));
+ write_data = g_new0(GuestFileWrite, 1);
write_data->count = (size_t) write_count;
}
@@ -390,11 +392,6 @@ void qmp_guest_file_flush(int64_t handle, Error **errp)
}
}
-static void guest_file_init(void)
-{
- QTAILQ_INIT(&guest_file_state.filehandles);
-}
-
#ifdef CONFIG_QGA_NTDDSCSI
static STORAGE_BUS_TYPE win2qemu[] = {
@@ -865,7 +862,7 @@ static DWORD WINAPI do_suspend(LPVOID opaque)
void qmp_guest_suspend_disk(Error **errp)
{
Error *local_err = NULL;
- GuestSuspendMode *mode = g_malloc(sizeof(GuestSuspendMode));
+ GuestSuspendMode *mode = g_new(GuestSuspendMode, 1);
*mode = GUEST_SUSPEND_MODE_DISK;
check_suspend_mode(*mode, &local_err);
@@ -881,7 +878,7 @@ void qmp_guest_suspend_disk(Error **errp)
void qmp_guest_suspend_ram(Error **errp)
{
Error *local_err = NULL;
- GuestSuspendMode *mode = g_malloc(sizeof(GuestSuspendMode));
+ GuestSuspendMode *mode = g_new(GuestSuspendMode, 1);
*mode = GUEST_SUSPEND_MODE_RAM;
check_suspend_mode(*mode, &local_err);
@@ -1330,5 +1327,4 @@ void ga_command_state_init(GAState *s, GACommandState *cs)
if (!vss_initialized()) {
ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup);
}
- ga_command_state_add(cs, guest_file_init, NULL);
}
diff --git a/qga/commands.c b/qga/commands.c
index 7834967..0f80ce6 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -15,6 +15,11 @@
#include "qga-qmp-commands.h"
#include "qapi/qmp/qerror.h"
+/* Maximum captured guest-exec out_data/err_data - 16MB */
+#define GUEST_EXEC_MAX_OUTPUT (16*1024*1024)
+/* Allocation and I/O buffer for reading guest-exec out_data/err_data - 4KB */
+#define GUEST_EXEC_IO_SIZE (4*1024)
+
/* Note: in some situations, like with the fsfreeze, logging may be
* temporarilly disabled. if it is necessary that a command be able
* to log for accounting purposes, check ga_logging_enabled() beforehand,
@@ -51,12 +56,12 @@ static void qmp_command_info(QmpCommand *cmd, void *opaque)
GuestAgentCommandInfo *cmd_info;
GuestAgentCommandInfoList *cmd_info_list;
- cmd_info = g_malloc0(sizeof(GuestAgentCommandInfo));
+ cmd_info = g_new0(GuestAgentCommandInfo, 1);
cmd_info->name = g_strdup(qmp_command_name(cmd));
cmd_info->enabled = qmp_command_is_enabled(cmd);
cmd_info->success_response = qmp_has_success_response(cmd);
- cmd_info_list = g_malloc0(sizeof(GuestAgentCommandInfoList));
+ cmd_info_list = g_new0(GuestAgentCommandInfoList, 1);
cmd_info_list->value = cmd_info;
cmd_info_list->next = info->supported_commands;
info->supported_commands = cmd_info_list;
@@ -64,9 +69,392 @@ static void qmp_command_info(QmpCommand *cmd, void *opaque)
struct GuestAgentInfo *qmp_guest_info(Error **errp)
{
- GuestAgentInfo *info = g_malloc0(sizeof(GuestAgentInfo));
+ GuestAgentInfo *info = g_new0(GuestAgentInfo, 1);
info->version = g_strdup(QEMU_VERSION);
qmp_for_each_command(qmp_command_info, info);
return info;
}
+
+struct GuestExecIOData {
+ guchar *data;
+ gsize size;
+ gsize length;
+ gint closed;
+ bool truncated;
+ const char *name;
+};
+typedef struct GuestExecIOData GuestExecIOData;
+
+struct GuestExecInfo {
+ GPid pid;
+ int64_t pid_numeric;
+ gint status;
+ bool has_output;
+ gint finished;
+ GuestExecIOData in;
+ GuestExecIOData out;
+ GuestExecIOData err;
+ QTAILQ_ENTRY(GuestExecInfo) next;
+};
+typedef struct GuestExecInfo GuestExecInfo;
+
+static struct {
+ QTAILQ_HEAD(, GuestExecInfo) processes;
+} guest_exec_state = {
+ .processes = QTAILQ_HEAD_INITIALIZER(guest_exec_state.processes),
+};
+
+static int64_t gpid_to_int64(GPid pid)
+{
+#ifdef G_OS_WIN32
+ return GetProcessId(pid);
+#else
+ return (int64_t)pid;
+#endif
+}
+
+static GuestExecInfo *guest_exec_info_add(GPid pid)
+{
+ GuestExecInfo *gei;
+
+ gei = g_new0(GuestExecInfo, 1);
+ gei->pid = pid;
+ gei->pid_numeric = gpid_to_int64(pid);
+ QTAILQ_INSERT_TAIL(&guest_exec_state.processes, gei, next);
+
+ return gei;
+}
+
+static GuestExecInfo *guest_exec_info_find(int64_t pid_numeric)
+{
+ GuestExecInfo *gei;
+
+ QTAILQ_FOREACH(gei, &guest_exec_state.processes, next) {
+ if (gei->pid_numeric == pid_numeric) {
+ return gei;
+ }
+ }
+
+ return NULL;
+}
+
+GuestExecStatus *qmp_guest_exec_status(int64_t pid, Error **err)
+{
+ GuestExecInfo *gei;
+ GuestExecStatus *ges;
+
+ slog("guest-exec-status called, pid: %u", (uint32_t)pid);
+
+ gei = guest_exec_info_find(pid);
+ if (gei == NULL) {
+ error_setg(err, QERR_INVALID_PARAMETER, "pid");
+ return NULL;
+ }
+
+ ges = g_new0(GuestExecStatus, 1);
+
+ bool finished = g_atomic_int_get(&gei->finished);
+
+ /* need to wait till output channels are closed
+ * to be sure we captured all output at this point */
+ if (gei->has_output) {
+ finished = finished && g_atomic_int_get(&gei->out.closed);
+ finished = finished && g_atomic_int_get(&gei->err.closed);
+ }
+
+ ges->exited = finished;
+ if (finished) {
+ /* Glib has no portable way to parse exit status.
+ * On UNIX, we can get either exit code from normal termination
+ * or signal number.
+ * On Windows, it is either the same exit code or the exception
+ * value for an unhandled exception that caused the process
+ * to terminate.
+ * See MSDN for GetExitCodeProcess() and ntstatus.h for possible
+ * well-known codes, e.g. C0000005 ACCESS_DENIED - analog of SIGSEGV
+ * References:
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms683189(v=vs.85).aspx
+ * https://msdn.microsoft.com/en-us/library/aa260331(v=vs.60).aspx
+ */
+#ifdef G_OS_WIN32
+ /* Additionally WIN32 does not provide any additional information
+ * on whetherthe child exited or terminated via signal.
+ * We use this simple range check to distingish application exit code
+ * (usually value less then 256) and unhandled exception code with
+ * ntstatus (always value greater then 0xC0000005). */
+ if ((uint32_t)gei->status < 0xC0000000U) {
+ ges->has_exitcode = true;
+ ges->exitcode = gei->status;
+ } else {
+ ges->has_signal = true;
+ ges->signal = gei->status;
+ }
+#else
+ if (WIFEXITED(gei->status)) {
+ ges->has_exitcode = true;
+ ges->exitcode = WEXITSTATUS(gei->status);
+ } else if (WIFSIGNALED(gei->status)) {
+ ges->has_signal = true;
+ ges->signal = WTERMSIG(gei->status);
+ }
+#endif
+ if (gei->out.length > 0) {
+ ges->has_out_data = true;
+ ges->out_data = g_base64_encode(gei->out.data, gei->out.length);
+ g_free(gei->out.data);
+ ges->has_out_truncated = gei->out.truncated;
+ }
+
+ if (gei->err.length > 0) {
+ ges->has_err_data = true;
+ ges->err_data = g_base64_encode(gei->err.data, gei->err.length);
+ g_free(gei->err.data);
+ ges->has_err_truncated = gei->err.truncated;
+ }
+
+ QTAILQ_REMOVE(&guest_exec_state.processes, gei, next);
+ g_free(gei);
+ }
+
+ return ges;
+}
+
+/* Get environment variables or arguments array for execve(). */
+static char **guest_exec_get_args(const strList *entry, bool log)
+{
+ const strList *it;
+ int count = 1, i = 0; /* reserve for NULL terminator */
+ char **args;
+ char *str; /* for logging array of arguments */
+ size_t str_size = 1;
+
+ for (it = entry; it != NULL; it = it->next) {
+ count++;
+ str_size += 1 + strlen(it->value);
+ }
+
+ str = g_malloc(str_size);
+ *str = 0;
+ args = g_malloc(count * sizeof(char *));
+ for (it = entry; it != NULL; it = it->next) {
+ args[i++] = it->value;
+ pstrcat(str, str_size, it->value);
+ if (it->next) {
+ pstrcat(str, str_size, " ");
+ }
+ }
+ args[i] = NULL;
+
+ if (log) {
+ slog("guest-exec called: \"%s\"", str);
+ }
+ g_free(str);
+
+ return args;
+}
+
+static void guest_exec_child_watch(GPid pid, gint status, gpointer data)
+{
+ GuestExecInfo *gei = (GuestExecInfo *)data;
+
+ g_debug("guest_exec_child_watch called, pid: %d, status: %u",
+ (int32_t)gpid_to_int64(pid), (uint32_t)status);
+
+ gei->status = status;
+ gei->finished = true;
+
+ g_spawn_close_pid(pid);
+}
+
+/** Reset ignored signals back to default. */
+static void guest_exec_task_setup(gpointer data)
+{
+#if !defined(G_OS_WIN32)
+ struct sigaction sigact;
+
+ memset(&sigact, 0, sizeof(struct sigaction));
+ sigact.sa_handler = SIG_DFL;
+
+ if (sigaction(SIGPIPE, &sigact, NULL) != 0) {
+ slog("sigaction() failed to reset child process's SIGPIPE: %s",
+ strerror(errno));
+ }
+#endif
+}
+
+static gboolean guest_exec_input_watch(GIOChannel *ch,
+ GIOCondition cond, gpointer p_)
+{
+ GuestExecIOData *p = (GuestExecIOData *)p_;
+ gsize bytes_written = 0;
+ GIOStatus status;
+ GError *gerr = NULL;
+
+ /* nothing left to write */
+ if (p->size == p->length) {
+ goto done;
+ }
+
+ status = g_io_channel_write_chars(ch, (gchar *)p->data + p->length,
+ p->size - p->length, &bytes_written, &gerr);
+
+ /* can be not 0 even if not G_IO_STATUS_NORMAL */
+ if (bytes_written != 0) {
+ p->length += bytes_written;
+ }
+
+ /* continue write, our callback will be called again */
+ if (status == G_IO_STATUS_NORMAL || status == G_IO_STATUS_AGAIN) {
+ return true;
+ }
+
+ if (gerr) {
+ g_warning("qga: i/o error writing to input_data channel: %s",
+ gerr->message);
+ g_error_free(gerr);
+ }
+
+done:
+ g_io_channel_shutdown(ch, true, NULL);
+ g_io_channel_unref(ch);
+ g_atomic_int_set(&p->closed, 1);
+ g_free(p->data);
+
+ return false;
+}
+
+static gboolean guest_exec_output_watch(GIOChannel *ch,
+ GIOCondition cond, gpointer p_)
+{
+ GuestExecIOData *p = (GuestExecIOData *)p_;
+ gsize bytes_read;
+ GIOStatus gstatus;
+
+ if (cond == G_IO_HUP || cond == G_IO_ERR) {
+ goto close;
+ }
+
+ if (p->size == p->length) {
+ gpointer t = NULL;
+ if (!p->truncated && p->size < GUEST_EXEC_MAX_OUTPUT) {
+ t = g_try_realloc(p->data, p->size + GUEST_EXEC_IO_SIZE);
+ }
+ if (t == NULL) {
+ /* ignore truncated output */
+ gchar buf[GUEST_EXEC_IO_SIZE];
+
+ p->truncated = true;
+ gstatus = g_io_channel_read_chars(ch, buf, sizeof(buf),
+ &bytes_read, NULL);
+ if (gstatus == G_IO_STATUS_EOF || gstatus == G_IO_STATUS_ERROR) {
+ goto close;
+ }
+
+ return true;
+ }
+ p->size += GUEST_EXEC_IO_SIZE;
+ p->data = t;
+ }
+
+ /* Calling read API once.
+ * On next available data our callback will be called again */
+ gstatus = g_io_channel_read_chars(ch, (gchar *)p->data + p->length,
+ p->size - p->length, &bytes_read, NULL);
+ if (gstatus == G_IO_STATUS_EOF || gstatus == G_IO_STATUS_ERROR) {
+ goto close;
+ }
+
+ p->length += bytes_read;
+
+ return true;
+
+close:
+ g_io_channel_unref(ch);
+ g_atomic_int_set(&p->closed, 1);
+ return false;
+}
+
+GuestExec *qmp_guest_exec(const char *path,
+ bool has_arg, strList *arg,
+ bool has_env, strList *env,
+ bool has_input_data, const char *input_data,
+ bool has_capture_output, bool capture_output,
+ Error **err)
+{
+ GPid pid;
+ GuestExec *ge = NULL;
+ GuestExecInfo *gei;
+ char **argv, **envp;
+ strList arglist;
+ gboolean ret;
+ GError *gerr = NULL;
+ gint in_fd, out_fd, err_fd;
+ GIOChannel *in_ch, *out_ch, *err_ch;
+ GSpawnFlags flags;
+ bool has_output = (has_capture_output && capture_output);
+
+ arglist.value = (char *)path;
+ arglist.next = has_arg ? arg : NULL;
+
+ argv = guest_exec_get_args(&arglist, true);
+ envp = guest_exec_get_args(has_env ? env : NULL, false);
+
+ flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD;
+ if (!has_output) {
+ flags |= G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL;
+ }
+
+ ret = g_spawn_async_with_pipes(NULL, argv, envp, flags,
+ guest_exec_task_setup, NULL, &pid, has_input_data ? &in_fd : NULL,
+ has_output ? &out_fd : NULL, has_output ? &err_fd : NULL, &gerr);
+ if (!ret) {
+ error_setg(err, QERR_QGA_COMMAND_FAILED, gerr->message);
+ g_error_free(gerr);
+ goto done;
+ }
+
+ ge = g_new0(GuestExec, 1);
+ ge->pid = gpid_to_int64(pid);
+
+ gei = guest_exec_info_add(pid);
+ gei->has_output = has_output;
+ g_child_watch_add(pid, guest_exec_child_watch, gei);
+
+ if (has_input_data) {
+ gei->in.data = g_base64_decode(input_data, &gei->in.size);
+#ifdef G_OS_WIN32
+ in_ch = g_io_channel_win32_new_fd(in_fd);
+#else
+ in_ch = g_io_channel_unix_new(in_fd);
+#endif
+ g_io_channel_set_encoding(in_ch, NULL, NULL);
+ g_io_channel_set_buffered(in_ch, false);
+ g_io_channel_set_flags(in_ch, G_IO_FLAG_NONBLOCK, NULL);
+ g_io_add_watch(in_ch, G_IO_OUT, guest_exec_input_watch, &gei->in);
+ }
+
+ if (has_output) {
+#ifdef G_OS_WIN32
+ out_ch = g_io_channel_win32_new_fd(out_fd);
+ err_ch = g_io_channel_win32_new_fd(err_fd);
+#else
+ out_ch = g_io_channel_unix_new(out_fd);
+ err_ch = g_io_channel_unix_new(err_fd);
+#endif
+ g_io_channel_set_encoding(out_ch, NULL, NULL);
+ g_io_channel_set_encoding(err_ch, NULL, NULL);
+ g_io_channel_set_buffered(out_ch, false);
+ g_io_channel_set_buffered(err_ch, false);
+ g_io_add_watch(out_ch, G_IO_IN | G_IO_HUP,
+ guest_exec_output_watch, &gei->out);
+ g_io_add_watch(err_ch, G_IO_IN | G_IO_HUP,
+ guest_exec_output_watch, &gei->err);
+ }
+
+done:
+ g_free(argv);
+ g_free(envp);
+
+ return ge;
+}
diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c
index 969da23..128c549 100644
--- a/qga/guest-agent-command-state.c
+++ b/qga/guest-agent-command-state.c
@@ -27,7 +27,7 @@ void ga_command_state_add(GACommandState *cs,
void (*init)(void),
void (*cleanup)(void))
{
- GACommandGroup *cg = g_malloc0(sizeof(GACommandGroup));
+ GACommandGroup *cg = g_new0(GACommandGroup, 1);
cg->init = init;
cg->cleanup = cleanup;
cs->groups = g_slist_append(cs->groups, cg);
@@ -67,7 +67,7 @@ void ga_command_state_cleanup_all(GACommandState *cs)
GACommandState *ga_command_state_new(void)
{
- GACommandState *cs = g_malloc0(sizeof(GACommandState));
+ GACommandState *cs = g_new0(GACommandState, 1);
cs->groups = NULL;
return cs;
}
diff --git a/qga/main.c b/qga/main.c
index d8e063a..068169f 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -161,6 +161,12 @@ static gboolean register_signal_handlers(void)
g_error("error configuring signal handler: %s", strerror(errno));
}
+ sigact.sa_handler = SIG_IGN;
+ if (sigaction(SIGPIPE, &sigact, NULL) != 0) {
+ g_error("error configuring SIGPIPE signal handler: %s",
+ strerror(errno));
+ }
+
return true;
}
@@ -945,10 +951,11 @@ static void config_load(GAConfig *config)
{
GError *gerr = NULL;
GKeyFile *keyfile;
+ const char *conf = g_getenv("QGA_CONF") ?: QGA_CONF_DEFAULT;
/* read system config */
keyfile = g_key_file_new();
- if (!g_key_file_load_from_file(keyfile, QGA_CONF_DEFAULT, 0, &gerr)) {
+ if (!g_key_file_load_from_file(keyfile, conf, 0, &gerr)) {
goto end;
}
if (g_key_file_has_key(keyfile, "general", "daemon", NULL)) {
@@ -1082,8 +1089,6 @@ static void config_parse(GAConfig *config, int argc, char **argv)
{ NULL, 0, NULL, 0 }
};
- config->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;
-
while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
switch (ch) {
case 'm':
@@ -1331,6 +1336,8 @@ int main(int argc, char **argv)
GAState *s = g_new0(GAState, 1);
GAConfig *config = g_new0(GAConfig, 1);
+ config->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;
+
module_call_init(MODULE_INIT_QAPI);
init_dfl_pathnames();
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 82894c6..78362e0 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -930,3 +930,70 @@
##
{ 'command': 'guest-get-memory-block-info',
'returns': 'GuestMemoryBlockInfo' }
+
+# @GuestExecStatus:
+#
+# @exited: true if process has already terminated.
+# @exitcode: #optional process exit code if it was normally terminated.
+# @signal: #optional signal number (linux) or unhandled exception code
+# (windows) if the process was abnormally terminated.
+# @out-data: #optional base64-encoded stdout of the process
+# @err-data: #optional base64-encoded stderr of the process
+# Note: @out-data and @err-data are present only
+# if 'capture-output' was specified for 'guest-exec'
+# @out-truncated: #optional true if stdout was not fully captured
+# due to size limitation.
+# @err-truncated: #optional true if stderr was not fully captured
+# due to size limitation.
+#
+# Since: 2.5
+##
+{ 'struct': 'GuestExecStatus',
+ 'data': { 'exited': 'bool', '*exitcode': 'int', '*signal': 'int',
+ '*out-data': 'str', '*err-data': 'str',
+ '*out-truncated': 'bool', '*err-truncated': 'bool' }}
+##
+# @guest-exec-status
+#
+# Check status of process associated with PID retrieved via guest-exec.
+# Reap the process and associated metadata if it has exited.
+#
+# @pid: pid returned from guest-exec
+#
+# Returns: GuestExecStatus on success.
+#
+# Since 2.5
+##
+{ 'command': 'guest-exec-status',
+ 'data': { 'pid': 'int' },
+ 'returns': 'GuestExecStatus' }
+
+##
+# @GuestExec:
+# @pid: pid of child process in guest OS
+#
+#Since: 2.5
+##
+{ 'struct': 'GuestExec',
+ 'data': { 'pid': 'int'} }
+
+##
+# @guest-exec:
+#
+# Execute a command in the guest
+#
+# @path: path or executable name to execute
+# @arg: #optional argument list to pass to executable
+# @env: #optional environment variables to pass to executable
+# @input-data: #optional data to be passed to process stdin (base64 encoded)
+# @capture-output: #optional bool flag to enable capture of
+# stdout/stderr of running process. defaults to false.
+#
+# Returns: PID on success.
+#
+# Since: 2.5
+##
+{ 'command': 'guest-exec',
+ 'data': { 'path': 'str', '*arg': ['str'], '*env': ['str'],
+ '*input-data': 'str', '*capture-output': 'bool' },
+ 'returns': 'GuestExec' }
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 457ef37..096d090 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -69,7 +69,7 @@ for arch in $ARCHLIST; do
fi
# Blacklist architectures which have KVM headers but are actually dead
- if [ "$arch" = "ia64" ]; then
+ if [ "$arch" = "ia64" -o "$arch" = "mips" ]; then
continue
fi
@@ -77,7 +77,7 @@ for arch in $ARCHLIST; do
rm -rf "$output/linux-headers/asm-$arch"
mkdir -p "$output/linux-headers/asm-$arch"
- for header in kvm.h kvm_para.h; do
+ for header in kvm.h kvm_para.h unistd.h; do
cp "$tmpdir/include/asm/$header" "$output/linux-headers/asm-$arch"
done
if [ $arch = powerpc ]; then
@@ -92,6 +92,9 @@ for arch in $ARCHLIST; do
fi
if [ $arch = x86 ]; then
cp_portable "$tmpdir/include/asm/hyperv.h" "$output/include/standard-headers/asm-x86/"
+ cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/"
+ cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/"
+ cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/"
fi
done
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 1862f84..251443b 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -34,3 +34,4 @@ stub-obj-y += cpus.o
stub-obj-y += kvm.o
stub-obj-y += qmp_pc_dimm_device_list.o
stub-obj-y += target-monitor-defs.o
+stub-obj-y += vhost.o
diff --git a/stubs/vhost.c b/stubs/vhost.c
new file mode 100644
index 0000000..d346b85
--- /dev/null
+++ b/stubs/vhost.c
@@ -0,0 +1,6 @@
+#include "hw/virtio/vhost.h"
+
+bool vhost_has_free_slot(void)
+{
+ return true;
+}
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index ff1926a..e5bdfa8 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -46,6 +46,12 @@ static bool alpha_cpu_has_work(CPUState *cs)
| CPU_INTERRUPT_MCHK);
}
+static void alpha_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
+{
+ info->mach = bfd_mach_alpha_ev6;
+ info->print_insn = print_insn_alpha;
+}
+
static void alpha_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -297,6 +303,8 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
dc->vmsd = &vmstate_alpha_cpu;
#endif
+ cc->disas_set_info = alpha_cpu_disas_set_info;
+
cc->gdb_num_core_regs = 67;
/*
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index d0ab278..0bc544c 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -131,6 +131,12 @@ static void lm32_cpu_reset(CPUState *s)
tlb_flush(s, 1);
}
+static void lm32_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
+{
+ info->mach = bfd_mach_lm32;
+ info->print_insn = print_insn_lm32;
+}
+
static void lm32_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -275,6 +281,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_num_core_regs = 32 + 7;
cc->gdb_stop_before_watchpoint = true;
cc->debug_excp_handler = lm32_debug_excp_handler;
+ cc->disas_set_info = lm32_cpu_disas_set_info;
/*
* Reason: lm32_cpu_initfn() calls cpu_exec_init(), which saves
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 97527ef..e8a4eed 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -61,6 +61,11 @@ static void m68k_cpu_reset(CPUState *s)
tlb_flush(s, 1);
}
+static void m68k_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
+{
+ info->print_insn = print_insn_m68k;
+}
+
/* CPU models */
static ObjectClass *m68k_cpu_class_by_name(const char *cpu_model)
@@ -208,11 +213,13 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
#endif
cc->cpu_exec_enter = m68k_cpu_exec_enter;
cc->cpu_exec_exit = m68k_cpu_exec_exit;
+ cc->disas_set_info = m68k_cpu_disas_set_info;
- dc->vmsd = &vmstate_m68k_cpu;
cc->gdb_num_core_regs = 18;
cc->gdb_core_xml_file = "cf-core.xml";
+ dc->vmsd = &vmstate_m68k_cpu;
+
/*
* Reason: m68k_cpu_initfn() calls cpu_exec_init(), which saves
* the object in cpus -> dangling pointer after final
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 7fe1f04..37880d2 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -97,6 +97,14 @@ static void mips_cpu_reset(CPUState *s)
#endif
}
+static void mips_cpu_disas_set_info(CPUState *s, disassemble_info *info) {
+#ifdef TARGET_WORDS_BIGENDIAN
+ info->print_insn = print_insn_big_mips;
+#else
+ info->print_insn = print_insn_little_mips;
+#endif
+}
+
static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -150,6 +158,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
cc->vmsd = &vmstate_mips_cpu;
#endif
+ cc->disas_set_info = mips_cpu_disas_set_info;
cc->gdb_num_core_regs = 73;
cc->gdb_stop_before_watchpoint = true;
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index 3af3779..0c60c65 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -48,6 +48,12 @@ static void moxie_cpu_reset(CPUState *s)
tlb_flush(s, 1);
}
+static void moxie_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
+{
+ info->mach = bfd_arch_moxie;
+ info->print_insn = print_insn_moxie;
+}
+
static void moxie_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -114,6 +120,7 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
cc->vmsd = &vmstate_moxie_cpu;
#endif
+ cc->disas_set_info = moxie_cpu_disas_set_info;
/*
* Reason: moxie_cpu_initfn() calls cpu_exec_init(), which saves
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index ccfaa8a..189a2af 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -184,6 +184,12 @@ static void s390_cpu_machine_reset_cb(void *opaque)
}
#endif
+static void s390_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
+{
+ info->mach = bfd_mach_s390_64;
+ info->print_insn = print_insn_s390;
+}
+
static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
@@ -351,6 +357,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
#endif
+ cc->disas_set_info = s390_cpu_disas_set_info;
+
cc->gdb_num_core_regs = S390_NUM_CORE_REGS;
cc->gdb_core_xml_file = "s390x-core64.xml";
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index e4de863..658cd9d 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1160,12 +1160,13 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
int vq, bool assign);
int kvm_s390_cpu_restart(S390CPU *cpu);
int kvm_s390_get_memslot_count(KVMState *s);
-void kvm_s390_clear_cmma_callback(void *opaque);
+void kvm_s390_cmma_reset(void);
int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
void kvm_s390_reset_vcpu(S390CPU *cpu);
int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit);
void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu);
+void kvm_s390_crypto_reset(void);
#else
static inline void kvm_s390_io_interrupt(uint16_t subchannel_id,
uint16_t subchannel_nr,
@@ -1189,7 +1190,7 @@ static inline int kvm_s390_cpu_restart(S390CPU *cpu)
{
return -ENOSYS;
}
-static inline void kvm_s390_clear_cmma_callback(void *opaque)
+static inline void kvm_s390_cmma_reset(void)
{
}
static inline int kvm_s390_get_memslot_count(KVMState *s)
@@ -1215,6 +1216,9 @@ static inline int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu)
{
return 0;
}
+static inline void kvm_s390_crypto_reset(void)
+{
+}
#endif
static inline int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit)
@@ -1225,11 +1229,10 @@ static inline int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit)
return 0;
}
-static inline void cmma_reset(S390CPU *cpu)
+static inline void s390_cmma_reset(void)
{
if (kvm_enabled()) {
- CPUState *cs = CPU(cpu);
- kvm_s390_clear_cmma_callback(cs->kvm_state);
+ kvm_s390_cmma_reset();
}
}
@@ -1261,6 +1264,13 @@ static inline int s390_assign_subch_ioeventfd(EventNotifier *notifier,
return kvm_s390_assign_subch_ioeventfd(notifier, sch_id, vq, assign);
}
+static inline void s390_crypto_reset(void)
+{
+ if (kvm_enabled()) {
+ kvm_s390_crypto_reset();
+ }
+}
+
#ifdef CONFIG_KVM
static inline bool vregs_needed(void *opaque)
{
@@ -1275,4 +1285,49 @@ static inline bool vregs_needed(void *opaque)
return 0;
}
#endif
+
+/* machine check interruption code */
+
+/* subclasses */
+#define MCIC_SC_SD 0x8000000000000000ULL
+#define MCIC_SC_PD 0x4000000000000000ULL
+#define MCIC_SC_SR 0x2000000000000000ULL
+#define MCIC_SC_CD 0x0800000000000000ULL
+#define MCIC_SC_ED 0x0400000000000000ULL
+#define MCIC_SC_DG 0x0100000000000000ULL
+#define MCIC_SC_W 0x0080000000000000ULL
+#define MCIC_SC_CP 0x0040000000000000ULL
+#define MCIC_SC_SP 0x0020000000000000ULL
+#define MCIC_SC_CK 0x0010000000000000ULL
+
+/* subclass modifiers */
+#define MCIC_SCM_B 0x0002000000000000ULL
+#define MCIC_SCM_DA 0x0000000020000000ULL
+#define MCIC_SCM_AP 0x0000000000080000ULL
+
+/* storage errors */
+#define MCIC_SE_SE 0x0000800000000000ULL
+#define MCIC_SE_SC 0x0000400000000000ULL
+#define MCIC_SE_KE 0x0000200000000000ULL
+#define MCIC_SE_DS 0x0000100000000000ULL
+#define MCIC_SE_IE 0x0000000080000000ULL
+
+/* validity bits */
+#define MCIC_VB_WP 0x0000080000000000ULL
+#define MCIC_VB_MS 0x0000040000000000ULL
+#define MCIC_VB_PM 0x0000020000000000ULL
+#define MCIC_VB_IA 0x0000010000000000ULL
+#define MCIC_VB_FA 0x0000008000000000ULL
+#define MCIC_VB_VR 0x0000004000000000ULL
+#define MCIC_VB_EC 0x0000002000000000ULL
+#define MCIC_VB_FP 0x0000001000000000ULL
+#define MCIC_VB_GR 0x0000000800000000ULL
+#define MCIC_VB_CR 0x0000000400000000ULL
+#define MCIC_VB_ST 0x0000000100000000ULL
+#define MCIC_VB_AR 0x0000000040000000ULL
+#define MCIC_VB_PR 0x0000000000200000ULL
+#define MCIC_VB_FC 0x0000000000100000ULL
+#define MCIC_VB_CT 0x0000000000020000ULL
+#define MCIC_VB_CC 0x0000000000010000ULL
+
#endif
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 0305ffa..c3be180 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -173,16 +173,15 @@ int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit)
return kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr);
}
-void kvm_s390_clear_cmma_callback(void *opaque)
+void kvm_s390_cmma_reset(void)
{
int rc;
- KVMState *s = opaque;
struct kvm_device_attr attr = {
.group = KVM_S390_VM_MEM_CTRL,
.attr = KVM_S390_VM_MEM_CLR_CMMA,
};
- rc = kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr);
+ rc = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
trace_kvm_clear_cmma(rc);
}
@@ -200,9 +199,6 @@ static void kvm_s390_enable_cmma(KVMState *s)
}
rc = kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr);
- if (!rc) {
- qemu_register_reset(kvm_s390_clear_cmma_callback, s);
- }
trace_kvm_enable_cmma(rc);
}
@@ -249,7 +245,7 @@ static void kvm_s390_init_dea_kw(void)
}
}
-static void kvm_s390_init_crypto(void)
+void kvm_s390_crypto_reset(void)
{
kvm_s390_init_aes_kw();
kvm_s390_init_dea_kw();
@@ -301,8 +297,6 @@ void kvm_s390_reset_vcpu(S390CPU *cpu)
if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL)) {
error_report("Initial CPU reset failed on CPU %i", cs->cpu_index);
}
-
- kvm_s390_init_crypto();
}
static int can_sync_regs(CPUState *cs, int regs)
@@ -2065,12 +2059,30 @@ void kvm_s390_io_interrupt(uint16_t subchannel_id,
kvm_s390_floating_interrupt(&irq);
}
+static uint64_t build_channel_report_mcic(void)
+{
+ uint64_t mcic;
+
+ /* subclass: indicate channel report pending */
+ mcic = MCIC_SC_CP |
+ /* subclass modifiers: none */
+ /* storage errors: none */
+ /* validity bits: no damage */
+ MCIC_VB_WP | MCIC_VB_MS | MCIC_VB_PM | MCIC_VB_IA | MCIC_VB_FP |
+ MCIC_VB_GR | MCIC_VB_CR | MCIC_VB_ST | MCIC_VB_AR | MCIC_VB_PR |
+ MCIC_VB_FC | MCIC_VB_CT | MCIC_VB_CC;
+ if (kvm_check_extension(kvm_state, KVM_CAP_S390_VECTOR_REGISTERS)) {
+ mcic |= MCIC_VB_VR;
+ }
+ return mcic;
+}
+
void kvm_s390_crw_mchk(void)
{
struct kvm_s390_irq irq = {
.type = KVM_S390_MCHK,
.u.mchk.cr14 = 1 << 28,
- .u.mchk.mcic = 0x00400f1d40330000ULL,
+ .u.mchk.mcic = build_channel_report_mcic(),
};
kvm_s390_floating_interrupt(&irq);
}
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 3a19e32..b601a33 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -127,8 +127,9 @@ static int modified_clear_reset(S390CPU *cpu)
CPU_FOREACH(t) {
run_on_cpu(t, s390_do_cpu_full_reset, t);
}
- cmma_reset(cpu);
+ s390_cmma_reset();
subsystem_reset();
+ s390_crypto_reset();
scc->load_normal(CPU(cpu));
cpu_synchronize_all_post_reset();
resume_all_vcpus();
@@ -145,7 +146,7 @@ static int load_normal_reset(S390CPU *cpu)
CPU_FOREACH(t) {
run_on_cpu(t, s390_do_cpu_reset, t);
}
- cmma_reset(cpu);
+ s390_cmma_reset();
subsystem_reset();
scc->initial_cpu_reset(CPU(cpu));
scc->load_normal(CPU(cpu));
@@ -233,11 +234,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
}
iplb = g_malloc0(sizeof(struct IplParameterBlock));
cpu_physical_memory_read(addr, iplb, sizeof(struct IplParameterBlock));
- if (!s390_ipl_update_diag308(iplb)) {
- env->regs[r1 + 1] = DIAG_308_RC_OK;
- } else {
- env->regs[r1 + 1] = DIAG_308_RC_INVALID;
- }
+ s390_ipl_update_diag308(iplb);
+ env->regs[r1 + 1] = DIAG_308_RC_OK;
g_free(iplb);
return;
case 6:
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 64e4467..d7e2fbd 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -70,6 +70,12 @@ static void superh_cpu_reset(CPUState *s)
set_default_nan_mode(1, &env->fp_status);
}
+static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
+{
+ info->mach = bfd_mach_sh4;
+ info->print_insn = print_insn_sh;
+}
+
typedef struct SuperHCPUListState {
fprintf_function cpu_fprintf;
FILE *file;
@@ -288,9 +294,12 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
#else
cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
#endif
- dc->vmsd = &vmstate_sh_cpu;
+ cc->disas_set_info = superh_cpu_disas_set_info;
+
cc->gdb_num_core_regs = 59;
+ dc->vmsd = &vmstate_sh_cpu;
+
/*
* Reason: superh_cpu_initfn() calls cpu_exec_init(), which saves
* the object in cpus -> dangling pointer after final
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 82bb72a..d98682b 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -90,6 +90,14 @@ static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return false;
}
+static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info)
+{
+ info->print_insn = print_insn_sparc;
+#ifdef TARGET_SPARC64
+ info->mach = bfd_mach_sparc_v9b;
+#endif
+}
+
static int cpu_sparc_register(SPARCCPU *cpu, const char *cpu_model)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
@@ -848,6 +856,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
cc->do_unaligned_access = sparc_cpu_do_unaligned_access;
cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
#endif
+ cc->disas_set_info = cpu_sparc_disas_set_info;
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
cc->gdb_num_core_regs = 86;
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 006bcb7..15ce010 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -64,6 +64,7 @@ enum {
XTENSA_OPTION_MP_SYNCHRO,
XTENSA_OPTION_CONDITIONAL_STORE,
XTENSA_OPTION_ATOMCTL,
+ XTENSA_OPTION_DEPBITS,
/* Interrupts and exceptions */
XTENSA_OPTION_EXCEPTION,
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 76be50d..2c3447b 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -541,8 +541,8 @@ static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,
wi = ++env->autorefill_idx & 0x3;
xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte);
env->sregs[EXCVADDR] = vaddr;
- qemu_log("%s: autorefill(%08x): %08x -> %08x\n",
- __func__, vaddr, vpn, pte);
+ qemu_log_mask(CPU_LOG_MMU, "%s: autorefill(%08x): %08x -> %08x\n",
+ __func__, vaddr, vpn, pte);
} else {
xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte);
entry = &tmp_entry;
@@ -590,8 +590,8 @@ static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte)
int ret = get_physical_addr_mmu(env, false, pt_vaddr, 0, 0,
&paddr, &page_size, &access, false);
- qemu_log("%s: trying autorefill(%08x) -> %08x\n", __func__,
- vaddr, ret ? ~0 : paddr);
+ qemu_log_mask(CPU_LOG_MMU, "%s: trying autorefill(%08x) -> %08x\n",
+ __func__, vaddr, ret ? ~0 : paddr);
if (ret == 0) {
*pte = ldl_phys(cs->as, paddr);
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index be657e6..718e54e 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -57,8 +57,8 @@ void tlb_fill(CPUState *cs,
int ret = xtensa_get_physical_addr(env, true, vaddr, is_write, mmu_idx,
&paddr, &page_size, &access);
- qemu_log("%s(%08x, %d, %d) -> %08x, ret = %d\n", __func__,
- vaddr, is_write, mmu_idx, paddr, ret);
+ qemu_log_mask(CPU_LOG_MMU, "%s(%08x, %d, %d) -> %08x, ret = %d\n",
+ __func__, vaddr, is_write, mmu_idx, paddr, ret);
if (ret == 0) {
tlb_set_page(cs,
diff --git a/target-xtensa/overlay_tool.h b/target-xtensa/overlay_tool.h
index eda03aa..e8a7fda 100644
--- a/target-xtensa/overlay_tool.h
+++ b/target-xtensa/overlay_tool.h
@@ -30,6 +30,10 @@
{ .targno = (no), .type = (typ), .group = (grp), .size = (sz) },
#define XTREG_END { .targno = -1 },
+#ifndef XCHAL_HAVE_DEPBITS
+#define XCHAL_HAVE_DEPBITS 0
+#endif
+
#ifndef XCHAL_HAVE_DIV32
#define XCHAL_HAVE_DIV32 0
#endif
@@ -69,6 +73,7 @@
XCHAL_OPTION(XCHAL_HAVE_S32C1I, XTENSA_OPTION_CONDITIONAL_STORE) | \
XCHAL_OPTION(XCHAL_HAVE_S32C1I && XCHAL_HW_MIN_VERSION >= 230000, \
XTENSA_OPTION_ATOMCTL) | \
+ XCHAL_OPTION(XCHAL_HAVE_DEPBITS, XTENSA_OPTION_DEPBITS) | \
/* Interrupts and exceptions */ \
XCHAL_OPTION(XCHAL_HAVE_EXCEPTIONS, XTENSA_OPTION_EXCEPTION) | \
XCHAL_OPTION(XCHAL_HAVE_VECBASE, XTENSA_OPTION_RELOCATABLE_VECTOR) | \
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index fda91b7..aa0c527 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -1943,7 +1943,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
switch (OP2) {
case 0: /*L32E*/
HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
- if (gen_check_privilege(dc)) {
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, RRR_S, RRR_T)) {
TCGv_i32 addr = tcg_temp_new_i32();
tcg_gen_addi_i32(addr, cpu_R[RRR_S],
(0xffffffc0 | (RRR_R << 2)));
@@ -1954,7 +1955,8 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
case 4: /*S32E*/
HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);
- if (gen_check_privilege(dc)) {
+ if (gen_check_privilege(dc) &&
+ gen_window_check2(dc, RRR_S, RRR_T)) {
TCGv_i32 addr = tcg_temp_new_i32();
tcg_gen_addi_i32(addr, cpu_R[RRR_S],
(0xffffffc0 | (RRR_R << 2)));
@@ -1963,6 +1965,17 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
}
break;
+ case 5: /*S32N*/
+ if (gen_window_check2(dc, RRI4_S, RRI4_T)) {
+ TCGv_i32 addr = tcg_temp_new_i32();
+
+ tcg_gen_addi_i32(addr, cpu_R[RRI4_S], RRI4_IMM4 << 2);
+ gen_load_store_alignment(dc, 2, addr, false);
+ tcg_gen_qemu_st32(cpu_R[RRI4_T], addr, dc->cring);
+ tcg_temp_free(addr);
+ }
+ break;
+
default:
RESERVED();
break;
@@ -1970,6 +1983,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
break;
case 10: /*FP0*/
+ /*DEPBITS*/
+ if (option_enabled(dc, XTENSA_OPTION_DEPBITS)) {
+ if (!gen_window_check2(dc, RRR_S, RRR_T)) {
+ break;
+ }
+ tcg_gen_deposit_i32(cpu_R[RRR_T], cpu_R[RRR_T], cpu_R[RRR_S],
+ OP2, RRR_R + 1);
+ break;
+ }
+
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
switch (OP2) {
case 0: /*ADD.Sf*/
@@ -2104,6 +2127,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
break;
case 11: /*FP1*/
+ /*DEPBITS*/
+ if (option_enabled(dc, XTENSA_OPTION_DEPBITS)) {
+ if (!gen_window_check2(dc, RRR_S, RRR_T)) {
+ break;
+ }
+ tcg_gen_deposit_i32(cpu_R[RRR_T], cpu_R[RRR_T], cpu_R[RRR_S],
+ OP2 + 16, RRR_R + 1);
+ break;
+ }
+
HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
#define gen_compare(rel, br, a, b) \
diff --git a/tests/Makefile b/tests/Makefile
index cb221de..0531b30 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -80,6 +80,7 @@ check-unit-$(CONFIG_GNUTLS_HASH) += tests/test-crypto-hash$(EXESUF)
check-unit-y += tests/test-crypto-cipher$(EXESUF)
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlssession$(EXESUF)
+check-unit-$(CONFIG_LINUX) += tests/test-qga$(EXESUF)
check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
@@ -534,6 +535,8 @@ endif
qtest-obj-y = tests/libqtest.o $(test-util-obj-y)
$(check-qtest-y): $(qtest-obj-y)
+tests/test-qga: tests/test-qga.o $(qtest-obj-y)
+
.PHONY: check-help
check-help:
@echo "Regression testing targets:"
diff --git a/tests/fw_cfg-test.c b/tests/fw_cfg-test.c
index 9be78e9..b7d4007 100644
--- a/tests/fw_cfg-test.c
+++ b/tests/fw_cfg-test.c
@@ -37,7 +37,9 @@ static void test_fw_cfg_signature(void)
static void test_fw_cfg_id(void)
{
- g_assert_cmpint(qfw_cfg_get_u32(fw_cfg, FW_CFG_ID), ==, 1);
+ uint32_t id = qfw_cfg_get_u32(fw_cfg, FW_CFG_ID);
+ g_assert((id == 1) ||
+ (id == 3));
}
static void test_fw_cfg_uuid(void)
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 2a396ba..b6d700c 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -356,7 +356,7 @@ static void qmp_response(JSONMessageParser *parser, QList *tokens)
qmp->response = (QDict *)obj;
}
-QDict *qtest_qmp_receive(QTestState *s)
+QDict *qmp_fd_receive(int fd)
{
QMPResponseParser qmp;
bool log = getenv("QTEST_LOG") != NULL;
@@ -367,7 +367,7 @@ QDict *qtest_qmp_receive(QTestState *s)
ssize_t len;
char c;
- len = read(s->qmp_fd, &c, 1);
+ len = read(fd, &c, 1);
if (len == -1 && errno == EINTR) {
continue;
}
@@ -387,12 +387,17 @@ QDict *qtest_qmp_receive(QTestState *s)
return qmp.response;
}
+QDict *qtest_qmp_receive(QTestState *s)
+{
+ return qmp_fd_receive(s->qmp_fd);
+}
+
/**
* Allow users to send a message without waiting for the reply,
* in the case that they choose to discard all replies up until
* a particular EVENT is received.
*/
-void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap)
+void qmp_fd_sendv(int fd, const char *fmt, va_list ap)
{
va_list ap_copy;
QObject *qobj;
@@ -416,13 +421,25 @@ void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap)
fprintf(stderr, "%s", str);
}
/* Send QMP request */
- socket_send(s->qmp_fd, str, size);
+ socket_send(fd, str, size);
QDECREF(qstr);
qobject_decref(qobj);
}
}
+void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap)
+{
+ qmp_fd_sendv(s->qmp_fd, fmt, ap);
+}
+
+QDict *qmp_fdv(int fd, const char *fmt, va_list ap)
+{
+ qmp_fd_sendv(fd, fmt, ap);
+
+ return qmp_fd_receive(fd);
+}
+
QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap)
{
qtest_async_qmpv(s, fmt, ap);
@@ -431,6 +448,26 @@ QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap)
return qtest_qmp_receive(s);
}
+QDict *qmp_fd(int fd, const char *fmt, ...)
+{
+ va_list ap;
+ QDict *response;
+
+ va_start(ap, fmt);
+ response = qmp_fdv(fd, fmt, ap);
+ va_end(ap);
+ return response;
+}
+
+void qmp_fd_send(int fd, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ qmp_fd_sendv(fd, fmt, ap);
+ va_end(ap);
+}
+
QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
{
va_list ap;
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 55bccbf..9818ef7 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -851,4 +851,11 @@ static inline int64_t clock_set(int64_t val)
*/
bool qtest_big_endian(void);
+
+QDict *qmp_fd_receive(int fd);
+void qmp_fd_sendv(int fd, const char *fmt, va_list ap);
+void qmp_fd_send(int fd, const char *fmt, ...);
+QDict *qmp_fdv(int fd, const char *fmt, va_list ap);
+QDict *qmp_fd(int fd, const char *fmt, ...);
+
#endif
diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
index b552d9f..f5951cb 100644
--- a/tests/test-coroutine.c
+++ b/tests/test-coroutine.c
@@ -12,8 +12,8 @@
*/
#include <glib.h>
-#include "block/coroutine.h"
-#include "block/coroutine_int.h"
+#include "qemu/coroutine.h"
+#include "qemu/coroutine_int.h"
/*
* Check that qemu_in_coroutine() works
diff --git a/tests/test-qga.c b/tests/test-qga.c
new file mode 100644
index 0000000..0531c9f
--- /dev/null
+++ b/tests/test-qga.c
@@ -0,0 +1,783 @@
+#include <locale.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include "libqtest.h"
+#include "config-host.h"
+
+typedef struct {
+ char *test_dir;
+ GMainLoop *loop;
+ int fd;
+ GPid pid;
+} TestFixture;
+
+static int connect_qga(char *path)
+{
+ int s, ret, len, i = 0;
+ struct sockaddr_un remote;
+
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
+ g_assert(s != -1);
+
+ remote.sun_family = AF_UNIX;
+ do {
+ strcpy(remote.sun_path, path);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+ ret = connect(s, (struct sockaddr *)&remote, len);
+ if (ret == -1) {
+ g_usleep(G_USEC_PER_SEC);
+ }
+ if (i++ == 10) {
+ return -1;
+ }
+ } while (ret == -1);
+
+ return s;
+}
+
+static void qga_watch(GPid pid, gint status, gpointer user_data)
+{
+ TestFixture *fixture = user_data;
+
+ g_assert_cmpint(status, ==, 0);
+ g_main_loop_quit(fixture->loop);
+}
+
+static void
+fixture_setup(TestFixture *fixture, gconstpointer data)
+{
+ const gchar *extra_arg = data;
+ GError *error = NULL;
+ gchar *cwd, *path, *cmd, **argv = NULL;
+
+ fixture->loop = g_main_loop_new(NULL, FALSE);
+
+ fixture->test_dir = g_strdup("/tmp/qgatest.XXXXXX");
+ g_assert_nonnull(mkdtemp(fixture->test_dir));
+
+ path = g_build_filename(fixture->test_dir, "sock", NULL);
+ cwd = g_get_current_dir();
+ cmd = g_strdup_printf("%s%cqemu-ga -m unix-listen -t %s -p %s %s %s",
+ cwd, G_DIR_SEPARATOR,
+ fixture->test_dir, path,
+ getenv("QTEST_LOG") ? "-v" : "",
+ extra_arg ?: "");
+ g_shell_parse_argv(cmd, NULL, &argv, &error);
+ g_assert_no_error(error);
+
+ g_spawn_async(fixture->test_dir, argv, NULL,
+ G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD,
+ NULL, NULL, &fixture->pid, &error);
+ g_assert_no_error(error);
+
+ g_child_watch_add(fixture->pid, qga_watch, fixture);
+
+ fixture->fd = connect_qga(path);
+ g_assert_cmpint(fixture->fd, !=, -1);
+
+ g_strfreev(argv);
+ g_free(cmd);
+ g_free(cwd);
+ g_free(path);
+}
+
+static void
+fixture_tear_down(TestFixture *fixture, gconstpointer data)
+{
+ gchar *tmp;
+
+ kill(fixture->pid, SIGTERM);
+
+ g_main_loop_run(fixture->loop);
+ g_main_loop_unref(fixture->loop);
+
+ g_spawn_close_pid(fixture->pid);
+
+ tmp = g_build_filename(fixture->test_dir, "foo", NULL);
+ g_unlink(tmp);
+ g_free(tmp);
+
+ tmp = g_build_filename(fixture->test_dir, "qga.state", NULL);
+ g_unlink(tmp);
+ g_free(tmp);
+
+ tmp = g_build_filename(fixture->test_dir, "sock", NULL);
+ g_unlink(tmp);
+ g_free(tmp);
+
+ g_rmdir(fixture->test_dir);
+ g_free(fixture->test_dir);
+}
+
+static void qmp_assertion_message_error(const char *domain,
+ const char *file,
+ int line,
+ const char *func,
+ const char *expr,
+ QDict *dict)
+{
+ const char *class, *desc;
+ char *s;
+ QDict *error;
+
+ error = qdict_get_qdict(dict, "error");
+ class = qdict_get_try_str(error, "class");
+ desc = qdict_get_try_str(error, "desc");
+
+ s = g_strdup_printf("assertion failed %s: %s %s", expr, class, desc);
+ g_assertion_message(domain, file, line, func, s);
+ g_free(s);
+}
+
+#define qmp_assert_no_error(err) do { \
+ if (qdict_haskey(err, "error")) { \
+ qmp_assertion_message_error(G_LOG_DOMAIN, __FILE__, __LINE__, \
+ G_STRFUNC, #err, err); \
+ } \
+} while (0)
+
+static void test_qga_sync_delimited(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ guint32 v, r = g_random_int();
+ unsigned char c;
+ QDict *ret;
+ gchar *cmd;
+
+ cmd = g_strdup_printf("%c{'execute': 'guest-sync-delimited',"
+ " 'arguments': {'id': %u } }", 0xff, r);
+ qmp_fd_send(fixture->fd, cmd);
+ g_free(cmd);
+
+ v = read(fixture->fd, &c, 1);
+ g_assert_cmpint(v, ==, 1);
+ g_assert_cmpint(c, ==, 0xff);
+
+ ret = qmp_fd_receive(fixture->fd);
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ v = qdict_get_int(ret, "return");
+ g_assert_cmpint(r, ==, v);
+
+ QDECREF(ret);
+}
+
+static void test_qga_sync(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ guint32 v, r = g_random_int();
+ QDict *ret;
+ gchar *cmd;
+
+ cmd = g_strdup_printf("%c{'execute': 'guest-sync',"
+ " 'arguments': {'id': %u } }", 0xff, r);
+ ret = qmp_fd(fixture->fd, cmd);
+ g_free(cmd);
+
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ v = qdict_get_int(ret, "return");
+ g_assert_cmpint(r, ==, v);
+
+ QDECREF(ret);
+}
+
+static void test_qga_ping(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-ping'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ QDECREF(ret);
+}
+
+static void test_qga_invalid_cmd(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret, *error;
+ const gchar *class, *desc;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-invalid-cmd'}");
+ g_assert_nonnull(ret);
+
+ error = qdict_get_qdict(ret, "error");
+ class = qdict_get_try_str(error, "class");
+ desc = qdict_get_try_str(error, "desc");
+
+ g_assert_cmpstr(class, ==, "CommandNotFound");
+ g_assert_cmpint(strlen(desc), >, 0);
+
+ QDECREF(ret);
+}
+
+static void test_qga_info(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret, *val;
+ const gchar *version;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-info'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ val = qdict_get_qdict(ret, "return");
+ version = qdict_get_try_str(val, "version");
+ g_assert_cmpstr(version, ==, QEMU_VERSION);
+
+ QDECREF(ret);
+}
+
+static void test_qga_get_vcpus(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+ QList *list;
+ const QListEntry *entry;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-vcpus'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ /* check there is at least a cpu */
+ list = qdict_get_qlist(ret, "return");
+ entry = qlist_first(list);
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "online"));
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "logical-id"));
+
+ QDECREF(ret);
+}
+
+static void test_qga_get_fsinfo(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+ QList *list;
+ const QListEntry *entry;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-fsinfo'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ /* check there is at least a fs */
+ list = qdict_get_qlist(ret, "return");
+ entry = qlist_first(list);
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "name"));
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "mountpoint"));
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "type"));
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "disk"));
+
+ QDECREF(ret);
+}
+
+static void test_qga_get_memory_block_info(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret, *val;
+ int64_t size;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-memory-block-info'}");
+ g_assert_nonnull(ret);
+
+ /* some systems might not expose memory block info in sysfs */
+ if (!qdict_haskey(ret, "error")) {
+ /* check there is at least some memory */
+ val = qdict_get_qdict(ret, "return");
+ size = qdict_get_int(val, "size");
+ g_assert_cmpint(size, >, 0);
+ }
+
+ QDECREF(ret);
+}
+
+static void test_qga_get_memory_blocks(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+ QList *list;
+ const QListEntry *entry;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-memory-blocks'}");
+ g_assert_nonnull(ret);
+
+ /* some systems might not expose memory block info in sysfs */
+ if (!qdict_haskey(ret, "error")) {
+ list = qdict_get_qlist(ret, "return");
+ entry = qlist_first(list);
+ /* newer versions of qga may return empty list without error */
+ if (entry) {
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "phys-index"));
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "online"));
+ }
+ }
+
+ QDECREF(ret);
+}
+
+static void test_qga_network_get_interfaces(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+ QList *list;
+ const QListEntry *entry;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-network-get-interfaces'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ /* check there is at least an interface */
+ list = qdict_get_qlist(ret, "return");
+ entry = qlist_first(list);
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "name"));
+
+ QDECREF(ret);
+}
+
+static void test_qga_file_ops(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ const guchar helloworld[] = "Hello World!\n";
+ const char *b64;
+ gchar *cmd, *path, *enc;
+ guchar *dec;
+ QDict *ret, *val;
+ int64_t id, eof;
+ gsize count;
+ FILE *f;
+ char tmp[100];
+
+ /* open */
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"
+ " 'arguments': { 'path': 'foo', 'mode': 'w+' } }");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ id = qdict_get_int(ret, "return");
+ QDECREF(ret);
+
+ enc = g_base64_encode(helloworld, sizeof(helloworld));
+ /* write */
+ cmd = g_strdup_printf("{'execute': 'guest-file-write',"
+ " 'arguments': { 'handle': %" PRId64 ","
+ " 'buf-b64': '%s' } }", id, enc);
+ ret = qmp_fd(fixture->fd, cmd);
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ val = qdict_get_qdict(ret, "return");
+ count = qdict_get_int(val, "count");
+ eof = qdict_get_bool(val, "eof");
+ g_assert_cmpint(count, ==, sizeof(helloworld));
+ g_assert_cmpint(eof, ==, 0);
+ QDECREF(ret);
+ g_free(cmd);
+
+ /* flush */
+ cmd = g_strdup_printf("{'execute': 'guest-file-flush',"
+ " 'arguments': {'handle': %" PRId64 "} }",
+ id);
+ ret = qmp_fd(fixture->fd, cmd);
+ QDECREF(ret);
+ g_free(cmd);
+
+ /* close */
+ cmd = g_strdup_printf("{'execute': 'guest-file-close',"
+ " 'arguments': {'handle': %" PRId64 "} }",
+ id);
+ ret = qmp_fd(fixture->fd, cmd);
+ QDECREF(ret);
+ g_free(cmd);
+
+ /* check content */
+ path = g_build_filename(fixture->test_dir, "foo", NULL);
+ f = fopen(path, "r");
+ g_assert_nonnull(f);
+ count = fread(tmp, 1, sizeof(tmp), f);
+ g_assert_cmpint(count, ==, sizeof(helloworld));
+ tmp[count] = 0;
+ g_assert_cmpstr(tmp, ==, (char *)helloworld);
+ fclose(f);
+
+ /* open */
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"
+ " 'arguments': { 'path': 'foo', 'mode': 'r' } }");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ id = qdict_get_int(ret, "return");
+ QDECREF(ret);
+
+ /* read */
+ cmd = g_strdup_printf("{'execute': 'guest-file-read',"
+ " 'arguments': { 'handle': %" PRId64 "} }",
+ id);
+ ret = qmp_fd(fixture->fd, cmd);
+ val = qdict_get_qdict(ret, "return");
+ count = qdict_get_int(val, "count");
+ eof = qdict_get_bool(val, "eof");
+ b64 = qdict_get_str(val, "buf-b64");
+ g_assert_cmpint(count, ==, sizeof(helloworld));
+ g_assert(eof);
+ g_assert_cmpstr(b64, ==, enc);
+
+ QDECREF(ret);
+ g_free(cmd);
+ g_free(enc);
+
+ /* read eof */
+ cmd = g_strdup_printf("{'execute': 'guest-file-read',"
+ " 'arguments': { 'handle': %" PRId64 "} }",
+ id);
+ ret = qmp_fd(fixture->fd, cmd);
+ val = qdict_get_qdict(ret, "return");
+ count = qdict_get_int(val, "count");
+ eof = qdict_get_bool(val, "eof");
+ b64 = qdict_get_str(val, "buf-b64");
+ g_assert_cmpint(count, ==, 0);
+ g_assert(eof);
+ g_assert_cmpstr(b64, ==, "");
+ QDECREF(ret);
+ g_free(cmd);
+
+ /* seek */
+ cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
+ " 'arguments': { 'handle': %" PRId64 ", "
+ " 'offset': %d, 'whence': %d } }",
+ id, 6, SEEK_SET);
+ ret = qmp_fd(fixture->fd, cmd);
+ qmp_assert_no_error(ret);
+ val = qdict_get_qdict(ret, "return");
+ count = qdict_get_int(val, "position");
+ eof = qdict_get_bool(val, "eof");
+ g_assert_cmpint(count, ==, 6);
+ g_assert(!eof);
+ QDECREF(ret);
+ g_free(cmd);
+
+ /* partial read */
+ cmd = g_strdup_printf("{'execute': 'guest-file-read',"
+ " 'arguments': { 'handle': %" PRId64 "} }",
+ id);
+ ret = qmp_fd(fixture->fd, cmd);
+ val = qdict_get_qdict(ret, "return");
+ count = qdict_get_int(val, "count");
+ eof = qdict_get_bool(val, "eof");
+ b64 = qdict_get_str(val, "buf-b64");
+ g_assert_cmpint(count, ==, sizeof(helloworld) - 6);
+ g_assert(eof);
+ dec = g_base64_decode(b64, &count);
+ g_assert_cmpint(count, ==, sizeof(helloworld) - 6);
+ g_assert_cmpmem(dec, count, helloworld + 6, sizeof(helloworld) - 6);
+ g_free(dec);
+
+ QDECREF(ret);
+ g_free(cmd);
+
+ /* close */
+ cmd = g_strdup_printf("{'execute': 'guest-file-close',"
+ " 'arguments': {'handle': %" PRId64 "} }",
+ id);
+ ret = qmp_fd(fixture->fd, cmd);
+ QDECREF(ret);
+ g_free(cmd);
+}
+
+static void test_qga_get_time(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+ int64_t time;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-time'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ time = qdict_get_int(ret, "return");
+ g_assert_cmpint(time, >, 0);
+
+ QDECREF(ret);
+}
+
+static void test_qga_set_time(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+ int64_t current, time;
+ gchar *cmd;
+
+ /* get current time */
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-time'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ current = qdict_get_int(ret, "return");
+ g_assert_cmpint(current, >, 0);
+ QDECREF(ret);
+
+ /* set some old time */
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-set-time',"
+ " 'arguments': { 'time': 1000 } }");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ QDECREF(ret);
+
+ /* check old time */
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-time'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ time = qdict_get_int(ret, "return");
+ g_assert_cmpint(time / 1000, <, G_USEC_PER_SEC * 10);
+ QDECREF(ret);
+
+ /* set back current time */
+ cmd = g_strdup_printf("{'execute': 'guest-set-time',"
+ " 'arguments': { 'time': %" PRId64 " } }",
+ current + time * 1000);
+ ret = qmp_fd(fixture->fd, cmd);
+ g_free(cmd);
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ QDECREF(ret);
+}
+
+static void test_qga_fstrim(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+ QList *list;
+ const QListEntry *entry;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-fstrim',"
+ " arguments: { minimum: 4194304 } }");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ list = qdict_get_qlist(ret, "return");
+ entry = qlist_first(list);
+ g_assert(qdict_haskey(qobject_to_qdict(entry->value), "paths"));
+
+ QDECREF(ret);
+}
+
+static void test_qga_blacklist(gconstpointer data)
+{
+ TestFixture fix;
+ QDict *ret, *error;
+ const gchar *class, *desc;
+
+ fixture_setup(&fix, "-b guest-ping,guest-get-time");
+
+ /* check blacklist */
+ ret = qmp_fd(fix.fd, "{'execute': 'guest-ping'}");
+ g_assert_nonnull(ret);
+ error = qdict_get_qdict(ret, "error");
+ class = qdict_get_try_str(error, "class");
+ desc = qdict_get_try_str(error, "desc");
+ g_assert_cmpstr(class, ==, "GenericError");
+ g_assert_nonnull(g_strstr_len(desc, -1, "has been disabled"));
+ QDECREF(ret);
+
+ ret = qmp_fd(fix.fd, "{'execute': 'guest-get-time'}");
+ g_assert_nonnull(ret);
+ error = qdict_get_qdict(ret, "error");
+ class = qdict_get_try_str(error, "class");
+ desc = qdict_get_try_str(error, "desc");
+ g_assert_cmpstr(class, ==, "GenericError");
+ g_assert_nonnull(g_strstr_len(desc, -1, "has been disabled"));
+ QDECREF(ret);
+
+ /* check something work */
+ ret = qmp_fd(fix.fd, "{'execute': 'guest-get-fsinfo'}");
+ qmp_assert_no_error(ret);
+ QDECREF(ret);
+
+ fixture_tear_down(&fix, NULL);
+}
+
+static void test_qga_config(gconstpointer data)
+{
+ GError *error = NULL;
+ char *cwd, *cmd, *out, *err, *str, **strv, *conf, **argv = NULL;
+ char *env[2];
+ int status, tmp;
+ gsize n;
+ GKeyFile *kf;
+ const char *qga_config =
+ "[general]\n"
+ "daemon=false\n"
+ "method=virtio-serial\n"
+ "path=/path/to/org.qemu.guest_agent.0\n"
+ "pidfile=/var/foo/qemu-ga.pid\n"
+ "statedir=/var/state\n"
+ "verbose=true\n"
+ "blacklist=guest-ping;guest-get-time\n";
+
+ tmp = g_file_open_tmp(NULL, &conf, &error);
+ g_assert_no_error(error);
+ g_assert_cmpint(tmp, >=, 0);
+ g_assert_cmpstr(conf, !=, "");
+
+ g_file_set_contents(conf, qga_config, -1, &error);
+ g_assert_no_error(error);
+
+ cwd = g_get_current_dir();
+ cmd = g_strdup_printf("%s%cqemu-ga -D",
+ cwd, G_DIR_SEPARATOR);
+ g_shell_parse_argv(cmd, NULL, &argv, &error);
+ g_assert_no_error(error);
+
+ env[0] = g_strdup_printf("QGA_CONF=%s", conf);
+ env[1] = NULL;
+ g_spawn_sync(NULL, argv, env, 0,
+ NULL, NULL, &out, &err, &status, &error);
+ g_assert_no_error(error);
+ g_assert_cmpstr(err, ==, "");
+ g_assert_cmpint(status, ==, 0);
+
+ kf = g_key_file_new();
+ g_key_file_load_from_data(kf, out, -1, G_KEY_FILE_NONE, &error);
+ g_assert_no_error(error);
+
+ str = g_key_file_get_start_group(kf);
+ g_assert_cmpstr(str, ==, "general");
+ g_free(str);
+
+ g_assert_false(g_key_file_get_boolean(kf, "general", "daemon", &error));
+ g_assert_no_error(error);
+
+ str = g_key_file_get_string(kf, "general", "method", &error);
+ g_assert_no_error(error);
+ g_assert_cmpstr(str, ==, "virtio-serial");
+ g_free(str);
+
+ str = g_key_file_get_string(kf, "general", "path", &error);
+ g_assert_no_error(error);
+ g_assert_cmpstr(str, ==, "/path/to/org.qemu.guest_agent.0");
+ g_free(str);
+
+ str = g_key_file_get_string(kf, "general", "pidfile", &error);
+ g_assert_no_error(error);
+ g_assert_cmpstr(str, ==, "/var/foo/qemu-ga.pid");
+ g_free(str);
+
+ str = g_key_file_get_string(kf, "general", "statedir", &error);
+ g_assert_no_error(error);
+ g_assert_cmpstr(str, ==, "/var/state");
+ g_free(str);
+
+ g_assert_true(g_key_file_get_boolean(kf, "general", "verbose", &error));
+ g_assert_no_error(error);
+
+ strv = g_key_file_get_string_list(kf, "general", "blacklist", &n, &error);
+ g_assert_cmpint(n, ==, 2);
+#if GLIB_CHECK_VERSION(2, 44, 0)
+ g_assert_true(g_strv_contains((const char * const *)strv,
+ "guest-ping"));
+ g_assert_true(g_strv_contains((const char * const *)strv,
+ "guest-get-time"));
+#endif
+ g_assert_no_error(error);
+ g_strfreev(strv);
+
+ g_free(out);
+ g_free(err);
+ g_free(conf);
+ g_free(env[0]);
+ g_key_file_free(kf);
+
+ close(tmp);
+}
+
+static void test_qga_fsfreeze_status(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+ const gchar *status;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-status'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ status = qdict_get_try_str(ret, "return");
+ g_assert_cmpstr(status, ==, "thawed");
+
+ QDECREF(ret);
+}
+
+static void test_qga_fsfreeze_and_thaw(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ QDict *ret;
+ const gchar *status;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-freeze'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ QDECREF(ret);
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-status'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ status = qdict_get_try_str(ret, "return");
+ g_assert_cmpstr(status, ==, "frozen");
+ QDECREF(ret);
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-thaw'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+ QDECREF(ret);
+}
+
+int main(int argc, char **argv)
+{
+ TestFixture fix;
+ int ret;
+
+ setlocale (LC_ALL, "");
+ g_test_init(&argc, &argv, NULL);
+ fixture_setup(&fix, NULL);
+
+ g_test_add_data_func("/qga/sync-delimited", &fix, test_qga_sync_delimited);
+ g_test_add_data_func("/qga/sync", &fix, test_qga_sync);
+ g_test_add_data_func("/qga/ping", &fix, test_qga_ping);
+ g_test_add_data_func("/qga/info", &fix, test_qga_info);
+ g_test_add_data_func("/qga/network-get-interfaces", &fix,
+ test_qga_network_get_interfaces);
+ g_test_add_data_func("/qga/get-vcpus", &fix, test_qga_get_vcpus);
+ g_test_add_data_func("/qga/get-fsinfo", &fix, test_qga_get_fsinfo);
+ g_test_add_data_func("/qga/get-memory-block-info", &fix,
+ test_qga_get_memory_block_info);
+ g_test_add_data_func("/qga/get-memory-blocks", &fix,
+ test_qga_get_memory_blocks);
+ g_test_add_data_func("/qga/file-ops", &fix, test_qga_file_ops);
+ g_test_add_data_func("/qga/get-time", &fix, test_qga_get_time);
+ g_test_add_data_func("/qga/invalid-cmd", &fix, test_qga_invalid_cmd);
+ g_test_add_data_func("/qga/fsfreeze-status", &fix,
+ test_qga_fsfreeze_status);
+
+ g_test_add_data_func("/qga/blacklist", NULL, test_qga_blacklist);
+ g_test_add_data_func("/qga/config", NULL, test_qga_config);
+
+ if (g_getenv("QGA_TEST_SIDE_EFFECTING")) {
+ g_test_add_data_func("/qga/fsfreeze-and-thaw", &fix,
+ test_qga_fsfreeze_and_thaw);
+ g_test_add_data_func("/qga/set-time", &fix, test_qga_set_time);
+ g_test_add_data_func("/qga/fstrim", &fix, test_qga_fstrim);
+ }
+
+ ret = g_test_run();
+
+ fixture_tear_down(&fix, NULL);
+
+ return ret;
+}
diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c
index 1d620e0..4d13bd0 100644
--- a/tests/test-vmstate.c
+++ b/tests/test-vmstate.c
@@ -27,7 +27,7 @@
#include "qemu-common.h"
#include "migration/migration.h"
#include "migration/vmstate.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
static char temp_file[] = "/tmp/vmst.test.XXXXXX";
static int temp_fd;
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 56df5cc..a74c934 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -12,6 +12,7 @@
#include "libqtest.h"
#include "qemu/option.h"
+#include "qemu/range.h"
#include "sysemu/char.h"
#include "sysemu/sysemu.h"
@@ -30,10 +31,10 @@
#endif
#define QEMU_CMD_ACCEL " -machine accel=tcg"
-#define QEMU_CMD_MEM " -m 512 -object memory-backend-file,id=mem,size=512M,"\
+#define QEMU_CMD_MEM " -m %d -object memory-backend-file,id=mem,size=%dM,"\
"mem-path=%s,share=on -numa node,memdev=mem"
-#define QEMU_CMD_CHR " -chardev socket,id=chr0,path=%s"
-#define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=chr0,vhostforce"
+#define QEMU_CMD_CHR " -chardev socket,id=%s,path=%s"
+#define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=%s,vhostforce"
#define QEMU_CMD_NET " -device virtio-net-pci,netdev=net0 "
#define QEMU_CMD_ROM " -option-rom ../pc-bios/pxe-virtio.rom"
@@ -47,6 +48,9 @@
#define VHOST_MEMORY_MAX_NREGIONS 8
#define VHOST_USER_F_PROTOCOL_FEATURES 30
+#define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
+
+#define VHOST_LOG_PAGE 0x1000
typedef enum VhostUserRequest {
VHOST_USER_NONE = 0,
@@ -108,10 +112,17 @@ static VhostUserMsg m __attribute__ ((unused));
#define VHOST_USER_VERSION (0x1)
/*****************************************************************************/
-int fds_num = 0, fds[VHOST_MEMORY_MAX_NREGIONS];
-static VhostUserMemory memory;
-static CompatGMutex data_mutex;
-static CompatGCond data_cond;
+typedef struct TestServer {
+ gchar *socket_path;
+ gchar *chr_name;
+ CharDriverState *chr;
+ int fds_num;
+ int fds[VHOST_MEMORY_MAX_NREGIONS];
+ VhostUserMemory memory;
+ GMutex data_mutex;
+ GCond data_cond;
+ int log_fd;
+} TestServer;
#if !GLIB_CHECK_VERSION(2, 32, 0)
static gboolean g_cond_wait_until(CompatGCond cond, CompatGMutex mutex,
@@ -126,58 +137,71 @@ static gboolean g_cond_wait_until(CompatGCond cond, CompatGMutex mutex,
}
#endif
-static void read_guest_mem(void)
+static const char *tmpfs;
+static const char *root;
+
+static void wait_for_fds(TestServer *s)
{
- uint32_t *guest_mem;
gint64 end_time;
- int i, j;
- size_t size;
- g_mutex_lock(&data_mutex);
+ g_mutex_lock(&s->data_mutex);
end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
- while (!fds_num) {
- if (!g_cond_wait_until(&data_cond, &data_mutex, end_time)) {
+ while (!s->fds_num) {
+ if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
/* timeout has passed */
- g_assert(fds_num);
+ g_assert(s->fds_num);
break;
}
}
/* check for sanity */
- g_assert_cmpint(fds_num, >, 0);
- g_assert_cmpint(fds_num, ==, memory.nregions);
+ g_assert_cmpint(s->fds_num, >, 0);
+ g_assert_cmpint(s->fds_num, ==, s->memory.nregions);
+
+ g_mutex_unlock(&s->data_mutex);
+}
+
+static void read_guest_mem(TestServer *s)
+{
+ uint32_t *guest_mem;
+ int i, j;
+ size_t size;
+
+ wait_for_fds(s);
+
+ g_mutex_lock(&s->data_mutex);
/* iterate all regions */
- for (i = 0; i < fds_num; i++) {
+ for (i = 0; i < s->fds_num; i++) {
/* We'll check only the region statring at 0x0*/
- if (memory.regions[i].guest_phys_addr != 0x0) {
+ if (s->memory.regions[i].guest_phys_addr != 0x0) {
continue;
}
- g_assert_cmpint(memory.regions[i].memory_size, >, 1024);
+ g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024);
- size = memory.regions[i].memory_size + memory.regions[i].mmap_offset;
+ size = s->memory.regions[i].memory_size +
+ s->memory.regions[i].mmap_offset;
guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fds[i], 0);
+ MAP_SHARED, s->fds[i], 0);
g_assert(guest_mem != MAP_FAILED);
- guest_mem += (memory.regions[i].mmap_offset / sizeof(*guest_mem));
+ guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem));
for (j = 0; j < 256; j++) {
- uint32_t a = readl(memory.regions[i].guest_phys_addr + j*4);
+ uint32_t a = readl(s->memory.regions[i].guest_phys_addr + j*4);
uint32_t b = guest_mem[j];
g_assert_cmpint(a, ==, b);
}
- munmap(guest_mem, memory.regions[i].memory_size);
+ munmap(guest_mem, s->memory.regions[i].memory_size);
}
- g_assert_cmpint(1, ==, 1);
- g_mutex_unlock(&data_mutex);
+ g_mutex_unlock(&s->data_mutex);
}
static void *thread_function(void *data)
@@ -195,7 +219,8 @@ static int chr_can_read(void *opaque)
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
- CharDriverState *chr = opaque;
+ TestServer *s = opaque;
+ CharDriverState *chr = s->chr;
VhostUserMsg msg;
uint8_t *p = (uint8_t *) &msg;
int fd;
@@ -205,12 +230,12 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
return;
}
- g_mutex_lock(&data_mutex);
+ g_mutex_lock(&s->data_mutex);
memcpy(p, buf, VHOST_USER_HDR_SIZE);
if (msg.size) {
p += VHOST_USER_HDR_SIZE;
- qemu_chr_fe_read_all(chr, p, msg.size);
+ g_assert_cmpint(qemu_chr_fe_read_all(chr, p, msg.size), ==, msg.size);
}
switch (msg.request) {
@@ -218,7 +243,8 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
/* send back features to qemu */
msg.flags |= VHOST_USER_REPLY_MASK;
msg.size = sizeof(m.u64);
- msg.u64 = 0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
+ msg.u64 = 0x1ULL << VHOST_F_LOG_ALL |
+ 0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
break;
@@ -232,7 +258,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
/* send back features to qemu */
msg.flags |= VHOST_USER_REPLY_MASK;
msg.size = sizeof(m.u64);
- msg.u64 = 0;
+ msg.u64 = 1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD;
p = (uint8_t *) &msg;
qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE + msg.size);
break;
@@ -248,11 +274,11 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
case VHOST_USER_SET_MEM_TABLE:
/* received the mem table */
- memcpy(&memory, &msg.memory, sizeof(msg.memory));
- fds_num = qemu_chr_fe_get_msgfds(chr, fds, sizeof(fds) / sizeof(int));
+ memcpy(&s->memory, &msg.memory, sizeof(msg.memory));
+ s->fds_num = qemu_chr_fe_get_msgfds(chr, s->fds, G_N_ELEMENTS(s->fds));
/* signal the test that it can continue */
- g_cond_signal(&data_cond);
+ g_cond_signal(&s->data_cond);
break;
case VHOST_USER_SET_VRING_KICK:
@@ -266,10 +292,30 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
*/
qemu_set_nonblock(fd);
break;
+
+ case VHOST_USER_SET_LOG_BASE:
+ if (s->log_fd != -1) {
+ close(s->log_fd);
+ s->log_fd = -1;
+ }
+ qemu_chr_fe_get_msgfds(chr, &s->log_fd, 1);
+ msg.flags |= VHOST_USER_REPLY_MASK;
+ msg.size = 0;
+ p = (uint8_t *) &msg;
+ qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE);
+
+ g_cond_signal(&s->data_cond);
+ break;
+
+ case VHOST_USER_RESET_DEVICE:
+ s->fds_num = 0;
+ break;
+
default:
break;
}
- g_mutex_unlock(&data_mutex);
+
+ g_mutex_unlock(&s->data_mutex);
}
static const char *init_hugepagefs(const char *path)
@@ -299,26 +345,246 @@ static const char *init_hugepagefs(const char *path)
return path;
}
+static TestServer *test_server_new(const gchar *name)
+{
+ TestServer *server = g_new0(TestServer, 1);
+ gchar *chr_path;
+
+ server->socket_path = g_strdup_printf("%s/%s.sock", tmpfs, name);
+
+ chr_path = g_strdup_printf("unix:%s,server,nowait", server->socket_path);
+ server->chr_name = g_strdup_printf("chr-%s", name);
+ server->chr = qemu_chr_new(server->chr_name, chr_path, NULL);
+ g_free(chr_path);
+
+ qemu_chr_add_handlers(server->chr, chr_can_read, chr_read, NULL, server);
+
+ g_mutex_init(&server->data_mutex);
+ g_cond_init(&server->data_cond);
+
+ server->log_fd = -1;
+
+ return server;
+}
+
+#define GET_QEMU_CMD(s) \
+ g_strdup_printf(QEMU_CMD, 512, 512, (root), (s)->chr_name, \
+ (s)->socket_path, (s)->chr_name)
+
+#define GET_QEMU_CMDE(s, mem, extra, ...) \
+ g_strdup_printf(QEMU_CMD extra, (mem), (mem), (root), (s)->chr_name, \
+ (s)->socket_path, (s)->chr_name, ##__VA_ARGS__)
+
+static void test_server_free(TestServer *server)
+{
+ int i;
+
+ qemu_chr_delete(server->chr);
+
+ for (i = 0; i < server->fds_num; i++) {
+ close(server->fds[i]);
+ }
+
+ if (server->log_fd != -1) {
+ close(server->log_fd);
+ }
+
+ unlink(server->socket_path);
+ g_free(server->socket_path);
+
+
+ g_free(server->chr_name);
+ g_free(server);
+}
+
+static void wait_for_log_fd(TestServer *s)
+{
+ gint64 end_time;
+
+ g_mutex_lock(&s->data_mutex);
+ end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
+ while (s->log_fd == -1) {
+ if (!g_cond_wait_until(&s->data_cond, &s->data_mutex, end_time)) {
+ /* timeout has passed */
+ g_assert(s->log_fd != -1);
+ break;
+ }
+ }
+
+ g_mutex_unlock(&s->data_mutex);
+}
+
+static void write_guest_mem(TestServer *s, uint32 seed)
+{
+ uint32_t *guest_mem;
+ int i, j;
+ size_t size;
+
+ wait_for_fds(s);
+
+ /* iterate all regions */
+ for (i = 0; i < s->fds_num; i++) {
+
+ /* We'll write only the region statring at 0x0 */
+ if (s->memory.regions[i].guest_phys_addr != 0x0) {
+ continue;
+ }
+
+ g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024);
+
+ size = s->memory.regions[i].memory_size +
+ s->memory.regions[i].mmap_offset;
+
+ guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, s->fds[i], 0);
+
+ g_assert(guest_mem != MAP_FAILED);
+ guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem));
+
+ for (j = 0; j < 256; j++) {
+ guest_mem[j] = seed + j;
+ }
+
+ munmap(guest_mem, s->memory.regions[i].memory_size);
+ break;
+ }
+}
+
+static guint64 get_log_size(TestServer *s)
+{
+ guint64 log_size = 0;
+ int i;
+
+ for (i = 0; i < s->memory.nregions; ++i) {
+ VhostUserMemoryRegion *reg = &s->memory.regions[i];
+ guint64 last = range_get_last(reg->guest_phys_addr,
+ reg->memory_size);
+ log_size = MAX(log_size, last / (8 * VHOST_LOG_PAGE) + 1);
+ }
+
+ return log_size;
+}
+
+typedef struct TestMigrateSource {
+ GSource source;
+ TestServer *src;
+ TestServer *dest;
+} TestMigrateSource;
+
+static gboolean
+test_migrate_source_check(GSource *source)
+{
+ TestMigrateSource *t = (TestMigrateSource *)source;
+ gboolean overlap = t->src->fds_num > 0 && t->dest->fds_num > 0;
+
+ g_assert(!overlap);
+
+ return FALSE;
+}
+
+GSourceFuncs test_migrate_source_funcs = {
+ NULL,
+ test_migrate_source_check,
+ NULL,
+ NULL
+};
+
+static void test_migrate(void)
+{
+ TestServer *s = test_server_new("src");
+ TestServer *dest = test_server_new("dest");
+ const char *uri = "tcp:127.0.0.1:1234";
+ QTestState *global = global_qtest, *from, *to;
+ GSource *source;
+ gchar *cmd;
+ QDict *rsp;
+ guint8 *log;
+ guint64 size;
+
+ cmd = GET_QEMU_CMDE(s, 2, "");
+ from = qtest_start(cmd);
+ g_free(cmd);
+
+ wait_for_fds(s);
+ size = get_log_size(s);
+ g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
+
+ cmd = GET_QEMU_CMDE(dest, 2, " -incoming %s", uri);
+ to = qtest_init(cmd);
+ g_free(cmd);
+
+ source = g_source_new(&test_migrate_source_funcs,
+ sizeof(TestMigrateSource));
+ ((TestMigrateSource *)source)->src = s;
+ ((TestMigrateSource *)source)->dest = dest;
+ g_source_attach(source, NULL);
+
+ /* slow down migration to have time to fiddle with log */
+ /* TODO: qtest could learn to break on some places */
+ rsp = qmp("{ 'execute': 'migrate_set_speed',"
+ "'arguments': { 'value': 10 } }");
+ g_assert(qdict_haskey(rsp, "return"));
+ QDECREF(rsp);
+
+ cmd = g_strdup_printf("{ 'execute': 'migrate',"
+ "'arguments': { 'uri': '%s' } }",
+ uri);
+ rsp = qmp(cmd);
+ g_free(cmd);
+ g_assert(qdict_haskey(rsp, "return"));
+ QDECREF(rsp);
+
+ wait_for_log_fd(s);
+
+ log = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->log_fd, 0);
+ g_assert(log != MAP_FAILED);
+
+ /* modify first page */
+ write_guest_mem(s, 0x42);
+ log[0] = 1;
+ munmap(log, size);
+
+ /* speed things up */
+ rsp = qmp("{ 'execute': 'migrate_set_speed',"
+ "'arguments': { 'value': 0 } }");
+ g_assert(qdict_haskey(rsp, "return"));
+ QDECREF(rsp);
+
+ qmp_eventwait("STOP");
+
+ global_qtest = to;
+ qmp_eventwait("RESUME");
+
+ read_guest_mem(dest);
+
+ g_source_destroy(source);
+ g_source_unref(source);
+
+ qtest_quit(to);
+ test_server_free(dest);
+ qtest_quit(from);
+ test_server_free(s);
+
+ global_qtest = global;
+}
+
int main(int argc, char **argv)
{
QTestState *s = NULL;
- CharDriverState *chr = NULL;
+ TestServer *server = NULL;
const char *hugefs;
- char *socket_path = 0;
- char *qemu_cmd = 0;
- char *chr_path = 0;
+ char *qemu_cmd = NULL;
int ret;
char template[] = "/tmp/vhost-test-XXXXXX";
- const char *tmpfs;
- const char *root;
g_test_init(&argc, &argv, NULL);
module_call_init(MODULE_INIT_QOM);
+ qemu_add_opts(&qemu_chardev_opts);
tmpfs = mkdtemp(template);
if (!tmpfs) {
- g_test_message("mkdtemp on path (%s): %s\n", template, strerror(errno));
+ g_test_message("mkdtemp on path (%s): %s\n", template, strerror(errno));
}
g_assert(tmpfs);
@@ -330,25 +596,18 @@ int main(int argc, char **argv)
root = tmpfs;
}
- socket_path = g_strdup_printf("%s/vhost.sock", tmpfs);
-
- /* create char dev and add read handlers */
- qemu_add_opts(&qemu_chardev_opts);
- chr_path = g_strdup_printf("unix:%s,server,nowait", socket_path);
- chr = qemu_chr_new("chr0", chr_path, NULL);
- g_free(chr_path);
- qemu_chr_add_handlers(chr, chr_can_read, chr_read, NULL, chr);
+ server = test_server_new("test");
/* run the main loop thread so the chardev may operate */
- g_mutex_init(&data_mutex);
- g_cond_init(&data_cond);
g_thread_new(NULL, thread_function, NULL);
- qemu_cmd = g_strdup_printf(QEMU_CMD, root, socket_path);
+ qemu_cmd = GET_QEMU_CMD(server);
+
s = qtest_start(qemu_cmd);
g_free(qemu_cmd);
- qtest_add_func("/vhost-user/read-guest-mem", read_guest_mem);
+ qtest_add_data_func("/vhost-user/read-guest-mem", server, read_guest_mem);
+ qtest_add_func("/vhost-user/migrate", test_migrate);
ret = g_test_run();
@@ -357,8 +616,7 @@ int main(int argc, char **argv)
}
/* cleanup */
- unlink(socket_path);
- g_free(socket_path);
+ test_server_free(server);
ret = rmdir(tmpfs);
if (ret != 0) {
diff --git a/thread-pool.c b/thread-pool.c
index ac909f4..402c778 100644
--- a/thread-pool.c
+++ b/thread-pool.c
@@ -18,7 +18,7 @@
#include "qemu/queue.h"
#include "qemu/thread.h"
#include "qemu/osdep.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "trace.h"
#include "block/thread-pool.h"
#include "qemu/main-loop.h"
diff --git a/trace-events b/trace-events
index a0ddc6b..f237c7f 100644
--- a/trace-events
+++ b/trace-events
@@ -1705,3 +1705,6 @@ qcrypto_tls_creds_x509_load_cert_list(void *creds, const char *file) "TLS creds
# crypto/tlssession.c
qcrypto_tls_session_new(void *session, void *creds, const char *hostname, const char *aclname, int endpoint) "TLS session new session=%p creds=%p hostname=%s aclname=%s endpoint=%d"
+
+# net/vhost-user.c
+vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
diff --git a/ui/vnc.c b/ui/vnc.c
index d73966a..faff054 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -647,49 +647,6 @@ void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
vnc_write_s32(vs, encoding);
}
-void buffer_reserve(Buffer *buffer, size_t len)
-{
- if ((buffer->capacity - buffer->offset) < len) {
- buffer->capacity += (len + 1024);
- buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
- }
-}
-
-static int buffer_empty(Buffer *buffer)
-{
- return buffer->offset == 0;
-}
-
-uint8_t *buffer_end(Buffer *buffer)
-{
- return buffer->buffer + buffer->offset;
-}
-
-void buffer_reset(Buffer *buffer)
-{
- buffer->offset = 0;
-}
-
-void buffer_free(Buffer *buffer)
-{
- g_free(buffer->buffer);
- buffer->offset = 0;
- buffer->capacity = 0;
- buffer->buffer = NULL;
-}
-
-void buffer_append(Buffer *buffer, const void *data, size_t len)
-{
- memcpy(buffer->buffer + buffer->offset, data, len);
- buffer->offset += len;
-}
-
-void buffer_advance(Buffer *buf, size_t len)
-{
- memmove(buf->buffer, buf->buffer + len,
- (buf->offset - len));
- buf->offset -= len;
-}
static void vnc_desktop_resize(VncState *vs)
{
@@ -3506,18 +3463,14 @@ void vnc_display_open(const char *id, Error **errp)
{
VncDisplay *vs = vnc_display_find(id);
QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
- QemuOpts *sopts, *wsopts;
+ SocketAddress *saddr = NULL, *wsaddr = NULL;
const char *share, *device_id;
QemuConsole *con;
bool password = false;
bool reverse = false;
const char *vnc;
- const char *has_to;
char *h;
- bool has_ipv4 = false;
- bool has_ipv6 = false;
const char *credid;
- const char *websocket;
bool sasl = false;
#ifdef CONFIG_VNC_SASL
int saslErr;
@@ -3539,44 +3492,83 @@ void vnc_display_open(const char *id, Error **errp)
return;
}
- sopts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
- wsopts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
-
h = strrchr(vnc, ':');
if (h) {
- char *host;
size_t hlen = h - vnc;
- if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
- host = g_strndup(vnc + 1, hlen - 2);
+ const char *websocket = qemu_opt_get(opts, "websocket");
+ int to = qemu_opt_get_number(opts, "to", 0);
+ bool has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
+ bool has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
+
+ saddr = g_new0(SocketAddress, 1);
+ if (websocket) {
+ if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
+ error_setg(errp,
+ "SHA1 hash support is required for websockets");
+ goto fail;
+ }
+
+ wsaddr = g_new0(SocketAddress, 1);
+ vs->ws_enabled = true;
+ }
+
+ if (strncmp(vnc, "unix:", 5) == 0) {
+ saddr->kind = SOCKET_ADDRESS_KIND_UNIX;
+ saddr->q_unix = g_new0(UnixSocketAddress, 1);
+ saddr->q_unix->path = g_strdup(vnc + 5);
+
+ if (vs->ws_enabled) {
+ error_setg(errp, "UNIX sockets not supported with websock");
+ goto fail;
+ }
} else {
- host = g_strndup(vnc, hlen);
+ unsigned long long baseport;
+ saddr->kind = SOCKET_ADDRESS_KIND_INET;
+ saddr->inet = g_new0(InetSocketAddress, 1);
+ if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
+ saddr->inet->host = g_strndup(vnc + 1, hlen - 2);
+ } else {
+ saddr->inet->host = g_strndup(vnc, hlen);
+ }
+ if (parse_uint_full(h + 1, &baseport, 10) < 0) {
+ error_setg(errp, "can't convert to a number: %s", h + 1);
+ goto fail;
+ }
+ if (baseport > 65535 ||
+ baseport + 5900 > 65535) {
+ error_setg(errp, "port %s out of range", h + 1);
+ goto fail;
+ }
+ saddr->inet->port = g_strdup_printf(
+ "%d", (int)baseport + 5900);
+
+ if (to) {
+ saddr->inet->has_to = true;
+ saddr->inet->to = to;
+ }
+ saddr->inet->ipv4 = saddr->inet->has_ipv4 = has_ipv4;
+ saddr->inet->ipv6 = saddr->inet->has_ipv6 = has_ipv6;
+
+ if (vs->ws_enabled) {
+ wsaddr->kind = SOCKET_ADDRESS_KIND_INET;
+ wsaddr->inet = g_new0(InetSocketAddress, 1);
+ wsaddr->inet->host = g_strdup(saddr->inet->host);
+ wsaddr->inet->port = g_strdup(websocket);
+
+ if (to) {
+ wsaddr->inet->has_to = true;
+ wsaddr->inet->to = to;
+ }
+ wsaddr->inet->ipv4 = wsaddr->inet->has_ipv4 = has_ipv4;
+ wsaddr->inet->ipv6 = wsaddr->inet->has_ipv6 = has_ipv6;
+ }
}
- qemu_opt_set(sopts, "host", host, &error_abort);
- qemu_opt_set(wsopts, "host", host, &error_abort);
- qemu_opt_set(sopts, "port", h+1, &error_abort);
- g_free(host);
} else {
error_setg(errp, "no vnc port specified");
goto fail;
}
- has_to = qemu_opt_get(opts, "to");
- has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
- has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
- if (has_to) {
- qemu_opt_set(sopts, "to", has_to, &error_abort);
- qemu_opt_set(wsopts, "to", has_to, &error_abort);
- }
- if (has_ipv4) {
- qemu_opt_set(sopts, "ipv4", "on", &error_abort);
- qemu_opt_set(wsopts, "ipv4", "on", &error_abort);
- }
- if (has_ipv6) {
- qemu_opt_set(sopts, "ipv6", "on", &error_abort);
- qemu_opt_set(wsopts, "ipv6", "on", &error_abort);
- }
-
password = qemu_opt_get_bool(opts, "password", false);
if (password) {
if (fips_get_state()) {
@@ -3682,16 +3674,6 @@ void vnc_display_open(const char *id, Error **errp)
}
vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
- websocket = qemu_opt_get(opts, "websocket");
- if (websocket) {
- vs->ws_enabled = true;
- qemu_opt_set(wsopts, "port", websocket, &error_abort);
- if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
- error_setg(errp, "SHA1 hash support is required for websockets");
- goto fail;
- }
- }
-
#ifdef CONFIG_VNC_JPEG
vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
#endif
@@ -3725,7 +3707,7 @@ void vnc_display_open(const char *id, Error **errp)
}
#endif
- if (vnc_display_setup_auth(vs, password, sasl, websocket, errp) < 0) {
+ if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
goto fail;
}
@@ -3770,37 +3752,31 @@ void vnc_display_open(const char *id, Error **errp)
int csock;
vs->lsock = -1;
vs->lwebsock = -1;
- if (strncmp(vnc, "unix:", 5) == 0) {
- csock = unix_connect(vnc+5, errp);
- } else {
- csock = inet_connect(vnc, errp);
+ if (vs->ws_enabled) {
+ error_setg(errp, "Cannot use websockets in reverse mode");
+ goto fail;
}
+ csock = socket_connect(saddr, errp, NULL, NULL);
if (csock < 0) {
goto fail;
}
+ vs->is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX;
vnc_connect(vs, csock, false, false);
} else {
/* listen for connects */
- if (strncmp(vnc, "unix:", 5) == 0) {
- vs->lsock = unix_listen(vnc+5, NULL, 0, errp);
- if (vs->lsock < 0) {
- goto fail;
- }
- vs->is_unix = true;
- } else {
- vs->lsock = inet_listen_opts(sopts, 5900, errp);
- if (vs->lsock < 0) {
- goto fail;
- }
- if (vs->ws_enabled) {
- vs->lwebsock = inet_listen_opts(wsopts, 0, errp);
- if (vs->lwebsock < 0) {
- if (vs->lsock != -1) {
- close(vs->lsock);
- vs->lsock = -1;
- }
- goto fail;
+ vs->lsock = socket_listen(saddr, errp);
+ if (vs->lsock < 0) {
+ goto fail;
+ }
+ vs->is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX;
+ if (vs->ws_enabled) {
+ vs->lwebsock = socket_listen(wsaddr, errp);
+ if (vs->lwebsock < 0) {
+ if (vs->lsock != -1) {
+ close(vs->lsock);
+ vs->lsock = -1;
}
+ goto fail;
}
}
vs->enabled = true;
@@ -3810,13 +3786,14 @@ void vnc_display_open(const char *id, Error **errp)
NULL, vs);
}
}
- qemu_opts_del(sopts);
- qemu_opts_del(wsopts);
+
+ qapi_free_SocketAddress(saddr);
+ qapi_free_SocketAddress(wsaddr);
return;
fail:
- qemu_opts_del(sopts);
- qemu_opts_del(wsopts);
+ qapi_free_SocketAddress(saddr);
+ qapi_free_SocketAddress(wsaddr);
vs->enabled = false;
vs->ws_enabled = false;
}
diff --git a/ui/vnc.h b/ui/vnc.h
index 4dd769c..2863f58 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -34,6 +34,7 @@
#include "audio/audio.h"
#include "qemu/bitmap.h"
#include "crypto/tlssession.h"
+#include "qemu/buffer.h"
#include <zlib.h>
#include <stdbool.h>
@@ -56,13 +57,6 @@
*
*****************************************************************************/
-typedef struct Buffer
-{
- size_t capacity;
- size_t offset;
- uint8_t *buffer;
-} Buffer;
-
typedef struct VncState VncState;
typedef struct VncJob VncJob;
typedef struct VncRect VncRect;
@@ -535,14 +529,6 @@ ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, int last_errno);
void start_client_init(VncState *vs);
void start_auth_vnc(VncState *vs);
-/* Buffer management */
-void buffer_reserve(Buffer *buffer, size_t len);
-void buffer_reset(Buffer *buffer);
-void buffer_free(Buffer *buffer);
-void buffer_append(Buffer *buffer, const void *data, size_t len);
-void buffer_advance(Buffer *buf, size_t len);
-uint8_t *buffer_end(Buffer *buffer);
-
/* Misc helpers */
diff --git a/util/Makefile.objs b/util/Makefile.objs
index 114d657..d7cc399 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -1,13 +1,20 @@
util-obj-y = osdep.o cutils.o unicode.o qemu-timer-common.o
-util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o event_notifier-win32.o
-util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o qemu-openpty.o
+util-obj-$(CONFIG_POSIX) += compatfd.o
+util-obj-$(CONFIG_POSIX) += event_notifier-posix.o
+util-obj-$(CONFIG_POSIX) += mmap-alloc.o
+util-obj-$(CONFIG_POSIX) += oslib-posix.o
+util-obj-$(CONFIG_POSIX) += qemu-openpty.o
+util-obj-$(CONFIG_POSIX) += qemu-thread-posix.o
+util-obj-$(CONFIG_WIN32) += event_notifier-win32.o
+util-obj-$(CONFIG_POSIX) += memfd.o
+util-obj-$(CONFIG_WIN32) += oslib-win32.o
+util-obj-$(CONFIG_WIN32) += qemu-thread-win32.o
util-obj-y += envlist.o path.o module.o
util-obj-$(call lnot,$(CONFIG_INT128)) += host-utils.o
util-obj-y += bitmap.o bitops.o hbitmap.o
util-obj-y += fifo8.o
util-obj-y += acl.o
util-obj-y += error.o qemu-error.o
-util-obj-$(CONFIG_POSIX) += compatfd.o
util-obj-y += id.o
util-obj-y += iov.o qemu-config.o qemu-sockets.o uri.o notify.o
util-obj-y += qemu-option.o qemu-progress.o
@@ -18,3 +25,7 @@ util-obj-y += getauxval.o
util-obj-y += readline.o
util-obj-y += rfifolock.o
util-obj-y += rcu.o
+util-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
+util-obj-y += qemu-coroutine-sleep.o
+util-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o
+util-obj-y += buffer.o
diff --git a/util/buffer.c b/util/buffer.c
new file mode 100644
index 0000000..cedd055
--- /dev/null
+++ b/util/buffer.c
@@ -0,0 +1,65 @@
+/*
+ * QEMU generic buffers
+ *
+ * Copyright (c) 2015 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/buffer.h"
+
+void buffer_reserve(Buffer *buffer, size_t len)
+{
+ if ((buffer->capacity - buffer->offset) < len) {
+ buffer->capacity += (len + 1024);
+ buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
+ }
+}
+
+gboolean buffer_empty(Buffer *buffer)
+{
+ return buffer->offset == 0;
+}
+
+uint8_t *buffer_end(Buffer *buffer)
+{
+ return buffer->buffer + buffer->offset;
+}
+
+void buffer_reset(Buffer *buffer)
+{
+ buffer->offset = 0;
+}
+
+void buffer_free(Buffer *buffer)
+{
+ g_free(buffer->buffer);
+ buffer->offset = 0;
+ buffer->capacity = 0;
+ buffer->buffer = NULL;
+}
+
+void buffer_append(Buffer *buffer, const void *data, size_t len)
+{
+ memcpy(buffer->buffer + buffer->offset, data, len);
+ buffer->offset += len;
+}
+
+void buffer_advance(Buffer *buffer, size_t len)
+{
+ memmove(buffer->buffer, buffer->buffer + len,
+ (buffer->offset - len));
+ buffer->offset -= len;
+}
diff --git a/coroutine-gthread.c b/util/coroutine-gthread.c
index 6bd6d6b..0bcd778 100644
--- a/coroutine-gthread.c
+++ b/util/coroutine-gthread.c
@@ -20,7 +20,7 @@
#include <glib.h>
#include "qemu-common.h"
-#include "block/coroutine_int.h"
+#include "qemu/coroutine_int.h"
typedef struct {
Coroutine base;
diff --git a/coroutine-sigaltstack.c b/util/coroutine-sigaltstack.c
index 63519ff..39842a4 100644
--- a/coroutine-sigaltstack.c
+++ b/util/coroutine-sigaltstack.c
@@ -31,7 +31,7 @@
#include <pthread.h>
#include <signal.h>
#include "qemu-common.h"
-#include "block/coroutine_int.h"
+#include "qemu/coroutine_int.h"
typedef struct {
Coroutine base;
diff --git a/coroutine-ucontext.c b/util/coroutine-ucontext.c
index 259fcb4..26cbebb 100644
--- a/coroutine-ucontext.c
+++ b/util/coroutine-ucontext.c
@@ -27,7 +27,7 @@
#include <stdint.h>
#include <ucontext.h>
#include "qemu-common.h"
-#include "block/coroutine_int.h"
+#include "qemu/coroutine_int.h"
#ifdef CONFIG_VALGRIND_H
#include <valgrind/valgrind.h>
diff --git a/coroutine-win32.c b/util/coroutine-win32.c
index 17ace37..4f922c5 100644
--- a/coroutine-win32.c
+++ b/util/coroutine-win32.c
@@ -23,7 +23,7 @@
*/
#include "qemu-common.h"
-#include "block/coroutine_int.h"
+#include "qemu/coroutine_int.h"
typedef struct
{
diff --git a/util/memfd.c b/util/memfd.c
new file mode 100644
index 0000000..7c40691
--- /dev/null
+++ b/util/memfd.c
@@ -0,0 +1,162 @@
+/*
+ * memfd.c
+ *
+ * Copyright (c) 2015 Red Hat, Inc.
+ *
+ * QEMU library functions on POSIX which are shared between QEMU and
+ * the QEMU tools.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+
+#include <glib.h>
+#include <glib/gprintf.h>
+
+#include <sys/mman.h>
+
+#include "qemu/memfd.h"
+
+#ifdef CONFIG_MEMFD
+#include <sys/memfd.h>
+#elif defined CONFIG_LINUX
+#include <sys/syscall.h>
+#include <asm/unistd.h>
+
+static int memfd_create(const char *name, unsigned int flags)
+{
+#ifdef __NR_memfd_create
+ return syscall(__NR_memfd_create, name, flags);
+#else
+ return -1;
+#endif
+}
+#endif
+
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC 0x0001U
+#endif
+
+#ifndef MFD_ALLOW_SEALING
+#define MFD_ALLOW_SEALING 0x0002U
+#endif
+
+/*
+ * This is a best-effort helper for shared memory allocation, with
+ * optional sealing. The helper will do his best to allocate using
+ * memfd with sealing, but may fallback on other methods without
+ * sealing.
+ */
+void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals,
+ int *fd)
+{
+ void *ptr;
+ int mfd = -1;
+
+ *fd = -1;
+
+#ifdef CONFIG_LINUX
+ if (seals) {
+ mfd = memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
+ }
+
+ if (mfd == -1) {
+ /* some systems have memfd without sealing */
+ mfd = memfd_create(name, MFD_CLOEXEC);
+ seals = 0;
+ }
+#endif
+
+ if (mfd != -1) {
+ if (ftruncate(mfd, size) == -1) {
+ perror("ftruncate");
+ close(mfd);
+ return NULL;
+ }
+
+ if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) {
+ perror("fcntl");
+ close(mfd);
+ return NULL;
+ }
+ } else {
+ const char *tmpdir = g_get_tmp_dir();
+ gchar *fname;
+
+ fname = g_strdup_printf("%s/memfd-XXXXXX", tmpdir);
+ mfd = mkstemp(fname);
+ unlink(fname);
+ g_free(fname);
+
+ if (mfd == -1) {
+ perror("mkstemp");
+ return NULL;
+ }
+
+ if (ftruncate(mfd, size) == -1) {
+ perror("ftruncate");
+ close(mfd);
+ return NULL;
+ }
+ }
+
+ ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, 0);
+ if (ptr == MAP_FAILED) {
+ perror("mmap");
+ close(mfd);
+ return NULL;
+ }
+
+ *fd = mfd;
+ return ptr;
+}
+
+void qemu_memfd_free(void *ptr, size_t size, int fd)
+{
+ if (ptr) {
+ munmap(ptr, size);
+ }
+
+ if (fd != -1) {
+ close(fd);
+ }
+}
+
+enum {
+ MEMFD_KO,
+ MEMFD_OK,
+ MEMFD_TODO
+};
+
+bool qemu_memfd_check(void)
+{
+ static int memfd_check = MEMFD_TODO;
+
+ if (memfd_check == MEMFD_TODO) {
+ int fd;
+ void *ptr;
+
+ ptr = qemu_memfd_alloc("test", 4096, 0, &fd);
+ memfd_check = ptr ? MEMFD_OK : MEMFD_KO;
+ qemu_memfd_free(ptr, 4096, fd);
+ }
+
+ return memfd_check == MEMFD_OK;
+}
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
new file mode 100644
index 0000000..1394269
--- /dev/null
+++ b/util/mmap-alloc.c
@@ -0,0 +1,71 @@
+/*
+ * Support for RAM backed by mmaped host memory.
+ *
+ * Copyright (c) 2015 Red Hat, Inc.
+ *
+ * Authors:
+ * Michael S. Tsirkin <mst@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+#include <qemu/mmap-alloc.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <assert.h>
+
+void *qemu_ram_mmap(int fd, size_t size, size_t align, bool shared)
+{
+ /*
+ * Note: this always allocates at least one extra page of virtual address
+ * space, even if size is already aligned.
+ */
+ size_t total = size + align;
+ void *ptr = mmap(0, total, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ size_t offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr;
+ void *ptr1;
+
+ if (ptr == MAP_FAILED) {
+ return NULL;
+ }
+
+ /* Make sure align is a power of 2 */
+ assert(!(align & (align - 1)));
+ /* Always align to host page size */
+ assert(align >= getpagesize());
+
+ ptr1 = mmap(ptr + offset, size, PROT_READ | PROT_WRITE,
+ MAP_FIXED |
+ (fd == -1 ? MAP_ANONYMOUS : 0) |
+ (shared ? MAP_SHARED : MAP_PRIVATE),
+ fd, 0);
+ if (ptr1 == MAP_FAILED) {
+ munmap(ptr, total);
+ return NULL;
+ }
+
+ ptr += offset;
+ total -= offset;
+
+ if (offset > 0) {
+ munmap(ptr - offset, offset);
+ }
+
+ /*
+ * Leave a single PROT_NONE page allocated after the RAM block, to serve as
+ * a guard page guarding against potential buffer overflows.
+ */
+ if (total > size + getpagesize()) {
+ munmap(ptr + size + getpagesize(), total - size - getpagesize());
+ }
+
+ return ptr;
+}
+
+void qemu_ram_munmap(void *ptr, size_t size)
+{
+ if (ptr) {
+ /* Unmap both the RAM block and the guard page */
+ munmap(ptr, size + getpagesize());
+ }
+}
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index a0fcdc2..914cef5 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -72,6 +72,8 @@ extern int daemon(int, int);
#include <sys/sysctl.h>
#endif
+#include <qemu/mmap-alloc.h>
+
int qemu_get_thread_id(void)
{
#if defined(__linux__)
@@ -128,10 +130,7 @@ void *qemu_memalign(size_t alignment, size_t size)
void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment)
{
size_t align = QEMU_VMALLOC_ALIGN;
- size_t total = size + align;
- void *ptr = mmap(0, total, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- size_t offset = QEMU_ALIGN_UP((uintptr_t)ptr, align) - (uintptr_t)ptr;
- void *ptr1;
+ void *ptr = qemu_ram_mmap(-1, size, align, false);
if (ptr == MAP_FAILED) {
return NULL;
@@ -141,23 +140,6 @@ void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment)
*alignment = align;
}
- ptr1 = mmap(ptr + offset, size, PROT_READ | PROT_WRITE,
- MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- if (ptr1 == MAP_FAILED) {
- munmap(ptr, total);
- return NULL;
- }
-
- ptr += offset;
- total -= offset;
-
- if (offset > 0) {
- munmap(ptr - offset, offset);
- }
- if (total > size + getpagesize()) {
- munmap(ptr + size + getpagesize(), total - size - getpagesize());
- }
-
trace_qemu_anon_ram_alloc(size, ptr);
return ptr;
}
@@ -171,9 +153,7 @@ void qemu_vfree(void *ptr)
void qemu_anon_ram_free(void *ptr, size_t size)
{
trace_qemu_anon_ram_free(ptr, size);
- if (ptr) {
- munmap(ptr, size + getpagesize());
- }
+ qemu_ram_munmap(ptr, size);
}
void qemu_set_block(int fd)
@@ -490,3 +470,74 @@ int qemu_read_password(char *buf, int buf_size)
printf("\n");
return ret;
}
+
+
+pid_t qemu_fork(Error **errp)
+{
+ sigset_t oldmask, newmask;
+ struct sigaction sig_action;
+ int saved_errno;
+ pid_t pid;
+
+ /*
+ * Need to block signals now, so that child process can safely
+ * kill off caller's signal handlers without a race.
+ */
+ sigfillset(&newmask);
+ if (pthread_sigmask(SIG_SETMASK, &newmask, &oldmask) != 0) {
+ error_setg_errno(errp, errno,
+ "cannot block signals");
+ return -1;
+ }
+
+ pid = fork();
+ saved_errno = errno;
+
+ if (pid < 0) {
+ /* attempt to restore signal mask, but ignore failure, to
+ * avoid obscuring the fork failure */
+ (void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
+ error_setg_errno(errp, saved_errno,
+ "cannot fork child process");
+ errno = saved_errno;
+ return -1;
+ } else if (pid) {
+ /* parent process */
+
+ /* Restore our original signal mask now that the child is
+ * safely running. Only documented failures are EFAULT (not
+ * possible, since we are using just-grabbed mask) or EINVAL
+ * (not possible, since we are using correct arguments). */
+ (void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
+ } else {
+ /* child process */
+ size_t i;
+
+ /* Clear out all signal handlers from parent so nothing
+ * unexpected can happen in our child once we unblock
+ * signals */
+ sig_action.sa_handler = SIG_DFL;
+ sig_action.sa_flags = 0;
+ sigemptyset(&sig_action.sa_mask);
+
+ for (i = 1; i < NSIG; i++) {
+ /* Only possible errors are EFAULT or EINVAL The former
+ * won't happen, the latter we expect, so no need to check
+ * return value */
+ (void)sigaction(i, &sig_action, NULL);
+ }
+
+ /* Unmask all signals in child, since we've no idea what the
+ * caller's done with their signal mask and don't want to
+ * propagate that to children */
+ sigemptyset(&newmask);
+ if (pthread_sigmask(SIG_SETMASK, &newmask, NULL) != 0) {
+ Error *local_err = NULL;
+ error_setg_errno(&local_err, errno,
+ "cannot unblock signals");
+ error_report_err(local_err);
+ _exit(1);
+ }
+ }
+ return pid;
+}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 08f5a9c..09f9e98 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -496,3 +496,12 @@ int qemu_read_password(char *buf, int buf_size)
buf[i] = '\0';
return 0;
}
+
+
+pid_t qemu_fork(Error **errp)
+{
+ errno = ENOSYS;
+ error_setg_errno(errp, errno,
+ "cannot fork child process");
+ return -1;
+}
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 5fcfd0e..687fd34 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -219,6 +219,14 @@ static QemuOptsList machine_opts = {
.name = "suppress-vmdesc",
.type = QEMU_OPT_BOOL,
.help = "Set on to disable self-describing migration",
+ },{
+ .name = "aes-key-wrap",
+ .type = QEMU_OPT_BOOL,
+ .help = "enable/disable AES key wrapping using the CPACF wrapping key",
+ },{
+ .name = "dea-key-wrap",
+ .type = QEMU_OPT_BOOL,
+ .help = "enable/disable DEA key wrapping using the CPACF wrapping key",
},
{ /* End of list */ }
}
diff --git a/qemu-coroutine-io.c b/util/qemu-coroutine-io.c
index 28dc735..e1eae73 100644
--- a/qemu-coroutine-io.c
+++ b/util/qemu-coroutine-io.c
@@ -24,7 +24,7 @@
*/
#include "qemu-common.h"
#include "qemu/sockets.h"
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "qemu/iov.h"
#include "qemu/main-loop.h"
diff --git a/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c
index 6b49033..130ee19 100644
--- a/qemu-coroutine-lock.c
+++ b/util/qemu-coroutine-lock.c
@@ -23,8 +23,8 @@
*/
#include "qemu-common.h"
-#include "block/coroutine.h"
-#include "block/coroutine_int.h"
+#include "qemu/coroutine.h"
+#include "qemu/coroutine_int.h"
#include "qemu/queue.h"
#include "trace.h"
diff --git a/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
index 9abb7fd..b35db56 100644
--- a/qemu-coroutine-sleep.c
+++ b/util/qemu-coroutine-sleep.c
@@ -11,7 +11,7 @@
*
*/
-#include "block/coroutine.h"
+#include "qemu/coroutine.h"
#include "qemu/timer.h"
#include "block/aio.h"
diff --git a/qemu-coroutine.c b/util/qemu-coroutine.c
index c17a92b..8953560 100644
--- a/qemu-coroutine.c
+++ b/util/qemu-coroutine.c
@@ -16,8 +16,8 @@
#include "qemu-common.h"
#include "qemu/thread.h"
#include "qemu/atomic.h"
-#include "block/coroutine.h"
-#include "block/coroutine_int.h"
+#include "qemu/coroutine.h"
+#include "qemu/coroutine_int.h"
enum {
POOL_BATCH_SIZE = 64,
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 0a041a9..9142917 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -25,6 +25,9 @@
#include "monitor/monitor.h"
#include "qemu/sockets.h"
#include "qemu/main-loop.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi-visit.h"
#ifndef AI_ADDRCONFIG
# define AI_ADDRCONFIG 0
@@ -125,12 +128,15 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
ai.ai_family = PF_UNSPEC;
ai.ai_socktype = SOCK_STREAM;
- if ((qemu_opt_get(opts, "host") == NULL) ||
- (qemu_opt_get(opts, "port") == NULL)) {
- error_setg(errp, "host and/or port not specified");
+ if ((qemu_opt_get(opts, "host") == NULL)) {
+ error_setg(errp, "host not specified");
return -1;
}
- pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port"));
+ if (qemu_opt_get(opts, "port") != NULL) {
+ pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port"));
+ } else {
+ port[0] = '\0';
+ }
addr = qemu_opt_get(opts, "host");
to = qemu_opt_get_number(opts, "to", 0);
@@ -142,6 +148,10 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
/* lookup */
if (port_offset) {
unsigned long long baseport;
+ if (strlen(port) == 0) {
+ error_setg(errp, "port not specified");
+ return -1;
+ }
if (parse_uint_full(port, &baseport, 10) < 0) {
error_setg(errp, "can't convert to a number: %s", port);
return -1;
@@ -153,7 +163,8 @@ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
}
snprintf(port, sizeof(port), "%d", (int)baseport + port_offset);
}
- rc = getaddrinfo(strlen(addr) ? addr : NULL, port, &ai, &res);
+ rc = getaddrinfo(strlen(addr) ? addr : NULL,
+ strlen(port) ? port : NULL, &ai, &res);
if (rc != 0) {
error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
gai_strerror(rc));
@@ -1018,3 +1029,140 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
qemu_opts_del(opts);
return fd;
}
+
+
+static SocketAddress *
+socket_sockaddr_to_address_inet(struct sockaddr_storage *sa,
+ socklen_t salen,
+ Error **errp)
+{
+ char host[NI_MAXHOST];
+ char serv[NI_MAXSERV];
+ SocketAddress *addr;
+ int ret;
+
+ ret = getnameinfo((struct sockaddr *)sa, salen,
+ host, sizeof(host),
+ serv, sizeof(serv),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (ret != 0) {
+ error_setg(errp, "Cannot format numeric socket address: %s",
+ gai_strerror(ret));
+ return NULL;
+ }
+
+ addr = g_new0(SocketAddress, 1);
+ addr->kind = SOCKET_ADDRESS_KIND_INET;
+ addr->inet = g_new0(InetSocketAddress, 1);
+ addr->inet->host = g_strdup(host);
+ addr->inet->port = g_strdup(serv);
+ if (sa->ss_family == AF_INET) {
+ addr->inet->has_ipv4 = addr->inet->ipv4 = true;
+ } else {
+ addr->inet->has_ipv6 = addr->inet->ipv6 = true;
+ }
+
+ return addr;
+}
+
+
+#ifndef WIN32
+static SocketAddress *
+socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
+ socklen_t salen,
+ Error **errp)
+{
+ SocketAddress *addr;
+ struct sockaddr_un *su = (struct sockaddr_un *)sa;
+
+ addr = g_new0(SocketAddress, 1);
+ addr->kind = SOCKET_ADDRESS_KIND_UNIX;
+ addr->q_unix = g_new0(UnixSocketAddress, 1);
+ if (su->sun_path[0]) {
+ addr->q_unix->path = g_strndup(su->sun_path,
+ sizeof(su->sun_path));
+ }
+
+ return addr;
+}
+#endif /* WIN32 */
+
+static SocketAddress *
+socket_sockaddr_to_address(struct sockaddr_storage *sa,
+ socklen_t salen,
+ Error **errp)
+{
+ switch (sa->ss_family) {
+ case AF_INET:
+ case AF_INET6:
+ return socket_sockaddr_to_address_inet(sa, salen, errp);
+
+#ifndef WIN32
+ case AF_UNIX:
+ return socket_sockaddr_to_address_unix(sa, salen, errp);
+#endif /* WIN32 */
+
+ default:
+ error_setg(errp, "socket family %d unsupported",
+ sa->ss_family);
+ return NULL;
+ }
+ return 0;
+}
+
+
+SocketAddress *socket_local_address(int fd, Error **errp)
+{
+ struct sockaddr_storage ss;
+ socklen_t sslen = sizeof(ss);
+
+ if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) {
+ error_setg_errno(errp, socket_error(), "%s",
+ "Unable to query local socket address");
+ return NULL;
+ }
+
+ return socket_sockaddr_to_address(&ss, sslen, errp);
+}
+
+
+SocketAddress *socket_remote_address(int fd, Error **errp)
+{
+ struct sockaddr_storage ss;
+ socklen_t sslen = sizeof(ss);
+
+ if (getpeername(fd, (struct sockaddr *)&ss, &sslen) < 0) {
+ error_setg_errno(errp, socket_error(), "%s",
+ "Unable to query remote socket address");
+ return NULL;
+ }
+
+ return socket_sockaddr_to_address(&ss, sslen, errp);
+}
+
+
+void qapi_copy_SocketAddress(SocketAddress **p_dest,
+ SocketAddress *src)
+{
+ QmpOutputVisitor *qov;
+ QmpInputVisitor *qiv;
+ Visitor *ov, *iv;
+ QObject *obj;
+
+ *p_dest = NULL;
+
+ qov = qmp_output_visitor_new();
+ ov = qmp_output_get_visitor(qov);
+ visit_type_SocketAddress(ov, &src, NULL, &error_abort);
+ obj = qmp_output_get_qobject(qov);
+ qmp_output_visitor_cleanup(qov);
+ if (!obj) {
+ return;
+ }
+
+ qiv = qmp_input_visitor_new(obj);
+ iv = qmp_input_get_visitor(qiv);
+ visit_type_SocketAddress(iv, p_dest, NULL, &error_abort);
+ qmp_input_visitor_cleanup(qiv);
+ qobject_decref(obj);
+}
diff --git a/vl.c b/vl.c
index 7c806a2..332d828 100644
--- a/vl.c
+++ b/vl.c
@@ -512,6 +512,10 @@ static QemuOptsList qemu_fw_cfg_opts = {
.type = QEMU_OPT_STRING,
.help = "Sets the name of the file from which\n"
"the fw_cfg blob will be loaded",
+ }, {
+ .name = "string",
+ .type = QEMU_OPT_STRING,
+ .help = "Sets content of the blob to be inserted from a string",
},
{ /* end of list */ }
},
@@ -2239,11 +2243,16 @@ char *qemu_find_file(int type, const char *name)
return NULL;
}
+static inline bool nonempty_str(const char *str)
+{
+ return str && *str;
+}
+
static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
{
gchar *buf;
size_t size;
- const char *name, *file;
+ const char *name, *file, *str;
if (opaque == NULL) {
error_report("fw_cfg device not available");
@@ -2251,8 +2260,15 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
}
name = qemu_opt_get(opts, "name");
file = qemu_opt_get(opts, "file");
- if (name == NULL || *name == '\0' || file == NULL || *file == '\0') {
- error_report("invalid argument value");
+ str = qemu_opt_get(opts, "string");
+
+ /* we need name and either a file or the content string */
+ if (!(nonempty_str(name) && (nonempty_str(file) || nonempty_str(str)))) {
+ error_report("invalid argument(s)");
+ return -1;
+ }
+ if (nonempty_str(file) && nonempty_str(str)) {
+ error_report("file and string are mutually exclusive");
return -1;
}
if (strlen(name) > FW_CFG_MAX_FILE_PATH - 1) {
@@ -2263,9 +2279,14 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
error_report("WARNING: externally provided fw_cfg item names "
"should be prefixed with \"opt/\"!");
}
- if (!g_file_get_contents(file, &buf, &size, NULL)) {
- error_report("can't load %s", file);
- return -1;
+ if (nonempty_str(str)) {
+ size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */
+ buf = g_memdup(str, size);
+ } else {
+ if (!g_file_get_contents(file, &buf, &size, NULL)) {
+ error_report("can't load %s", file);
+ return -1;
+ }
}
fw_cfg_add_file((FWCfgState *)opaque, name, buf, size);
return 0;
OpenPOWER on IntegriCloud