mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 09:43:56 -06:00
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
42 changed files with 1051 additions and 248 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue