Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging

virtio,pci: features, cleanups

vdpa:
      shadow vq vlan support
      net migration with cvq
cxl:
     support emulating 4 HDM decoders
     serial number extended capability
virtio:
      hared dma-buf

Fixes, cleanups all over the place.

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

* tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: (53 commits)
  libvhost-user: handle shared_object msg
  vhost-user: add shared_object msg
  hw/display: introduce virtio-dmabuf
  util/uuid: add a hash function
  virtio: remove unused next argument from virtqueue_split_read_next_desc()
  virtio: remove unnecessary thread fence while reading next descriptor
  virtio: use shadow_avail_idx while checking number of heads
  libvhost-user.c: add assertion to vu_message_read_default
  pcie_sriov: unregister_vfs(): fix error path
  hw/i386/pc: improve physical address space bound check for 32-bit x86 systems
  amd_iommu: Fix APIC address check
  vdpa net: follow VirtIO initialization properly at cvq isolation probing
  vdpa net: stop probing if cannot set features
  vdpa net: fix error message setting virtio status
  hw/pci-bridge/cxl-upstream: Add serial number extended capability support
  hw/cxl: Support 4 HDM decoders at all levels of topology
  hw/cxl: Fix and use same calculation for HDM decoder block size everywhere
  hw/cxl: Add utility functions decoder interleave ways and target count.
  hw/cxl: Push cxl_decoder_count_enc() and cxl_decode_ig() into .c
  vdpa net: zero vhost_vdpa iova_tree pointer at cleanup
  ...

