diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2024-03-13 15:11:53 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2024-03-13 15:11:53 +0000 |
| commit | 6fc69312313a2207a8fbc083658e0548746b707f (patch) | |
| tree | bec474d21181ee12f06f0b185552d0726dcb8d40 /hw/virtio/virtio-pci.c | |
| parent | 51e31f21407190df9bd048a539267534cea7dd66 (diff) | |
| parent | 73279cecca03f7c2b4489c5fea994e7349eaafaa (diff) | |
| download | focaccia-qemu-6fc69312313a2207a8fbc083658e0548746b707f.tar.gz focaccia-qemu-6fc69312313a2207a8fbc083658e0548746b707f.zip | |
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging
virtio,pc,pci: features, cleanups, fixes more memslots support in libvhost-user support PCIe Gen5/Gen6 link speeds in pcie more traces in vdpa network simulation devices support in vdpa SMBIOS type 9 descriptor implementation Bump max_cpus to 4096 vcpus in q35 aw-bits and granule options in VIRTIO-IOMMU Support report NUMA nodes for device memory using GI in acpi Beginning of shutdown event support in pvpanic fixes, cleanups all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmXw0TMPHG1zdEByZWRo # YXQuY29tAAoJECgfDbjSjVRp8x4H+gLMoGwaGAX7gDGPgn2Ix4j/3kO77ZJ9X9k/ # 1KqZu/9eMS1j2Ei+vZqf05w7qRjxxhwDq3ilEXF/+UFqgAehLqpRRB8j5inqvzYt # +jv0DbL11PBp/oFjWcytm5CbiVsvq8KlqCF29VNzc162XdtcduUOWagL96y8lJfZ # uPrOoyeR7SMH9lp3LLLHWgu+9W4nOS03RroZ6Umj40y5B7yR0Rrppz8lMw5AoQtr # 0gMRnFhYXeiW6CXdz+Tzcr7XfvkkYDi/j7ibiNSURLBfOpZa6Y8+kJGKxz5H1K1G # 6ZY4PBcOpQzl+NMrktPHogczgJgOK10t+1i/R3bGZYw2Qn/93Eg= # =C0UU # -----END PGP SIGNATURE----- # gpg: Signature made Tue 12 Mar 2024 22:03:31 GMT # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # 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 * tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: (68 commits) docs/specs/pvpanic: document shutdown event hw/cxl: Fix missing reserved data in CXL Device DVSEC hmat acpi: Fix out of bounds access due to missing use of indirection hmat acpi: Do not add Memory Proximity Domain Attributes Structure targetting non existent memory. qemu-options.hx: Document the virtio-iommu-pci aw-bits option hw/arm/virt: Set virtio-iommu aw-bits default value to 48 hw/i386/q35: Set virtio-iommu aw-bits default value to 39 virtio-iommu: Add an option to define the input range width virtio-iommu: Trace domain range limits as unsigned int qemu-options.hx: Document the virtio-iommu-pci granule option virtio-iommu: Change the default granule to the host page size virtio-iommu: Add a granule property hw/i386/acpi-build: Add support for SRAT Generic Initiator structures hw/acpi: Implement the SRAT GI affinity structure qom: new object to associate device to NUMA node hw/i386/pc: Inline pc_cmos_init() into pc_cmos_init_late() and remove it hw/i386/pc: Set "normal" boot device order in pc_basic_device_init() hw/i386/pc: Avoid one use of the current_machine global hw/i386/pc: Remove "rtc_state" link again Revert "hw/i386/pc: Confine system flash handling to pc_sysfw" ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # hw/core/machine.c
Diffstat (limited to 'hw/virtio/virtio-pci.c')
| -rw-r--r-- | hw/virtio/virtio-pci.c | 189 |
1 files changed, 186 insertions, 3 deletions
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index cb6940fc0e..eaaf86402c 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1442,6 +1442,155 @@ int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy, return virtio_pci_add_mem_cap(proxy, &cap.cap); } +/* Called within call_rcu(). */ +static void bitmap_free_region_cache(BitmapMemoryRegionCaches *caches) +{ + assert(caches != NULL); + address_space_cache_destroy(&caches->bitmap); + g_free(caches); +} + +static void lm_disable(VirtIODevice *vdev) +{ + BitmapMemoryRegionCaches *caches; + caches = qatomic_read(&vdev->caches); + qatomic_rcu_set(&vdev->caches, NULL); + if (caches) { + call_rcu(caches, bitmap_free_region_cache, rcu); + } +} + +static void lm_enable(VirtIODevice *vdev) +{ + BitmapMemoryRegionCaches *old = vdev->caches; + BitmapMemoryRegionCaches *new = NULL; + hwaddr addr, end, size; + int64_t len; + + addr = vdev->lm_base_addr_low | ((hwaddr)(vdev->lm_base_addr_high) << 32); + end = vdev->lm_end_addr_low | ((hwaddr)(vdev->lm_end_addr_high) << 32); + size = end - addr; + if (size <= 0) { + error_report("Invalid lm size."); + return; + } + + new = g_new0(BitmapMemoryRegionCaches, 1); + len = address_space_cache_init(&new->bitmap, vdev->dma_as, addr, size, + true); + if (len < size) { + virtio_error(vdev, "Cannot map bitmap"); + goto err_bitmap; + } + qatomic_rcu_set(&vdev->caches, new); + + if (old) { + call_rcu(old, bitmap_free_region_cache, rcu); + } + + return; + +err_bitmap: + address_space_cache_destroy(&new->bitmap); + g_free(new); +} + +static uint64_t virtio_pci_lm_read(void *opaque, hwaddr addr, + unsigned size) +{ + VirtIOPCIProxy *proxy = opaque; + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + hwaddr offset_end = LM_VRING_STATE_OFFSET + + virtio_pci_queue_mem_mult(proxy) * VIRTIO_QUEUE_MAX; + uint32_t val; + int qid; + + if (vdev == NULL) { + return UINT64_MAX; + } + switch (addr) { + case LM_LOGGING_CTRL: + val = vdev->lm_logging_ctrl; + break; + case LM_BASE_ADDR_LOW: + val = vdev->lm_base_addr_low; + break; + case LM_BASE_ADDR_HIGH: + val = vdev->lm_base_addr_high; + break; + case LM_END_ADDR_LOW: + val = vdev->lm_end_addr_low; + break; + case LM_END_ADDR_HIGH: + val = vdev->lm_end_addr_high; + break; + default: + if (addr >= LM_VRING_STATE_OFFSET && addr <= offset_end) { + qid = (addr - LM_VRING_STATE_OFFSET) / + virtio_pci_queue_mem_mult(proxy); + val = virtio_queue_get_vring_states(vdev, qid); + } else + val = 0; + + break; + } + + return val; +} + +static void virtio_pci_lm_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + VirtIOPCIProxy *proxy = opaque; + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + hwaddr offset_end = LM_VRING_STATE_OFFSET + + virtio_pci_queue_mem_mult(proxy) * VIRTIO_QUEUE_MAX; + int qid; + + if (vdev == NULL) { + return; + } + + switch (addr) { + case LM_LOGGING_CTRL: + vdev->lm_logging_ctrl = val; + switch (val) { + case LM_DISABLE: + lm_disable(vdev); + break; + case LM_ENABLE: + lm_enable(vdev); + break; + default: + virtio_error(vdev, "Unsupport LM_LOGGING_CTRL value: %"PRIx64, + val); + break; + }; + + break; + case LM_BASE_ADDR_LOW: + vdev->lm_base_addr_low = val; + break; + case LM_BASE_ADDR_HIGH: + vdev->lm_base_addr_high = val; + break; + case LM_END_ADDR_LOW: + vdev->lm_end_addr_low = val; + break; + case LM_END_ADDR_HIGH: + vdev->lm_end_addr_high = val; + break; + default: + if (addr >= LM_VRING_STATE_OFFSET && addr <= offset_end) { + qid = (addr - LM_VRING_STATE_OFFSET) / + virtio_pci_queue_mem_mult(proxy); + virtio_queue_set_vring_states(vdev, qid, val); + } else + virtio_error(vdev, "Unsupport addr: %"PRIx64, addr); + break; + } +} + static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr, unsigned size) { @@ -1823,6 +1972,15 @@ static void virtio_pci_modern_regions_init(VirtIOPCIProxy *proxy, }, .endianness = DEVICE_LITTLE_ENDIAN, }; + static const MemoryRegionOps lm_ops = { + .read = virtio_pci_lm_read, + .write = virtio_pci_lm_write, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + }, + .endianness = DEVICE_LITTLE_ENDIAN, + }; g_autoptr(GString) name = g_string_new(NULL); g_string_printf(name, "virtio-pci-common-%s", vdev_name); @@ -1859,6 +2017,14 @@ static void virtio_pci_modern_regions_init(VirtIOPCIProxy *proxy, proxy, name->str, proxy->notify_pio.size); + if (proxy->flags & VIRTIO_PCI_FLAG_VDPA) { + g_string_printf(name, "virtio-pci-lm-%s", vdev_name); + memory_region_init_io(&proxy->lm.mr, OBJECT(proxy), + &lm_ops, + proxy, + name->str, + proxy->lm.size); + } } static void virtio_pci_modern_region_map(VirtIOPCIProxy *proxy, @@ -2021,6 +2187,10 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) virtio_pci_modern_mem_region_map(proxy, &proxy->isr, &cap); virtio_pci_modern_mem_region_map(proxy, &proxy->device, &cap); virtio_pci_modern_mem_region_map(proxy, &proxy->notify, ¬ify.cap); + if (proxy->flags & VIRTIO_PCI_FLAG_VDPA) { + memory_region_add_subregion(&proxy->modern_bar, + proxy->lm.offset, &proxy->lm.mr); + } if (modern_pio) { memory_region_init(&proxy->io_bar, OBJECT(proxy), @@ -2090,6 +2260,9 @@ static void virtio_pci_device_unplugged(DeviceState *d) virtio_pci_modern_mem_region_unmap(proxy, &proxy->isr); virtio_pci_modern_mem_region_unmap(proxy, &proxy->device); virtio_pci_modern_mem_region_unmap(proxy, &proxy->notify); + if (proxy->flags & VIRTIO_PCI_FLAG_VDPA) { + memory_region_del_subregion(&proxy->modern_bar, &proxy->lm.mr); + } if (modern_pio) { virtio_pci_modern_io_region_unmap(proxy, &proxy->notify_pio); } @@ -2144,9 +2317,17 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp) proxy->notify_pio.type = VIRTIO_PCI_CAP_NOTIFY_CFG; /* subclasses can enforce modern, so do this unconditionally */ - memory_region_init(&proxy->modern_bar, OBJECT(proxy), "virtio-pci", - /* PCI BAR regions must be powers of 2 */ - pow2ceil(proxy->notify.offset + proxy->notify.size)); + if (!(proxy->flags & VIRTIO_PCI_FLAG_VDPA)) { + memory_region_init(&proxy->modern_bar, OBJECT(proxy), "virtio-pci", + /* PCI BAR regions must be powers of 2 */ + pow2ceil(proxy->notify.offset + proxy->notify.size)); + } else { + proxy->lm.offset = proxy->notify.offset + proxy->notify.size; + proxy->lm.size = 0x20 + VIRTIO_QUEUE_MAX * 4; + memory_region_init(&proxy->modern_bar, OBJECT(proxy), "virtio-pci", + /* PCI BAR regions must be powers of 2 */ + pow2ceil(proxy->lm.offset + proxy->lm.size)); + } if (proxy->disable_legacy == ON_OFF_AUTO_AUTO) { proxy->disable_legacy = pcie_port ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; @@ -2301,6 +2482,8 @@ static Property virtio_pci_properties[] = { VIRTIO_PCI_FLAG_INIT_FLR_BIT, true), DEFINE_PROP_BIT("aer", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_AER_BIT, false), + DEFINE_PROP_BIT("vdpa", VirtIOPCIProxy, flags, + VIRTIO_PCI_FLAG_VDPA_BIT, false), DEFINE_PROP_END_OF_LIST(), }; |