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:
Peter Maydell
2023-03-03 13:35:54 +00:00
61 changed files with 357 additions and 396 deletions
+1
View File
@@ -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
-11
View File
@@ -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;
}
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}
+2
View File
@@ -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);
+1 -1
View File
@@ -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
View File
@@ -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);
}
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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++) {
-2
View File
@@ -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);
}
-2
View File
@@ -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
View File
@@ -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
View File
@@ -401,14 +401,13 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
MemoryRegion *mr = &regs->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;
+15
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -15,7 +15,7 @@
#include "hw/pci/pcie_port.h"
#include "qapi/error.h"
typedef struct CXLDownStreamPort {
typedef struct CXLDownstreamPort {
/*< private >*/
PCIESlot parent_obj;
+8
View File
@@ -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