Conflicts:
  hw/core/machine.c
  Context conflict with commit 314e0a84cd ("hw/core: remove needless
  includes") because it removed an adjacent #include.
This commit is contained in:
Stefan Hajnoczi
2023-10-05 09:01:01 -04:00
71 changed files with 2025 additions and 450 deletions
+7
View File
@@ -2154,6 +2154,13 @@ T: git https://gitlab.com/cohuck/qemu.git s390-next
T: git https://github.com/borntraeger/qemu.git s390-next
L: qemu-s390x@nongnu.org
virtio-dmabuf
M: Albert Esteve <aesteve@redhat.com>
S: Supported
F: hw/display/virtio-dmabuf.c
F: include/hw/virtio/virtio-dmabuf.h
F: tests/unit/test-virtio-dmabuf.c
virtiofs
M: Stefan Hajnoczi <stefanha@redhat.com>
S: Supported
+57
View File
@@ -1440,6 +1440,18 @@ Front-end message types
query the back-end for its device status as defined in the Virtio
specification.
``VHOST_USER_GET_SHARED_OBJECT``
:id: 41
:equivalent ioctl: N/A
:request payload: ``struct VhostUserShared``
:reply payload: dmabuf fd
When the ``VHOST_USER_PROTOCOL_F_SHARED_OBJECT`` protocol
feature has been successfully negotiated, and the UUID is found
in the exporters cache, this message is submitted by the front-end
to retrieve a given dma-buf fd from a given back-end, determined by
the requested UUID. Back-end will reply passing the fd when the operation
is successful, or no fd otherwise.
Back-end message types
----------------------
@@ -1528,6 +1540,51 @@ is sent by the front-end.
The state.num field is currently reserved and must be set to 0.
``VHOST_USER_BACKEND_SHARED_OBJECT_ADD``
:id: 6
:equivalent ioctl: N/A
:request payload: ``struct VhostUserShared``
:reply payload: N/A
When the ``VHOST_USER_PROTOCOL_F_SHARED_OBJECT`` protocol
feature has been successfully negotiated, this message can be submitted
by the backends to add themselves as exporters to the virtio shared lookup
table. The back-end device gets associated with a UUID in the shared table.
The back-end is responsible of keeping its own table with exported dma-buf fds.
When another back-end tries to import the resource associated with the UUID,
it will send a message to the front-end, which will act as a proxy to the
exporter back-end. If ``VHOST_USER_PROTOCOL_F_REPLY_ACK`` is negotiated, and
the back-end sets the ``VHOST_USER_NEED_REPLY`` flag, the front-end must
respond with zero when operation is successfully completed, or non-zero
otherwise.
``VHOST_USER_BACKEND_SHARED_OBJECT_REMOVE``
:id: 7
:equivalent ioctl: N/A
:request payload: ``struct VhostUserShared``
:reply payload: N/A
When the ``VHOST_USER_PROTOCOL_F_SHARED_OBJECT`` protocol
feature has been successfully negotiated, this message can be submitted
by the backend to remove themselves from to the virtio-dmabuf shared
table API. The shared table will remove the back-end device associated with
the UUID. If ``VHOST_USER_PROTOCOL_F_REPLY_ACK`` is negotiated, and the
back-end sets the ``VHOST_USER_NEED_REPLY`` flag, the front-end must respond
with zero when operation is successfully completed, or non-zero otherwise.
``VHOST_USER_BACKEND_SHARED_OBJECT_LOOKUP``
:id: 8
:equivalent ioctl: N/A
:request payload: ``struct VhostUserShared``
:reply payload: dmabuf fd and ``u64``
When the ``VHOST_USER_PROTOCOL_F_SHARED_OBJECT`` protocol
feature has been successfully negotiated, this message can be submitted
by the backends to retrieve a given dma-buf fd from the virtio-dmabuf
shared table given a UUID. Frontend will reply passing the fd and a zero
when the operation is successful, or non-zero otherwise. Note that if the
operation fails, no fd is sent to the backend.
.. _reply_ack:
VHOST_USER_PROTOCOL_F_REPLY_ACK
-6
View File
@@ -1,12 +1,6 @@
#include "qemu/osdep.h"
#include "hw/i386/pc.h"
#include "hw/i386/acpi-build.h"
void pc_madt_cpu_entry(int uid, const CPUArchIdList *apic_ids,
GArray *entry, bool force_enabled)
{
}
Object *acpi_get_i386_pci_host(void)
{
return NULL;
+9
View File
@@ -32,6 +32,7 @@
#include "qemu/module.h"
#include "qemu/option.h"
#include "sysemu/runstate.h"
#include "trace.h"
struct acpi_table_header {
uint16_t _length; /* our length, not actual part of the hdr */
@@ -688,9 +689,11 @@ void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val)
cur = acpi_gpe_ioport_get_ptr(ar, addr);
if (addr < ar->gpe.len / 2) {
trace_acpi_gpe_sts_ioport_writeb(addr, val);
/* GPE_STS */
*cur = (*cur) & ~val;
} else if (addr < ar->gpe.len) {
trace_acpi_gpe_en_ioport_writeb(addr - (ar->gpe.len / 2), val);
/* GPE_EN */
*cur = val;
} else {
@@ -709,6 +712,12 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
val = *cur;
}
if (addr < ar->gpe.len / 2) {
trace_acpi_gpe_sts_ioport_readb(addr, val);
} else {
trace_acpi_gpe_en_ioport_readb(addr - (ar->gpe.len / 2), val);
}
return val;
}
+3 -6
View File
@@ -1,6 +1,7 @@
#include "qemu/osdep.h"
#include "migration/vmstate.h"
#include "hw/acpi/cpu.h"
#include "hw/core/cpu.h"
#include "qapi/error.h"
#include "qapi/qapi-events-acpi.h"
#include "trace.h"
@@ -338,7 +339,7 @@ const VMStateDescription vmstate_cpu_hotplug = {
#define CPU_FW_EJECT_EVENT "CEJF"
void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
hwaddr io_base,
build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
const char *res_root,
const char *event_handler_method)
{
@@ -353,8 +354,6 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
MachineClass *mc = MACHINE_GET_CLASS(machine);
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
char *cphp_res_path = g_strdup_printf("%s." CPUHP_RES_DEVICE, res_root);
Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, NULL);
AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
cpu_ctrl_dev = aml_device("%s", cphp_res_path);
{
@@ -664,9 +663,7 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
aml_append(dev, method);
/* build _MAT object */
assert(adevc && adevc->madt_cpu);
adevc->madt_cpu(i, arch_ids, madt_buf,
true); /* set enabled flag */
build_madt_cpu(i, arch_ids, madt_buf, true); /* set enabled flag */
aml_append(dev, aml_name_decl("_MAT",
aml_buffer(madt_buf->len, (uint8_t *)madt_buf->data)));
g_array_free(madt_buf, true);
+1
View File
@@ -27,6 +27,7 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "sysemu/numa.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/hmat.h"
/*
+2 -1
View File
@@ -27,7 +27,8 @@
#ifndef HMAT_H
#define HMAT_H
#include "hw/acpi/aml-build.h"
#include "hw/acpi/bios-linker-loader.h"
#include "sysemu/numa.h"
/*
* ACPI 6.3: 5.2.27.3 Memory Proximity Domain Attributes Structure,
+1
View File
@@ -1,6 +1,7 @@
#include "qemu/osdep.h"
#include "hw/acpi/memory_hotplug.h"
#include "hw/mem/pc-dimm.h"
#include "hw/boards.h"
#include "hw/qdev-core.h"
#include "migration/vmstate.h"
#include "trace.h"
-5
View File
@@ -20,7 +20,6 @@
*/
#include "qemu/osdep.h"
#include "hw/i386/pc.h"
#include "hw/irq.h"
#include "hw/isa/apm.h"
#include "hw/i2c/pm_smbus.h"
@@ -43,7 +42,6 @@
#include "hw/acpi/acpi_dev_interface.h"
#include "migration/vmstate.h"
#include "hw/core/cpu.h"
#include "trace.h"
#include "qom/object.h"
#define GPE_BASE 0xafe0
@@ -518,7 +516,6 @@ static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width)
PIIX4PMState *s = opaque;
uint32_t val = acpi_gpe_ioport_readb(&s->ar, addr);
trace_piix4_gpe_readb(addr, width, val);
return val;
}
@@ -527,7 +524,6 @@ static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
{
PIIX4PMState *s = opaque;
trace_piix4_gpe_writeb(addr, width, val);
acpi_gpe_ioport_writeb(&s->ar, addr, val);
acpi_update_sci(&s->ar, s->irq);
}
@@ -654,7 +650,6 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
hc->is_hotpluggable_bus = piix4_is_hotpluggable_bus;
adevc->ospm_status = piix4_ospm_status;
adevc->send_event = piix4_send_gpe;
adevc->madt_cpu = pc_madt_cpu_entry;
}
static const TypeInfo piix4_pm_info = {
+6 -4
View File
@@ -17,6 +17,12 @@ mhp_acpi_clear_remove_evt(uint32_t slot) "slot[0x%"PRIx32"] clear remove event"
mhp_acpi_pc_dimm_deleted(uint32_t slot) "slot[0x%"PRIx32"] pc-dimm deleted"
mhp_acpi_pc_dimm_delete_failed(uint32_t slot) "slot[0x%"PRIx32"] pc-dimm delete failed"
# core.c
acpi_gpe_en_ioport_readb(uint32_t addr, uint8_t val) "addr: 0x%" PRIx32 " ==> 0x%02" PRIx8
acpi_gpe_en_ioport_writeb(uint32_t addr, uint8_t val) "addr: 0x%" PRIx32 " <== 0x%02" PRIx8
acpi_gpe_sts_ioport_readb(uint32_t addr, uint8_t val) "addr: 0x%" PRIx32 " ==> 0x%02" PRIx8
acpi_gpe_sts_ioport_writeb(uint32_t addr, uint8_t val) "addr: 0x%" PRIx32 " <== 0x%02" PRIx8
# cpu.c
cpuhp_acpi_invalid_idx_selected(uint32_t idx) "0x%"PRIx32
cpuhp_acpi_read_flags(uint32_t idx, uint8_t flags) "idx[0x%"PRIx32"] flags: 0x%"PRIx8
@@ -48,10 +54,6 @@ acpi_pci_sel_read(uint32_t val) "%" PRIu32
acpi_pci_ej_write(uint64_t addr, uint64_t data) "0x%" PRIx64 " <== %" PRIu64
acpi_pci_sel_write(uint64_t addr, uint64_t data) "0x%" PRIx64 " <== %" PRIu64
# piix4.c
piix4_gpe_readb(uint64_t addr, unsigned width, uint64_t val) "addr: 0x%" PRIx64 " width: %d ==> 0x%" PRIx64
piix4_gpe_writeb(uint64_t addr, unsigned width, uint64_t val) "addr: 0x%" PRIx64 " width: %d <== 0x%" PRIx64
# tco.c
tco_timer_reload(int ticks, int msec) "ticks=%d (%d ms)"
tco_timer_expired(int timeouts_no, bool strap, bool no_reboot) "timeouts_no=%d no_reboot=%d/%d"
+4 -1
View File
@@ -24,6 +24,7 @@
#include "sysemu/runstate.h"
#include "sysemu/xen.h"
#include "sysemu/qtest.h"
#include "hw/pci/pci_bridge.h"
#include "hw/mem/nvdimm.h"
#include "migration/global_state.h"
#include "exec/confidential-guest-support.h"
@@ -31,7 +32,9 @@
#include "hw/virtio/virtio-net.h"
#include "audio/audio.h"
GlobalProperty hw_compat_8_1[] = {};
GlobalProperty hw_compat_8_1[] = {
{ TYPE_PCI_BRIDGE, "x-pci-express-writeable-slt-bug", "true" },
};
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
GlobalProperty hw_compat_8_0[] = {
+82 -10
View File
@@ -13,6 +13,54 @@
#include "hw/pci/pci.h"
#include "hw/cxl/cxl.h"
/* CXL r3.0 Section 8.2.4.19.1 CXL HDM Decoder Capability Register */
int cxl_decoder_count_enc(int count)
{
switch (count) {
case 1: return 0x0;
case 2: return 0x1;
case 4: return 0x2;
case 6: return 0x3;
case 8: return 0x4;
case 10: return 0x5;
/* Switches and Host Bridges may have more than 10 decoders */
case 12: return 0x6;
case 14: return 0x7;
case 16: return 0x8;
case 20: return 0x9;
case 24: return 0xa;
case 28: return 0xb;
case 32: return 0xc;
}
return 0;
}
int cxl_decoder_count_dec(int enc_cnt)
{
switch (enc_cnt) {
case 0x0: return 1;
case 0x1: return 2;
case 0x2: return 4;
case 0x3: return 6;
case 0x4: return 8;
case 0x5: return 10;
/* Switches and Host Bridges may have more than 10 decoders */
case 0x6: return 12;
case 0x7: return 14;
case 0x8: return 16;
case 0x9: return 20;
case 0xa: return 24;
case 0xb: return 28;
case 0xc: return 32;
}
return 0;
}
hwaddr cxl_decode_ig(int ig)
{
return 1ULL << (ig + 8);
}
static uint64_t cxl_cache_mem_read_reg(void *opaque, hwaddr offset,
unsigned size)
{
@@ -42,6 +90,9 @@ static void dumb_hdm_handler(CXLComponentState *cxl_cstate, hwaddr offset,
switch (offset) {
case A_CXL_HDM_DECODER0_CTRL:
case A_CXL_HDM_DECODER1_CTRL:
case A_CXL_HDM_DECODER2_CTRL:
case A_CXL_HDM_DECODER3_CTRL:
should_commit = FIELD_EX32(value, CXL_HDM_DECODER0_CTRL, COMMIT);
should_uncommit = !should_commit;
break;
@@ -81,7 +132,7 @@ static void cxl_cache_mem_write_reg(void *opaque, hwaddr offset, uint64_t value,
}
if (offset >= A_CXL_HDM_DECODER_CAPABILITY &&
offset <= A_CXL_HDM_DECODER0_TARGET_LIST_HI) {
offset <= A_CXL_HDM_DECODER3_TARGET_LIST_HI) {
dumb_hdm_handler(cxl_cstate, offset, value);
} else {
cregs->cache_mem_registers[offset / sizeof(*cregs->cache_mem_registers)] = value;
@@ -161,7 +212,8 @@ static void ras_init_common(uint32_t *reg_state, uint32_t *write_msk)
static void hdm_init_common(uint32_t *reg_state, uint32_t *write_msk,
enum reg_type type)
{
int decoder_count = 1;
int decoder_count = CXL_HDM_DECODER_COUNT;
int hdm_inc = R_CXL_HDM_DECODER1_BASE_LO - R_CXL_HDM_DECODER0_BASE_LO;
int i;
ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, DECODER_COUNT,
@@ -174,19 +226,21 @@ static void hdm_init_common(uint32_t *reg_state, uint32_t *write_msk,
HDM_DECODER_ENABLE, 0);
write_msk[R_CXL_HDM_DECODER_GLOBAL_CONTROL] = 0x3;
for (i = 0; i < decoder_count; i++) {
write_msk[R_CXL_HDM_DECODER0_BASE_LO + i * 0x20] = 0xf0000000;
write_msk[R_CXL_HDM_DECODER0_BASE_HI + i * 0x20] = 0xffffffff;
write_msk[R_CXL_HDM_DECODER0_SIZE_LO + i * 0x20] = 0xf0000000;
write_msk[R_CXL_HDM_DECODER0_SIZE_HI + i * 0x20] = 0xffffffff;
write_msk[R_CXL_HDM_DECODER0_CTRL + i * 0x20] = 0x13ff;
write_msk[R_CXL_HDM_DECODER0_BASE_LO + i * hdm_inc] = 0xf0000000;
write_msk[R_CXL_HDM_DECODER0_BASE_HI + i * hdm_inc] = 0xffffffff;
write_msk[R_CXL_HDM_DECODER0_SIZE_LO + i * hdm_inc] = 0xf0000000;
write_msk[R_CXL_HDM_DECODER0_SIZE_HI + i * hdm_inc] = 0xffffffff;
write_msk[R_CXL_HDM_DECODER0_CTRL + i * hdm_inc] = 0x13ff;
if (type == CXL2_DEVICE ||
type == CXL2_TYPE3_DEVICE ||
type == CXL2_LOGICAL_DEVICE) {
write_msk[R_CXL_HDM_DECODER0_TARGET_LIST_LO + i * 0x20] = 0xf0000000;
write_msk[R_CXL_HDM_DECODER0_TARGET_LIST_LO + i * hdm_inc] =
0xf0000000;
} else {
write_msk[R_CXL_HDM_DECODER0_TARGET_LIST_LO + i * 0x20] = 0xffffffff;
write_msk[R_CXL_HDM_DECODER0_TARGET_LIST_LO + i * hdm_inc] =
0xffffffff;
}
write_msk[R_CXL_HDM_DECODER0_TARGET_LIST_HI + i * 0x20] = 0xffffffff;
write_msk[R_CXL_HDM_DECODER0_TARGET_LIST_HI + i * hdm_inc] = 0xffffffff;
}
}
@@ -375,6 +429,7 @@ void cxl_component_create_dvsec(CXLComponentState *cxl,
cxl->dvsec_offset += length;
}
/* CXL r3.0 Section 8.2.4.19.7 CXL HDM Decoder n Control Register */
uint8_t cxl_interleave_ways_enc(int iw, Error **errp)
{
switch (iw) {
@@ -392,6 +447,23 @@ uint8_t cxl_interleave_ways_enc(int iw, Error **errp)
}
}
int cxl_interleave_ways_dec(uint8_t iw_enc, Error **errp)
{
switch (iw_enc) {
case 0x0: return 1;
case 0x1: return 2;
case 0x2: return 4;
case 0x3: return 8;
case 0x4: return 16;
case 0x8: return 3;
case 0x9: return 6;
case 0xa: return 12;
default:
error_setg(errp, "Encoded interleave ways: %d not supported", iw_enc);
return 0;
}
}
uint8_t cxl_interleave_granularity_enc(uint64_t gran, Error **errp)
{
switch (gran) {
+46 -21
View File
@@ -97,33 +97,58 @@ void cxl_fmws_link_targets(CXLState *cxl_state, Error **errp)
}
}
/* TODO: support, multiple hdm decoders */
static bool cxl_hdm_find_target(uint32_t *cache_mem, hwaddr addr,
uint8_t *target)
{
uint32_t ctrl;
uint32_t ig_enc;
uint32_t iw_enc;
uint32_t target_idx;
int hdm_inc = R_CXL_HDM_DECODER1_BASE_LO - R_CXL_HDM_DECODER0_BASE_LO;
unsigned int hdm_count;
bool found = false;
int i;
uint32_t cap;
ctrl = cache_mem[R_CXL_HDM_DECODER0_CTRL];
if (!FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, COMMITTED)) {
return false;
cap = ldl_le_p(cache_mem + R_CXL_HDM_DECODER_CAPABILITY);
hdm_count = cxl_decoder_count_dec(FIELD_EX32(cap,
CXL_HDM_DECODER_CAPABILITY,
DECODER_COUNT));
for (i = 0; i < hdm_count; i++) {
uint32_t ctrl, ig_enc, iw_enc, target_idx;
uint32_t low, high;
uint64_t base, size;
low = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_BASE_LO + i * hdm_inc);
high = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_BASE_HI + i * hdm_inc);
base = (low & 0xf0000000) | ((uint64_t)high << 32);
low = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_SIZE_LO + i * hdm_inc);
high = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_SIZE_HI + i * hdm_inc);
size = (low & 0xf0000000) | ((uint64_t)high << 32);
if (addr < base || addr >= base + size) {
continue;
}
ctrl = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_CTRL + i * hdm_inc);
if (!FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, COMMITTED)) {
return false;
}
found = true;
ig_enc = FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, IG);
iw_enc = FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, IW);
target_idx = (addr / cxl_decode_ig(ig_enc)) % (1 << iw_enc);
if (target_idx < 4) {
uint32_t val = ldl_le_p(cache_mem +
R_CXL_HDM_DECODER0_TARGET_LIST_LO +
i * hdm_inc);
*target = extract32(val, target_idx * 8, 8);
} else {
uint32_t val = ldl_le_p(cache_mem +
R_CXL_HDM_DECODER0_TARGET_LIST_HI +
i * hdm_inc);
*target = extract32(val, (target_idx - 4) * 8, 8);
}
break;
}
ig_enc = FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, IG);
iw_enc = FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, IW);
target_idx = (addr / cxl_decode_ig(ig_enc)) % (1 << iw_enc);
if (target_idx < 4) {
*target = extract32(cache_mem[R_CXL_HDM_DECODER0_TARGET_LIST_LO],
target_idx * 8, 8);
} else {
*target = extract32(cache_mem[R_CXL_HDM_DECODER0_TARGET_LIST_HI],
(target_idx - 4) * 8, 8);
}
return true;
return found;
}
static PCIDevice *cxl_cfmws_find_device(CXLFixedWindow *fw, hwaddr addr)
+1
View File
@@ -37,6 +37,7 @@ system_ss.add(when: 'CONFIG_MACFB', if_true: files('macfb.c'))
system_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-fb.c'))
system_ss.add(when: 'CONFIG_VGA', if_true: files('vga.c'))
system_ss.add(when: 'CONFIG_VIRTIO', if_true: files('virtio-dmabuf.c'))
if (config_all_devices.has_key('CONFIG_VGA_CIRRUS') or
config_all_devices.has_key('CONFIG_VGA_PCI') or
+138
View File
@@ -0,0 +1,138 @@
/*
* Virtio Shared dma-buf
*
* Copyright Red Hat, Inc. 2023
*
* Authors:
* Albert Esteve <aesteve@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "hw/virtio/virtio-dmabuf.h"
static GMutex lock;
static GHashTable *resource_uuids;
/*
* uuid_equal_func: wrapper for UUID is_equal function to
* satisfy g_hash_table_new expected parameters signatures.
*/
static int uuid_equal_func(const void *lhv, const void *rhv)
{
return qemu_uuid_is_equal(lhv, rhv);
}
static bool virtio_add_resource(QemuUUID *uuid, VirtioSharedObject *value)
{
bool result = false;
g_mutex_lock(&lock);
if (resource_uuids == NULL) {
resource_uuids = g_hash_table_new_full(qemu_uuid_hash,
uuid_equal_func,
NULL,
g_free);
}
if (g_hash_table_lookup(resource_uuids, uuid) == NULL) {
result = g_hash_table_insert(resource_uuids, uuid, value);
}
g_mutex_unlock(&lock);
return result;
}
bool virtio_add_dmabuf(QemuUUID *uuid, int udmabuf_fd)
{
bool result;
VirtioSharedObject *vso;
if (udmabuf_fd < 0) {
return false;
}
vso = g_new(VirtioSharedObject, 1);
vso->type = TYPE_DMABUF;
vso->value = GINT_TO_POINTER(udmabuf_fd);
result = virtio_add_resource(uuid, vso);
return result;
}
bool virtio_add_vhost_device(QemuUUID *uuid, struct vhost_dev *dev)
{
bool result;
VirtioSharedObject *vso;
if (dev == NULL) {
return false;
}
vso = g_new(VirtioSharedObject, 1);
vso->type = TYPE_VHOST_DEV;
vso->value = dev;
result = virtio_add_resource(uuid, vso);
return result;
}
bool virtio_remove_resource(const QemuUUID *uuid)
{
bool result;
g_mutex_lock(&lock);
result = g_hash_table_remove(resource_uuids, uuid);
g_mutex_unlock(&lock);
return result;
}
static VirtioSharedObject *get_shared_object(const QemuUUID *uuid)
{
gpointer lookup_res = NULL;
g_mutex_lock(&lock);
if (resource_uuids != NULL) {
lookup_res = g_hash_table_lookup(resource_uuids, uuid);
}
g_mutex_unlock(&lock);
return (VirtioSharedObject *) lookup_res;
}
int virtio_lookup_dmabuf(const QemuUUID *uuid)
{
VirtioSharedObject *vso = get_shared_object(uuid);
if (vso == NULL) {
return -1;
}
assert(vso->type == TYPE_DMABUF);
return GPOINTER_TO_INT(vso->value);
}
struct vhost_dev *virtio_lookup_vhost_device(const QemuUUID *uuid)
{
VirtioSharedObject *vso = get_shared_object(uuid);
if (vso == NULL) {
return NULL;
}
assert(vso->type == TYPE_VHOST_DEV);
return (struct vhost_dev *) vso->value;
}
SharedObjectType virtio_object_type(const QemuUUID *uuid)
{
VirtioSharedObject *vso = get_shared_object(uuid);
if (vso == NULL) {
return TYPE_INVALID;
}
return vso->type;
}
void virtio_free_resources(void)
{
g_mutex_lock(&lock);
g_hash_table_destroy(resource_uuids);
/* Reference count shall be 0 after the implicit unref on destroy */
resource_uuids = NULL;
g_mutex_unlock(&lock);
}
+6 -7
View File
@@ -1495,14 +1495,14 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
aml_append(crs,
aml_io(
AML_DECODE16,
ACPI_PORT_SMI_CMD,
ACPI_PORT_SMI_CMD,
pm->fadt.smi_cmd,
pm->fadt.smi_cmd,
1,
2)
);
aml_append(dev, aml_name_decl("_CRS", crs));
aml_append(dev, aml_operation_region("SMIR", AML_SYSTEM_IO,
aml_int(ACPI_PORT_SMI_CMD), 2));
aml_int(pm->fadt.smi_cmd), 2));
field = aml_field("SMIR", AML_BYTE_ACC, AML_NOLOCK,
AML_WRITE_AS_ZEROS);
aml_append(field, aml_named_field("SMIC", 8));
@@ -1549,8 +1549,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
.smi_path = pm->smi_on_cpuhp ? "\\_SB.PCI0.SMI0.SMIC" : NULL,
.fw_unplugs_cpu = pm->smi_on_cpu_unplug,
};
build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,
"\\_SB.PCI0", "\\_GPE._E02");
build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02");
}
if (pcms->memhp_io_base && nr_mem) {
@@ -2547,8 +2547,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
acpi_add_table(table_offsets, tables_blob);
acpi_build_madt(tables_blob, tables->linker, x86ms,
ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
x86ms->oem_table_id);
x86ms->oem_id, x86ms->oem_table_id);
#ifdef CONFIG_ACPI_ERST
{
+2 -3
View File
@@ -94,14 +94,13 @@ build_xrupt_override(GArray *entry, uint8_t src, uint32_t gsi, uint16_t flags)
* 5.2.8 Multiple APIC Description Table
*/
void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
X86MachineState *x86ms, AcpiDeviceIf *adev,
X86MachineState *x86ms,
const char *oem_id, const char *oem_table_id)
{
int i;
bool x2apic_mode = false;
MachineClass *mc = MACHINE_GET_CLASS(x86ms);
const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(x86ms));
AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(adev);
AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = oem_id,
.oem_table_id = oem_table_id };
@@ -111,7 +110,7 @@ void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */
for (i = 0; i < apic_ids->len; i++) {
adevc->madt_cpu(i, apic_ids, table_data, false);
pc_madt_cpu_entry(i, apic_ids, table_data, false);
if (apic_ids->cpus[i].arch_id > 254) {
x2apic_mode = true;
}
+1 -2
View File
@@ -1,7 +1,6 @@
#ifndef HW_I386_ACPI_COMMON_H
#define HW_I386_ACPI_COMMON_H
#include "hw/acpi/acpi_dev_interface.h"
#include "hw/acpi/bios-linker-loader.h"
#include "hw/i386/x86.h"
@@ -9,7 +8,7 @@
#define ACPI_BUILD_IOAPIC_ID 0x0
void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
X86MachineState *x86ms, AcpiDeviceIf *adev,
X86MachineState *x86ms,
const char *oem_id, const char *oem_table_id);
#endif
+1 -2
View File
@@ -214,8 +214,7 @@ static void acpi_build_microvm(AcpiBuildTables *tables,
acpi_add_table(table_offsets, tables_blob);
acpi_build_madt(tables_blob, tables->linker, X86_MACHINE(machine),
ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
x86ms->oem_table_id);
x86ms->oem_id, x86ms->oem_table_id);
#ifdef CONFIG_ACPI_ERST
{
+2 -7
View File
@@ -1246,13 +1246,8 @@ static int amdvi_int_remap_msi(AMDVIState *iommu,
return -AMDVI_IR_ERR;
}
if (origin->address & AMDVI_MSI_ADDR_HI_MASK) {
trace_amdvi_err("MSI address high 32 bits non-zero when "
"Interrupt Remapping enabled.");
return -AMDVI_IR_ERR;
}
if ((origin->address & AMDVI_MSI_ADDR_LO_MASK) != APIC_DEFAULT_ADDRESS) {
if (origin->address < AMDVI_INT_ADDR_FIRST ||
origin->address + sizeof(origin->data) > AMDVI_INT_ADDR_LAST + 1) {
trace_amdvi_err("MSI is not from IOAPIC.");
return -AMDVI_IR_ERR;
}

Some files were not shown because too many files have changed in this diff Show More