qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging

virtio,vhost: fixes, features, cleanups.

FLR support.
Misc fixes, cleanups.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Wed 04 Sep 2019 12:53:35 BST
# 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:
libvhost-user: introduce and use vu_has_protocol_feature()
libvhost-user: fix SLAVE_SEND_FD handling
virtio-pci: Add Function Level Reset support
virtio-rng: change default backend to rng-builtin
virtio-rng: Keep the default backend out of VirtIORNGConf
rng-builtin: add an RNG backend that uses qemu_guest_getrandom()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+122 -24
+1 -1
backends/Makefile.objs
··· 1 - common-obj-y += rng.o rng-egd.o 1 + common-obj-y += rng.o rng-egd.o rng-builtin.o 2 2 common-obj-$(CONFIG_POSIX) += rng-random.o 3 3 4 4 common-obj-$(CONFIG_TPM) += tpm.o
+77
backends/rng-builtin.c
··· 1 + /* 2 + * QEMU Builtin Random Number Generator Backend 3 + * 4 + * This work is licensed under the terms of the GNU GPL, version 2 or later. 5 + * See the COPYING file in the top-level directory. 6 + */ 7 + 8 + #include "qemu/osdep.h" 9 + #include "sysemu/rng.h" 10 + #include "qemu/main-loop.h" 11 + #include "qemu/guest-random.h" 12 + 13 + #define RNG_BUILTIN(obj) OBJECT_CHECK(RngBuiltin, (obj), TYPE_RNG_BUILTIN) 14 + 15 + typedef struct RngBuiltin { 16 + RngBackend parent; 17 + QEMUBH *bh; 18 + } RngBuiltin; 19 + 20 + static void rng_builtin_receive_entropy_bh(void *opaque) 21 + { 22 + RngBuiltin *s = opaque; 23 + 24 + while (!QSIMPLEQ_EMPTY(&s->parent.requests)) { 25 + RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests); 26 + 27 + qemu_guest_getrandom_nofail(req->data, req->size); 28 + 29 + req->receive_entropy(req->opaque, req->data, req->size); 30 + 31 + rng_backend_finalize_request(&s->parent, req); 32 + } 33 + } 34 + 35 + static void rng_builtin_request_entropy(RngBackend *b, RngRequest *req) 36 + { 37 + RngBuiltin *s = RNG_BUILTIN(b); 38 + 39 + qemu_bh_schedule(s->bh); 40 + } 41 + 42 + static void rng_builtin_init(Object *obj) 43 + { 44 + RngBuiltin *s = RNG_BUILTIN(obj); 45 + 46 + s->bh = qemu_bh_new(rng_builtin_receive_entropy_bh, s); 47 + } 48 + 49 + static void rng_builtin_finalize(Object *obj) 50 + { 51 + RngBuiltin *s = RNG_BUILTIN(obj); 52 + 53 + qemu_bh_delete(s->bh); 54 + } 55 + 56 + static void rng_builtin_class_init(ObjectClass *klass, void *data) 57 + { 58 + RngBackendClass *rbc = RNG_BACKEND_CLASS(klass); 59 + 60 + rbc->request_entropy = rng_builtin_request_entropy; 61 + } 62 + 63 + static const TypeInfo rng_builtin_info = { 64 + .name = TYPE_RNG_BUILTIN, 65 + .parent = TYPE_RNG_BACKEND, 66 + .instance_size = sizeof(RngBuiltin), 67 + .instance_init = rng_builtin_init, 68 + .instance_finalize = rng_builtin_finalize, 69 + .class_init = rng_builtin_class_init, 70 + }; 71 + 72 + static void register_types(void) 73 + { 74 + type_register_static(&rng_builtin_info); 75 + } 76 + 77 + type_init(register_types);
+10 -9
contrib/libvhost-user/libvhost-user.c
··· 94 94 return has_feature(dev->features, fbit); 95 95 } 96 96 97 + static inline bool vu_has_protocol_feature(VuDev *dev, unsigned int fbit) 98 + { 99 + return has_feature(dev->protocol_features, fbit); 100 + } 101 + 97 102 static const char * 98 103 vu_request_to_string(unsigned int req) 99 104 { ··· 951 956 { 952 957 int i = 0; 953 958 954 - if (!has_feature(dev->protocol_features, 955 - VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) { 959 + if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) { 956 960 return 0; 957 961 } 958 962 ··· 1097 1101 1098 1102 vmsg.fd_num = fd_num; 1099 1103 1100 - if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) { 1104 + if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) { 1101 1105 return false; 1102 1106 } 1103 1107 ··· 2190 2194 static int 2191 2195 vu_queue_inflight_get(VuDev *dev, VuVirtq *vq, int desc_idx) 2192 2196 { 2193 - if (!has_feature(dev->protocol_features, 2194 - VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) { 2197 + if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) { 2195 2198 return 0; 2196 2199 } 2197 2200 ··· 2208 2211 static int 2209 2212 vu_queue_inflight_pre_put(VuDev *dev, VuVirtq *vq, int desc_idx) 2210 2213 { 2211 - if (!has_feature(dev->protocol_features, 2212 - VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) { 2214 + if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) { 2213 2215 return 0; 2214 2216 } 2215 2217 ··· 2225 2227 static int 2226 2228 vu_queue_inflight_post_put(VuDev *dev, VuVirtq *vq, int desc_idx) 2227 2229 { 2228 - if (!has_feature(dev->protocol_features, 2229 - VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) { 2230 + if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) { 2230 2231 return 0; 2231 2232 } 2232 2233
+3 -1
hw/core/machine.c
··· 27 27 #include "hw/pci/pci.h" 28 28 #include "hw/mem/nvdimm.h" 29 29 30 - GlobalProperty hw_compat_4_1[] = {}; 30 + GlobalProperty hw_compat_4_1[] = { 31 + { "virtio-pci", "x-pcie-flr-init", "off" }, 32 + }; 31 33 const size_t hw_compat_4_1_len = G_N_ELEMENTS(hw_compat_4_1); 32 34 33 35 GlobalProperty hw_compat_4_0[] = {
+10
hw/virtio/virtio-pci.c
··· 604 604 605 605 pci_default_write_config(pci_dev, address, val, len); 606 606 607 + if (proxy->flags & VIRTIO_PCI_FLAG_INIT_FLR) { 608 + pcie_cap_flr_write_config(pci_dev, address, val, len); 609 + } 610 + 607 611 if (range_covers_byte(address, len, PCI_COMMAND) && 608 612 !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { 609 613 virtio_pci_stop_ioeventfd(proxy); ··· 1780 1784 pcie_ats_init(pci_dev, 256); 1781 1785 } 1782 1786 1787 + if (proxy->flags & VIRTIO_PCI_FLAG_INIT_FLR) { 1788 + /* Set Function Level Reset capability bit */ 1789 + pcie_cap_flr_init(pci_dev); 1790 + } 1783 1791 } else { 1784 1792 /* 1785 1793 * make future invocations of pci_is_express() return false ··· 1847 1855 VIRTIO_PCI_FLAG_INIT_LNKCTL_BIT, true), 1848 1856 DEFINE_PROP_BIT("x-pcie-pm-init", VirtIOPCIProxy, flags, 1849 1857 VIRTIO_PCI_FLAG_INIT_PM_BIT, true), 1858 + DEFINE_PROP_BIT("x-pcie-flr-init", VirtIOPCIProxy, flags, 1859 + VIRTIO_PCI_FLAG_INIT_FLR_BIT, true), 1850 1860 DEFINE_PROP_END_OF_LIST(), 1851 1861 }; 1852 1862
+4
hw/virtio/virtio-pci.h
··· 44 44 VIRTIO_PCI_FLAG_INIT_DEVERR_BIT, 45 45 VIRTIO_PCI_FLAG_INIT_LNKCTL_BIT, 46 46 VIRTIO_PCI_FLAG_INIT_PM_BIT, 47 + VIRTIO_PCI_FLAG_INIT_FLR_BIT, 47 48 }; 48 49 49 50 /* Need to activate work-arounds for buggy guests at vmstate load. */ ··· 79 80 80 81 /* Init Power Management */ 81 82 #define VIRTIO_PCI_FLAG_INIT_PM (1 << VIRTIO_PCI_FLAG_INIT_PM_BIT) 83 + 84 + /* Init Function Level Reset capability */ 85 + #define VIRTIO_PCI_FLAG_INIT_FLR (1 << VIRTIO_PCI_FLAG_INIT_FLR_BIT) 82 86 83 87 typedef struct { 84 88 MSIMessage msg;
+8 -11
hw/virtio/virtio-rng.c
··· 192 192 } 193 193 194 194 if (vrng->conf.rng == NULL) { 195 - vrng->conf.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM)); 195 + Object *default_backend = object_new(TYPE_RNG_BUILTIN); 196 196 197 - user_creatable_complete(USER_CREATABLE(vrng->conf.default_backend), 197 + user_creatable_complete(USER_CREATABLE(default_backend), 198 198 &local_err); 199 199 if (local_err) { 200 200 error_propagate(errp, local_err); 201 - object_unref(OBJECT(vrng->conf.default_backend)); 201 + object_unref(default_backend); 202 202 return; 203 203 } 204 204 205 - object_property_add_child(OBJECT(dev), 206 - "default-backend", 207 - OBJECT(vrng->conf.default_backend), 208 - NULL); 205 + object_property_add_child(OBJECT(dev), "default-backend", 206 + default_backend, &error_abort); 209 207 210 208 /* The child property took a reference, we can safely drop ours now */ 211 - object_unref(OBJECT(vrng->conf.default_backend)); 209 + object_unref(default_backend); 212 210 213 - object_property_set_link(OBJECT(dev), 214 - OBJECT(vrng->conf.default_backend), 215 - "rng", NULL); 211 + object_property_set_link(OBJECT(dev), default_backend, 212 + "rng", &error_abort); 216 213 } 217 214 218 215 vrng->rng = vrng->conf.rng;
-2
include/hw/virtio/virtio-rng.h
··· 14 14 15 15 #include "hw/virtio/virtio.h" 16 16 #include "sysemu/rng.h" 17 - #include "sysemu/rng-random.h" 18 17 #include "standard-headers/linux/virtio_rng.h" 19 18 20 19 #define TYPE_VIRTIO_RNG "virtio-rng-device" ··· 27 26 RngBackend *rng; 28 27 uint64_t max_bytes; 29 28 uint32_t period_ms; 30 - RngRandom *default_backend; 31 29 }; 32 30 33 31 typedef struct VirtIORNG {
+2
include/sysemu/rng.h
··· 24 24 #define RNG_BACKEND_CLASS(klass) \ 25 25 OBJECT_CLASS_CHECK(RngBackendClass, (klass), TYPE_RNG_BACKEND) 26 26 27 + #define TYPE_RNG_BUILTIN "rng-builtin" 28 + 27 29 typedef struct RngRequest RngRequest; 28 30 typedef struct RngBackendClass RngBackendClass; 29 31 typedef struct RngBackend RngBackend;
+7
qemu-options.hx
··· 4332 4332 4333 4333 The @option{share} boolean option is @var{on} by default with memfd. 4334 4334 4335 + @item -object rng-builtin,id=@var{id} 4336 + 4337 + Creates a random number generator backend which obtains entropy from 4338 + QEMU builtin functions. The @option{id} parameter is a unique ID that 4339 + will be used to reference this entropy backend from the @option{virtio-rng} 4340 + device. By default, the @option{virtio-rng} device uses this RNG backend. 4341 + 4335 4342 @item -object rng-random,id=@var{id},filename=@var{/dev/random} 4336 4343 4337 4344 Creates a random number generator backend which obtains entropy from