virtio,pc,pci: fixes, features, cleanups
Mostly just fixes, cleanups all over the place. Some optimizations. More control over slot_reserved_mask. More feature bits supported for SVQ. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmRHQvAPHG1zdEByZWRo YXQuY29tAAoJECgfDbjSjVRpQc0H/RD+RXy7IAnmhkdCyjj0hM8pftPTwCJfrSCW DLHP4c5jiKO5ngUoAv3YJdM77TBCXlJn6gceeKBrzhGUTtJ7dTLC+Udeq/jW43EF /E2ldLLbTNFyUqW8yX7D+EVio7Jy4zXTHpczKCF5vO7MaVWS/b3QdCpmjXpEHLNb janv24vQHHgmRwK96uIdIauJJT8aqYW0arn1po8anxuFS8ok9Tf8LTEF5uBHokJP MriTwMaqMgRK+4rzh+b6wc7QC5GqIr44gFrsfFYuNOUY0+BizvGvUAtMt+B/XZwt OF4RSShUh2bhsQoYwgvShfEsR/vWwOl3yMAhcsB+wMgMzMG8MUQ= =e8DF -----END PGP SIGNATURE----- Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging virtio,pc,pci: fixes, features, cleanups Mostly just fixes, cleanups all over the place. Some optimizations. More control over slot_reserved_mask. More feature bits supported for SVQ. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmRHQvAPHG1zdEByZWRo # YXQuY29tAAoJECgfDbjSjVRpQc0H/RD+RXy7IAnmhkdCyjj0hM8pftPTwCJfrSCW # DLHP4c5jiKO5ngUoAv3YJdM77TBCXlJn6gceeKBrzhGUTtJ7dTLC+Udeq/jW43EF # /E2ldLLbTNFyUqW8yX7D+EVio7Jy4zXTHpczKCF5vO7MaVWS/b3QdCpmjXpEHLNb # janv24vQHHgmRwK96uIdIauJJT8aqYW0arn1po8anxuFS8ok9Tf8LTEF5uBHokJP # MriTwMaqMgRK+4rzh+b6wc7QC5GqIr44gFrsfFYuNOUY0+BizvGvUAtMt+B/XZwt # OF4RSShUh2bhsQoYwgvShfEsR/vWwOl3yMAhcsB+wMgMzMG8MUQ= # =e8DF # -----END PGP SIGNATURE----- # gpg: Signature made Tue 25 Apr 2023 04:03:12 AM BST # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [undefined] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # 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: (31 commits) hw/pci-bridge: Make PCIe and CXL PXB Devices inherit from TYPE_PXB_DEV hw/pci-bridge: pci_expander_bridge fix type in pxb_cxl_dev_reset() docs/specs: Convert pci-testdev.txt to rst docs/specs: Convert pci-serial.txt to rst docs/specs/pci-ids: Convert from txt to rST acpi: pcihp: allow repeating hot-unplug requests virtio: i2c: Check notifier helpers for VIRTIO_CONFIG_IRQ_IDX docs: Remove obsolete descriptions of SR-IOV support intel_iommu: refine iotlb hash calculation docs/cxl: Fix sentence MAINTAINERS: Add Eugenio Pérez as vhost-shadow-virtqueue reviewer tests: bios-tables-test: replace memset with initializer hw/acpi: limit warning on acpi table size to pc machines older than version 2.3 Add my old and new work email mapping and use work email to support acpi vhost-user-blk-server: notify client about disk resize pci: avoid accessing slot_reserved_mask directly outside of pci.c hw: Add compat machines for 8.1 hw/i386/amd_iommu: Factor amdvi_pci_realize out of amdvi_sysbus_realize hw/i386/amd_iommu: Set PCI static/const fields via PCIDeviceClass hw/i386/amd_iommu: Move capab_offset from AMDVIState to AMDVIPCIState ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
a14b8206c5
1
.mailmap
1
.mailmap
@ -54,6 +54,7 @@ Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <amarkovic@wavecomp.com>
|
||||
Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> <arikalo@wavecomp.com>
|
||||
Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> <aleksandar.rikalo@rt-rk.com>
|
||||
Alexander Graf <agraf@csgraf.de> <agraf@suse.de>
|
||||
Ani Sinha <anisinha@redhat.com> <ani@anisinha.ca>
|
||||
Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com>
|
||||
Christian Borntraeger <borntraeger@linux.ibm.com> <borntraeger@de.ibm.com>
|
||||
Damien Hedde <damien.hedde@dahe.fr> <damien.hedde@greensocs.com>
|
||||
|
12
MAINTAINERS
12
MAINTAINERS
@ -1895,7 +1895,7 @@ F: hw/pci/pcie_doe.c
|
||||
ACPI/SMBIOS
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
M: Igor Mammedov <imammedo@redhat.com>
|
||||
R: Ani Sinha <ani@anisinha.ca>
|
||||
R: Ani Sinha <anisinha@redhat.com>
|
||||
S: Supported
|
||||
F: include/hw/acpi/*
|
||||
F: include/hw/firmware/smbios.h
|
||||
@ -1932,7 +1932,7 @@ F: hw/acpi/viot.c
|
||||
F: hw/acpi/viot.h
|
||||
|
||||
ACPI/AVOCADO/BIOSBITS
|
||||
M: Ani Sinha <ani@anisinha.ca>
|
||||
M: Ani Sinha <anisinha@redhat.com>
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
S: Supported
|
||||
F: tests/avocado/acpi-bits/*
|
||||
@ -2076,6 +2076,10 @@ F: backends/vhost-user.c
|
||||
F: include/sysemu/vhost-user-backend.h
|
||||
F: subprojects/libvhost-user/
|
||||
|
||||
vhost-shadow-virtqueue
|
||||
R: Eugenio Pérez <eperezma@redhat.com>
|
||||
F: hw/virtio/vhost-shadow-virtqueue.*
|
||||
|
||||
virtio
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
S: Supported
|
||||
@ -3368,6 +3372,10 @@ F: hw/i386/intel_iommu.c
|
||||
F: hw/i386/intel_iommu_internal.h
|
||||
F: include/hw/i386/intel_iommu.h
|
||||
|
||||
AMD-Vi Emulation
|
||||
S: Orphan
|
||||
F: hw/i386/amd_iommu.?
|
||||
|
||||
OpenSBI Firmware
|
||||
M: Bin Meng <bmeng.cn@gmail.com>
|
||||
S: Supported
|
||||
|
@ -10,6 +10,7 @@
|
||||
* later. See the COPYING file in the top-level directory.
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "block/block.h"
|
||||
#include "subprojects/libvhost-user/libvhost-user.h" /* only for the type definitions */
|
||||
#include "standard-headers/linux/virtio_blk.h"
|
||||
@ -251,6 +252,27 @@ static void vu_blk_exp_request_shutdown(BlockExport *exp)
|
||||
vhost_user_server_stop(&vexp->vu_server);
|
||||
}
|
||||
|
||||
static void vu_blk_exp_resize(void *opaque)
|
||||
{
|
||||
VuBlkExport *vexp = opaque;
|
||||
BlockDriverState *bs = blk_bs(vexp->handler.blk);
|
||||
int64_t new_size = bdrv_getlength(bs);
|
||||
|
||||
if (new_size < 0) {
|
||||
error_printf("Failed to get length of block node '%s'",
|
||||
bdrv_get_node_name(bs));
|
||||
return;
|
||||
}
|
||||
|
||||
vexp->blkcfg.capacity = cpu_to_le64(new_size >> VIRTIO_BLK_SECTOR_BITS);
|
||||
|
||||
vu_config_change_msg(&vexp->vu_server.vu_dev);
|
||||
}
|
||||
|
||||
static const BlockDevOps vu_blk_dev_ops = {
|
||||
.resize_cb = vu_blk_exp_resize,
|
||||
};
|
||||
|
||||
static int vu_blk_exp_create(BlockExport *exp, BlockExportOptions *opts,
|
||||
Error **errp)
|
||||
{
|
||||
@ -292,6 +314,8 @@ static int vu_blk_exp_create(BlockExport *exp, BlockExportOptions *opts,
|
||||
blk_add_aio_context_notifier(exp->blk, blk_aio_attached, blk_aio_detach,
|
||||
vexp);
|
||||
|
||||
blk_set_dev_ops(exp->blk, &vu_blk_dev_ops, vexp);
|
||||
|
||||
if (!vhost_user_server_start(&vexp->vu_server, vu_opts->addr, exp->ctx,
|
||||
num_queues, &vu_blk_iface, errp)) {
|
||||
blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
|
||||
|
@ -135,7 +135,7 @@ Under ``tests/avocado/`` as the root we have:
|
||||
(c) They need not be loaded by avocado framework when running tests.
|
||||
|
||||
|
||||
Author: Ani Sinha <ani@anisinha.ca>
|
||||
Author: Ani Sinha <anisinha@redhat.com>
|
||||
|
||||
References:
|
||||
-----------
|
||||
|
@ -130,18 +130,8 @@ A vring address description
|
||||
Note that a ring address is an IOVA if ``VIRTIO_F_IOMMU_PLATFORM`` has
|
||||
been negotiated. Otherwise it is a user address.
|
||||
|
||||
Memory regions description
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
+-------------+---------+---------+-----+---------+
|
||||
| num regions | padding | region0 | ... | region7 |
|
||||
+-------------+---------+---------+-----+---------+
|
||||
|
||||
:num regions: a 32-bit number of regions
|
||||
|
||||
:padding: 32-bit
|
||||
|
||||
A region is:
|
||||
Memory region description
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
+---------------+------+--------------+-------------+
|
||||
| guest address | size | user address | mmap offset |
|
||||
@ -155,22 +145,49 @@ A region is:
|
||||
|
||||
:mmap offset: 64-bit offset where region starts in the mapped memory
|
||||
|
||||
When the ``VHOST_USER_PROTOCOL_F_XEN_MMAP`` protocol feature has been
|
||||
successfully negotiated, the memory region description contains two extra
|
||||
fields at the end.
|
||||
|
||||
+---------------+------+--------------+-------------+----------------+-------+
|
||||
| guest address | size | user address | mmap offset | xen mmap flags | domid |
|
||||
+---------------+------+--------------+-------------+----------------+-------+
|
||||
|
||||
:xen mmap flags: 32-bit bit field
|
||||
|
||||
- Bit 0 is set for Xen foreign memory mapping.
|
||||
- Bit 1 is set for Xen grant memory mapping.
|
||||
- Bit 8 is set if the memory region can not be mapped in advance, and memory
|
||||
areas within this region must be mapped / unmapped only when required by the
|
||||
back-end. The back-end shouldn't try to map the entire region at once, as the
|
||||
front-end may not allow it. The back-end should rather map only the required
|
||||
amount of memory at once and unmap it after it is used.
|
||||
|
||||
:domid: a 32-bit Xen hypervisor specific domain id.
|
||||
|
||||
Single memory region description
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
+---------+---------------+------+--------------+-------------+
|
||||
| padding | guest address | size | user address | mmap offset |
|
||||
+---------+---------------+------+--------------+-------------+
|
||||
+---------+--------+
|
||||
| padding | region |
|
||||
+---------+--------+
|
||||
|
||||
:padding: 64-bit
|
||||
|
||||
:guest address: a 64-bit guest address of the region
|
||||
A region is represented by Memory region description.
|
||||
|
||||
:size: a 64-bit size
|
||||
Multiple Memory regions description
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
:user address: a 64-bit user address
|
||||
+-------------+---------+---------+-----+---------+
|
||||
| num regions | padding | region0 | ... | region7 |
|
||||
+-------------+---------+---------+-----+---------+
|
||||
|
||||
:mmap offset: 64-bit offset where region starts in the mapped memory
|
||||
:num regions: a 32-bit number of regions
|
||||
|
||||
:padding: 32-bit
|
||||
|
||||
A region is represented by Memory region description.
|
||||
|
||||
Log description
|
||||
^^^^^^^^^^^^^^^
|
||||
@ -867,6 +884,7 @@ Protocol features
|
||||
#define VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS 14
|
||||
#define VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS 15
|
||||
#define VHOST_USER_PROTOCOL_F_STATUS 16
|
||||
#define VHOST_USER_PROTOCOL_F_XEN_MMAP 17
|
||||
|
||||
Front-end message types
|
||||
-----------------------
|
||||
@ -952,8 +970,8 @@ Front-end message types
|
||||
``VHOST_USER_SET_MEM_TABLE``
|
||||
:id: 5
|
||||
:equivalent ioctl: ``VHOST_SET_MEM_TABLE``
|
||||
:request payload: memory regions description
|
||||
:reply payload: (postcopy only) memory regions description
|
||||
:request payload: multiple memory regions description
|
||||
:reply payload: (postcopy only) multiple memory regions description
|
||||
|
||||
Sets the memory map regions on the back-end so it can translate the
|
||||
vring addresses. In the ancillary data there is an array of file
|
||||
|
@ -9,10 +9,7 @@ virtual functions (VFs) for the main purpose of eliminating software
|
||||
overhead in I/O from virtual machines.
|
||||
|
||||
QEMU now implements the basic common functionality to enable an emulated device
|
||||
to support SR/IOV. Yet no fully implemented devices exists in QEMU, but a
|
||||
proof-of-concept hack of the Intel igb can be found here:
|
||||
|
||||
git://github.com/knuto/qemu.git sriov_patches_v5
|
||||
to support SR/IOV.
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
@ -8,6 +8,9 @@ guest hardware that is specific to QEMU.
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
pci-ids
|
||||
pci-serial
|
||||
pci-testdev
|
||||
ppc-xive
|
||||
ppc-spapr-xive
|
||||
ppc-spapr-numa
|
||||
|
98
docs/specs/pci-ids.rst
Normal file
98
docs/specs/pci-ids.rst
Normal file
@ -0,0 +1,98 @@
|
||||
================
|
||||
PCI IDs for QEMU
|
||||
================
|
||||
|
||||
Red Hat, Inc. donates a part of its device ID range to QEMU, to be used for
|
||||
virtual devices. The vendor IDs are 1af4 (formerly Qumranet ID) and 1b36.
|
||||
|
||||
Contact Gerd Hoffmann <kraxel@redhat.com> to get a device ID assigned
|
||||
for your devices.
|
||||
|
||||
1af4 vendor ID
|
||||
--------------
|
||||
|
||||
The 1000 -> 10ff device ID range is used as follows for virtio-pci devices.
|
||||
Note that this allocation is separate from the virtio device IDs, which are
|
||||
maintained as part of the virtio specification.
|
||||
|
||||
1af4:1000
|
||||
network device (legacy)
|
||||
1af4:1001
|
||||
block device (legacy)
|
||||
1af4:1002
|
||||
balloon device (legacy)
|
||||
1af4:1003
|
||||
console device (legacy)
|
||||
1af4:1004
|
||||
SCSI host bus adapter device (legacy)
|
||||
1af4:1005
|
||||
entropy generator device (legacy)
|
||||
1af4:1009
|
||||
9p filesystem device (legacy)
|
||||
1af4:1012
|
||||
vsock device (bug compatibility)
|
||||
|
||||
1af4:1040 to 1af4:10ef
|
||||
ID range for modern virtio devices. The PCI device
|
||||
ID is calculated from the virtio device ID by adding the
|
||||
0x1040 offset. The virtio IDs are defined in the virtio
|
||||
specification. The Linux kernel has a header file with
|
||||
defines for all virtio IDs (``linux/virtio_ids.h``); QEMU has a
|
||||
copy in ``include/standard-headers/``.
|
||||
|
||||
1af4:10f0 to 1a4f:10ff
|
||||
Available for experimental usage without registration. Must get
|
||||
official ID when the code leaves the test lab (i.e. when seeking
|
||||
upstream merge or shipping a distro/product) to avoid conflicts.
|
||||
|
||||
1af4:1100
|
||||
Used as PCI Subsystem ID for existing hardware devices emulated
|
||||
by QEMU.
|
||||
|
||||
1af4:1110
|
||||
ivshmem device (shared memory, ``docs/specs/ivshmem-spec.txt``)
|
||||
|
||||
All other device IDs are reserved.
|
||||
|
||||
1b36 vendor ID
|
||||
--------------
|
||||
|
||||
The 0000 -> 00ff device ID range is used as follows for QEMU-specific
|
||||
PCI devices (other than virtio):
|
||||
|
||||
1b36:0001
|
||||
PCI-PCI bridge
|
||||
1b36:0002
|
||||
PCI serial port (16550A) adapter (:doc:`pci-serial`)
|
||||
1b36:0003
|
||||
PCI Dual-port 16550A adapter (:doc:`pci-serial`)
|
||||
1b36:0004
|
||||
PCI Quad-port 16550A adapter (:doc:`pci-serial`)
|
||||
1b36:0005
|
||||
PCI test device (:doc:`pci-testdev`)
|
||||
1b36:0006
|
||||
PCI Rocker Ethernet switch device
|
||||
1b36:0007
|
||||
PCI SD Card Host Controller Interface (SDHCI)
|
||||
1b36:0008
|
||||
PCIe host bridge
|
||||
1b36:0009
|
||||
PCI Expander Bridge (-device pxb)
|
||||
1b36:000a
|
||||
PCI-PCI bridge (multiseat)
|
||||
1b36:000b
|
||||
PCIe Expander Bridge (-device pxb-pcie)
|
||||
1b36:000d
|
||||
PCI xhci usb host adapter
|
||||
1b36:000f
|
||||
mdpy (mdev sample device), ``linux/samples/vfio-mdev/mdpy.c``
|
||||
1b36:0010
|
||||
PCIe NVMe device (``-device nvme``)
|
||||
1b36:0011
|
||||
PCI PVPanic device (``-device pvpanic-pci``)
|
||||
1b36:0012
|
||||
PCI ACPI ERST device (``-device acpi-erst``)
|
||||
|
||||
All these devices are documented in :doc:`index`.
|
||||
|
||||
The 0100 device ID is used for the QXL video card device.
|
@ -1,70 +0,0 @@
|
||||
|
||||
PCI IDs for qemu
|
||||
================
|
||||
|
||||
Red Hat, Inc. donates a part of its device ID range to qemu, to be used for
|
||||
virtual devices. The vendor IDs are 1af4 (formerly Qumranet ID) and 1b36.
|
||||
|
||||
Contact Gerd Hoffmann <kraxel@redhat.com> to get a device ID assigned
|
||||
for your devices.
|
||||
|
||||
1af4 vendor ID
|
||||
--------------
|
||||
|
||||
The 1000 -> 10ff device ID range is used as follows for virtio-pci devices.
|
||||
Note that this allocation separate from the virtio device IDs, which are
|
||||
maintained as part of the virtio specification.
|
||||
|
||||
1af4:1000 network device (legacy)
|
||||
1af4:1001 block device (legacy)
|
||||
1af4:1002 balloon device (legacy)
|
||||
1af4:1003 console device (legacy)
|
||||
1af4:1004 SCSI host bus adapter device (legacy)
|
||||
1af4:1005 entropy generator device (legacy)
|
||||
1af4:1009 9p filesystem device (legacy)
|
||||
1af4:1012 vsock device (bug compatibility)
|
||||
|
||||
1af4:1040 Start of ID range for modern virtio devices. The PCI device
|
||||
to ID is calculated from the virtio device ID by adding the
|
||||
1af4:10ef 0x1040 offset. The virtio IDs are defined in the virtio
|
||||
specification. The Linux kernel has a header file with
|
||||
defines for all virtio IDs (linux/virtio_ids.h), qemu has a
|
||||
copy in include/standard-headers/.
|
||||
|
||||
1af4:10f0 Available for experimental usage without registration. Must get
|
||||
to official ID when the code leaves the test lab (i.e. when seeking
|
||||
1af4:10ff upstream merge or shipping a distro/product) to avoid conflicts.
|
||||
|
||||
1af4:1100 Used as PCI Subsystem ID for existing hardware devices emulated
|
||||
by qemu.
|
||||
|
||||
1af4:1110 ivshmem device (shared memory, docs/specs/ivshmem-spec.txt)
|
||||
|
||||
All other device IDs are reserved.
|
||||
|
||||
1b36 vendor ID
|
||||
--------------
|
||||
|
||||
The 0000 -> 00ff device ID range is used as follows for QEMU-specific
|
||||
PCI devices (other than virtio):
|
||||
|
||||
1b36:0001 PCI-PCI bridge
|
||||
1b36:0002 PCI serial port (16550A) adapter (docs/specs/pci-serial.txt)
|
||||
1b36:0003 PCI Dual-port 16550A adapter (docs/specs/pci-serial.txt)
|
||||
1b36:0004 PCI Quad-port 16550A adapter (docs/specs/pci-serial.txt)
|
||||
1b36:0005 PCI test device (docs/specs/pci-testdev.txt)
|
||||
1b36:0006 PCI Rocker Ethernet switch device
|
||||
1b36:0007 PCI SD Card Host Controller Interface (SDHCI)
|
||||
1b36:0008 PCIe host bridge
|
||||
1b36:0009 PCI Expander Bridge (-device pxb)
|
||||
1b36:000a PCI-PCI bridge (multiseat)
|
||||
1b36:000b PCIe Expander Bridge (-device pxb-pcie)
|
||||
1b36:000d PCI xhci usb host adapter
|
||||
1b36:000f mdpy (mdev sample device), linux/samples/vfio-mdev/mdpy.c
|
||||
1b36:0010 PCIe NVMe device (-device nvme)
|
||||
1b36:0011 PCI PVPanic device (-device pvpanic-pci)
|
||||
1b36:0012 PCI ACPI ERST device (-device acpi-erst)
|
||||
|
||||
All these devices are documented in docs/specs.
|
||||
|
||||
The 0100 device ID is used for the QXL video card device.
|
37
docs/specs/pci-serial.rst
Normal file
37
docs/specs/pci-serial.rst
Normal file
@ -0,0 +1,37 @@
|
||||
=======================
|
||||
QEMU PCI serial devices
|
||||
=======================
|
||||
|
||||
QEMU implements some PCI serial devices which are simple PCI
|
||||
wrappers around one or more 16550 UARTs.
|
||||
|
||||
There is one single-port variant and two multiport-variants. Linux
|
||||
guests work out-of-the box with all cards. There is a Windows inf file
|
||||
(``docs/qemupciserial.inf``) to set up the cards in Windows guests.
|
||||
|
||||
|
||||
Single-port card
|
||||
----------------
|
||||
|
||||
Name:
|
||||
``pci-serial``
|
||||
PCI ID:
|
||||
1b36:0002
|
||||
PCI Region 0:
|
||||
IO bar, 8 bytes long, with the 16550 UART mapped to it.
|
||||
Interrupt:
|
||||
Wired to pin A.
|
||||
|
||||
|
||||
Multiport cards
|
||||
---------------
|
||||
|
||||
Name:
|
||||
``pci-serial-2x``, ``pci-serial-4x``
|
||||
PCI ID:
|
||||
1b36:0003 (``-2x``) and 1b36:0004 (``-4x``)
|
||||
PCI Region 0:
|
||||
IO bar, with two or four 16550 UARTs mapped after each other.
|
||||
The first is at offset 0, the second at offset 8, and so on.
|
||||
Interrupt:
|
||||
Wired to pin A.
|
@ -1,34 +0,0 @@
|
||||
|
||||
QEMU pci serial devices
|
||||
=======================
|
||||
|
||||
There is one single-port variant and two muliport-variants. Linux
|
||||
guests out-of-the box with all cards. There is a Windows inf file
|
||||
(docs/qemupciserial.inf) to setup the single-port card in Windows
|
||||
guests.
|
||||
|
||||
|
||||
single-port card
|
||||
----------------
|
||||
|
||||
Name: pci-serial
|
||||
PCI ID: 1b36:0002
|
||||
|
||||
PCI Region 0:
|
||||
IO bar, 8 bytes long, with the 16550 uart mapped to it.
|
||||
Interrupt is wired to pin A.
|
||||
|
||||
|
||||
multiport cards
|
||||
---------------
|
||||
|
||||
Name: pci-serial-2x
|
||||
PCI ID: 1b36:0003
|
||||
|
||||
Name: pci-serial-4x
|
||||
PCI ID: 1b36:0004
|
||||
|
||||
PCI Region 0:
|
||||
IO bar, with two/four 16550 uart mapped after each other.
|
||||
The first is at offset 0, second at offset 8, ...
|
||||
Interrupt is wired to pin A.
|
39
docs/specs/pci-testdev.rst
Normal file
39
docs/specs/pci-testdev.rst
Normal file
@ -0,0 +1,39 @@
|
||||
====================
|
||||
QEMU PCI test device
|
||||
====================
|
||||
|
||||
``pci-testdev`` is a device used for testing low level IO.
|
||||
|
||||
The device implements up to three BARs: BAR0, BAR1 and BAR2.
|
||||
Each of BAR 0+1 can be memory or IO. Guests must detect
|
||||
BAR types and act accordingly.
|
||||
|
||||
BAR 0+1 size is up to 4K bytes each.
|
||||
BAR 0+1 starts with the following header:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
typedef struct PCITestDevHdr {
|
||||
uint8_t test; /* write-only, starts a given test number */
|
||||
uint8_t width_type; /*
|
||||
* read-only, type and width of access for a given test.
|
||||
* 1,2,4 for byte,word or long write.
|
||||
* any other value if test not supported on this BAR
|
||||
*/
|
||||
uint8_t pad0[2];
|
||||
uint32_t offset; /* read-only, offset in this BAR for a given test */
|
||||
uint32_t data; /* read-only, data to use for a given test */
|
||||
uint32_t count; /* for debugging. number of writes detected. */
|
||||
uint8_t name[]; /* for debugging. 0-terminated ASCII string. */
|
||||
} PCITestDevHdr;
|
||||
|
||||
All registers are little endian.
|
||||
|
||||
The device is expected to always implement tests 0 to N on each BAR, and to add new
|
||||
tests with higher numbers. In this way a guest can scan test numbers until it
|
||||
detects an access type that it does not support on this BAR, then stop.
|
||||
|
||||
BAR2 is a 64bit memory BAR, without backing storage. It is disabled
|
||||
by default and can be enabled using the ``membar=<size>`` property. This
|
||||
can be used to test whether guests handle PCI BARs of a specific
|
||||
(possibly quite large) size correctly.
|
@ -1,31 +0,0 @@
|
||||
pci-test is a device used for testing low level IO
|
||||
|
||||
device implements up to three BARs: BAR0, BAR1 and BAR2.
|
||||
Each of BAR 0+1 can be memory or IO. Guests must detect
|
||||
BAR types and act accordingly.
|
||||
|
||||
BAR 0+1 size is up to 4K bytes each.
|
||||
BAR 0+1 starts with the following header:
|
||||
|
||||
typedef struct PCITestDevHdr {
|
||||
uint8_t test; <- write-only, starts a given test number
|
||||
uint8_t width_type; <- read-only, type and width of access for a given test.
|
||||
1,2,4 for byte,word or long write.
|
||||
any other value if test not supported on this BAR
|
||||
uint8_t pad0[2];
|
||||
uint32_t offset; <- read-only, offset in this BAR for a given test
|
||||
uint32_t data; <- read-only, data to use for a given test
|
||||
uint32_t count; <- for debugging. number of writes detected.
|
||||
uint8_t name[]; <- for debugging. 0-terminated ASCII string.
|
||||
} PCITestDevHdr;
|
||||
|
||||
All registers are little endian.
|
||||
|
||||
device is expected to always implement tests 0 to N on each BAR, and to add new
|
||||
tests with higher numbers. In this way a guest can scan test numbers until it
|
||||
detects an access type that it does not support on this BAR, then stop.
|
||||
|
||||
BAR2 is a 64bit memory bar, without backing storage. It is disabled
|
||||
by default and can be enabled using the membar=<size> property. This
|
||||
can be used to test whether guests handle pci bars of a specific
|
||||
(possibly quite large) size correctly.
|
@ -30,9 +30,10 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/uuid.h"
|
||||
|
||||
static void cedt_build_chbs(GArray *table_data, PXBDev *cxl)
|
||||
static void cedt_build_chbs(GArray *table_data, PXBCXLDev *cxl)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(cxl->cxl.cxl_host_bridge);
|
||||
PXBDev *pxb = PXB_DEV(cxl);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(cxl->cxl_host_bridge);
|
||||
struct MemoryRegion *mr = sbd->mmio[0].memory;
|
||||
|
||||
/* Type */
|
||||
@ -45,7 +46,7 @@ static void cedt_build_chbs(GArray *table_data, PXBDev *cxl)
|
||||
build_append_int_noprefix(table_data, 32, 2);
|
||||
|
||||
/* UID - currently equal to bus number */
|
||||
build_append_int_noprefix(table_data, cxl->bus_nr, 4);
|
||||
build_append_int_noprefix(table_data, pxb->bus_nr, 4);
|
||||
|
||||
/* Version */
|
||||
build_append_int_noprefix(table_data, 1, 4);
|
||||
@ -112,7 +113,7 @@ static void cedt_build_cfmws(GArray *table_data, CXLState *cxls)
|
||||
/* Host Bridge List (list of UIDs - currently bus_nr) */
|
||||
for (i = 0; i < fw->num_targets; i++) {
|
||||
g_assert(fw->target_hbs[i]);
|
||||
build_append_int_noprefix(table_data, fw->target_hbs[i]->bus_nr, 4);
|
||||
build_append_int_noprefix(table_data, PXB_DEV(fw->target_hbs[i])->bus_nr, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,7 +122,7 @@ static int cxl_foreach_pxb_hb(Object *obj, void *opaque)
|
||||
{
|
||||
Aml *cedt = opaque;
|
||||
|
||||
if (object_dynamic_cast(obj, TYPE_PXB_CXL_DEVICE)) {
|
||||
if (object_dynamic_cast(obj, TYPE_PXB_CXL_DEV)) {
|
||||
cedt_build_chbs(cedt->buf, PXB_CXL_DEV(obj));
|
||||
}
|
||||
|
||||
|
@ -357,6 +357,16 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
* acpi_pcihp_eject_slot() when the operation is completed.
|
||||
*/
|
||||
pdev->qdev.pending_deleted_event = true;
|
||||
/* if unplug was requested before OSPM is initialized,
|
||||
* linux kernel will clear GPE0.sts[] bits during boot, which effectively
|
||||
* hides unplug event. And than followup qmp_device_del() calls remain
|
||||
* blocked by above flag permanently.
|
||||
* Unblock qmp_device_del() by setting expire limit, so user can
|
||||
* repeat unplug request later when OSPM has been booted.
|
||||
*/
|
||||
pdev->qdev.pending_deleted_expires_ms =
|
||||
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); /* 1 msec */
|
||||
|
||||
s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
|
||||
acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* see docs/specs/pci-serial.txt */
|
||||
/* see docs/specs/pci-serial.rst */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
|
@ -23,7 +23,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* see docs/specs/pci-serial.txt */
|
||||
/* see docs/specs/pci-serial.rst */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
|
@ -84,7 +84,7 @@ void cxl_fmws_link_targets(CXLState *cxl_state, Error **errp)
|
||||
bool ambig;
|
||||
|
||||
o = object_resolve_path_type(fw->targets[i],
|
||||
TYPE_PXB_CXL_DEVICE,
|
||||
TYPE_PXB_CXL_DEV,
|
||||
&ambig);
|
||||
if (!o) {
|
||||
error_setg(errp, "Could not resolve CXLFM target %s",
|
||||
@ -141,7 +141,7 @@ static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow *fw, hwaddr addr)
|
||||
addr += fw->base;
|
||||
|
||||
rb_index = (addr / cxl_decode_ig(fw->enc_int_gran)) % fw->num_targets;
|
||||
hb = PCI_HOST_BRIDGE(fw->target_hbs[rb_index]->cxl.cxl_host_bridge);
|
||||
hb = PCI_HOST_BRIDGE(fw->target_hbs[rb_index]->cxl_host_bridge);
|
||||
if (!hb || !hb->bus || !pci_bus_is_cxl(hb->bus)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2395,9 +2395,11 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id,
|
||||
/* IVHD length */
|
||||
build_append_int_noprefix(table_data, ivhd_table_len, 2);
|
||||
/* DeviceID */
|
||||
build_append_int_noprefix(table_data, s->devid, 2);
|
||||
build_append_int_noprefix(table_data,
|
||||
object_property_get_int(OBJECT(&s->pci), "addr",
|
||||
&error_abort), 2);
|
||||
/* Capability offset */
|
||||
build_append_int_noprefix(table_data, s->capab_offset, 2);
|
||||
build_append_int_noprefix(table_data, s->pci.capab_offset, 2);
|
||||
/* IOMMU base address */
|
||||
build_append_int_noprefix(table_data, s->mmio.addr, 8);
|
||||
/* PCI Segment Group */
|
||||
@ -2695,7 +2697,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
int legacy_table_size =
|
||||
ROUND_UP(tables_blob->len - aml_len + legacy_aml_len,
|
||||
ACPI_BUILD_ALIGN_SIZE);
|
||||
if (tables_blob->len > legacy_table_size) {
|
||||
if ((tables_blob->len > legacy_table_size) &&
|
||||
!pcmc->resizable_acpi_blob) {
|
||||
/* Should happen only with PCI bridges and -M pc-i440fx-2.0. */
|
||||
warn_report("ACPI table size %u exceeds %d bytes,"
|
||||
" migration may not work",
|
||||
@ -2706,7 +2709,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
g_array_set_size(tables_blob, legacy_table_size);
|
||||
} else {
|
||||
/* Make sure we have a buffer in case we need to resize the tables. */
|
||||
if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) {
|
||||
if ((tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) &&
|
||||
!pcmc->resizable_acpi_blob) {
|
||||
/* As of QEMU 2.1, this fires with 160 VCPUs and 255 memory slots. */
|
||||
warn_report("ACPI table size %u exceeds %d bytes,"
|
||||
" migration may not work",
|
||||
|
@ -1509,23 +1509,48 @@ static void amdvi_init(AMDVIState *s)
|
||||
amdvi_set_quad(s, AMDVI_MMIO_EXT_FEATURES, AMDVI_EXT_FEATURES,
|
||||
0xffffffffffffffef, 0);
|
||||
amdvi_set_quad(s, AMDVI_MMIO_STATUS, 0, 0x98, 0x67);
|
||||
}
|
||||
|
||||
static void amdvi_pci_realize(PCIDevice *pdev, Error **errp)
|
||||
{
|
||||
AMDVIPCIState *s = AMD_IOMMU_PCI(pdev);
|
||||
int ret;
|
||||
|
||||
ret = pci_add_capability(pdev, AMDVI_CAPAB_ID_SEC, 0,
|
||||
AMDVI_CAPAB_SIZE, errp);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
s->capab_offset = ret;
|
||||
|
||||
ret = pci_add_capability(pdev, PCI_CAP_ID_MSI, 0,
|
||||
AMDVI_CAPAB_REG_SIZE, errp);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
ret = pci_add_capability(pdev, PCI_CAP_ID_HT, 0,
|
||||
AMDVI_CAPAB_REG_SIZE, errp);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msi_init(pdev, 0, 1, true, false, errp) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* reset device ident */
|
||||
pci_config_set_vendor_id(s->pci.dev.config, PCI_VENDOR_ID_AMD);
|
||||
pci_config_set_prog_interface(s->pci.dev.config, 00);
|
||||
pci_config_set_device_id(s->pci.dev.config, s->devid);
|
||||
pci_config_set_class(s->pci.dev.config, 0x0806);
|
||||
pci_config_set_prog_interface(pdev->config, 0);
|
||||
|
||||
/* reset AMDVI specific capabilities, all r/o */
|
||||
pci_set_long(s->pci.dev.config + s->capab_offset, AMDVI_CAPAB_FEATURES);
|
||||
pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_BAR_LOW,
|
||||
s->mmio.addr & ~(0xffff0000));
|
||||
pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_BAR_HIGH,
|
||||
(s->mmio.addr & ~(0xffff)) >> 16);
|
||||
pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_RANGE,
|
||||
pci_set_long(pdev->config + s->capab_offset, AMDVI_CAPAB_FEATURES);
|
||||
pci_set_long(pdev->config + s->capab_offset + AMDVI_CAPAB_BAR_LOW,
|
||||
AMDVI_BASE_ADDR & ~(0xffff0000));
|
||||
pci_set_long(pdev->config + s->capab_offset + AMDVI_CAPAB_BAR_HIGH,
|
||||
(AMDVI_BASE_ADDR & ~(0xffff)) >> 16);
|
||||
pci_set_long(pdev->config + s->capab_offset + AMDVI_CAPAB_RANGE,
|
||||
0xff000000);
|
||||
pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_MISC, 0);
|
||||
pci_set_long(s->pci.dev.config + s->capab_offset + AMDVI_CAPAB_MISC,
|
||||
pci_set_long(pdev->config + s->capab_offset + AMDVI_CAPAB_MISC, 0);
|
||||
pci_set_long(pdev->config + s->capab_offset + AMDVI_CAPAB_MISC,
|
||||
AMDVI_MAX_PH_ADDR | AMDVI_MAX_GVA_ADDR | AMDVI_MAX_VA_ADDR);
|
||||
}
|
||||
|
||||
@ -1539,7 +1564,6 @@ static void amdvi_sysbus_reset(DeviceState *dev)
|
||||
|
||||
static void amdvi_sysbus_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
int ret = 0;
|
||||
AMDVIState *s = AMD_IOMMU_DEVICE(dev);
|
||||
MachineState *ms = MACHINE(qdev_get_machine());
|
||||
PCMachineState *pcms = PC_MACHINE(ms);
|
||||
@ -1553,23 +1577,6 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp)
|
||||
if (!qdev_realize(DEVICE(&s->pci), &bus->qbus, errp)) {
|
||||
return;
|
||||
}
|
||||
ret = pci_add_capability(&s->pci.dev, AMDVI_CAPAB_ID_SEC, 0,
|
||||
AMDVI_CAPAB_SIZE, errp);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
s->capab_offset = ret;
|
||||
|
||||
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_MSI, 0,
|
||||
AMDVI_CAPAB_REG_SIZE, errp);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_HT, 0,
|
||||
AMDVI_CAPAB_REG_SIZE, errp);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Pseudo address space under root PCI bus. */
|
||||
x86ms->ioapic_as = amdvi_host_dma_iommu(bus, s, AMDVI_IOAPIC_SB_DEVID);
|
||||
@ -1581,8 +1588,6 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mmio);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(s), 0, AMDVI_BASE_ADDR);
|
||||
pci_setup_iommu(bus, amdvi_host_dma_iommu, s);
|
||||
s->devid = object_property_get_int(OBJECT(&s->pci), "addr", &error_abort);
|
||||
msi_init(&s->pci.dev, 0, 1, true, false, errp);
|
||||
amdvi_init(s);
|
||||
}
|
||||
|
||||
@ -1625,6 +1630,11 @@ static const TypeInfo amdvi_sysbus = {
|
||||
static void amdvi_pci_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->vendor_id = PCI_VENDOR_ID_AMD;
|
||||
k->class_id = 0x0806;
|
||||
k->realize = amdvi_pci_realize;
|
||||
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
dc->desc = "AMD IOMMU (AMD-Vi) DMA Remapping device";
|
||||
|
@ -300,27 +300,26 @@ struct irte_ga {
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(AMDVIState, AMD_IOMMU_DEVICE)
|
||||
|
||||
#define TYPE_AMD_IOMMU_PCI "AMDVI-PCI"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(AMDVIPCIState, AMD_IOMMU_PCI)
|
||||
|
||||
#define TYPE_AMD_IOMMU_MEMORY_REGION "amd-iommu-iommu-memory-region"
|
||||
|
||||
typedef struct AMDVIAddressSpace AMDVIAddressSpace;
|
||||
|
||||
/* functions to steal PCI config space */
|
||||
typedef struct AMDVIPCIState {
|
||||
struct AMDVIPCIState {
|
||||
PCIDevice dev; /* The PCI device itself */
|
||||
} AMDVIPCIState;
|
||||
uint32_t capab_offset; /* capability offset pointer */
|
||||
};
|
||||
|
||||
struct AMDVIState {
|
||||
X86IOMMUState iommu; /* IOMMU bus device */
|
||||
AMDVIPCIState pci; /* IOMMU PCI device */
|
||||
|
||||
uint32_t version;
|
||||
uint32_t capab_offset; /* capability offset pointer */
|
||||
|
||||
uint64_t mmio_addr;
|
||||
|
||||
uint32_t devid; /* auto-assigned devid */
|
||||
|
||||
bool enabled; /* IOMMU enabled */
|
||||
bool ats_enabled; /* address translation enabled */
|
||||
bool cmdbuf_enabled; /* command buffer enabled */
|
||||
|
@ -64,8 +64,8 @@ struct vtd_as_key {
|
||||
struct vtd_iotlb_key {
|
||||
uint64_t gfn;
|
||||
uint32_t pasid;
|
||||
uint32_t level;
|
||||
uint16_t sid;
|
||||
uint8_t level;
|
||||
};
|
||||
|
||||
static void vtd_address_space_refresh_all(IntelIOMMUState *s);
|
||||
@ -221,10 +221,11 @@ static gboolean vtd_iotlb_equal(gconstpointer v1, gconstpointer v2)
|
||||
static guint vtd_iotlb_hash(gconstpointer v)
|
||||
{
|
||||
const struct vtd_iotlb_key *key = v;
|
||||
uint64_t hash64 = key->gfn | ((uint64_t)(key->sid) << VTD_IOTLB_SID_SHIFT) |
|
||||
(uint64_t)(key->level - 1) << VTD_IOTLB_LVL_SHIFT |
|
||||
(uint64_t)(key->pasid) << VTD_IOTLB_PASID_SHIFT;
|
||||
|
||||
return key->gfn | ((key->sid) << VTD_IOTLB_SID_SHIFT) |
|
||||
(key->level) << VTD_IOTLB_LVL_SHIFT |
|
||||
(key->pasid) << VTD_IOTLB_PASID_SHIFT;
|
||||
return (guint)((hash64 >> 32) ^ (hash64 & 0xffffffffU));
|
||||
}
|
||||
|
||||
static gboolean vtd_as_equal(gconstpointer v1, gconstpointer v2)
|
||||
|
@ -114,9 +114,9 @@
|
||||
VTD_INTERRUPT_ADDR_FIRST + 1)
|
||||
|
||||
/* The shift of source_id in the key of IOTLB hash table */
|
||||
#define VTD_IOTLB_SID_SHIFT 20
|
||||
#define VTD_IOTLB_LVL_SHIFT 28
|
||||
#define VTD_IOTLB_PASID_SHIFT 30
|
||||
#define VTD_IOTLB_SID_SHIFT 26
|
||||
#define VTD_IOTLB_LVL_SHIFT 42
|
||||
#define VTD_IOTLB_PASID_SHIFT 44
|
||||
#define VTD_IOTLB_MAX_SIZE 1024 /* Max size of the hash table */
|
||||
|
||||
/* IOTLB_REG */
|
||||
|
@ -1946,6 +1946,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
pcmc->acpi_data_size = 0x20000 + 0x8000;
|
||||
pcmc->pvh_enabled = true;
|
||||
pcmc->kvmclock_create_always = true;
|
||||
pcmc->resizable_acpi_blob = true;
|
||||
assert(!mc->get_hotplug_handler);
|
||||
mc->get_hotplug_handler = pc_get_hotplug_handler;
|
||||
mc->hotplug_allowed = pc_hotplug_allowed;
|
||||
|
@ -756,6 +756,7 @@ static void pc_i440fx_2_2_machine_options(MachineClass *m)
|
||||
compat_props_add(m->compat_props, hw_compat_2_2, hw_compat_2_2_len);
|
||||
compat_props_add(m->compat_props, pc_compat_2_2, pc_compat_2_2_len);
|
||||
pcmc->rsdp_in_ram = false;
|
||||
pcmc->resizable_acpi_blob = false;
|
||||
}
|
||||
|
||||
DEFINE_I440FX_MACHINE(v2_2, "pc-i440fx-2.2", pc_compat_2_2_fn,
|
||||
|
@ -81,6 +81,10 @@ void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine)
|
||||
|
||||
memory_device_plug(MEMORY_DEVICE(dimm), machine);
|
||||
vmstate_register_ram(vmstate_mr, DEVICE(dimm));
|
||||
/* count only "real" DIMMs, not NVDIMMs */
|
||||
if (!object_dynamic_cast(OBJECT(dimm), TYPE_NVDIMM)) {
|
||||
machine->device_memory->dimm_size += memory_region_size(vmstate_mr);
|
||||
}
|
||||
}
|
||||
|
||||
void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine)
|
||||
@ -90,6 +94,9 @@ void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine)
|
||||
|
||||
memory_device_unplug(MEMORY_DEVICE(dimm), machine);
|
||||
vmstate_unregister_ram(vmstate_mr, DEVICE(dimm));
|
||||
if (!object_dynamic_cast(OBJECT(dimm), TYPE_NVDIMM)) {
|
||||
machine->device_memory->dimm_size -= memory_region_size(vmstate_mr);
|
||||
}
|
||||
}
|
||||
|
||||
static int pc_dimm_slot2bitmap(Object *obj, void *opaque)
|
||||
|
@ -50,24 +50,8 @@ struct PXBBus {
|
||||
char bus_path[8];
|
||||
};
|
||||
|
||||
#define TYPE_PXB_DEVICE "pxb"
|
||||
DECLARE_INSTANCE_CHECKER(PXBDev, PXB_DEV,
|
||||
TYPE_PXB_DEVICE)
|
||||
|
||||
#define TYPE_PXB_PCIE_DEVICE "pxb-pcie"
|
||||
DECLARE_INSTANCE_CHECKER(PXBDev, PXB_PCIE_DEV,
|
||||
TYPE_PXB_PCIE_DEVICE)
|
||||
|
||||
static PXBDev *convert_to_pxb(PCIDevice *dev)
|
||||
{
|
||||
/* A CXL PXB's parent bus is PCIe, so the normal check won't work */
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PXB_CXL_DEVICE)) {
|
||||
return PXB_CXL_DEV(dev);
|
||||
}
|
||||
|
||||
return pci_bus_is_express(pci_get_bus(dev))
|
||||
? PXB_PCIE_DEV(dev) : PXB_DEV(dev);
|
||||
}
|
||||
#define TYPE_PXB_PCIE_DEV "pxb-pcie"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(PXBPCIEDev, PXB_PCIE_DEV)
|
||||
|
||||
static GList *pxb_dev_list;
|
||||
|
||||
@ -89,14 +73,14 @@ bool cxl_get_hb_passthrough(PCIHostState *hb)
|
||||
|
||||
static int pxb_bus_num(PCIBus *bus)
|
||||
{
|
||||
PXBDev *pxb = convert_to_pxb(bus->parent_dev);
|
||||
PXBDev *pxb = PXB_DEV(bus->parent_dev);
|
||||
|
||||
return pxb->bus_nr;
|
||||
}
|
||||
|
||||
static uint16_t pxb_bus_numa_node(PCIBus *bus)
|
||||
{
|
||||
PXBDev *pxb = convert_to_pxb(bus->parent_dev);
|
||||
PXBDev *pxb = PXB_DEV(bus->parent_dev);
|
||||
|
||||
return pxb->numa_node;
|
||||
}
|
||||
@ -154,7 +138,7 @@ static char *pxb_host_ofw_unit_address(const SysBusDevice *dev)
|
||||
|
||||
pxb_host = PCI_HOST_BRIDGE(dev);
|
||||
pxb_bus = pxb_host->bus;
|
||||
pxb_dev = convert_to_pxb(pxb_bus->parent_dev);
|
||||
pxb_dev = PXB_DEV(pxb_bus->parent_dev);
|
||||
position = g_list_index(pxb_dev_list, pxb_dev);
|
||||
assert(position >= 0);
|
||||
|
||||
@ -212,8 +196,8 @@ static void pxb_cxl_realize(DeviceState *dev, Error **errp)
|
||||
*/
|
||||
void pxb_cxl_hook_up_registers(CXLState *cxl_state, PCIBus *bus, Error **errp)
|
||||
{
|
||||
PXBDev *pxb = PXB_CXL_DEV(pci_bridge_get_device(bus));
|
||||
CXLHost *cxl = pxb->cxl.cxl_host_bridge;
|
||||
PXBCXLDev *pxb = PXB_CXL_DEV(pci_bridge_get_device(bus));
|
||||
CXLHost *cxl = pxb->cxl_host_bridge;
|
||||
CXLComponentState *cxl_cstate = &cxl->cxl_cstate;
|
||||
struct MemoryRegion *mr = &cxl_cstate->crb.component_registers;
|
||||
hwaddr offset;
|
||||
@ -299,7 +283,7 @@ static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
|
||||
|
||||
static void pxb_cxl_dev_reset(DeviceState *dev)
|
||||
{
|
||||
CXLHost *cxl = PXB_CXL_DEV(dev)->cxl.cxl_host_bridge;
|
||||
CXLHost *cxl = PXB_CXL_DEV(dev)->cxl_host_bridge;
|
||||
CXLComponentState *cxl_cstate = &cxl->cxl_cstate;
|
||||
PCIHostState *hb = PCI_HOST_BRIDGE(cxl);
|
||||
uint32_t *reg_state = cxl_cstate->crb.cache_mem_registers;
|
||||
@ -311,7 +295,7 @@ static void pxb_cxl_dev_reset(DeviceState *dev)
|
||||
* The CXL specification allows for host bridges with no HDM decoders
|
||||
* if they only have a single root port.
|
||||
*/
|
||||
if (!PXB_DEV(dev)->hdm_for_passthrough) {
|
||||
if (!PXB_CXL_DEV(dev)->hdm_for_passthrough) {
|
||||
dsp_count = pcie_count_ds_ports(hb->bus);
|
||||
}
|
||||
/* Initial reset will have 0 dsp so wait until > 0 */
|
||||
@ -337,7 +321,7 @@ static gint pxb_compare(gconstpointer a, gconstpointer b)
|
||||
static void pxb_dev_realize_common(PCIDevice *dev, enum BusType type,
|
||||
Error **errp)
|
||||
{
|
||||
PXBDev *pxb = convert_to_pxb(dev);
|
||||
PXBDev *pxb = PXB_DEV(dev);
|
||||
DeviceState *ds, *bds = NULL;
|
||||
PCIBus *bus;
|
||||
const char *dev_name = NULL;
|
||||
@ -365,7 +349,7 @@ static void pxb_dev_realize_common(PCIDevice *dev, enum BusType type,
|
||||
} else if (type == CXL) {
|
||||
bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_CXL_BUS);
|
||||
bus->flags |= PCI_BUS_CXL;
|
||||
PXB_CXL_DEV(dev)->cxl.cxl_host_bridge = PXB_CXL_HOST(ds);
|
||||
PXB_CXL_DEV(dev)->cxl_host_bridge = PXB_CXL_HOST(ds);
|
||||
} else {
|
||||
bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
|
||||
bds = qdev_new("pci-bridge");
|
||||
@ -418,7 +402,7 @@ static void pxb_dev_realize(PCIDevice *dev, Error **errp)
|
||||
|
||||
static void pxb_dev_exitfn(PCIDevice *pci_dev)
|
||||
{
|
||||
PXBDev *pxb = convert_to_pxb(pci_dev);
|
||||
PXBDev *pxb = PXB_DEV(pci_dev);
|
||||
|
||||
pxb_dev_list = g_list_remove(pxb_dev_list, pxb);
|
||||
}
|
||||
@ -449,7 +433,7 @@ static void pxb_dev_class_init(ObjectClass *klass, void *data)
|
||||
}
|
||||
|
||||
static const TypeInfo pxb_dev_info = {
|
||||
.name = TYPE_PXB_DEVICE,
|
||||
.name = TYPE_PXB_DEV,
|
||||
.parent = TYPE_PCI_DEVICE,
|
||||
.instance_size = sizeof(PXBDev),
|
||||
.class_init = pxb_dev_class_init,
|
||||
@ -481,15 +465,14 @@ static void pxb_pcie_dev_class_init(ObjectClass *klass, void *data)
|
||||
k->class_id = PCI_CLASS_BRIDGE_HOST;
|
||||
|
||||
dc->desc = "PCI Express Expander Bridge";
|
||||
device_class_set_props(dc, pxb_dev_properties);
|
||||
dc->hotpluggable = false;
|
||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||
}
|
||||
|
||||
static const TypeInfo pxb_pcie_dev_info = {
|
||||
.name = TYPE_PXB_PCIE_DEVICE,
|
||||
.parent = TYPE_PCI_DEVICE,
|
||||
.instance_size = sizeof(PXBDev),
|
||||
.name = TYPE_PXB_PCIE_DEV,
|
||||
.parent = TYPE_PXB_DEV,
|
||||
.instance_size = sizeof(PXBPCIEDev),
|
||||
.class_init = pxb_pcie_dev_class_init,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
|
||||
@ -510,11 +493,7 @@ static void pxb_cxl_dev_realize(PCIDevice *dev, Error **errp)
|
||||
}
|
||||
|
||||
static Property pxb_cxl_dev_properties[] = {
|
||||
/* Note: 0 is not a legal PXB bus number. */
|
||||
DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0),
|
||||
DEFINE_PROP_UINT16("numa_node", PXBDev, numa_node, NUMA_NODE_UNASSIGNED),
|
||||
DEFINE_PROP_BOOL("bypass_iommu", PXBDev, bypass_iommu, false),
|
||||
DEFINE_PROP_BOOL("hdm_for_passthrough", PXBDev, hdm_for_passthrough, false),
|
||||
DEFINE_PROP_BOOL("hdm_for_passthrough", PXBCXLDev, hdm_for_passthrough, false),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@ -540,9 +519,9 @@ static void pxb_cxl_dev_class_init(ObjectClass *klass, void *data)
|
||||
}
|
||||
|
||||
static const TypeInfo pxb_cxl_dev_info = {
|
||||
.name = TYPE_PXB_CXL_DEVICE,
|
||||
.parent = TYPE_PCI_DEVICE,
|
||||
.instance_size = sizeof(PXBDev),
|
||||
.name = TYPE_PXB_CXL_DEV,
|
||||
.parent = TYPE_PXB_PCIE_DEV,
|
||||
.instance_size = sizeof(PXBCXLDev),
|
||||
.class_init = pxb_cxl_dev_class_init,
|
||||
.interfaces =
|
||||
(InterfaceInfo[]){
|
||||
|
15
hw/pci/pci.c
15
hw/pci/pci.c
@ -1116,6 +1116,21 @@ static bool pci_bus_devfn_reserved(PCIBus *bus, int devfn)
|
||||
return bus->slot_reserved_mask & (1UL << PCI_SLOT(devfn));
|
||||
}
|
||||
|
||||
uint32_t pci_bus_get_slot_reserved_mask(PCIBus *bus)
|
||||
{
|
||||
return bus->slot_reserved_mask;
|
||||
}
|
||||
|
||||
void pci_bus_set_slot_reserved_mask(PCIBus *bus, uint32_t mask)
|
||||
{
|
||||
bus->slot_reserved_mask |= mask;
|
||||
}
|
||||
|
||||
void pci_bus_clear_slot_reserved_mask(PCIBus *bus, uint32_t mask)
|
||||
{
|
||||
bus->slot_reserved_mask &= ~mask;
|
||||
}
|
||||
|
||||
/* -1 for devfn means auto assign */
|
||||
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
|
||||
const char *name, int devfn,
|
||||
|
@ -237,6 +237,7 @@ static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info,
|
||||
return -EINVAL;
|
||||
}
|
||||
virtio_queue_set_num(vdev, index, num);
|
||||
virtio_init_region_cache(vdev, index);
|
||||
} else if (virtio_queue_get_num(vdev, index) > num) {
|
||||
/* Fail if we don't have a big enough queue. */
|
||||
return -EINVAL;
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "hw/irq.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/pci/pci_bridge.h"
|
||||
#include "hw/pci/pci_bus.h"
|
||||
#include "hw/pci/pci_host.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/pci-host/sabre.h"
|
||||
@ -608,9 +607,9 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
|
||||
/* Only in-built Simba APBs can exist on the root bus, slot 0 on busA is
|
||||
reserved (leaving no slots free after on-board devices) however slots
|
||||
0-3 are free on busB */
|
||||
pci_bus->slot_reserved_mask = 0xfffffffc;
|
||||
pci_busA->slot_reserved_mask = 0xfffffff1;
|
||||
pci_busB->slot_reserved_mask = 0xfffffff0;
|
||||
pci_bus_set_slot_reserved_mask(pci_bus, 0xfffffffc);
|
||||
pci_bus_set_slot_reserved_mask(pci_busA, 0xfffffff1);
|
||||
pci_bus_set_slot_reserved_mask(pci_busB, 0xfffffff0);
|
||||
|
||||
ebus = pci_new_multifunction(PCI_DEVFN(1, 0), true, TYPE_EBUS);
|
||||
qdev_prop_set_uint64(DEVICE(ebus), "console-serial-base",
|
||||
|
@ -128,6 +128,14 @@ static void vu_i2c_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
|
||||
{
|
||||
VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
|
||||
|
||||
/*
|
||||
* We don't support interrupts, return early if index is set to
|
||||
* VIRTIO_CONFIG_IRQ_IDX.
|
||||
*/
|
||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
||||
return;
|
||||
}
|
||||
|
||||
vhost_virtqueue_mask(&i2c->vhost_dev, vdev, idx, mask);
|
||||
}
|
||||
|
||||
@ -135,6 +143,14 @@ static bool vu_i2c_guest_notifier_pending(VirtIODevice *vdev, int idx)
|
||||
{
|
||||
VHostUserI2C *i2c = VHOST_USER_I2C(vdev);
|
||||
|
||||
/*
|
||||
* We don't support interrupts, return early if index is set to
|
||||
* VIRTIO_CONFIG_IRQ_IDX.
|
||||
*/
|
||||
if (idx == VIRTIO_CONFIG_IRQ_IDX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return vhost_virtqueue_pending(&i2c->vhost_dev, idx);
|
||||
}
|
||||
|
||||
|
@ -1291,18 +1291,6 @@ void vhost_virtqueue_stop(struct vhost_dev *dev,
|
||||
0, virtio_queue_get_desc_size(vdev, idx));
|
||||
}
|
||||
|
||||
static void vhost_eventfd_add(MemoryListener *listener,
|
||||
MemoryRegionSection *section,
|
||||
bool match_data, uint64_t data, EventNotifier *e)
|
||||
{
|
||||
}
|
||||
|
||||
static void vhost_eventfd_del(MemoryListener *listener,
|
||||
MemoryRegionSection *section,
|
||||
bool match_data, uint64_t data, EventNotifier *e)
|
||||
{
|
||||
}
|
||||
|
||||
static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev,
|
||||
int n, uint32_t timeout)
|
||||
{
|
||||
@ -1457,8 +1445,6 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
||||
.log_sync = vhost_log_sync,
|
||||
.log_global_start = vhost_log_global_start,
|
||||
.log_global_stop = vhost_log_global_stop,
|
||||
.eventfd_add = vhost_eventfd_add,
|
||||
.eventfd_del = vhost_eventfd_del,
|
||||
.priority = 10
|
||||
};
|
||||
|
||||
|
@ -730,37 +730,14 @@ static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
|
||||
memcpy(config_data, &config, virtio_balloon_config_size(dev));
|
||||
}
|
||||
|
||||
static int build_dimm_list(Object *obj, void *opaque)
|
||||
{
|
||||
GSList **list = opaque;
|
||||
|
||||
if (object_dynamic_cast(obj, TYPE_PC_DIMM)) {
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
if (dev->realized) { /* only realized DIMMs matter */
|
||||
*list = g_slist_prepend(*list, dev);
|
||||
}
|
||||
}
|
||||
|
||||
object_child_foreach(obj, build_dimm_list, opaque);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ram_addr_t get_current_ram_size(void)
|
||||
{
|
||||
GSList *list = NULL, *item;
|
||||
ram_addr_t size = current_machine->ram_size;
|
||||
|
||||
build_dimm_list(qdev_get_machine(), &list);
|
||||
for (item = list; item; item = g_slist_next(item)) {
|
||||
Object *obj = OBJECT(item->data);
|
||||
if (!strcmp(object_get_typename(obj), TYPE_PC_DIMM)) {
|
||||
size += object_property_get_int(obj, PC_DIMM_SIZE_PROP,
|
||||
&error_abort);
|
||||
}
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
if (machine->device_memory) {
|
||||
return machine->ram_size + machine->device_memory->dimm_size;
|
||||
} else {
|
||||
return machine->ram_size;
|
||||
}
|
||||
g_slist_free(list);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static bool virtio_balloon_page_poison_support(void *opaque)
|
||||
|
@ -354,6 +354,7 @@ static void virtio_mmio_write(void *opaque, hwaddr offset, uint64_t value,
|
||||
if (proxy->legacy) {
|
||||
virtio_queue_update_rings(vdev, vdev->queue_sel);
|
||||
} else {
|
||||
virtio_init_region_cache(vdev, vdev->queue_sel);
|
||||
proxy->vqs[vdev->queue_sel].num = value;
|
||||
}
|
||||
break;
|
||||
|
@ -1554,6 +1554,7 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
|
||||
proxy->vqs[vdev->queue_sel].num = val;
|
||||
virtio_queue_set_num(vdev, vdev->queue_sel,
|
||||
proxy->vqs[vdev->queue_sel].num);
|
||||
virtio_init_region_cache(vdev, vdev->queue_sel);
|
||||
break;
|
||||
case VIRTIO_PCI_COMMON_Q_MSIX:
|
||||
vector = virtio_queue_vector(vdev, vdev->queue_sel);
|
||||
|
@ -226,7 +226,7 @@ static void virtio_virtqueue_reset_region_cache(struct VirtQueue *vq)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtio_init_region_cache(VirtIODevice *vdev, int n)
|
||||
void virtio_init_region_cache(VirtIODevice *vdev, int n)
|
||||
{
|
||||
VirtQueue *vq = &vdev->vq[n];
|
||||
VRingMemoryRegionCaches *old = vq->vring.caches;
|
||||
|
@ -57,7 +57,6 @@
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/pci/pci_bus.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/qdev-properties-system.h"
|
||||
#include "xen_pt.h"
|
||||
@ -951,7 +950,7 @@ void xen_igd_reserve_slot(PCIBus *pci_bus)
|
||||
}
|
||||
|
||||
XEN_PT_LOG(0, "Reserving PCI slot 2 for IGD\n");
|
||||
pci_bus->slot_reserved_mask |= XEN_PCI_IGD_SLOT_MASK;
|
||||
pci_bus_set_slot_reserved_mask(pci_bus, XEN_PCI_IGD_SLOT_MASK);
|
||||
}
|
||||
|
||||
static void xen_igd_clear_slot(DeviceState *qdev, Error **errp)
|
||||
@ -971,7 +970,7 @@ static void xen_igd_clear_slot(DeviceState *qdev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(pci_bus->slot_reserved_mask & XEN_PCI_IGD_SLOT_MASK)) {
|
||||
if (!(pci_bus_get_slot_reserved_mask(pci_bus) & XEN_PCI_IGD_SLOT_MASK)) {
|
||||
xpdc->pci_qdev_realize(qdev, errp);
|
||||
return;
|
||||
}
|
||||
@ -982,7 +981,7 @@ static void xen_igd_clear_slot(DeviceState *qdev, Error **errp)
|
||||
s->real_device.dev == XEN_PCI_IGD_DEV &&
|
||||
s->real_device.func == XEN_PCI_IGD_FN &&
|
||||
s->real_device.vendor_id == PCI_VENDOR_ID_INTEL) {
|
||||
pci_bus->slot_reserved_mask &= ~XEN_PCI_IGD_SLOT_MASK;
|
||||
pci_bus_clear_slot_reserved_mask(pci_bus, XEN_PCI_IGD_SLOT_MASK);
|
||||
XEN_PT_LOG(pci_dev, "Intel IGD found, using slot 2\n");
|
||||
}
|
||||
xpdc->pci_qdev_realize(qdev, errp);
|
||||
|
@ -292,10 +292,12 @@ struct MachineClass {
|
||||
* @base: address in guest physical address space where the memory
|
||||
* address space for memory devices starts
|
||||
* @mr: address space container for memory devices
|
||||
* @dimm_size: the sum of plugged DIMMs' sizes
|
||||
*/
|
||||
typedef struct DeviceMemoryState {
|
||||
hwaddr base;
|
||||
MemoryRegion mr;
|
||||
uint64_t dimm_size;
|
||||
} DeviceMemoryState;
|
||||
|
||||
/**
|
||||
|
@ -23,12 +23,12 @@
|
||||
|
||||
#define CXL_WINDOW_MAX 10
|
||||
|
||||
typedef struct PXBDev PXBDev;
|
||||
typedef struct PXBCXLDev PXBCXLDev;
|
||||
|
||||
typedef struct CXLFixedWindow {
|
||||
uint64_t size;
|
||||
char **targets;
|
||||
PXBDev *target_hbs[8];
|
||||
PXBCXLDev *target_hbs[8];
|
||||
uint8_t num_targets;
|
||||
uint8_t enc_int_ways;
|
||||
uint8_t enc_int_gran;
|
||||
|
@ -127,6 +127,9 @@ struct PCMachineClass {
|
||||
|
||||
/* create kvmclock device even when KVM PV features are not exposed */
|
||||
bool kvmclock_create_always;
|
||||
|
||||
/* resizable acpi blob compat */
|
||||
bool resizable_acpi_blob;
|
||||
};
|
||||
|
||||
#define TYPE_PC_MACHINE "generic-pc-machine"
|
||||
|
@ -287,6 +287,9 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq,
|
||||
void pci_bus_map_irqs(PCIBus *bus, pci_map_irq_fn map_irq);
|
||||
void pci_bus_irqs_cleanup(PCIBus *bus);
|
||||
int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
|
||||
uint32_t pci_bus_get_slot_reserved_mask(PCIBus *bus);
|
||||
void pci_bus_set_slot_reserved_mask(PCIBus *bus, uint32_t mask);
|
||||
void pci_bus_clear_slot_reserved_mask(PCIBus *bus, uint32_t mask);
|
||||
/* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */
|
||||
static inline int pci_swizzle(int slot, int pin)
|
||||
{
|
||||
|
@ -84,7 +84,7 @@ struct PCIBridge {
|
||||
#define PCI_BRIDGE_DEV_PROP_SHPC "shpc"
|
||||
typedef struct CXLHost CXLHost;
|
||||
|
||||
struct PXBDev {
|
||||
typedef struct PXBDev {
|
||||
/*< private >*/
|
||||
PCIDevice parent_obj;
|
||||
/*< public >*/
|
||||
@ -92,15 +92,27 @@ struct PXBDev {
|
||||
uint8_t bus_nr;
|
||||
uint16_t numa_node;
|
||||
bool bypass_iommu;
|
||||
bool hdm_for_passthrough;
|
||||
struct cxl_dev {
|
||||
CXLHost *cxl_host_bridge; /* Pointer to a CXLHost */
|
||||
} cxl;
|
||||
};
|
||||
} PXBDev;
|
||||
|
||||
#define TYPE_PXB_CXL_DEVICE "pxb-cxl"
|
||||
DECLARE_INSTANCE_CHECKER(PXBDev, PXB_CXL_DEV,
|
||||
TYPE_PXB_CXL_DEVICE)
|
||||
typedef struct PXBPCIEDev {
|
||||
/*< private >*/
|
||||
PXBDev parent_obj;
|
||||
} PXBPCIEDev;
|
||||
|
||||
#define TYPE_PXB_DEV "pxb"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(PXBDev, PXB_DEV)
|
||||
|
||||
typedef struct PXBCXLDev {
|
||||
/*< private >*/
|
||||
PXBPCIEDev parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
bool hdm_for_passthrough;
|
||||
CXLHost *cxl_host_bridge; /* Pointer to a CXLHost */
|
||||
} PXBCXLDev;
|
||||
|
||||
#define TYPE_PXB_CXL_DEV "pxb-cxl"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(PXBCXLDev, PXB_CXL_DEV)
|
||||
|
||||
int pci_bridge_ssvid_init(PCIDevice *dev, uint8_t offset,
|
||||
uint16_t svid, uint16_t ssid,
|
||||
|
@ -309,6 +309,7 @@ int virtio_get_num_queues(VirtIODevice *vdev);
|
||||
void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc,
|
||||
hwaddr avail, hwaddr used);
|
||||
void virtio_queue_update_rings(VirtIODevice *vdev, int n);
|
||||
void virtio_init_region_cache(VirtIODevice *vdev, int n);
|
||||
void virtio_queue_set_align(VirtIODevice *vdev, int n, int align);
|
||||
void virtio_queue_notify(VirtIODevice *vdev, int n);
|
||||
uint16_t virtio_queue_vector(VirtIODevice *vdev, int n);
|
||||
|
@ -315,7 +315,7 @@ option('debug_mutex', type: 'boolean', value: false,
|
||||
description: 'mutex debugging support')
|
||||
option('debug_stack_usage', type: 'boolean', value: false,
|
||||
description: 'measure coroutine stack usage')
|
||||
option('qom_cast_debug', type: 'boolean', value: false,
|
||||
option('qom_cast_debug', type: 'boolean', value: true,
|
||||
description: 'cast debugging support')
|
||||
option('gprof', type: 'boolean', value: false,
|
||||
description: 'QEMU profiling with gprof',
|
||||
|
@ -104,7 +104,8 @@ static const uint64_t vdpa_svq_device_features =
|
||||
/* VHOST_F_LOG_ALL is exposed by SVQ */
|
||||
BIT_ULL(VHOST_F_LOG_ALL) |
|
||||
BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
|
||||
BIT_ULL(VIRTIO_NET_F_STANDBY);
|
||||
BIT_ULL(VIRTIO_NET_F_STANDBY) |
|
||||
BIT_ULL(VIRTIO_NET_F_SPEED_DUPLEX);
|
||||
|
||||
#define VHOST_VDPA_NET_CVQ_ASID 1
|
||||
|
||||
|
@ -14,6 +14,7 @@ meson_options_help() {
|
||||
printf "%s\n" ' use idef-parser to automatically generate TCG'
|
||||
printf "%s\n" ' code for the Hexagon frontend'
|
||||
printf "%s\n" ' --disable-install-blobs install provided firmware blobs'
|
||||
printf "%s\n" ' --disable-qom-cast-debug cast debugging support'
|
||||
printf "%s\n" ' --docdir=VALUE Base directory for documentation installation'
|
||||
printf "%s\n" ' (can be empty) [share/doc]'
|
||||
printf "%s\n" ' --enable-block-drv-whitelist-in-tools'
|
||||
@ -35,7 +36,6 @@ meson_options_help() {
|
||||
printf "%s\n" ' --enable-module-upgrades try to load modules from alternate paths for'
|
||||
printf "%s\n" ' upgrades'
|
||||
printf "%s\n" ' --enable-profiler profiler support'
|
||||
printf "%s\n" ' --enable-qom-cast-debug cast debugging support'
|
||||
printf "%s\n" ' --enable-rng-none dummy RNG, avoid using /dev/(u)random and'
|
||||
printf "%s\n" ' getrandom()'
|
||||
printf "%s\n" ' --enable-strip Strip targets on install'
|
||||
|
@ -2455,6 +2455,16 @@ void vu_queue_notify_sync(VuDev *dev, VuVirtq *vq)
|
||||
_vu_queue_notify(dev, vq, true);
|
||||
}
|
||||
|
||||
void vu_config_change_msg(VuDev *dev)
|
||||
{
|
||||
VhostUserMsg vmsg = {
|
||||
.request = VHOST_USER_BACKEND_CONFIG_CHANGE_MSG,
|
||||
.flags = VHOST_USER_VERSION,
|
||||
};
|
||||
|
||||
vu_message_write(dev, dev->slave_fd, &vmsg);
|
||||
}
|
||||
|
||||
static inline void
|
||||
vring_used_flags_set_bit(VuVirtq *vq, int mask)
|
||||
{
|
||||
|
@ -585,6 +585,8 @@ bool vu_queue_empty(VuDev *dev, VuVirtq *vq);
|
||||
*/
|
||||
void vu_queue_notify(VuDev *dev, VuVirtq *vq);
|
||||
|
||||
void vu_config_change_msg(VuDev *dev);
|
||||
|
||||
/**
|
||||
* vu_queue_notify_sync:
|
||||
* @dev: a VuDev context
|
||||
|
Loading…
Reference in New Issue
Block a user