pci, pc, virtio: fixes, cleanups, tests
Lots of work on tests: BiosTablesTest UEFI app, vhost-user testing for non-Linux hosts. Misc cleanups and fixes all over the place Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJccBqMAAoJECgfDbjSjVRpvSEIAKYPRNdCBX/SSS/L/tmJS5Zt 8IyU/HW1YJ249vO+aT6z4Q3QPgqNC3KjXC3brx/WRoPZnRroen4rv2Kqnk6SayPa a52d2ubXKWxb3swdG1CAVzFRhq/ABpgAPx0dr1JW+RXgo2lxpJ4GNYxKMosQTaPE hRNeXl1XlcIK525kJhFH3Hlij9mTRuY6T7ydpPQd8dUq2dBRaL9RrzZRrkZxCy6l gQPUqNzPhG0XXyOiJmwYyVX0zGzbYrMLrMQAor2SBIYmU+zv2eZGPJUYxoMTUMzt YR0WCpvkvPITlAryaBoozAIDYVz8PxBRT1KRwpDal+2rzlm6o+veKDiF8R46gn0= =GzUz -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging pci, pc, virtio: fixes, cleanups, tests Lots of work on tests: BiosTablesTest UEFI app, vhost-user testing for non-Linux hosts. Misc cleanups and fixes all over the place Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Fri 22 Feb 2019 15:51:40 GMT # gpg: using RSA key 281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: (26 commits) pci: Sanity test minimum downstream LNKSTA hw/smbios: fix offset of type 3 sku field pci: Move NVIDIA vendor id to the rest of ids virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size virtio-balloon: Use ram_block_discard_range() instead of raw madvise() virtio-balloon: Rework ballon_page() interface virtio-balloon: Corrections to address verification virtio-balloon: Remove unnecessary MADV_WILLNEED on deflate i386/kvm: ignore masked irqs when update msi routes contrib/vhost-user-blk: fix the compilation issue Revert "contrib/vhost-user-blk: fix the compilation issue" pc-dimm: use same mechanism for [get|set]_addr tests/data: introduce "uefi-boot-images" with the "bios-tables-test" ISOs tests/uefi-test-tools: add build scripts tests: introduce "uefi-test-tools" with the BiosTablesTest UEFI app roms: build the EfiRom utility from the roms/edk2 submodule roms: add the edk2 project as a git submodule vhost-user-test: create a temporary directory per TestServer vhost-user-test: small changes to init_hugepagefs vhost-user-test: create a main loop per TestServer ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1d31f1872b
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -49,3 +49,6 @@
|
||||
[submodule "tests/fp/berkeley-softfloat-3"]
|
||||
path = tests/fp/berkeley-softfloat-3
|
||||
url = https://github.com/cota/berkeley-softfloat-3
|
||||
[submodule "roms/edk2"]
|
||||
path = roms/edk2
|
||||
url = https://github.com/tianocore/edk2.git
|
||||
|
6
Makefile
6
Makefile
@ -609,7 +609,11 @@ clean:
|
||||
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
|
||||
rm -f qemu-options.def
|
||||
rm -f *.msi
|
||||
find . \( -name '*.so' -o -name '*.dll' -o -name '*.mo' -o -name '*.[oda]' \) -type f -exec rm {} +
|
||||
find . \( -name '*.so' -o -name '*.dll' -o -name '*.mo' -o -name '*.[oda]' \) -type f \
|
||||
! -path ./roms/edk2/ArmPkg/Library/GccLto/liblto-aarch64.a \
|
||||
! -path ./roms/edk2/ArmPkg/Library/GccLto/liblto-arm.a \
|
||||
! -path ./roms/edk2/BaseTools/Source/Python/UPT/Dll/sqlite3.dll \
|
||||
-exec rm {} +
|
||||
rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
|
||||
rm -f fsdev/*.pod scsi/*.pod
|
||||
rm -f qemu-img-cmds.h
|
||||
|
@ -9,10 +9,9 @@ common-obj-$(CONFIG_POSIX) += hostmem-file.o
|
||||
common-obj-y += cryptodev.o
|
||||
common-obj-y += cryptodev-builtin.o
|
||||
|
||||
ifeq ($(CONFIG_VIRTIO),y)
|
||||
ifeq ($(CONFIG_VIRTIO_CRYPTO),y)
|
||||
common-obj-y += cryptodev-vhost.o
|
||||
common-obj-$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) += \
|
||||
cryptodev-vhost-user.o
|
||||
common-obj-$(CONFIG_VHOST_CRYPTO) += cryptodev-vhost-user.o
|
||||
endif
|
||||
|
||||
common-obj-$(CONFIG_LINUX) += hostmem-memfd.o
|
||||
|
102
configure
vendored
102
configure
vendored
@ -368,10 +368,10 @@ libattr=""
|
||||
xfs=""
|
||||
tcg="yes"
|
||||
membarrier=""
|
||||
vhost_net="no"
|
||||
vhost_crypto="no"
|
||||
vhost_scsi="no"
|
||||
vhost_vsock="no"
|
||||
vhost_net=""
|
||||
vhost_crypto=""
|
||||
vhost_scsi=""
|
||||
vhost_vsock=""
|
||||
vhost_user=""
|
||||
kvm="no"
|
||||
hax="no"
|
||||
@ -783,6 +783,7 @@ case $targetos in
|
||||
MINGW32*)
|
||||
mingw32="yes"
|
||||
hax="yes"
|
||||
vhost_user="no"
|
||||
audio_possible_drivers="dsound sdl"
|
||||
if check_include dsound.h; then
|
||||
audio_drv_list="dsound"
|
||||
@ -884,10 +885,6 @@ Linux)
|
||||
linux="yes"
|
||||
linux_user="yes"
|
||||
kvm="yes"
|
||||
vhost_net="yes"
|
||||
vhost_crypto="yes"
|
||||
vhost_scsi="yes"
|
||||
vhost_vsock="yes"
|
||||
QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$PWD/linux-headers $QEMU_INCLUDES"
|
||||
supported_os="yes"
|
||||
libudev="yes"
|
||||
@ -1263,11 +1260,7 @@ for opt do
|
||||
;;
|
||||
--disable-vhost-crypto) vhost_crypto="no"
|
||||
;;
|
||||
--enable-vhost-crypto)
|
||||
vhost_crypto="yes"
|
||||
if test "$mingw32" = "yes"; then
|
||||
error_exit "vhost-crypto isn't available on win32"
|
||||
fi
|
||||
--enable-vhost-crypto) vhost_crypto="yes"
|
||||
;;
|
||||
--disable-vhost-scsi) vhost_scsi="no"
|
||||
;;
|
||||
@ -1476,11 +1469,11 @@ for opt do
|
||||
;;
|
||||
--disable-vhost-user) vhost_user="no"
|
||||
;;
|
||||
--enable-vhost-user)
|
||||
vhost_user="yes"
|
||||
if test "$mingw32" = "yes"; then
|
||||
error_exit "vhost-user isn't available on win32"
|
||||
fi
|
||||
--enable-vhost-user) vhost_user="yes"
|
||||
;;
|
||||
--disable-vhost-kernel) vhost_kernel="no"
|
||||
;;
|
||||
--enable-vhost-kernel) vhost_kernel="yes"
|
||||
;;
|
||||
--disable-capstone) capstone="no"
|
||||
;;
|
||||
@ -1512,14 +1505,6 @@ for opt do
|
||||
esac
|
||||
done
|
||||
|
||||
if test "$vhost_user" = ""; then
|
||||
if test "$mingw32" = "yes"; then
|
||||
vhost_user="no"
|
||||
else
|
||||
vhost_user="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$cpu" in
|
||||
ppc)
|
||||
CPU_CFLAGS="-m32"
|
||||
@ -1743,8 +1728,12 @@ disabled with --disable-FEATURE, default is enabled if available:
|
||||
linux-aio Linux AIO support
|
||||
cap-ng libcap-ng support
|
||||
attr attr and xattr support
|
||||
vhost-net vhost-net acceleration support
|
||||
vhost-crypto vhost-crypto acceleration support
|
||||
vhost-net vhost-net kernel acceleration support
|
||||
vhost-vsock virtio sockets device support
|
||||
vhost-scsi vhost-scsi kernel target support
|
||||
vhost-crypto vhost-user-crypto backend support
|
||||
vhost-kernel vhost kernel backend support
|
||||
vhost-user vhost-user backend support
|
||||
spice spice
|
||||
rbd rados block device (rbd)
|
||||
libiscsi iscsi support
|
||||
@ -1770,7 +1759,6 @@ disabled with --disable-FEATURE, default is enabled if available:
|
||||
jemalloc jemalloc support
|
||||
avx2 AVX2 optimization support
|
||||
replication replication support
|
||||
vhost-vsock virtio sockets device support
|
||||
opengl opengl support
|
||||
virglrenderer virgl rendering support
|
||||
xfsctl xfsctl support
|
||||
@ -1787,7 +1775,6 @@ disabled with --disable-FEATURE, default is enabled if available:
|
||||
parallels parallels image format support
|
||||
sheepdog sheepdog block driver support
|
||||
crypto-afalg Linux AF_ALG crypto backend driver
|
||||
vhost-user vhost-user support
|
||||
capstone capstone disassembler support
|
||||
debug-mutex mutex debugging support
|
||||
libpmem libpmem support
|
||||
@ -2177,6 +2164,45 @@ else
|
||||
l2tpv3=no
|
||||
fi
|
||||
|
||||
#########################################
|
||||
# vhost interdependencies and host support
|
||||
|
||||
# vhost backends
|
||||
test "$vhost_user" = "" && vhost_user=yes
|
||||
if test "$vhost_user" = "yes" && test "$mingw32" = "yes"; then
|
||||
error_exit "vhost-user isn't available on win32"
|
||||
fi
|
||||
test "$vhost_kernel" = "" && vhost_kernel=$linux
|
||||
if test "$vhost_kernel" = "yes" && test "$linux" != "yes"; then
|
||||
error_exit "vhost-kernel is only available on Linux"
|
||||
fi
|
||||
|
||||
# vhost-kernel devices
|
||||
test "$vhost_scsi" = "" && vhost_scsi=$vhost_kernel
|
||||
if test "$vhost_scsi" = "yes" && test "$vhost_kernel" != "yes"; then
|
||||
error_exit "--enable-vhost-scsi requires --enable-vhost-kernel"
|
||||
fi
|
||||
test "$vhost_vsock" = "" && vhost_vsock=$vhost_kernel
|
||||
if test "$vhost_vsock" = "yes" && test "$vhost_kernel" != "yes"; then
|
||||
error_exit "--enable-vhost-vsock requires --enable-vhost-kernel"
|
||||
fi
|
||||
|
||||
# vhost-user backends
|
||||
test "$vhost_net_user" = "" && vhost_net_user=$vhost_user
|
||||
if test "$vhost_net_user" = "yes" && test "$vhost_user" = "no"; then
|
||||
error_exit "--enable-vhost-net-user requires --enable-vhost-user"
|
||||
fi
|
||||
test "$vhost_crypto" = "" && vhost_crypto=$vhost_user
|
||||
if test "$vhost_crypto" = "yes" && test "$vhost_user" = "no"; then
|
||||
error_exit "--enable-vhost-crypto requires --enable-vhost-user"
|
||||
fi
|
||||
|
||||
# OR the vhost-kernel and vhost-user values for simplicity
|
||||
if test "$vhost_net" = ""; then
|
||||
test "$vhost_net_user" = "yes" && vhost_net=yes
|
||||
test "$vhost_kernel" = "yes" && vhost_net=yes
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# MinGW / Mingw-w64 localtime_r/gmtime_r check
|
||||
|
||||
@ -6622,8 +6648,11 @@ fi
|
||||
if test "$vhost_scsi" = "yes" ; then
|
||||
echo "CONFIG_VHOST_SCSI=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$vhost_net" = "yes" && test "$vhost_user" = "yes"; then
|
||||
echo "CONFIG_VHOST_NET_USED=y" >> $config_host_mak
|
||||
if test "$vhost_net" = "yes" ; then
|
||||
echo "CONFIG_VHOST_NET=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$vhost_net_user" = "yes" ; then
|
||||
echo "CONFIG_VHOST_NET_USER=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$vhost_crypto" = "yes" ; then
|
||||
echo "CONFIG_VHOST_CRYPTO=y" >> $config_host_mak
|
||||
@ -6631,6 +6660,9 @@ fi
|
||||
if test "$vhost_vsock" = "yes" ; then
|
||||
echo "CONFIG_VHOST_VSOCK=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$vhost_kernel" = "yes" ; then
|
||||
echo "CONFIG_VHOST_KERNEL=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$vhost_user" = "yes" ; then
|
||||
echo "CONFIG_VHOST_USER=y" >> $config_host_mak
|
||||
fi
|
||||
@ -7401,12 +7433,6 @@ if supported_xen_target $target; then
|
||||
fi
|
||||
if supported_kvm_target $target; then
|
||||
echo "CONFIG_KVM=y" >> $config_target_mak
|
||||
if test "$vhost_net" = "yes" ; then
|
||||
echo "CONFIG_VHOST_NET=y" >> $config_target_mak
|
||||
if test "$vhost_user" = "yes" ; then
|
||||
echo "CONFIG_VHOST_USER_NET_TEST_$target_name=y" >> $config_host_mak
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if supported_hax_target $target; then
|
||||
echo "CONFIG_HAX=y" >> $config_target_mak
|
||||
|
@ -1,5 +1,5 @@
|
||||
CONFIG_VHOST_USER_SCSI=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX))
|
||||
CONFIG_VHOST_USER_BLK=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX))
|
||||
CONFIG_VHOST_USER_SCSI=$(CONFIG_VHOST_USER)
|
||||
CONFIG_VHOST_USER_BLK=$(CONFIG_VHOST_USER)
|
||||
CONFIG_VIRTIO=y
|
||||
CONFIG_VIRTIO_9P=$(CONFIG_VIRTFS)
|
||||
CONFIG_VIRTIO_BALLOON=y
|
||||
|
@ -204,9 +204,7 @@ static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
|
||||
|
||||
static uint64_t pc_dimm_md_get_addr(const MemoryDeviceState *md)
|
||||
{
|
||||
const PCDIMMDevice *dimm = PC_DIMM(md);
|
||||
|
||||
return dimm->addr;
|
||||
return object_property_get_uint(OBJECT(md), PC_DIMM_ADDR_PROP, &error_abort);
|
||||
}
|
||||
|
||||
static void pc_dimm_md_set_addr(MemoryDeviceState *md, uint64_t addr,
|
||||
|
@ -37,7 +37,9 @@ obj-$(CONFIG_PSERIES) += spapr_llan.o
|
||||
obj-$(CONFIG_XILINX_ETHLITE) += xilinx_ethlite.o
|
||||
|
||||
obj-$(CONFIG_VIRTIO_NET) += virtio-net.o
|
||||
obj-y += vhost_net.o
|
||||
common-obj-$(call land,$(CONFIG_VIRTIO_NET),$(CONFIG_VHOST_NET)) += vhost_net.o
|
||||
common-obj-$(call lnot,$(call land,$(CONFIG_VIRTIO_NET),$(CONFIG_VHOST_NET))) += vhost_net-stub.o
|
||||
common-obj-$(CONFIG_ALL) += vhost_net-stub.o
|
||||
|
||||
obj-$(CONFIG_ETSEC) += fsl_etsec/etsec.o fsl_etsec/registers.o \
|
||||
fsl_etsec/rings.o fsl_etsec/miim.o
|
||||
|
92
hw/net/vhost_net-stub.c
Normal file
92
hw/net/vhost_net-stub.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* vhost-net support
|
||||
*
|
||||
* Copyright Red Hat, Inc. 2010
|
||||
*
|
||||
* 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/osdep.h"
|
||||
#include "net/net.h"
|
||||
#include "net/tap.h"
|
||||
#include "net/vhost-user.h"
|
||||
|
||||
#include "hw/virtio/virtio-net.h"
|
||||
#include "net/vhost_net.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
|
||||
uint64_t vhost_net_get_max_queues(VHostNetState *net)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct vhost_net *vhost_net_init(VhostNetOptions *options)
|
||||
{
|
||||
error_report("vhost-net support is not compiled in");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int vhost_net_start(VirtIODevice *dev,
|
||||
NetClientState *ncs,
|
||||
int total_queues)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
void vhost_net_stop(VirtIODevice *dev,
|
||||
NetClientState *ncs,
|
||||
int total_queues)
|
||||
{
|
||||
}
|
||||
|
||||
void vhost_net_cleanup(struct vhost_net *net)
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
|
||||
{
|
||||
return features;
|
||||
}
|
||||
|
||||
void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t vhost_net_get_acked_features(VHostNetState *net)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
|
||||
int idx, bool mask)
|
||||
{
|
||||
}
|
||||
|
||||
int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
VHostNetState *get_vhost_net(NetClientState *nc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vhost_set_vring_enable(NetClientState *nc, int enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu)
|
||||
{
|
||||
return 0;
|
||||
}
|
@ -18,17 +18,13 @@
|
||||
#include "net/tap.h"
|
||||
#include "net/vhost-user.h"
|
||||
|
||||
#include "standard-headers/linux/vhost_types.h"
|
||||
#include "hw/virtio/virtio-net.h"
|
||||
#include "net/vhost_net.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_VHOST_NET
|
||||
#include <linux/vhost.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/kvm.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
@ -136,7 +132,7 @@ static int vhost_net_get_fd(NetClientState *backend)
|
||||
return tap_get_fd(backend);
|
||||
default:
|
||||
fprintf(stderr, "vhost-net requires tap backend\n");
|
||||
return -EBADFD;
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,6 +190,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
|
||||
}
|
||||
|
||||
/* Set sane init value. Override when guest acks. */
|
||||
#ifdef CONFIG_VHOST_NET_USER
|
||||
if (net->nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) {
|
||||
features = vhost_user_get_acked_features(net->nc);
|
||||
if (~net->dev.features & features) {
|
||||
@ -203,6 +200,7 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vhost_net_ack_features(net, features);
|
||||
|
||||
@ -414,10 +412,12 @@ VHostNetState *get_vhost_net(NetClientState *nc)
|
||||
case NET_CLIENT_DRIVER_TAP:
|
||||
vhost_net = tap_get_vhost_net(nc);
|
||||
break;
|
||||
#ifdef CONFIG_VHOST_NET_USER
|
||||
case NET_CLIENT_DRIVER_VHOST_USER:
|
||||
vhost_net = vhost_user_get_vhost_net(nc);
|
||||
assert(vhost_net);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -449,76 +449,3 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu)
|
||||
|
||||
return vhost_ops->vhost_net_set_mtu(&net->dev, mtu);
|
||||
}
|
||||
|
||||
#else
|
||||
uint64_t vhost_net_get_max_queues(VHostNetState *net)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct vhost_net *vhost_net_init(VhostNetOptions *options)
|
||||
{
|
||||
error_report("vhost-net support is not compiled in");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int vhost_net_start(VirtIODevice *dev,
|
||||
NetClientState *ncs,
|
||||
int total_queues)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
void vhost_net_stop(VirtIODevice *dev,
|
||||
NetClientState *ncs,
|
||||
int total_queues)
|
||||
{
|
||||
}
|
||||
|
||||
void vhost_net_cleanup(struct vhost_net *net)
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
|
||||
{
|
||||
return features;
|
||||
}
|
||||
|
||||
void vhost_net_ack_features(struct vhost_net *net, uint64_t features)
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t vhost_net_get_acked_features(VHostNetState *net)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool vhost_net_virtqueue_pending(VHostNetState *net, int idx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
|
||||
int idx, bool mask)
|
||||
{
|
||||
}
|
||||
|
||||
int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
VHostNetState *get_vhost_net(NetClientState *nc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vhost_set_vring_enable(NetClientState *nc, int enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -834,9 +834,12 @@ void pcie_add_capability(PCIDevice *dev,
|
||||
/*
|
||||
* Sync the PCIe Link Status negotiated speed and width of a bridge with the
|
||||
* downstream device. If downstream device is not present, re-write with the
|
||||
* Link Capability fields. Limit width and speed to bridge capabilities for
|
||||
* compatibility. Use config_read to access the downstream device since it
|
||||
* could be an assigned device with volatile link information.
|
||||
* Link Capability fields. If downstream device reports invalid width or
|
||||
* speed, replace with minimum values (LnkSta fields are RsvdZ on VFs but such
|
||||
* values interfere with PCIe native hotplug detecting new devices). Limit
|
||||
* width and speed to bridge capabilities for compatibility. Use config_read
|
||||
* to access the downstream device since it could be an assigned device with
|
||||
* volatile link information.
|
||||
*/
|
||||
void pcie_sync_bridge_lnk(PCIDevice *bridge_dev)
|
||||
{
|
||||
@ -856,11 +859,15 @@ void pcie_sync_bridge_lnk(PCIDevice *bridge_dev)
|
||||
if ((lnksta & PCI_EXP_LNKSTA_NLW) > (lnkcap & PCI_EXP_LNKCAP_MLW)) {
|
||||
lnksta &= ~PCI_EXP_LNKSTA_NLW;
|
||||
lnksta |= lnkcap & PCI_EXP_LNKCAP_MLW;
|
||||
} else if (!(lnksta & PCI_EXP_LNKSTA_NLW)) {
|
||||
lnksta |= QEMU_PCI_EXP_LNKSTA_NLW(QEMU_PCI_EXP_LNK_X1);
|
||||
}
|
||||
|
||||
if ((lnksta & PCI_EXP_LNKSTA_CLS) > (lnkcap & PCI_EXP_LNKCAP_SLS)) {
|
||||
lnksta &= ~PCI_EXP_LNKSTA_CLS;
|
||||
lnksta |= lnkcap & PCI_EXP_LNKCAP_SLS;
|
||||
} else if (!(lnksta & PCI_EXP_LNKSTA_CLS)) {
|
||||
lnksta |= QEMU_PCI_EXP_LNKSTA_CLS(QEMU_PCI_EXP_LNK_2_5GT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -563,6 +563,7 @@ static void smbios_build_type_3_table(void)
|
||||
t->height = 0;
|
||||
t->number_of_power_cords = 0;
|
||||
t->contained_element_count = 0;
|
||||
t->contained_element_record_length = 0;
|
||||
SMBIOS_TABLE_SET_STR(3, sku_number_str, type3.sku);
|
||||
|
||||
SMBIOS_BUILD_TABLE_POST;
|
||||
|
@ -526,8 +526,6 @@ static void vfio_probe_ati_bar2_quirk(VFIOPCIDevice *vdev, int nr)
|
||||
* note it for future reference.
|
||||
*/
|
||||
|
||||
#define PCI_VENDOR_ID_NVIDIA 0x10de
|
||||
|
||||
/*
|
||||
* Nvidia has several different methods to get to config space, the
|
||||
* nouveu project has several of these documented here:
|
||||
|
@ -2,15 +2,18 @@ ifeq ($(CONFIG_VIRTIO),y)
|
||||
common-obj-y += virtio-bus.o
|
||||
obj-y += virtio.o
|
||||
|
||||
obj-$(call lor,$(CONFIG_VHOST_USER),$(CONFIG_VHOST_KERNEL)) += vhost.o vhost-backend.o
|
||||
common-obj-$(call lnot,$(call lor,$(CONFIG_VHOST_USER),$(CONFIG_VHOST_KERNEL))) += vhost-stub.o
|
||||
obj-$(CONFIG_VHOST_USER) += vhost-user.o
|
||||
|
||||
common-obj-$(CONFIG_VIRTIO_RNG) += virtio-rng.o
|
||||
common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
|
||||
common-obj-$(CONFIG_VIRTIO_MMIO) += virtio-mmio.o
|
||||
obj-$(CONFIG_VIRTIO_BALLOON) += virtio-balloon.o
|
||||
obj-$(CONFIG_VIRTIO_CRYPTO) += virtio-crypto.o
|
||||
obj-$(call land,$(CONFIG_VIRTIO_CRYPTO),$(CONFIG_VIRTIO_PCI)) += virtio-crypto-pci.o
|
||||
|
||||
obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
|
||||
obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
|
||||
|
||||
ifeq ($(CONFIG_VIRTIO_PCI),y)
|
||||
obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock-pci.o
|
||||
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk-pci.o
|
||||
@ -28,5 +31,4 @@ obj-$(CONFIG_VIRTIO_SERIAL) += virtio-serial-pci.o
|
||||
endif
|
||||
endif
|
||||
|
||||
common-obj-$(call lnot,$(call land,$(CONFIG_VIRTIO),$(CONFIG_LINUX))) += vhost-stub.o
|
||||
common-obj-$(CONFIG_ALL) += vhost-stub.o
|
||||
|
@ -9,11 +9,14 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <linux/vhost.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "hw/virtio/vhost.h"
|
||||
#include "hw/virtio/vhost-backend.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "standard-headers/linux/vhost_types.h"
|
||||
|
||||
#ifdef CONFIG_VHOST_KERNEL
|
||||
#include <linux/vhost.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
|
||||
void *arg)
|
||||
@ -265,18 +268,23 @@ static const VhostOps kernel_ops = {
|
||||
.vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback,
|
||||
.vhost_send_device_iotlb_msg = vhost_kernel_send_device_iotlb_msg,
|
||||
};
|
||||
#endif
|
||||
|
||||
int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
switch (backend_type) {
|
||||
#ifdef CONFIG_VHOST_KERNEL
|
||||
case VHOST_BACKEND_TYPE_KERNEL:
|
||||
dev->vhost_ops = &kernel_ops;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_VHOST_USER
|
||||
case VHOST_BACKEND_TYPE_USER:
|
||||
dev->vhost_ops = &user_ops;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error_report("Unknown vhost backend type");
|
||||
r = -1;
|
||||
|
@ -27,8 +27,12 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <linux/vhost.h>
|
||||
|
||||
#include "standard-headers/linux/vhost_types.h"
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
#include <linux/userfaultfd.h>
|
||||
#endif
|
||||
|
||||
#define VHOST_MEMORY_MAX_NREGIONS 8
|
||||
#define VHOST_USER_F_PROTOCOL_FEATURES 30
|
||||
@ -1110,6 +1114,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
/*
|
||||
* Called back from the postcopy fault thread when a fault is received on our
|
||||
* ufd.
|
||||
@ -1177,6 +1182,7 @@ static int vhost_user_postcopy_waker(struct PostCopyFD *pcfd, RAMBlock *rb,
|
||||
trace_vhost_user_postcopy_waker_nomatch(qemu_ram_get_idstr(rb), offset);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Called at the start of an inbound postcopy on reception of the
|
||||
@ -1184,6 +1190,7 @@ static int vhost_user_postcopy_waker(struct PostCopyFD *pcfd, RAMBlock *rb,
|
||||
*/
|
||||
static int vhost_user_postcopy_advise(struct vhost_dev *dev, Error **errp)
|
||||
{
|
||||
#ifdef CONFIG_LINUX
|
||||
struct vhost_user *u = dev->opaque;
|
||||
CharBackend *chr = u->user->chr;
|
||||
int ufd;
|
||||
@ -1227,6 +1234,10 @@ static int vhost_user_postcopy_advise(struct vhost_dev *dev, Error **errp)
|
||||
u->postcopy_fd.idstr = "vhost-user"; /* Need to find unique name */
|
||||
postcopy_register_shared_ufd(&u->postcopy_fd);
|
||||
return 0;
|
||||
#else
|
||||
error_setg(errp, "Postcopy not supported on non-Linux systems");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "qemu/range.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/memfd.h"
|
||||
#include <linux/vhost.h>
|
||||
#include "standard-headers/linux/vhost_types.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "hw/virtio/virtio-access.h"
|
||||
|
@ -33,11 +33,81 @@
|
||||
|
||||
#define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT)
|
||||
|
||||
static void balloon_page(void *addr, int deflate)
|
||||
struct PartiallyBalloonedPage {
|
||||
RAMBlock *rb;
|
||||
ram_addr_t base;
|
||||
unsigned long bitmap[];
|
||||
};
|
||||
|
||||
static void balloon_inflate_page(VirtIOBalloon *balloon,
|
||||
MemoryRegion *mr, hwaddr offset)
|
||||
{
|
||||
if (!qemu_balloon_is_inhibited()) {
|
||||
qemu_madvise(addr, BALLOON_PAGE_SIZE,
|
||||
deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED);
|
||||
void *addr = memory_region_get_ram_ptr(mr) + offset;
|
||||
RAMBlock *rb;
|
||||
size_t rb_page_size;
|
||||
int subpages;
|
||||
ram_addr_t ram_offset, host_page_base;
|
||||
|
||||
/* XXX is there a better way to get to the RAMBlock than via a
|
||||
* host address? */
|
||||
rb = qemu_ram_block_from_host(addr, false, &ram_offset);
|
||||
rb_page_size = qemu_ram_pagesize(rb);
|
||||
host_page_base = ram_offset & ~(rb_page_size - 1);
|
||||
|
||||
if (rb_page_size == BALLOON_PAGE_SIZE) {
|
||||
/* Easy case */
|
||||
|
||||
ram_block_discard_range(rb, ram_offset, rb_page_size);
|
||||
/* We ignore errors from ram_block_discard_range(), because it
|
||||
* has already reported them, and failing to discard a balloon
|
||||
* page is not fatal */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Hard case
|
||||
*
|
||||
* We've put a piece of a larger host page into the balloon - we
|
||||
* need to keep track until we have a whole host page to
|
||||
* discard
|
||||
*/
|
||||
warn_report_once(
|
||||
"Balloon used with backing page size > 4kiB, this may not be reliable");
|
||||
|
||||
subpages = rb_page_size / BALLOON_PAGE_SIZE;
|
||||
|
||||
if (balloon->pbp
|
||||
&& (rb != balloon->pbp->rb
|
||||
|| host_page_base != balloon->pbp->base)) {
|
||||
/* We've partially ballooned part of a host page, but now
|
||||
* we're trying to balloon part of a different one. Too hard,
|
||||
* give up on the old partial page */
|
||||
free(balloon->pbp);
|
||||
balloon->pbp = NULL;
|
||||
}
|
||||
|
||||
if (!balloon->pbp) {
|
||||
/* Starting on a new host page */
|
||||
size_t bitlen = BITS_TO_LONGS(subpages) * sizeof(unsigned long);
|
||||
balloon->pbp = g_malloc0(sizeof(PartiallyBalloonedPage) + bitlen);
|
||||
balloon->pbp->rb = rb;
|
||||
balloon->pbp->base = host_page_base;
|
||||
}
|
||||
|
||||
bitmap_set(balloon->pbp->bitmap,
|
||||
(ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE,
|
||||
subpages);
|
||||
|
||||
if (bitmap_full(balloon->pbp->bitmap, subpages)) {
|
||||
/* We've accumulated a full host page, we can actually discard
|
||||
* it now */
|
||||
|
||||
ram_block_discard_range(rb, balloon->pbp->base, rb_page_size);
|
||||
/* We ignore errors from ram_block_discard_range(), because it
|
||||
* has already reported them, and failing to discard a balloon
|
||||
* page is not fatal */
|
||||
|
||||
free(balloon->pbp);
|
||||
balloon->pbp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,17 +292,19 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
}
|
||||
|
||||
while (iov_to_buf(elem->out_sg, elem->out_num, offset, &pfn, 4) == 4) {
|
||||
ram_addr_t pa;
|
||||
ram_addr_t addr;
|
||||
hwaddr pa;
|
||||
int p = virtio_ldl_p(vdev, &pfn);
|
||||
|
||||
pa = (ram_addr_t) p << VIRTIO_BALLOON_PFN_SHIFT;
|
||||
pa = (hwaddr) p << VIRTIO_BALLOON_PFN_SHIFT;
|
||||
offset += 4;
|
||||
|
||||
/* FIXME: remove get_system_memory(), but how? */
|
||||
section = memory_region_find(get_system_memory(), pa, 1);
|
||||
if (!int128_nz(section.size) ||
|
||||
!memory_region_is_ram(section.mr) ||
|
||||
section = memory_region_find(get_system_memory(), pa,
|
||||
BALLOON_PAGE_SIZE);
|
||||
if (!section.mr) {
|
||||
trace_virtio_balloon_bad_addr(pa);
|
||||
continue;
|
||||
}
|
||||
if (!memory_region_is_ram(section.mr) ||
|
||||
memory_region_is_rom(section.mr) ||
|
||||
memory_region_is_romd(section.mr)) {
|
||||
trace_virtio_balloon_bad_addr(pa);
|
||||
@ -242,11 +314,9 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
|
||||
|
||||
trace_virtio_balloon_handle_output(memory_region_name(section.mr),
|
||||
pa);
|
||||
/* Using memory_region_get_ram_ptr is bending the rules a bit, but
|
||||
should be OK because we only want a single page. */
|
||||
addr = section.offset_within_region;
|
||||
balloon_page(memory_region_get_ram_ptr(section.mr) + addr,
|
||||
!!(vq == s->dvq));
|
||||
if (!qemu_balloon_is_inhibited() && vq != s->dvq) {
|
||||
balloon_inflate_page(s, section.mr, section.offset_within_region);
|
||||
}
|
||||
memory_region_unref(section.mr);
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,6 @@
|
||||
#pragma GCC poison CONFIG_XTENSA_DIS
|
||||
|
||||
#pragma GCC poison CONFIG_LINUX_USER
|
||||
#pragma GCC poison CONFIG_VHOST_NET
|
||||
#pragma GCC poison CONFIG_KVM
|
||||
#pragma GCC poison CONFIG_SOFTMMU
|
||||
|
||||
|
@ -162,6 +162,7 @@ struct smbios_type_3 {
|
||||
uint8_t height;
|
||||
uint8_t number_of_power_cords;
|
||||
uint8_t contained_element_count;
|
||||
uint8_t contained_element_record_length;
|
||||
uint8_t sku_number_str;
|
||||
/* contained elements follow */
|
||||
} QEMU_PACKED;
|
||||
|
@ -271,4 +271,6 @@
|
||||
|
||||
#define PCI_VENDOR_ID_SYNOPSYS 0x16C3
|
||||
|
||||
#define PCI_VENDOR_ID_NVIDIA 0x10de
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,8 @@ typedef struct virtio_balloon_stat_modern {
|
||||
uint64_t val;
|
||||
} VirtIOBalloonStatModern;
|
||||
|
||||
typedef struct PartiallyBalloonedPage PartiallyBalloonedPage;
|
||||
|
||||
typedef struct VirtIOBalloon {
|
||||
VirtIODevice parent_obj;
|
||||
VirtQueue *ivq, *dvq, *svq;
|
||||
@ -42,6 +44,7 @@ typedef struct VirtIOBalloon {
|
||||
int64_t stats_last_update;
|
||||
int64_t stats_poll_interval;
|
||||
uint32_t host_features;
|
||||
PartiallyBalloonedPage *pbp;
|
||||
} VirtIOBalloon;
|
||||
|
||||
#endif
|
||||
|
@ -3,7 +3,9 @@ common-obj-y += socket.o
|
||||
common-obj-y += dump.o
|
||||
common-obj-y += eth.o
|
||||
common-obj-$(CONFIG_L2TPV3) += l2tpv3.o
|
||||
common-obj-$(CONFIG_POSIX) += vhost-user.o
|
||||
common-obj-$(call land,$(CONFIG_VIRTIO_NET),$(CONFIG_VHOST_NET_USER)) += vhost-user.o
|
||||
common-obj-$(call land,$(call lnot,$(CONFIG_VIRTIO_NET)),$(CONFIG_VHOST_NET_USER)) += vhost-user-stub.o
|
||||
common-obj-$(CONFIG_ALL) += vhost-user-stub.o
|
||||
common-obj-$(CONFIG_SLIRP) += slirp.o
|
||||
common-obj-$(CONFIG_VDE) += vde.o
|
||||
common-obj-$(CONFIG_NETMAP) += netmap.o
|
||||
|
@ -961,7 +961,7 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
|
||||
[NET_CLIENT_DRIVER_BRIDGE] = net_init_bridge,
|
||||
#endif
|
||||
[NET_CLIENT_DRIVER_HUBPORT] = net_init_hubport,
|
||||
#ifdef CONFIG_VHOST_NET_USED
|
||||
#ifdef CONFIG_VHOST_NET_USER
|
||||
[NET_CLIENT_DRIVER_VHOST_USER] = net_init_vhost_user,
|
||||
#endif
|
||||
#ifdef CONFIG_L2TPV3
|
||||
|
23
net/vhost-user-stub.c
Normal file
23
net/vhost-user-stub.c
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* vhost-user-stub.c
|
||||
*
|
||||
* Copyright (c) 2018 Red Hat, Inc.
|
||||
*
|
||||
* 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/osdep.h"
|
||||
#include "clients.h"
|
||||
#include "net/vhost_net.h"
|
||||
#include "net/vhost-user.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
int net_init_vhost_user(const Netdev *netdev, const char *name,
|
||||
NetClientState *peer, Error **errp)
|
||||
{
|
||||
error_setg(errp, "vhost-user requires frontend driver virtio-net-*");
|
||||
return -1;
|
||||
}
|
@ -172,6 +172,17 @@ static void net_vhost_user_cleanup(NetClientState *nc)
|
||||
qemu_purge_queued_packets(nc);
|
||||
}
|
||||
|
||||
static int vhost_user_set_vnet_endianness(NetClientState *nc,
|
||||
bool enable)
|
||||
{
|
||||
/* Nothing to do. If the server supports
|
||||
* VHOST_USER_PROTOCOL_F_CROSS_ENDIAN, it will get the
|
||||
* vnet header endianness from there. If it doesn't, negotiation
|
||||
* fails.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool vhost_user_has_vnet_hdr(NetClientState *nc)
|
||||
{
|
||||
assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_USER);
|
||||
@ -193,6 +204,8 @@ static NetClientInfo net_vhost_user_info = {
|
||||
.cleanup = net_vhost_user_cleanup,
|
||||
.has_vnet_hdr = vhost_user_has_vnet_hdr,
|
||||
.has_ufo = vhost_user_has_ufo,
|
||||
.set_vnet_be = vhost_user_set_vnet_endianness,
|
||||
.set_vnet_le = vhost_user_set_vnet_endianness,
|
||||
};
|
||||
|
||||
static gboolean net_vhost_user_watch(GIOChannel *chan, GIOCondition cond,
|
||||
|
@ -47,10 +47,7 @@ SEABIOS_EXTRAVERSION="-prebuilt.qemu.org"
|
||||
# We need that to combine multiple images (legacy bios,
|
||||
# efi ia32, efi x64) into a single rom binary.
|
||||
#
|
||||
# We try to find it in the path. You can also pass the location on
|
||||
# the command line, i.e. "make EFIROM=/path/to/EfiRom efirom"
|
||||
#
|
||||
EFIROM ?= $(shell which EfiRom 2>/dev/null)
|
||||
EFIROM = edk2/BaseTools/Source/C/bin/EfiRom
|
||||
|
||||
default:
|
||||
@echo "nothing is build by default"
|
||||
@ -59,8 +56,7 @@ default:
|
||||
@echo " vgabios -- update vgabios binaries (seabios)"
|
||||
@echo " sgabios -- update sgabios binaries"
|
||||
@echo " pxerom -- update nic roms (bios only)"
|
||||
@echo " efirom -- update nic roms (bios+efi, this needs"
|
||||
@echo " the EfiRom utility from edk2 / tianocore)"
|
||||
@echo " efirom -- update nic roms (bios+efi)"
|
||||
@echo " slof -- update slof.bin"
|
||||
@echo " skiboot -- update skiboot.lid"
|
||||
@echo " u-boot.e500 -- update u-boot.e500"
|
||||
@ -106,7 +102,7 @@ pxe-rom-%: build-pxe-roms
|
||||
|
||||
efirom: $(patsubst %,efi-rom-%,$(pxerom_variants))
|
||||
|
||||
efi-rom-%: build-pxe-roms build-efi-roms
|
||||
efi-rom-%: build-pxe-roms build-efi-roms $(EFIROM)
|
||||
$(EFIROM) -f "0x$(VID)" -i "0x$(DID)" -l 0x02 \
|
||||
-b ipxe/src/bin/$(VID)$(DID).rom \
|
||||
-ec ipxe/src/bin-i386-efi/$(VID)$(DID).efidrv \
|
||||
@ -124,6 +120,8 @@ build-efi-roms: build-pxe-roms
|
||||
$(patsubst %,bin-i386-efi/%.efidrv,$(pxerom_targets)) \
|
||||
$(patsubst %,bin-x86_64-efi/%.efidrv,$(pxerom_targets))
|
||||
|
||||
$(EFIROM):
|
||||
$(MAKE) -C edk2/BaseTools
|
||||
|
||||
slof:
|
||||
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) qemu
|
||||
@ -150,6 +148,7 @@ clean:
|
||||
$(MAKE) -C sgabios clean
|
||||
rm -f sgabios/.depend
|
||||
$(MAKE) -C ipxe/src veryclean
|
||||
$(MAKE) -C edk2/BaseTools clean
|
||||
$(MAKE) -C SLOF clean
|
||||
rm -rf u-boot/build.e500
|
||||
$(MAKE) -C u-boot-sam460ex distclean
|
||||
|
1
roms/edk2
Submodule
1
roms/edk2
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 85588389222a3636baf0f9ed8227f2434af4c3f9
|
@ -216,10 +216,7 @@ check-qtest-i386-$(CONFIG_USB_XHCI_NEC) += tests/usb-hcd-xhci-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/cpu-plug-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/q35-test$(EXESUF)
|
||||
check-qtest-i386-y += tests/vmgenid-test$(EXESUF)
|
||||
check-qtest-i386-$(CONFIG_VHOST_USER_NET_TEST_i386) += tests/vhost-user-test$(EXESUF)
|
||||
ifeq ($(CONFIG_VHOST_USER_NET_TEST_i386),)
|
||||
check-qtest-x86_64-$(CONFIG_VHOST_USER_NET_TEST_x86_64) += tests/vhost-user-test$(EXESUF)
|
||||
endif
|
||||
check-qtest-i386-$(CONFIG_VHOST_NET_USER) += tests/vhost-user-test$(EXESUF)
|
||||
check-qtest-i386-$(CONFIG_TPM_CRB) += tests/tpm-crb-swtpm-test$(EXESUF)
|
||||
check-qtest-i386-$(CONFIG_TPM_CRB) += tests/tpm-crb-test$(EXESUF)
|
||||
check-qtest-i386-$(CONFIG_TPM_TIS) += tests/tpm-tis-swtpm-test$(EXESUF)
|
||||
|
BIN
tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
Normal file
BIN
tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2
Normal file
Binary file not shown.
BIN
tests/data/uefi-boot-images/bios-tables-test.arm.iso.qcow2
Normal file
BIN
tests/data/uefi-boot-images/bios-tables-test.arm.iso.qcow2
Normal file
Binary file not shown.
BIN
tests/data/uefi-boot-images/bios-tables-test.i386.iso.qcow2
Normal file
BIN
tests/data/uefi-boot-images/bios-tables-test.i386.iso.qcow2
Normal file
Binary file not shown.
BIN
tests/data/uefi-boot-images/bios-tables-test.x86_64.iso.qcow2
Normal file
BIN
tests/data/uefi-boot-images/bios-tables-test.x86_64.iso.qcow2
Normal file
Binary file not shown.
3
tests/uefi-test-tools/.gitignore
vendored
Normal file
3
tests/uefi-test-tools/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
Build
|
||||
Conf
|
||||
log
|
25
tests/uefi-test-tools/LICENSE
Normal file
25
tests/uefi-test-tools/LICENSE
Normal file
@ -0,0 +1,25 @@
|
||||
All the files in this directory and subdirectories are released under the
|
||||
2-Clause BSD License (see header in each file).
|
||||
|
||||
Copyright (C) 2019, Red Hat, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
106
tests/uefi-test-tools/Makefile
Normal file
106
tests/uefi-test-tools/Makefile
Normal file
@ -0,0 +1,106 @@
|
||||
# Makefile for the test helper UEFI applications that run in guests.
|
||||
#
|
||||
# Copyright (C) 2019, Red Hat, Inc.
|
||||
#
|
||||
# This program and the accompanying materials are licensed and made available
|
||||
# under the terms and conditions of the BSD License that accompanies this
|
||||
# distribution. The full text of the license may be found at
|
||||
# <http://opensource.org/licenses/bsd-license.php>.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
edk2_dir := ../../roms/edk2
|
||||
images_dir := ../data/uefi-boot-images
|
||||
emulation_targets := arm aarch64 i386 x86_64
|
||||
uefi_binaries := bios-tables-test
|
||||
intermediate_suffixes := .efi .fat .iso.raw
|
||||
|
||||
images: $(foreach binary,$(uefi_binaries), \
|
||||
$(foreach target,$(emulation_targets), \
|
||||
$(images_dir)/$(binary).$(target).iso.qcow2))
|
||||
|
||||
# Preserve all intermediate targets if the build succeeds.
|
||||
# - Intermediate targets help with development & debugging.
|
||||
# - Preserving intermediate targets also keeps spurious changes out of the
|
||||
# final build products, in case the user re-runs "make" without any changes
|
||||
# to the UEFI source code. Normally, the intermediate files would have been
|
||||
# removed by the last "make" invocation, hence the re-run would rebuild them
|
||||
# from the unchanged UEFI sources. Unfortunately, the "mkdosfs" and
|
||||
# "genisoimage" utilities embed timestamp-based information in their outputs,
|
||||
# which causes git to report differences for the tracked qcow2 ISO images.
|
||||
.SECONDARY: $(foreach binary,$(uefi_binaries), \
|
||||
$(foreach target,$(emulation_targets), \
|
||||
$(foreach suffix,$(intermediate_suffixes), \
|
||||
Build/$(binary).$(target)$(suffix))))
|
||||
|
||||
# In the pattern rules below, the stem (%, $*) stands for
|
||||
# "$(binary).$(target)".
|
||||
|
||||
# Convert the raw ISO image to a qcow2 one, enabling compression, and using a
|
||||
# small cluster size. This allows for small binary files under git control,
|
||||
# hence for small binary patches.
|
||||
$(images_dir)/%.iso.qcow2: Build/%.iso.raw
|
||||
mkdir -p -- $(images_dir)
|
||||
$${QTEST_QEMU_IMG:-qemu-img} convert -f raw -O qcow2 -c \
|
||||
-o cluster_size=512 -- $< $@
|
||||
|
||||
# Embed the "UEFI system partition" into an ISO9660 file system as an ElTorito
|
||||
# boot image.
|
||||
Build/%.iso.raw: Build/%.fat
|
||||
genisoimage -input-charset ASCII -efi-boot $(notdir $<) -no-emul-boot \
|
||||
-quiet -o $@ -- $<
|
||||
|
||||
# Define chained macros in order to map QEMU system emulation targets to
|
||||
# *short* UEFI architecture identifiers. Periods are allowed in, and ultimately
|
||||
# stripped from, the argument.
|
||||
map_arm_to_uefi = $(subst arm,ARM,$(1))
|
||||
map_aarch64_to_uefi = $(subst aarch64,AA64,$(call map_arm_to_uefi,$(1)))
|
||||
map_i386_to_uefi = $(subst i386,IA32,$(call map_aarch64_to_uefi,$(1)))
|
||||
map_x86_64_to_uefi = $(subst x86_64,X64,$(call map_i386_to_uefi,$(1)))
|
||||
map_to_uefi = $(subst .,,$(call map_x86_64_to_uefi,$(1)))
|
||||
|
||||
# Format a "UEFI system partition", using the UEFI binary as the default boot
|
||||
# loader. Add 10% size for filesystem metadata, round up to the next KB, and
|
||||
# make sure the size is large enough for a FAT filesystem. Name the filesystem
|
||||
# after the UEFI binary. (Excess characters are automatically dropped from the
|
||||
# filesystem label.)
|
||||
Build/%.fat: Build/%.efi
|
||||
rm -f -- $@
|
||||
uefi_bin_b=$$(stat --format=%s -- $<) && \
|
||||
uefi_fat_kb=$$(( (uefi_bin_b * 11 / 10 + 1023) / 1024 )) && \
|
||||
uefi_fat_kb=$$(( uefi_fat_kb >= 64 ? uefi_fat_kb : 64 )) && \
|
||||
mkdosfs -C $@ -n $(basename $(@F)) -- $$uefi_fat_kb
|
||||
MTOOLS_SKIP_CHECK=1 mmd -i $@ ::EFI
|
||||
MTOOLS_SKIP_CHECK=1 mmd -i $@ ::EFI/BOOT
|
||||
MTOOLS_SKIP_CHECK=1 mcopy -i $@ -- $< \
|
||||
::EFI/BOOT/BOOT$(call map_to_uefi,$(suffix $*)).EFI
|
||||
|
||||
# In the pattern rules below, the stem (%, $*) stands for "$(target)" only. The
|
||||
# association between the UEFI binary (such as "bios-tables-test") and the
|
||||
# component name from the edk2 platform DSC file (such as "BiosTablesTest") is
|
||||
# explicit in each rule.
|
||||
|
||||
# "build.sh" invokes the "build" utility of edk2 BaseTools. In any given edk2
|
||||
# workspace, at most one "build" instance may be operating at a time. Therefore
|
||||
# we must serialize the rebuilding of targets in this Makefile.
|
||||
.NOTPARALLEL:
|
||||
|
||||
# In turn, the "build" utility of edk2 BaseTools invokes another "make".
|
||||
# Although the outer "make" process advertizes its job server to all child
|
||||
# processes via MAKEFLAGS in the environment, the outer "make" closes the job
|
||||
# server file descriptors (exposed in MAKEFLAGS) before executing a recipe --
|
||||
# unless the recipe is recognized as a recursive "make" recipe. Recipes that
|
||||
# call $(MAKE) are classified automatically as recursive; for "build.sh" below,
|
||||
# we must mark the recipe manually as recursive, by using the "+" indicator.
|
||||
# This way, when the inner "make" starts a parallel build of the target edk2
|
||||
# module, it can communicate with the outer "make"'s job server.
|
||||
Build/bios-tables-test.%.efi: build-edk2-tools
|
||||
+./build.sh $(edk2_dir) BiosTablesTest $* $@
|
||||
|
||||
build-edk2-tools:
|
||||
$(MAKE) -C $(edk2_dir)/BaseTools
|
||||
|
||||
clean:
|
||||
rm -rf Build Conf log
|
||||
$(MAKE) -C $(edk2_dir)/BaseTools clean
|
@ -0,0 +1,130 @@
|
||||
/** @file
|
||||
Populate the BIOS_TABLES_TEST structure.
|
||||
|
||||
Copyright (C) 2019, Red Hat, Inc.
|
||||
|
||||
This program and the accompanying materials are licensed and made available
|
||||
under the terms and conditions of the BSD License that accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
<http://opensource.org/licenses/bsd-license.php>.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
|
||||
#include <Guid/Acpi.h>
|
||||
#include <Guid/BiosTablesTest.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
|
||||
/**
|
||||
Wait for a keypress with a message that the application is about to exit.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
WaitForExitKeyPress (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Idx;
|
||||
EFI_INPUT_KEY Key;
|
||||
|
||||
if (gST->ConIn == NULL) {
|
||||
return;
|
||||
}
|
||||
AsciiPrint ("%a: press any key to exit\n", gEfiCallerBaseName);
|
||||
Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Idx);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BiosTablesTestMain (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
VOID *Pages;
|
||||
volatile BIOS_TABLES_TEST *BiosTablesTest;
|
||||
CONST VOID *Rsdp10;
|
||||
CONST VOID *Rsdp20;
|
||||
CONST EFI_CONFIGURATION_TABLE *ConfigTable;
|
||||
CONST EFI_CONFIGURATION_TABLE *ConfigTablesEnd;
|
||||
volatile EFI_GUID *InverseSignature;
|
||||
UINTN Idx;
|
||||
|
||||
Pages = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof *BiosTablesTest),
|
||||
SIZE_1MB);
|
||||
if (Pages == NULL) {
|
||||
AsciiErrorPrint ("%a: AllocateAlignedPages() failed\n",
|
||||
gEfiCallerBaseName);
|
||||
//
|
||||
// Assuming the application was launched by the boot manager as a boot
|
||||
// loader, exiting with error will cause the boot manager to proceed with
|
||||
// the remaining boot options. If there are no other boot options, the boot
|
||||
// manager menu will be pulled up. Give the user a chance to read the error
|
||||
// message.
|
||||
//
|
||||
WaitForExitKeyPress ();
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Locate both gEfiAcpi10TableGuid and gEfiAcpi20TableGuid config tables in
|
||||
// one go.
|
||||
//
|
||||
Rsdp10 = NULL;
|
||||
Rsdp20 = NULL;
|
||||
ConfigTable = gST->ConfigurationTable;
|
||||
ConfigTablesEnd = gST->ConfigurationTable + gST->NumberOfTableEntries;
|
||||
while ((Rsdp10 == NULL || Rsdp20 == NULL) && ConfigTable < ConfigTablesEnd) {
|
||||
if (CompareGuid (&ConfigTable->VendorGuid, &gEfiAcpi10TableGuid)) {
|
||||
Rsdp10 = ConfigTable->VendorTable;
|
||||
} else if (CompareGuid (&ConfigTable->VendorGuid, &gEfiAcpi20TableGuid)) {
|
||||
Rsdp20 = ConfigTable->VendorTable;
|
||||
}
|
||||
++ConfigTable;
|
||||
}
|
||||
|
||||
AsciiPrint ("%a: BiosTablesTest=%p Rsdp10=%p Rsdp20=%p\n",
|
||||
gEfiCallerBaseName, Pages, Rsdp10, Rsdp20);
|
||||
|
||||
//
|
||||
// Store the RSD PTR address(es) first, then the signature second.
|
||||
//
|
||||
BiosTablesTest = Pages;
|
||||
BiosTablesTest->Rsdp10 = (UINTN)Rsdp10;
|
||||
BiosTablesTest->Rsdp20 = (UINTN)Rsdp20;
|
||||
|
||||
MemoryFence();
|
||||
|
||||
InverseSignature = &BiosTablesTest->InverseSignatureGuid;
|
||||
InverseSignature->Data1 = gBiosTablesTestGuid.Data1;
|
||||
InverseSignature->Data1 ^= MAX_UINT32;
|
||||
InverseSignature->Data2 = gBiosTablesTestGuid.Data2;
|
||||
InverseSignature->Data2 ^= MAX_UINT16;
|
||||
InverseSignature->Data3 = gBiosTablesTestGuid.Data3;
|
||||
InverseSignature->Data3 ^= MAX_UINT16;
|
||||
for (Idx = 0; Idx < sizeof InverseSignature->Data4; ++Idx) {
|
||||
InverseSignature->Data4[Idx] = gBiosTablesTestGuid.Data4[Idx];
|
||||
InverseSignature->Data4[Idx] ^= MAX_UINT8;
|
||||
}
|
||||
|
||||
//
|
||||
// The wait below has dual purpose. First, it blocks the application without
|
||||
// wasting VCPU cycles while the hypervisor is scanning guest RAM. Second,
|
||||
// assuming the application was launched by the boot manager as a boot
|
||||
// loader, exiting the app with success causes the boot manager to pull up
|
||||
// the boot manager menu at once (regardless of other boot options); the wait
|
||||
// gives the user a chance to read the info printed above.
|
||||
//
|
||||
WaitForExitKeyPress ();
|
||||
return EFI_SUCCESS;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
## @file
|
||||
# Populate the BIOS_TABLES_TEST structure.
|
||||
#
|
||||
# Copyright (C) 2019, Red Hat, Inc.
|
||||
#
|
||||
# This program and the accompanying materials are licensed and made available
|
||||
# under the terms and conditions of the BSD License that accompanies this
|
||||
# distribution. The full text of the license may be found at
|
||||
# <http://opensource.org/licenses/bsd-license.php>.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 1.27
|
||||
BASE_NAME = BiosTablesTest
|
||||
UEFI_SPECIFICATION_VERSION = 2.31
|
||||
FILE_GUID = 87f00433-3b7c-45c3-ae78-a56495bd4e62
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
ENTRY_POINT = BiosTablesTestMain
|
||||
|
||||
[Sources]
|
||||
BiosTablesTest.c
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
UefiApplicationEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
UefiLib
|
||||
|
||||
[Guids]
|
||||
gBiosTablesTestGuid
|
||||
gEfiAcpi10TableGuid
|
||||
gEfiAcpi20TableGuid
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
UefiTestToolsPkg/UefiTestToolsPkg.dec
|
@ -0,0 +1,67 @@
|
||||
/** @file
|
||||
Expose the address(es) of the ACPI RSD PTR table(s) in a MB-aligned structure
|
||||
to the hypervisor.
|
||||
|
||||
The hypervisor locates the MB-aligned structure based on the signature GUID
|
||||
that is at offset 0 in the structure. Once the RSD PTR address(es) are
|
||||
retrieved, the hypervisor may perform various ACPI checks.
|
||||
|
||||
This feature is a development aid, for supporting ACPI table unit tests in
|
||||
hypervisors. Do not enable in production builds.
|
||||
|
||||
Copyright (C) 2019, Red Hat, Inc.
|
||||
|
||||
This program and the accompanying materials are licensed and made available
|
||||
under the terms and conditions of the BSD License that accompanies this
|
||||
distribution. The full text of the license may be found at
|
||||
<http://opensource.org/licenses/bsd-license.php>.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
|
||||
#ifndef __BIOS_TABLES_TEST_H__
|
||||
#define __BIOS_TABLES_TEST_H__
|
||||
|
||||
#include <Uefi/UefiBaseType.h>
|
||||
|
||||
#define BIOS_TABLES_TEST_GUID \
|
||||
{ \
|
||||
0x5478594e, \
|
||||
0xdfcb, \
|
||||
0x425f, \
|
||||
{ 0x8e, 0x42, 0xc8, 0xaf, 0xf8, 0x8a, 0x88, 0x7a } \
|
||||
}
|
||||
|
||||
extern EFI_GUID gBiosTablesTestGuid;
|
||||
|
||||
//
|
||||
// The following structure must be allocated in Boot Services Data type memory,
|
||||
// aligned at a 1MB boundary.
|
||||
//
|
||||
#pragma pack (1)
|
||||
typedef struct {
|
||||
//
|
||||
// The signature GUID is written to the MB-aligned structure from
|
||||
// gBiosTablesTestGuid, but with all bits inverted. That's the actual GUID
|
||||
// value that the hypervisor should look for at each MB boundary, looping
|
||||
// over all guest RAM pages with that alignment, until a match is found. The
|
||||
// bit-flipping occurs in order not to store the actual GUID in any UEFI
|
||||
// executable, which might confuse guest memory analysis. Note that EFI_GUID
|
||||
// has little endian representation.
|
||||
//
|
||||
EFI_GUID InverseSignatureGuid;
|
||||
//
|
||||
// The Rsdp10 and Rsdp20 fields may be read when the signature GUID matches.
|
||||
// Rsdp10 is the guest-physical address of the ACPI 1.0 specification RSD PTR
|
||||
// table, in 8-byte little endian representation. Rsdp20 is the same, for the
|
||||
// ACPI 2.0 or later specification RSD PTR table. Each of these fields may be
|
||||
// zero (independently of the other) if the UEFI System Table does not
|
||||
// provide the corresponding UEFI Configuration Table.
|
||||
//
|
||||
EFI_PHYSICAL_ADDRESS Rsdp10;
|
||||
EFI_PHYSICAL_ADDRESS Rsdp20;
|
||||
} BIOS_TABLES_TEST;
|
||||
#pragma pack ()
|
||||
|
||||
#endif // __BIOS_TABLES_TEST_H__
|
27
tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dec
Normal file
27
tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dec
Normal file
@ -0,0 +1,27 @@
|
||||
## @file
|
||||
# edk2 package declaration for the test helper UEFI applications that run in
|
||||
# guests.
|
||||
#
|
||||
# Copyright (C) 2019, Red Hat, Inc.
|
||||
#
|
||||
# This program and the accompanying materials are licensed and made available
|
||||
# under the terms and conditions of the BSD License that accompanies this
|
||||
# distribution. The full text of the license may be found at
|
||||
# <http://opensource.org/licenses/bsd-license.php>.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
##
|
||||
|
||||
[Defines]
|
||||
DEC_SPECIFICATION = 1.27
|
||||
PACKAGE_NAME = UefiTestToolsPkg
|
||||
PACKAGE_GUID = 7b3f1794-0c85-4b27-a536-44dbf0b0669c
|
||||
PACKAGE_VERSION = 0.1
|
||||
|
||||
[Includes]
|
||||
Include
|
||||
|
||||
[Guids]
|
||||
gBiosTablesTestGuid = {0x5478594e, 0xdfcb, 0x425f, {0x8e, 0x42, 0xc8, 0xaf, 0xf8, 0x8a, 0x88, 0x7a}}
|
||||
|
69
tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc
Normal file
69
tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc
Normal file
@ -0,0 +1,69 @@
|
||||
## @file
|
||||
# edk2 platform description for the test helper UEFI applications that run in
|
||||
# guests.
|
||||
#
|
||||
# Copyright (C) 2019, Red Hat, Inc.
|
||||
#
|
||||
# This program and the accompanying materials are licensed and made available
|
||||
# under the terms and conditions of the BSD License that accompanies this
|
||||
# distribution. The full text of the license may be found at
|
||||
# <http://opensource.org/licenses/bsd-license.php>.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
##
|
||||
|
||||
[Defines]
|
||||
DSC_SPECIFICATION = 1.28
|
||||
PLATFORM_GUID = 6750ccc1-8365-49f0-8437-948e516a9f55
|
||||
PLATFORM_VERSION = 0.1
|
||||
PLATFORM_NAME = UefiTestTools
|
||||
SKUID_IDENTIFIER = DEFAULT
|
||||
SUPPORTED_ARCHITECTURES = ARM|AARCH64|IA32|X64
|
||||
BUILD_TARGETS = DEBUG
|
||||
|
||||
[BuildOptions.IA32]
|
||||
GCC:*_*_IA32_CC_FLAGS = -mno-mmx -mno-sse
|
||||
|
||||
[BuildOptions.X64]
|
||||
GCC:*_*_X64_CC_FLAGS = -mno-mmx -mno-sse
|
||||
|
||||
[BuildOptions.ARM.EDKII.UEFI_APPLICATION]
|
||||
GCC:*_*_ARM_DLINK_FLAGS = -z common-page-size=0x1000
|
||||
|
||||
[BuildOptions.AARCH64.EDKII.UEFI_APPLICATION]
|
||||
GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x1000
|
||||
|
||||
[BuildOptions]
|
||||
GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
|
||||
|
||||
[SkuIds]
|
||||
0|DEFAULT
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
||||
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
|
||||
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
|
||||
DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
|
||||
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
||||
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
|
||||
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
||||
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
|
||||
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
|
||||
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
|
||||
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
||||
|
||||
[LibraryClasses.ARM, LibraryClasses.AARCH64]
|
||||
BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
|
||||
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
|
||||
NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
|
||||
|
||||
[LibraryClasses.IA32, LibraryClasses.X64]
|
||||
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
|
||||
|
||||
[PcdsFixedAtBuild]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8040004F
|
||||
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
|
||||
|
||||
[Components]
|
||||
UefiTestToolsPkg/BiosTablesTest/BiosTablesTest.inf
|
145
tests/uefi-test-tools/build.sh
Executable file
145
tests/uefi-test-tools/build.sh
Executable file
@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Build script that determines the edk2 toolchain to use, invokes the edk2
|
||||
# "build" utility, and copies the built UEFI binary to the requested location.
|
||||
#
|
||||
# Copyright (C) 2019, Red Hat, Inc.
|
||||
#
|
||||
# This program and the accompanying materials are licensed and made available
|
||||
# under the terms and conditions of the BSD License that accompanies this
|
||||
# distribution. The full text of the license may be found at
|
||||
# <http://opensource.org/licenses/bsd-license.php>.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
set -e -u -C
|
||||
|
||||
# Save the command line arguments. We need to reset $# to 0 before sourcing
|
||||
# "edksetup.sh", as it will inherit $@.
|
||||
program_name=$(basename -- "$0")
|
||||
edk2_dir=$1
|
||||
dsc_component=$2
|
||||
emulation_target=$3
|
||||
uefi_binary=$4
|
||||
shift 4
|
||||
|
||||
# Set up the environment for edk2 building.
|
||||
export PACKAGES_PATH=$(realpath -- "$edk2_dir")
|
||||
export WORKSPACE=$PWD
|
||||
mkdir -p Conf
|
||||
|
||||
# Source "edksetup.sh" carefully.
|
||||
set +e +u +C
|
||||
source "$PACKAGES_PATH/edksetup.sh"
|
||||
ret=$?
|
||||
set -e -u -C
|
||||
if [ $ret -ne 0 ]; then
|
||||
exit $ret
|
||||
fi
|
||||
|
||||
# Map the QEMU system emulation target to the following types of architecture
|
||||
# identifiers:
|
||||
# - edk2,
|
||||
# - gcc cross-compilation.
|
||||
# Cover only those targets that are supported by the UEFI spec and edk2.
|
||||
case "$emulation_target" in
|
||||
(arm)
|
||||
edk2_arch=ARM
|
||||
gcc_arch=arm
|
||||
;;
|
||||
(aarch64)
|
||||
edk2_arch=AARCH64
|
||||
gcc_arch=aarch64
|
||||
;;
|
||||
(i386)
|
||||
edk2_arch=IA32
|
||||
gcc_arch=i686
|
||||
;;
|
||||
(x86_64)
|
||||
edk2_arch=X64
|
||||
gcc_arch=x86_64
|
||||
;;
|
||||
(*)
|
||||
printf '%s: unknown/unsupported QEMU system emulation target "%s"\n' \
|
||||
"$program_name" "$emulation_target" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check if cross-compilation is needed.
|
||||
host_arch=$(uname -m)
|
||||
if [ "$gcc_arch" == "$host_arch" ] ||
|
||||
( [ "$gcc_arch" == i686 ] && [ "$host_arch" == x86_64 ] ); then
|
||||
cross_prefix=
|
||||
else
|
||||
cross_prefix=${gcc_arch}-linux-gnu-
|
||||
fi
|
||||
|
||||
# Expose cross_prefix (which is possibly empty) to the edk2 tools. While at it,
|
||||
# determine the suitable edk2 toolchain as well.
|
||||
# - For ARM and AARCH64, edk2 only offers the GCC5 toolchain tag, which covers
|
||||
# the gcc-5+ releases.
|
||||
# - For IA32 and X64, edk2 offers the GCC44 through GCC49 toolchain tags, in
|
||||
# addition to GCC5. Unfortunately, the mapping between the toolchain tags and
|
||||
# the actual gcc releases isn't entirely trivial. Run "git-blame" on
|
||||
# "OvmfPkg/build.sh" in edk2 for more information.
|
||||
# And, because the above is too simple, we have to assign cross_prefix to an
|
||||
# edk2 build variable that is specific to both the toolchain tag and the target
|
||||
# architecture.
|
||||
case "$edk2_arch" in
|
||||
(ARM)
|
||||
edk2_toolchain=GCC5
|
||||
export GCC5_ARM_PREFIX=$cross_prefix
|
||||
;;
|
||||
(AARCH64)
|
||||
edk2_toolchain=GCC5
|
||||
export GCC5_AARCH64_PREFIX=$cross_prefix
|
||||
;;
|
||||
(IA32|X64)
|
||||
gcc_version=$("${cross_prefix}gcc" -v 2>&1 | tail -1 | awk '{print $3}')
|
||||
case "$gcc_version" in
|
||||
([1-3].*|4.[0-3].*)
|
||||
printf '%s: unsupported gcc version "%s"\n' \
|
||||
"$program_name" "$gcc_version" >&2
|
||||
exit 1
|
||||
;;
|
||||
(4.4.*)
|
||||
edk2_toolchain=GCC44
|
||||
;;
|
||||
(4.5.*)
|
||||
edk2_toolchain=GCC45
|
||||
;;
|
||||
(4.6.*)
|
||||
edk2_toolchain=GCC46
|
||||
;;
|
||||
(4.7.*)
|
||||
edk2_toolchain=GCC47
|
||||
;;
|
||||
(4.8.*)
|
||||
edk2_toolchain=GCC48
|
||||
;;
|
||||
(4.9.*|6.[0-2].*)
|
||||
edk2_toolchain=GCC49
|
||||
;;
|
||||
(*)
|
||||
edk2_toolchain=GCC5
|
||||
;;
|
||||
esac
|
||||
eval "export ${edk2_toolchain}_BIN=\$cross_prefix"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Build the UEFI binary
|
||||
mkdir -p log
|
||||
build \
|
||||
--arch="$edk2_arch" \
|
||||
--buildtarget=DEBUG \
|
||||
--platform=UefiTestToolsPkg/UefiTestToolsPkg.dsc \
|
||||
--tagname="$edk2_toolchain" \
|
||||
--module="UefiTestToolsPkg/$dsc_component/$dsc_component.inf" \
|
||||
--log="log/$dsc_component.$edk2_arch.log" \
|
||||
--report-file="log/$dsc_component.$edk2_arch.report"
|
||||
cp -a -- \
|
||||
"Build/UefiTestTools/DEBUG_${edk2_toolchain}/$edk2_arch/$dsc_component.efi" \
|
||||
"$uefi_binary"
|
@ -27,10 +27,13 @@
|
||||
#include "libqos/malloc-pc.h"
|
||||
#include "hw/virtio/virtio-net.h"
|
||||
|
||||
#include <linux/vhost.h>
|
||||
#include <linux/virtio_ids.h>
|
||||
#include <linux/virtio_net.h>
|
||||
#include "standard-headers/linux/vhost_types.h"
|
||||
#include "standard-headers/linux/virtio_ids.h"
|
||||
#include "standard-headers/linux/virtio_net.h"
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
#include <sys/vfs.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define QEMU_CMD_MEM " -m %d -object memory-backend-file,id=mem,size=%dM," \
|
||||
@ -139,10 +142,15 @@ typedef struct TestServer {
|
||||
gchar *socket_path;
|
||||
gchar *mig_path;
|
||||
gchar *chr_name;
|
||||
const gchar *mem_path;
|
||||
gchar *tmpfs;
|
||||
CharBackend chr;
|
||||
int fds_num;
|
||||
int fds[VHOST_MEMORY_MAX_NREGIONS];
|
||||
VhostUserMemory memory;
|
||||
GMainContext *context;
|
||||
GMainLoop *loop;
|
||||
GThread *thread;
|
||||
GMutex data_mutex;
|
||||
GCond data_cond;
|
||||
int log_fd;
|
||||
@ -157,9 +165,6 @@ static TestServer *test_server_new(const gchar *name);
|
||||
static void test_server_free(TestServer *server);
|
||||
static void test_server_listen(TestServer *server);
|
||||
|
||||
static const char *tmpfs;
|
||||
static const char *root;
|
||||
|
||||
enum test_memfd {
|
||||
TEST_MEMFD_AUTO,
|
||||
TEST_MEMFD_YES,
|
||||
@ -167,7 +172,7 @@ enum test_memfd {
|
||||
};
|
||||
|
||||
static char *get_qemu_cmd(TestServer *s,
|
||||
int mem, enum test_memfd memfd, const char *mem_path,
|
||||
int mem, enum test_memfd memfd,
|
||||
const char *chr_opts, const char *extra)
|
||||
{
|
||||
if (memfd == TEST_MEMFD_AUTO && qemu_memfd_check(0)) {
|
||||
@ -182,7 +187,7 @@ static char *get_qemu_cmd(TestServer *s,
|
||||
} else {
|
||||
return g_strdup_printf(QEMU_CMD_MEM QEMU_CMD_CHR
|
||||
QEMU_CMD_NETDEV QEMU_CMD_NET "%s", mem, mem,
|
||||
mem_path, s->chr_name, s->socket_path,
|
||||
s->mem_path, s->chr_name, s->socket_path,
|
||||
chr_opts, s->chr_name, extra);
|
||||
}
|
||||
}
|
||||
@ -459,13 +464,20 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
g_mutex_unlock(&s->data_mutex);
|
||||
}
|
||||
|
||||
static const char *init_hugepagefs(const char *path)
|
||||
static const char *init_hugepagefs(void)
|
||||
{
|
||||
#ifdef CONFIG_LINUX
|
||||
const char *path = getenv("QTEST_HUGETLBFS_PATH");
|
||||
struct statfs fs;
|
||||
int ret;
|
||||
|
||||
if (!path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (access(path, R_OK | W_OK | X_OK)) {
|
||||
g_test_message("access on path (%s): %s\n", path, strerror(errno));
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -475,21 +487,42 @@ static const char *init_hugepagefs(const char *path)
|
||||
|
||||
if (ret != 0) {
|
||||
g_test_message("statfs on path (%s): %s\n", path, strerror(errno));
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fs.f_type != HUGETLBFS_MAGIC) {
|
||||
g_test_message("Warning: path not on HugeTLBFS: %s\n", path);
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return path;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static TestServer *test_server_new(const gchar *name)
|
||||
{
|
||||
TestServer *server = g_new0(TestServer, 1);
|
||||
char template[] = "/tmp/vhost-test-XXXXXX";
|
||||
const char *tmpfs;
|
||||
|
||||
server->context = g_main_context_new();
|
||||
server->loop = g_main_loop_new(server->context, FALSE);
|
||||
|
||||
/* run the main loop thread so the chardev may operate */
|
||||
server->thread = g_thread_new(NULL, thread_function, server->loop);
|
||||
|
||||
tmpfs = mkdtemp(template);
|
||||
if (!tmpfs) {
|
||||
g_test_message("mkdtemp on path (%s): %s", template, strerror(errno));
|
||||
}
|
||||
g_assert(tmpfs);
|
||||
|
||||
server->tmpfs = g_strdup(tmpfs);
|
||||
server->mem_path = init_hugepagefs() ? : server->tmpfs;
|
||||
server->socket_path = g_strdup_printf("%s/%s.sock", tmpfs, name);
|
||||
server->mig_path = g_strdup_printf("%s/%s.mig", tmpfs, name);
|
||||
server->chr_name = g_strdup_printf("chr-%s", name);
|
||||
@ -519,13 +552,13 @@ static void test_server_create_chr(TestServer *server, const gchar *opt)
|
||||
Chardev *chr;
|
||||
|
||||
chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt);
|
||||
chr = qemu_chr_new(server->chr_name, chr_path, NULL);
|
||||
chr = qemu_chr_new(server->chr_name, chr_path, server->context);
|
||||
g_free(chr_path);
|
||||
|
||||
g_assert_nonnull(chr);
|
||||
qemu_chr_fe_init(&server->chr, chr, &error_abort);
|
||||
qemu_chr_fe_set_handlers(&server->chr, chr_can_read, chr_read,
|
||||
chr_event, NULL, server, NULL, true);
|
||||
chr_event, NULL, server, server->context, true);
|
||||
}
|
||||
|
||||
static void test_server_listen(TestServer *server)
|
||||
@ -533,9 +566,28 @@ static void test_server_listen(TestServer *server)
|
||||
test_server_create_chr(server, ",server,nowait");
|
||||
}
|
||||
|
||||
static gboolean _test_server_free(TestServer *server)
|
||||
static void test_server_free(TestServer *server)
|
||||
{
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
/* finish the helper thread and dispatch pending sources */
|
||||
g_main_loop_quit(server->loop);
|
||||
g_thread_join(server->thread);
|
||||
while (g_main_context_pending(NULL)) {
|
||||
g_main_context_iteration(NULL, TRUE);
|
||||
}
|
||||
|
||||
unlink(server->socket_path);
|
||||
g_free(server->socket_path);
|
||||
|
||||
unlink(server->mig_path);
|
||||
g_free(server->mig_path);
|
||||
|
||||
ret = rmdir(server->tmpfs);
|
||||
if (ret != 0) {
|
||||
g_test_message("unable to rmdir: path (%s): %s",
|
||||
server->tmpfs, strerror(errno));
|
||||
}
|
||||
|
||||
qemu_chr_fe_deinit(&server->chr, true);
|
||||
|
||||
@ -547,24 +599,13 @@ static gboolean _test_server_free(TestServer *server)
|
||||
close(server->log_fd);
|
||||
}
|
||||
|
||||
unlink(server->socket_path);
|
||||
g_free(server->socket_path);
|
||||
|
||||
unlink(server->mig_path);
|
||||
g_free(server->mig_path);
|
||||
|
||||
g_free(server->chr_name);
|
||||
g_assert(server->bus);
|
||||
qpci_free_pc(server->bus);
|
||||
|
||||
g_main_loop_unref(server->loop);
|
||||
g_main_context_unref(server->context);
|
||||
g_free(server);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void test_server_free(TestServer *server)
|
||||
{
|
||||
g_idle_add((GSourceFunc)_test_server_free, server);
|
||||
}
|
||||
|
||||
static void wait_for_log_fd(TestServer *s)
|
||||
@ -665,7 +706,7 @@ static void test_read_guest_mem(const void *arg)
|
||||
"read-guest-memfd" : "read-guest-mem");
|
||||
test_server_listen(server);
|
||||
|
||||
qemu_cmd = get_qemu_cmd(server, 512, memfd, root, "", "");
|
||||
qemu_cmd = get_qemu_cmd(server, 512, memfd, "", "");
|
||||
|
||||
s = qtest_start(qemu_cmd);
|
||||
g_free(qemu_cmd);
|
||||
@ -700,7 +741,7 @@ static void test_migrate(void)
|
||||
test_server_listen(s);
|
||||
test_server_listen(dest);
|
||||
|
||||
cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, "", "");
|
||||
cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, "", "");
|
||||
from = qtest_start(cmd);
|
||||
g_free(cmd);
|
||||
|
||||
@ -713,7 +754,7 @@ static void test_migrate(void)
|
||||
g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
|
||||
|
||||
tmp = g_strdup_printf(" -incoming %s", uri);
|
||||
cmd = get_qemu_cmd(dest, 2, TEST_MEMFD_AUTO, root, "", tmp);
|
||||
cmd = get_qemu_cmd(dest, 2, TEST_MEMFD_AUTO, "", tmp);
|
||||
g_free(tmp);
|
||||
to = qtest_init(cmd);
|
||||
g_free(cmd);
|
||||
@ -723,7 +764,7 @@ static void test_migrate(void)
|
||||
sizeof(TestMigrateSource));
|
||||
((TestMigrateSource *)source)->src = s;
|
||||
((TestMigrateSource *)source)->dest = dest;
|
||||
g_source_attach(source, NULL);
|
||||
g_source_attach(source, s->context);
|
||||
|
||||
/* slow down migration to have time to fiddle with log */
|
||||
/* TODO: qtest could learn to break on some places */
|
||||
@ -820,10 +861,11 @@ connect_thread(gpointer data)
|
||||
static void test_reconnect_subprocess(void)
|
||||
{
|
||||
TestServer *s = test_server_new("reconnect");
|
||||
GSource *src;
|
||||
char *cmd;
|
||||
|
||||
g_thread_new("connect", connect_thread, s);
|
||||
cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, ",server", "");
|
||||
cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, ",server", "");
|
||||
qtest_start(cmd);
|
||||
g_free(cmd);
|
||||
|
||||
@ -837,7 +879,10 @@ static void test_reconnect_subprocess(void)
|
||||
/* reconnect */
|
||||
s->fds_num = 0;
|
||||
s->rings = 0;
|
||||
g_idle_add(reconnect_cb, s);
|
||||
src = g_idle_source_new();
|
||||
g_source_set_callback(src, reconnect_cb, s, NULL);
|
||||
g_source_attach(src, s->context);
|
||||
g_source_unref(src);
|
||||
g_assert(wait_for_fds(s));
|
||||
wait_for_rings_started(s, 2);
|
||||
|
||||
@ -865,7 +910,7 @@ static void test_connect_fail_subprocess(void)
|
||||
|
||||
s->test_fail = true;
|
||||
g_thread_new("connect", connect_thread, s);
|
||||
cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, ",server", "");
|
||||
cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, ",server", "");
|
||||
qtest_start(cmd);
|
||||
g_free(cmd);
|
||||
|
||||
@ -898,7 +943,7 @@ static void test_flags_mismatch_subprocess(void)
|
||||
|
||||
s->test_flags = TEST_FLAGS_DISCONNECT;
|
||||
g_thread_new("connect", connect_thread, s);
|
||||
cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, root, ",server", "");
|
||||
cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, ",server", "");
|
||||
qtest_start(cmd);
|
||||
g_free(cmd);
|
||||
|
||||
@ -946,7 +991,7 @@ static void test_multiqueue(void)
|
||||
cmd = g_strdup_printf(
|
||||
QEMU_CMD_MEM QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d "
|
||||
"-device virtio-net-pci,netdev=net0,mq=on,vectors=%d",
|
||||
512, 512, root, s->chr_name,
|
||||
512, 512, s->mem_path, s->chr_name,
|
||||
s->socket_path, "", s->chr_name,
|
||||
s->queues, s->queues * 2 + 2);
|
||||
}
|
||||
@ -966,35 +1011,11 @@ static void test_multiqueue(void)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *hugefs;
|
||||
int ret;
|
||||
char template[] = "/tmp/vhost-test-XXXXXX";
|
||||
GMainLoop *loop;
|
||||
GThread *thread;
|
||||
|
||||
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_assert(tmpfs);
|
||||
|
||||
hugefs = getenv("QTEST_HUGETLBFS_PATH");
|
||||
if (hugefs) {
|
||||
root = init_hugepagefs(hugefs);
|
||||
g_assert(root);
|
||||
} else {
|
||||
root = tmpfs;
|
||||
}
|
||||
|
||||
loop = g_main_loop_new(NULL, FALSE);
|
||||
/* run the main loop thread so the chardev may operate */
|
||||
thread = g_thread_new(NULL, thread_function, loop);
|
||||
|
||||
if (qemu_memfd_check(0)) {
|
||||
qtest_add_data_func("/vhost-user/read-guest-mem/memfd",
|
||||
GINT_TO_POINTER(TEST_MEMFD_YES),
|
||||
@ -1018,24 +1039,5 @@ int main(int argc, char **argv)
|
||||
qtest_add_func("/vhost-user/flags-mismatch", test_flags_mismatch);
|
||||
}
|
||||
|
||||
ret = g_test_run();
|
||||
|
||||
/* cleanup */
|
||||
|
||||
/* finish the helper thread and dispatch pending sources */
|
||||
g_main_loop_quit(loop);
|
||||
g_thread_join(thread);
|
||||
while (g_main_context_pending(NULL)) {
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
}
|
||||
g_main_loop_unref(loop);
|
||||
|
||||
ret = rmdir(tmpfs);
|
||||
if (ret != 0) {
|
||||
g_test_message("unable to rmdir: path (%s): %s\n",
|
||||
tmpfs, strerror(errno));
|
||||
}
|
||||
g_assert_cmpint(ret, ==, 0);
|
||||
|
||||
return ret;
|
||||
return g_test_run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user