mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging
virtio,pc,pci: features, cleanups, fixes vhost-user support without ioeventfd word replacements in vhost user spec shpc improvements cleanups, fixes all over the place Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmQBO8QPHG1zdEByZWRo # YXQuY29tAAoJECgfDbjSjVRpMUMH/3/FVp4qaF4CDwCHn7xWFRJpOREIhX/iWfUu # lGkwxnB7Lfyqdg7i4CAfgMf2emWKZchEE2DamfCo5bIX0IgRU3DWcOdR9ePvJ29J # cKwIYpxZcB4RYSoWL5OUakQLCT3JOu4XWaXeVjyHABjQhf3lGpwN4KmIOBGOy/N6 # 0YHOQScW2eW62wIOwhAEuYQceMt6KU32Uw3tLnMbJliiBf3a/hPctVNM9TFY9pcd # UYHGfBx/zD45owf1lTVEQFDg0eqPZKWW29g5haiOd5oAyXHHolzu+bt3bU7lH46b # f7iP12LqDudyrgoF5YWv3NJ4HaGm5V3kPqNqLLF/mjF7alxG+N8= # =hN3h # -----END PGP SIGNATURE----- # gpg: Signature made Fri 03 Mar 2023 00:13:56 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: (53 commits) tests/data/acpi/virt: drop (most) duplicate files. hw/cxl/mailbox: Use new UUID network order define for cel_uuid qemu/uuid: Add UUID static initializer qemu/bswap: Add const_le64() tests: acpi: Update q35/DSDT.cxl for removed duplicate UID hw/i386/acpi: Drop duplicate _UID entry for CXL root bridge tests/acpi: Allow update of q35/DSDT.cxl hw/cxl: Add CXL_CAPACITY_MULTIPLIER definition hw/cxl: set cxl-type3 device type to PCI_CLASS_MEMORY_CXL hw/pci-bridge/cxl_downstream: Fix type naming mismatch hw/mem/cxl_type3: Improve error handling in realize() MAINTAINERS: Add Fan Ni as Compute eXpress Link QEMU reviewer intel-iommu: send UNMAP notifications for domain or global inv desc smmu: switch to use memory_region_unmap_iommu_notifier_range() memory: introduce memory_region_unmap_iommu_notifier_range() intel-iommu: fail DEVIOTLB_UNMAP without dt mode intel-iommu: fail MAP notifier without caching mode memory: Optimize replay of guest mapping chardev/char-socket: set s->listener = NULL in char_socket_finalize hw/pci: Trace IRQ routing on PCI topology ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -2637,6 +2637,7 @@ T: git https://gitlab.com/vsementsov/qemu.git block
|
||||
Compute Express Link
|
||||
M: Ben Widawsky <ben.widawsky@intel.com>
|
||||
M: Jonathan Cameron <jonathan.cameron@huawei.com>
|
||||
R: Fan Ni <fan.ni@samsung.com>
|
||||
S: Supported
|
||||
F: hw/cxl/
|
||||
F: hw/mem/cxl_type3.c
|
||||
|
||||
@@ -20,12 +20,6 @@
|
||||
#include "io/channel-command.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
|
||||
static bool
|
||||
ioeventfd_enabled(void)
|
||||
{
|
||||
return kvm_enabled() && kvm_eventfds_enabled();
|
||||
}
|
||||
|
||||
int
|
||||
vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
|
||||
unsigned nvqs, Error **errp)
|
||||
@@ -34,11 +28,6 @@ vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
|
||||
|
||||
assert(!b->vdev && vdev);
|
||||
|
||||
if (!ioeventfd_enabled()) {
|
||||
error_setg(errp, "vhost initialization failed: requires kvm");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!vhost_user_init(&b->vhost_user, &b->chr, errp)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1065,6 +1065,7 @@ static void char_socket_finalize(Object *obj)
|
||||
qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
|
||||
NULL, chr->gcontext);
|
||||
object_unref(OBJECT(s->listener));
|
||||
s->listener = NULL;
|
||||
}
|
||||
if (s->tls_creds) {
|
||||
object_unref(OBJECT(s->tls_creds));
|
||||
|
||||
+20
-20
@@ -315,7 +315,7 @@ in the ancillary data:
|
||||
* ``VHOST_USER_SET_VRING_KICK``
|
||||
* ``VHOST_USER_SET_VRING_CALL``
|
||||
* ``VHOST_USER_SET_VRING_ERR``
|
||||
* ``VHOST_USER_SET_SLAVE_REQ_FD``
|
||||
* ``VHOST_USER_SET_BACKEND_REQ_FD`` (previous name ``VHOST_USER_SET_SLAVE_REQ_FD``)
|
||||
* ``VHOST_USER_SET_INFLIGHT_FD`` (if ``VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD``)
|
||||
|
||||
If *front-end* is unable to send the full message or receives a wrong
|
||||
@@ -516,7 +516,7 @@ expected to reply with a zero payload, non-zero otherwise.
|
||||
|
||||
The back-end relies on the back-end communication channel (see :ref:`Back-end
|
||||
communication <backend_communication>` section below) to send IOTLB miss
|
||||
and access failure events, by sending ``VHOST_USER_SLAVE_IOTLB_MSG``
|
||||
and access failure events, by sending ``VHOST_USER_BACKEND_IOTLB_MSG``
|
||||
requests to the front-end with a ``struct vhost_iotlb_msg`` as
|
||||
payload. For miss events, the iotlb payload has to be filled with the
|
||||
miss message type (1), the I/O virtual address and the permissions
|
||||
@@ -540,15 +540,15 @@ Back-end communication
|
||||
----------------------
|
||||
|
||||
An optional communication channel is provided if the back-end declares
|
||||
``VHOST_USER_PROTOCOL_F_SLAVE_REQ`` protocol feature, to allow the
|
||||
``VHOST_USER_PROTOCOL_F_BACKEND_REQ`` protocol feature, to allow the
|
||||
back-end to make requests to the front-end.
|
||||
|
||||
The fd is provided via ``VHOST_USER_SET_SLAVE_REQ_FD`` ancillary data.
|
||||
The fd is provided via ``VHOST_USER_SET_BACKEND_REQ_FD`` ancillary data.
|
||||
|
||||
A back-end may then send ``VHOST_USER_SLAVE_*`` messages to the front-end
|
||||
A back-end may then send ``VHOST_USER_BACKEND_*`` messages to the front-end
|
||||
using this fd communication channel.
|
||||
|
||||
If ``VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD`` protocol feature is
|
||||
If ``VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD`` protocol feature is
|
||||
negotiated, back-end can send file descriptors (at most 8 descriptors in
|
||||
each message) to front-end via ancillary data using this fd communication
|
||||
channel.
|
||||
@@ -835,7 +835,7 @@ Note that due to the fact that too many messages on the sockets can
|
||||
cause the sending application(s) to block, it is not advised to use
|
||||
this feature unless absolutely necessary. It is also considered an
|
||||
error to negotiate this feature without also negotiating
|
||||
``VHOST_USER_PROTOCOL_F_SLAVE_REQ`` and ``VHOST_USER_PROTOCOL_F_REPLY_ACK``,
|
||||
``VHOST_USER_PROTOCOL_F_BACKEND_REQ`` and ``VHOST_USER_PROTOCOL_F_REPLY_ACK``,
|
||||
the former is necessary for getting a message channel from the back-end
|
||||
to the front-end, while the latter needs to be used with the in-band
|
||||
notification messages to block until they are processed, both to avoid
|
||||
@@ -855,12 +855,12 @@ Protocol features
|
||||
#define VHOST_USER_PROTOCOL_F_RARP 2
|
||||
#define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
|
||||
#define VHOST_USER_PROTOCOL_F_MTU 4
|
||||
#define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5
|
||||
#define VHOST_USER_PROTOCOL_F_BACKEND_REQ 5
|
||||
#define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6
|
||||
#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
|
||||
#define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
|
||||
#define VHOST_USER_PROTOCOL_F_CONFIG 9
|
||||
#define VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD 10
|
||||
#define VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD 10
|
||||
#define VHOST_USER_PROTOCOL_F_HOST_NOTIFIER 11
|
||||
#define VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD 12
|
||||
#define VHOST_USER_PROTOCOL_F_RESET_DEVICE 13
|
||||
@@ -1059,8 +1059,8 @@ Front-end message types
|
||||
in the ancillary data. This signals that polling will be used
|
||||
instead of waiting for the call. Note that if the protocol features
|
||||
``VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS`` and
|
||||
``VHOST_USER_PROTOCOL_F_SLAVE_REQ`` have been negotiated this message
|
||||
isn't necessary as the ``VHOST_USER_SLAVE_VRING_CALL`` message can be
|
||||
``VHOST_USER_PROTOCOL_F_BACKEND_REQ`` have been negotiated this message
|
||||
isn't necessary as the ``VHOST_USER_BACKEND_VRING_CALL`` message can be
|
||||
used, it may however still be used to set an event file descriptor
|
||||
or to enable polling.
|
||||
|
||||
@@ -1077,8 +1077,8 @@ Front-end message types
|
||||
invalid FD flag. This flag is set when there is no file descriptor
|
||||
in the ancillary data. Note that if the protocol features
|
||||
``VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS`` and
|
||||
``VHOST_USER_PROTOCOL_F_SLAVE_REQ`` have been negotiated this message
|
||||
isn't necessary as the ``VHOST_USER_SLAVE_VRING_ERR`` message can be
|
||||
``VHOST_USER_PROTOCOL_F_BACKEND_REQ`` have been negotiated this message
|
||||
isn't necessary as the ``VHOST_USER_BACKEND_VRING_ERR`` message can be
|
||||
used, it may however still be used to set an event file descriptor
|
||||
(which will be preferred over the message).
|
||||
|
||||
@@ -1139,7 +1139,7 @@ Front-end message types
|
||||
respond with zero in case the specified MTU is valid, or non-zero
|
||||
otherwise.
|
||||
|
||||
``VHOST_USER_SET_SLAVE_REQ_FD``
|
||||
``VHOST_USER_SET_BACKEND_REQ_FD`` (previous name ``VHOST_USER_SET_SLAVE_REQ_FD``)
|
||||
:id: 21
|
||||
:equivalent ioctl: N/A
|
||||
:request payload: N/A
|
||||
@@ -1150,7 +1150,7 @@ Front-end message types
|
||||
|
||||
This request should be sent only when
|
||||
``VHOST_USER_F_PROTOCOL_FEATURES`` has been negotiated, and protocol
|
||||
feature bit ``VHOST_USER_PROTOCOL_F_SLAVE_REQ`` bit is present in
|
||||
feature bit ``VHOST_USER_PROTOCOL_F_BACKEND_REQ`` bit is present in
|
||||
``VHOST_USER_GET_PROTOCOL_FEATURES``. If
|
||||
``VHOST_USER_PROTOCOL_F_REPLY_ACK`` is negotiated, the back-end must
|
||||
respond with zero for success, non-zero otherwise.
|
||||
@@ -1429,7 +1429,7 @@ Back-end message types
|
||||
For this type of message, the request is sent by the back-end and the reply
|
||||
is sent by the front-end.
|
||||
|
||||
``VHOST_USER_SLAVE_IOTLB_MSG``
|
||||
``VHOST_USER_BACKEND_IOTLB_MSG`` (previous name ``VHOST_USER_SLAVE_IOTLB_MSG``)
|
||||
:id: 1
|
||||
:equivalent ioctl: N/A (equivalent to ``VHOST_IOTLB_MSG`` message type)
|
||||
:request payload: ``struct vhost_iotlb_msg``
|
||||
@@ -1444,7 +1444,7 @@ is sent by the front-end.
|
||||
``VIRTIO_F_IOMMU_PLATFORM`` feature has been successfully
|
||||
negotiated.
|
||||
|
||||
``VHOST_USER_SLAVE_CONFIG_CHANGE_MSG``
|
||||
``VHOST_USER_BACKEND_CONFIG_CHANGE_MSG`` (previous name ``VHOST_USER_SLAVE_CONFIG_CHANGE_MSG``)
|
||||
:id: 2
|
||||
:equivalent ioctl: N/A
|
||||
:request payload: N/A
|
||||
@@ -1459,7 +1459,7 @@ is sent by the front-end.
|
||||
``VHOST_USER_NEED_REPLY`` flag, the front-end must respond with zero when
|
||||
operation is successfully completed, or non-zero otherwise.
|
||||
|
||||
``VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG``
|
||||
``VHOST_USER_BACKEND_VRING_HOST_NOTIFIER_MSG`` (previous name ``VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG``)
|
||||
:id: 3
|
||||
:equivalent ioctl: N/A
|
||||
:request payload: vring area description
|
||||
@@ -1482,7 +1482,7 @@ is sent by the front-end.
|
||||
``VHOST_USER_PROTOCOL_F_HOST_NOTIFIER`` protocol feature has been
|
||||
successfully negotiated.
|
||||
|
||||
``VHOST_USER_SLAVE_VRING_CALL``
|
||||
``VHOST_USER_BACKEND_VRING_CALL`` (previous name ``VHOST_USER_SLAVE_VRING_CALL``)
|
||||
:id: 4
|
||||
:equivalent ioctl: N/A
|
||||
:request payload: vring state description
|
||||
@@ -1496,7 +1496,7 @@ is sent by the front-end.
|
||||
|
||||
The state.num field is currently reserved and must be set to 0.
|
||||
|
||||
``VHOST_USER_SLAVE_VRING_ERR``
|
||||
``VHOST_USER_BACKEND_VRING_ERR`` (previous name ``VHOST_USER_SLAVE_VRING_ERR``)
|
||||
:id: 5
|
||||
:equivalent ioctl: N/A
|
||||
:request payload: vring state description
|
||||
|
||||
+1
-15
@@ -467,20 +467,6 @@ IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Unmap the whole notifier's range */
|
||||
static void smmu_unmap_notifier_range(IOMMUNotifier *n)
|
||||
{
|
||||
IOMMUTLBEvent event;
|
||||
|
||||
event.type = IOMMU_NOTIFIER_UNMAP;
|
||||
event.entry.target_as = &address_space_memory;
|
||||
event.entry.iova = n->start;
|
||||
event.entry.perm = IOMMU_NONE;
|
||||
event.entry.addr_mask = n->end - n->start;
|
||||
|
||||
memory_region_notify_iommu_one(n, &event);
|
||||
}
|
||||
|
||||
/* Unmap all notifiers attached to @mr */
|
||||
static void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
|
||||
{
|
||||
@@ -488,7 +474,7 @@ static void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
|
||||
|
||||
trace_smmu_inv_notifiers_mr(mr->parent_obj.name);
|
||||
IOMMU_NOTIFIER_FOREACH(n, mr) {
|
||||
smmu_unmap_notifier_range(n);
|
||||
memory_region_unmap_iommu_notifier_range(n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
|
||||
GlobalProperty hw_compat_7_1[] = {
|
||||
{ "virtio-device", "queue_reset", "false" },
|
||||
{ "virtio-rng-pci", "vectors", "0" },
|
||||
{ "virtio-rng-pci-transitional", "vectors", "0" },
|
||||
{ "virtio-rng-pci-non-transitional", "vectors", "0" },
|
||||
};
|
||||
const size_t hw_compat_7_1_len = G_N_ELEMENTS(hw_compat_7_1);
|
||||
|
||||
|
||||
@@ -267,5 +267,5 @@ void cxl_device_register_init_common(CXLDeviceState *cxl_dstate)
|
||||
cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000);
|
||||
memdev_reg_init_common(cxl_dstate);
|
||||
|
||||
assert(cxl_initialize_mailbox(cxl_dstate) == 0);
|
||||
cxl_initialize_mailbox(cxl_dstate);
|
||||
}
|
||||
|
||||
+15
-13
@@ -12,8 +12,11 @@
|
||||
#include "hw/pci/pci.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/units.h"
|
||||
#include "qemu/uuid.h"
|
||||
|
||||
#define CXL_CAPACITY_MULTIPLIER (256 * MiB)
|
||||
|
||||
/*
|
||||
* How to add a new command, example. The command set FOO, with cmd BAR.
|
||||
* 1. Add the command set and cmd to the enum.
|
||||
@@ -138,7 +141,7 @@ static ret_code cmd_firmware_update_get_info(struct cxl_cmd *cmd,
|
||||
} QEMU_PACKED *fw_info;
|
||||
QEMU_BUILD_BUG_ON(sizeof(*fw_info) != 0x50);
|
||||
|
||||
if (cxl_dstate->pmem_size < (256 << 20)) {
|
||||
if (cxl_dstate->pmem_size < CXL_CAPACITY_MULTIPLIER) {
|
||||
return CXL_MBOX_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@@ -190,7 +193,11 @@ static ret_code cmd_timestamp_set(struct cxl_cmd *cmd,
|
||||
return CXL_MBOX_SUCCESS;
|
||||
}
|
||||
|
||||
static QemuUUID cel_uuid;
|
||||
/* CXL 3.0 8.2.9.5.2.1 Command Effects Log (CEL) */
|
||||
static const QemuUUID cel_uuid = {
|
||||
.data = UUID(0x0da9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79,
|
||||
0x96, 0xb1, 0x62, 0x3b, 0x3f, 0x17)
|
||||
};
|
||||
|
||||
/* 8.2.9.4.1 */
|
||||
static ret_code cmd_logs_get_supported(struct cxl_cmd *cmd,
|
||||
@@ -283,7 +290,7 @@ static ret_code cmd_identify_memory_device(struct cxl_cmd *cmd,
|
||||
CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
|
||||
uint64_t size = cxl_dstate->pmem_size;
|
||||
|
||||
if (!QEMU_IS_ALIGNED(size, 256 << 20)) {
|
||||
if (!QEMU_IS_ALIGNED(size, CXL_CAPACITY_MULTIPLIER)) {
|
||||
return CXL_MBOX_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@@ -293,8 +300,8 @@ static ret_code cmd_identify_memory_device(struct cxl_cmd *cmd,
|
||||
/* PMEM only */
|
||||
snprintf(id->fw_revision, 0x10, "BWFW VERSION %02d", 0);
|
||||
|
||||
id->total_capacity = size / (256 << 20);
|
||||
id->persistent_capacity = size / (256 << 20);
|
||||
id->total_capacity = size / CXL_CAPACITY_MULTIPLIER;
|
||||
id->persistent_capacity = size / CXL_CAPACITY_MULTIPLIER;
|
||||
id->lsa_size = cvc->get_lsa_size(ct3d);
|
||||
|
||||
*len = sizeof(*id);
|
||||
@@ -314,14 +321,14 @@ static ret_code cmd_ccls_get_partition_info(struct cxl_cmd *cmd,
|
||||
QEMU_BUILD_BUG_ON(sizeof(*part_info) != 0x20);
|
||||
uint64_t size = cxl_dstate->pmem_size;
|
||||
|
||||
if (!QEMU_IS_ALIGNED(size, 256 << 20)) {
|
||||
if (!QEMU_IS_ALIGNED(size, CXL_CAPACITY_MULTIPLIER)) {
|
||||
return CXL_MBOX_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
/* PMEM only */
|
||||
part_info->active_vmem = 0;
|
||||
part_info->next_vmem = 0;
|
||||
part_info->active_pmem = size / (256 << 20);
|
||||
part_info->active_pmem = size / CXL_CAPACITY_MULTIPLIER;
|
||||
part_info->next_pmem = 0;
|
||||
|
||||
*len = sizeof(*part_info);
|
||||
@@ -455,11 +462,8 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
|
||||
DOORBELL, 0);
|
||||
}
|
||||
|
||||
int cxl_initialize_mailbox(CXLDeviceState *cxl_dstate)
|
||||
void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate)
|
||||
{
|
||||
/* CXL 2.0: Table 169 Get Supported Logs Log Entry */
|
||||
const char *cel_uuidstr = "0da9c0b5-bf41-4b78-8f79-96b1623b3f17";
|
||||
|
||||
for (int set = 0; set < 256; set++) {
|
||||
for (int cmd = 0; cmd < 256; cmd++) {
|
||||
if (cxl_cmd_set[set][cmd].handler) {
|
||||
@@ -473,6 +477,4 @@ int cxl_initialize_mailbox(CXLDeviceState *cxl_dstate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qemu_uuid_parse(cel_uuidstr, &cel_uuid);
|
||||
}
|
||||
|
||||
@@ -1514,7 +1514,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
|
||||
aml_append(pkg, aml_eisaid("PNP0A03"));
|
||||
aml_append(dev, aml_name_decl("_CID", pkg));
|
||||
aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
|
||||
aml_append(dev, aml_name_decl("_UID", aml_int(bus_num)));
|
||||
build_cxl_osc_method(dev);
|
||||
} else if (pci_bus_is_express(bus)) {
|
||||
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
|
||||
|
||||
+25
-6
@@ -1530,13 +1530,17 @@ static int vtd_sync_shadow_page_table_range(VTDAddressSpace *vtd_as,
|
||||
return vtd_page_walk(s, ce, addr, addr + size, &info, vtd_as->pasid);
|
||||
}
|
||||
|
||||
static int vtd_sync_shadow_page_table(VTDAddressSpace *vtd_as)
|
||||
static int vtd_address_space_sync(VTDAddressSpace *vtd_as)
|
||||
{
|
||||
int ret;
|
||||
VTDContextEntry ce;
|
||||
IOMMUNotifier *n;
|
||||
|
||||
if (!(vtd_as->iommu.iommu_notify_flags & IOMMU_NOTIFIER_IOTLB_EVENTS)) {
|
||||
/* If no MAP notifier registered, we simply invalidate all the cache */
|
||||
if (!vtd_as_has_map_notifier(vtd_as)) {
|
||||
IOMMU_NOTIFIER_FOREACH(n, &vtd_as->iommu) {
|
||||
memory_region_unmap_iommu_notifier_range(n);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2000,7 +2004,7 @@ static void vtd_iommu_replay_all(IntelIOMMUState *s)
|
||||
VTDAddressSpace *vtd_as;
|
||||
|
||||
QLIST_FOREACH(vtd_as, &s->vtd_as_with_notifiers, next) {
|
||||
vtd_sync_shadow_page_table(vtd_as);
|
||||
vtd_address_space_sync(vtd_as);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2082,7 +2086,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
|
||||
* framework will skip MAP notifications if that
|
||||
* happened.
|
||||
*/
|
||||
vtd_sync_shadow_page_table(vtd_as);
|
||||
vtd_address_space_sync(vtd_as);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2140,7 +2144,7 @@ static void vtd_iotlb_domain_invalidate(IntelIOMMUState *s, uint16_t domain_id)
|
||||
if (!vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
|
||||
vtd_as->devfn, &ce) &&
|
||||
domain_id == vtd_get_domain_id(s, &ce, vtd_as->pasid)) {
|
||||
vtd_sync_shadow_page_table(vtd_as);
|
||||
vtd_address_space_sync(vtd_as);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3179,6 +3183,7 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
|
||||
{
|
||||
VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
|
||||
IntelIOMMUState *s = vtd_as->iommu_state;
|
||||
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
|
||||
|
||||
/* TODO: add support for VFIO and vhost users */
|
||||
if (s->snoop_control) {
|
||||
@@ -3186,6 +3191,20 @@ static int vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
|
||||
"Snoop Control with vhost or VFIO is not supported");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
if (!s->caching_mode && (new & IOMMU_NOTIFIER_MAP)) {
|
||||
error_setg_errno(errp, ENOTSUP,
|
||||
"device %02x.%02x.%x requires caching mode",
|
||||
pci_bus_num(vtd_as->bus), PCI_SLOT(vtd_as->devfn),
|
||||
PCI_FUNC(vtd_as->devfn));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
if (!x86_iommu->dt_supported && (new & IOMMU_NOTIFIER_DEVIOTLB_UNMAP)) {
|
||||
error_setg_errno(errp, ENOTSUP,
|
||||
"device %02x.%02x.%x requires device IOTLB mode",
|
||||
pci_bus_num(vtd_as->bus), PCI_SLOT(vtd_as->devfn),
|
||||
PCI_FUNC(vtd_as->devfn));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Update per-address-space notifier flags */
|
||||
vtd_as->notifier_flags = new;
|
||||
@@ -3831,7 +3850,7 @@ static void vtd_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n)
|
||||
.domain_id = vtd_get_domain_id(s, &ce, vtd_as->pasid),
|
||||
};
|
||||
|
||||
vtd_page_walk(s, &ce, 0, ~0ULL, &info, vtd_as->pasid);
|
||||
vtd_page_walk(s, &ce, n->start, n->end, &info, vtd_as->pasid);
|
||||
}
|
||||
} else {
|
||||
trace_vtd_replay_ce_invalid(bus_n, PCI_SLOT(vtd_as->devfn),
|
||||
|
||||
+6
-11
@@ -328,7 +328,7 @@ static void microvm_memory_init(MicrovmMachineState *mms)
|
||||
rom_set_fw(fw_cfg);
|
||||
|
||||
if (machine->kernel_filename != NULL) {
|
||||
x86_load_linux(x86ms, fw_cfg, 0, true, false);
|
||||
x86_load_linux(x86ms, fw_cfg, 0, true);
|
||||
}
|
||||
|
||||
if (mms->option_roms) {
|
||||
@@ -376,8 +376,7 @@ static void microvm_fix_kernel_cmdline(MachineState *machine)
|
||||
MicrovmMachineState *mms = MICROVM_MACHINE(machine);
|
||||
BusState *bus;
|
||||
BusChild *kid;
|
||||
char *cmdline, *existing_cmdline;
|
||||
size_t len;
|
||||
char *cmdline;
|
||||
|
||||
/*
|
||||
* Find MMIO transports with attached devices, and add them to the kernel
|
||||
@@ -386,8 +385,7 @@ static void microvm_fix_kernel_cmdline(MachineState *machine)
|
||||
* Yes, this is a hack, but one that heavily improves the UX without
|
||||
* introducing any significant issues.
|
||||
*/
|
||||
existing_cmdline = fw_cfg_read_bytes_ptr(x86ms->fw_cfg, FW_CFG_CMDLINE_DATA);
|
||||
cmdline = g_strdup(existing_cmdline);
|
||||
cmdline = g_strdup(machine->kernel_cmdline);
|
||||
bus = sysbus_get_default();
|
||||
QTAILQ_FOREACH(kid, &bus->children, sibling) {
|
||||
DeviceState *dev = kid->child;
|
||||
@@ -411,12 +409,9 @@ static void microvm_fix_kernel_cmdline(MachineState *machine)
|
||||
}
|
||||
}
|
||||
|
||||
len = strlen(cmdline);
|
||||
if (len > VIRTIO_CMDLINE_TOTAL_MAX_LEN + strlen(existing_cmdline)) {
|
||||
fprintf(stderr, "qemu: virtio mmio cmdline too large, skipping\n");
|
||||
} else {
|
||||
memcpy(existing_cmdline, cmdline, len + 1);
|
||||
}
|
||||
fw_cfg_modify_i32(x86ms->fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(cmdline) + 1);
|
||||
fw_cfg_modify_string(x86ms->fw_cfg, FW_CFG_CMDLINE_DATA, cmdline);
|
||||
|
||||
g_free(cmdline);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -810,7 +810,7 @@ void xen_load_linux(PCMachineState *pcms)
|
||||
rom_set_fw(fw_cfg);
|
||||
|
||||
x86_load_linux(x86ms, fw_cfg, pcmc->acpi_data_size,
|
||||
pcmc->pvh_enabled, pcmc->legacy_no_rng_seed);
|
||||
pcmc->pvh_enabled);
|
||||
for (i = 0; i < nb_option_roms; i++) {
|
||||
assert(!strcmp(option_rom[i].name, "linuxboot.bin") ||
|
||||
!strcmp(option_rom[i].name, "linuxboot_dma.bin") ||
|
||||
@@ -1130,7 +1130,7 @@ void pc_memory_init(PCMachineState *pcms,
|
||||
|
||||
if (linux_boot) {
|
||||
x86_load_linux(x86ms, fw_cfg, pcmc->acpi_data_size,
|
||||
pcmc->pvh_enabled, pcmc->legacy_no_rng_seed);
|
||||
pcmc->pvh_enabled);
|
||||
}
|
||||
|
||||
for (i = 0; i < nb_option_roms; i++) {
|
||||
|
||||
@@ -477,9 +477,7 @@ DEFINE_I440FX_MACHINE(v7_2, "pc-i440fx-7.2", NULL,
|
||||
|
||||
static void pc_i440fx_7_1_machine_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
pc_i440fx_7_2_machine_options(m);
|
||||
pcmc->legacy_no_rng_seed = true;
|
||||
compat_props_add(m->compat_props, hw_compat_7_1, hw_compat_7_1_len);
|
||||
compat_props_add(m->compat_props, pc_compat_7_1, pc_compat_7_1_len);
|
||||
}
|
||||
|
||||
@@ -395,9 +395,7 @@ DEFINE_Q35_MACHINE(v7_2, "pc-q35-7.2", NULL,
|
||||
|
||||
static void pc_q35_7_1_machine_options(MachineClass *m)
|
||||
{
|
||||
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
|
||||
pc_q35_7_2_machine_options(m);
|
||||
pcmc->legacy_no_rng_seed = true;
|
||||
compat_props_add(m->compat_props, hw_compat_7_1, hw_compat_7_1_len);
|
||||
compat_props_add(m->compat_props, pc_compat_7_1, pc_compat_7_1_len);
|
||||
}
|
||||
|
||||
+32
-90
@@ -26,7 +26,6 @@
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/units.h"
|
||||
#include "qemu/datadir.h"
|
||||
#include "qemu/guest-random.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-visit-common.h"
|
||||
#include "qapi/clone-visitor.h"
|
||||
@@ -36,7 +35,6 @@
|
||||
#include "sysemu/whpx.h"
|
||||
#include "sysemu/numa.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "sysemu/reset.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/cpu-timers.h"
|
||||
#include "sysemu/xen.h"
|
||||
@@ -49,7 +47,6 @@
|
||||
#include "hw/intc/i8259.h"
|
||||
#include "hw/rtc/mc146818rtc.h"
|
||||
#include "target/i386/sev.h"
|
||||
#include "hw/i386/microvm.h"
|
||||
|
||||
#include "hw/acpi/cpu_hotplug.h"
|
||||
#include "hw/irq.h"
|
||||
@@ -675,12 +672,12 @@ DeviceState *ioapic_init_secondary(GSIState *gsi_state)
|
||||
return dev;
|
||||
}
|
||||
|
||||
typedef struct SetupData {
|
||||
struct setup_data {
|
||||
uint64_t next;
|
||||
uint32_t type;
|
||||
uint32_t len;
|
||||
uint8_t data[];
|
||||
} __attribute__((packed)) SetupData;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/*
|
||||
@@ -787,35 +784,10 @@ static bool load_elfboot(const char *kernel_filename,
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef struct SetupDataFixup {
|
||||
void *pos;
|
||||
hwaddr orig_val, new_val;
|
||||
uint32_t addr;
|
||||
} SetupDataFixup;
|
||||
|
||||
static void fixup_setup_data(void *opaque)
|
||||
{
|
||||
SetupDataFixup *fixup = opaque;
|
||||
stq_p(fixup->pos, fixup->new_val);
|
||||
}
|
||||
|
||||
static void reset_setup_data(void *opaque)
|
||||
{
|
||||
SetupDataFixup *fixup = opaque;
|
||||
stq_p(fixup->pos, fixup->orig_val);
|
||||
}
|
||||
|
||||
static void reset_rng_seed(void *opaque)
|
||||
{
|
||||
SetupData *setup_data = opaque;
|
||||
qemu_guest_getrandom_nofail(setup_data->data, le32_to_cpu(setup_data->len));
|
||||
}
|
||||
|
||||
void x86_load_linux(X86MachineState *x86ms,
|
||||
FWCfgState *fw_cfg,
|
||||
int acpi_data_size,
|
||||
bool pvh_enabled,
|
||||
bool legacy_no_rng_seed)
|
||||
bool pvh_enabled)
|
||||
{
|
||||
bool linuxboot_dma_enabled = X86_MACHINE_GET_CLASS(x86ms)->fwcfg_dma_enabled;
|
||||
uint16_t protocol;
|
||||
@@ -823,26 +795,19 @@ void x86_load_linux(X86MachineState *x86ms,
|
||||
int dtb_size, setup_data_offset;
|
||||
uint32_t initrd_max;
|
||||
uint8_t header[8192], *setup, *kernel;
|
||||
hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0, first_setup_data = 0;
|
||||
hwaddr real_addr, prot_addr, cmdline_addr, initrd_addr = 0;
|
||||
FILE *f;
|
||||
char *vmode;
|
||||
MachineState *machine = MACHINE(x86ms);
|
||||
SetupData *setup_data;
|
||||
struct setup_data *setup_data;
|
||||
const char *kernel_filename = machine->kernel_filename;
|
||||
const char *initrd_filename = machine->initrd_filename;
|
||||
const char *dtb_filename = machine->dtb;
|
||||
char *kernel_cmdline;
|
||||
const char *kernel_cmdline = machine->kernel_cmdline;
|
||||
SevKernelLoaderContext sev_load_ctx = {};
|
||||
enum { RNG_SEED_LENGTH = 32 };
|
||||
|
||||
/*
|
||||
* Add the NUL terminator, some padding for the microvm cmdline fiddling
|
||||
* hack, and then align to 16 bytes as a paranoia measure
|
||||
*/
|
||||
cmdline_size = (strlen(machine->kernel_cmdline) + 1 +
|
||||
VIRTIO_CMDLINE_TOTAL_MAX_LEN + 16) & ~15;
|
||||
/* Make a copy, since we might append arbitrary bytes to it later. */
|
||||
kernel_cmdline = g_strndup(machine->kernel_cmdline, cmdline_size);
|
||||
/* Align to 16 bytes as a paranoia measure */
|
||||
cmdline_size = (strlen(kernel_cmdline) + 16) & ~15;
|
||||
|
||||
/* load the kernel header */
|
||||
f = fopen(kernel_filename, "rb");
|
||||
@@ -983,6 +948,12 @@ void x86_load_linux(X86MachineState *x86ms,
|
||||
initrd_max = x86ms->below_4g_mem_size - acpi_data_size - 1;
|
||||
}
|
||||
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1);
|
||||
fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
|
||||
sev_load_ctx.cmdline_data = (char *)kernel_cmdline;
|
||||
sev_load_ctx.cmdline_size = strlen(kernel_cmdline) + 1;
|
||||
|
||||
if (protocol >= 0x202) {
|
||||
stl_p(header + 0x228, cmdline_addr);
|
||||
} else {
|
||||
@@ -1109,45 +1080,20 @@ void x86_load_linux(X86MachineState *x86ms,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
setup_data_offset = cmdline_size;
|
||||
cmdline_size += sizeof(SetupData) + dtb_size;
|
||||
kernel_cmdline = g_realloc(kernel_cmdline, cmdline_size);
|
||||
setup_data = (void *)kernel_cmdline + setup_data_offset;
|
||||
setup_data->next = cpu_to_le64(first_setup_data);
|
||||
first_setup_data = cmdline_addr + setup_data_offset;
|
||||
setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
|
||||
kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size;
|
||||
kernel = g_realloc(kernel, kernel_size);
|
||||
|
||||
stq_p(header + 0x250, prot_addr + setup_data_offset);
|
||||
|
||||
setup_data = (struct setup_data *)(kernel + setup_data_offset);
|
||||
setup_data->next = 0;
|
||||
setup_data->type = cpu_to_le32(SETUP_DTB);
|
||||
setup_data->len = cpu_to_le32(dtb_size);
|
||||
|
||||
load_image_size(dtb_filename, setup_data->data, dtb_size);
|
||||
}
|
||||
|
||||
if (!legacy_no_rng_seed && protocol >= 0x209) {
|
||||
setup_data_offset = cmdline_size;
|
||||
cmdline_size += sizeof(SetupData) + RNG_SEED_LENGTH;
|
||||
kernel_cmdline = g_realloc(kernel_cmdline, cmdline_size);
|
||||
setup_data = (void *)kernel_cmdline + setup_data_offset;
|
||||
setup_data->next = cpu_to_le64(first_setup_data);
|
||||
first_setup_data = cmdline_addr + setup_data_offset;
|
||||
setup_data->type = cpu_to_le32(SETUP_RNG_SEED);
|
||||
setup_data->len = cpu_to_le32(RNG_SEED_LENGTH);
|
||||
qemu_guest_getrandom_nofail(setup_data->data, RNG_SEED_LENGTH);
|
||||
qemu_register_reset_nosnapshotload(reset_rng_seed, setup_data);
|
||||
fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_KERNEL_DATA, reset_rng_seed, NULL,
|
||||
setup_data, kernel, kernel_size, true);
|
||||
} else {
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
|
||||
}
|
||||
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, cmdline_size);
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline, cmdline_size);
|
||||
sev_load_ctx.cmdline_data = (char *)kernel_cmdline;
|
||||
sev_load_ctx.cmdline_size = cmdline_size;
|
||||
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
|
||||
sev_load_ctx.kernel_data = (char *)kernel;
|
||||
sev_load_ctx.kernel_size = kernel_size;
|
||||
|
||||
/*
|
||||
* If we're starting an encrypted VM, it will be OVMF based, which uses the
|
||||
* efi stub for booting and doesn't require any values to be placed in the
|
||||
@@ -1155,21 +1101,17 @@ void x86_load_linux(X86MachineState *x86ms,
|
||||
* kernel on the other side of the fw_cfg interface matches the hash of the
|
||||
* file the user passed in.
|
||||
*/
|
||||
if (!sev_enabled() && first_setup_data) {
|
||||
SetupDataFixup *fixup = g_malloc(sizeof(*fixup));
|
||||
|
||||
if (!sev_enabled()) {
|
||||
memcpy(setup, header, MIN(sizeof(header), setup_size));
|
||||
/* Offset 0x250 is a pointer to the first setup_data link. */
|
||||
fixup->pos = setup + 0x250;
|
||||
fixup->orig_val = ldq_p(fixup->pos);
|
||||
fixup->new_val = first_setup_data;
|
||||
fixup->addr = cpu_to_le32(real_addr);
|
||||
fw_cfg_add_bytes_callback(fw_cfg, FW_CFG_SETUP_ADDR, fixup_setup_data, NULL,
|
||||
fixup, &fixup->addr, sizeof(fixup->addr), true);
|
||||
qemu_register_reset(reset_setup_data, fixup);
|
||||
} else {
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
|
||||
}
|
||||
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size);
|
||||
sev_load_ctx.kernel_data = (char *)kernel;
|
||||
sev_load_ctx.kernel_size = kernel_size;
|
||||
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
|
||||
sev_load_ctx.setup_data = (char *)setup;
|
||||
|
||||
+11
-4
@@ -401,14 +401,13 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
|
||||
MemoryRegion *mr = ®s->component_registers;
|
||||
uint8_t *pci_conf = pci_dev->config;
|
||||
unsigned short msix_num = 1;
|
||||
int i;
|
||||
int i, rc;
|
||||
|
||||
if (!cxl_setup_memory(ct3d, errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
pci_config_set_prog_interface(pci_conf, 0x10);
|
||||
pci_config_set_class(pci_conf, PCI_CLASS_MEMORY_CXL);
|
||||
|
||||
pcie_endpoint_cap_init(pci_dev, 0x80);
|
||||
if (ct3d->sn != UI64_NULL) {
|
||||
@@ -438,7 +437,10 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
|
||||
&ct3d->cxl_dstate.device_registers);
|
||||
|
||||
/* MSI(-X) Initailization */
|
||||
msix_init_exclusive_bar(pci_dev, msix_num, 4, NULL);
|
||||
rc = msix_init_exclusive_bar(pci_dev, msix_num, 4, NULL);
|
||||
if (rc) {
|
||||
goto err_address_space_free;
|
||||
}
|
||||
for (i = 0; i < msix_num; i++) {
|
||||
msix_vector_use(pci_dev, i);
|
||||
}
|
||||
@@ -450,6 +452,11 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
|
||||
cxl_cstate->cdat.free_cdat_table = ct3_free_cdat_table;
|
||||
cxl_cstate->cdat.private = ct3d;
|
||||
cxl_doe_cdat_init(cxl_cstate, errp);
|
||||
return;
|
||||
|
||||
err_address_space_free:
|
||||
address_space_destroy(&ct3d->hostmem_as);
|
||||
return;
|
||||
}
|
||||
|
||||
static void ct3_exit(PCIDevice *pci_dev)
|
||||
@@ -619,7 +626,7 @@ static void ct3_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
pc->realize = ct3_realize;
|
||||
pc->exit = ct3_exit;
|
||||
pc->class_id = PCI_CLASS_STORAGE_EXPRESS;
|
||||
pc->class_id = PCI_CLASS_MEMORY_CXL;
|
||||
pc->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
pc->device_id = 0xd93; /* LVF for now */
|
||||
pc->revision = 1;
|
||||
|
||||
@@ -820,6 +820,21 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
|
||||
features |= (1ULL << VIRTIO_NET_F_MTU);
|
||||
}
|
||||
|
||||
/*
|
||||
* Since GUEST_ANNOUNCE is emulated the feature bit could be set without
|
||||
* enabled. This happens in the vDPA case.
|
||||
*
|
||||
* Make sure the feature set is not incoherent, as the driver could refuse
|
||||
* to start.
|
||||
*
|
||||
* TODO: QEMU is able to emulate a CVQ just for guest_announce purposes,
|
||||
* helping guest to notify the new location with vDPA devices that does not
|
||||
* support it.
|
||||
*/
|
||||
if (!virtio_has_feature(vdev->backend_features, VIRTIO_NET_F_CTRL_VQ)) {
|
||||
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ANNOUNCE);
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
|
||||
+6
-15
@@ -693,12 +693,12 @@ static const VMStateDescription vmstate_fw_cfg = {
|
||||
}
|
||||
};
|
||||
|
||||
void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
|
||||
FWCfgCallback select_cb,
|
||||
FWCfgWriteCallback write_cb,
|
||||
void *callback_opaque,
|
||||
void *data, size_t len,
|
||||
bool read_only)
|
||||
static void fw_cfg_add_bytes_callback(FWCfgState *s, uint16_t key,
|
||||
FWCfgCallback select_cb,
|
||||
FWCfgWriteCallback write_cb,
|
||||
void *callback_opaque,
|
||||
void *data, size_t len,
|
||||
bool read_only)
|
||||
{
|
||||
int arch = !!(key & FW_CFG_ARCH_LOCAL);
|
||||
|
||||
@@ -741,15 +741,6 @@ void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
|
||||
fw_cfg_add_bytes_callback(s, key, NULL, NULL, NULL, data, len, true);
|
||||
}
|
||||
|
||||
void *fw_cfg_read_bytes_ptr(FWCfgState *s, uint16_t key)
|
||||
{
|
||||
int arch = !!(key & FW_CFG_ARCH_LOCAL);
|
||||
|
||||
key &= FW_CFG_ENTRY_MASK;
|
||||
assert(key < fw_cfg_max_entry(s));
|
||||
return s->entries[arch][key].data;
|
||||
}
|
||||
|
||||
void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value)
|
||||
{
|
||||
size_t sz = strlen(value) + 1;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "hw/pci/pcie_port.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
typedef struct CXLDownStreamPort {
|
||||
typedef struct CXLDownstreamPort {
|
||||
/*< private >*/
|
||||
PCIESlot parent_obj;
|
||||
|
||||
|
||||
@@ -282,9 +282,13 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
|
||||
{
|
||||
PCIBus *bus;
|
||||
for (;;) {
|
||||
int dev_irq = irq_num;
|
||||
bus = pci_get_bus(pci_dev);
|
||||
assert(bus->map_irq);
|
||||
irq_num = bus->map_irq(pci_dev, irq_num);
|
||||
trace_pci_route_irq(dev_irq, DEVICE(pci_dev)->canonical_path, irq_num,
|
||||
pci_bus_is_root(bus) ? "root-complex"
|
||||
: DEVICE(bus->parent_dev)->canonical_path);
|
||||
if (bus->set_irq)
|
||||
break;
|
||||
pci_dev = bus->parent_dev;
|
||||
@@ -1617,8 +1621,12 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
|
||||
PCIBus *bus;
|
||||
|
||||
do {
|
||||
int dev_irq = pin;
|
||||
bus = pci_get_bus(dev);
|
||||
pin = bus->map_irq(dev, pin);
|
||||
trace_pci_route_irq(dev_irq, DEVICE(dev)->canonical_path, pin,
|
||||
pci_bus_is_root(bus) ? "root-complex"
|
||||
: DEVICE(bus->parent_dev)->canonical_path);
|
||||
dev = bus->parent_dev;
|
||||
} while (dev);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user